2011-10-27 14 views
7

Mam projekt, który może używać SQL Server lub MS Access jako magazyn danych. W jednym SELECT, muszę przeprowadzić operację łączyć na jednej kolumnie i pojedynczej wartości, tak:Funkcja COALESCE, IFNULL lub NZ(), która może być używana w SQL Server i MS Access

SELECT COALESCE([Amount], 0) FROM PaymentsDue; 

chciałbym napisać pojedynczą instrukcję SQL, który będzie wykonywał poprawnie zarówno w SQL Server i MS Access . Wersja SQL Server, która jest bezpośrednio zainteresowana, to 2008, chociaż preferowane byłoby rozwiązanie mające zastosowanie w różnych wersjach.

Wcześniej dzisiaj ktoś był w stanie to show me an SQL trick, który pozwolił mi użyć pojedynczej instrukcji SELECT do efektywnego CAST DATETIME do DATE. Zastanawiam się, czy ktoś ma podobny trik do wykonania operacji COALESCE (np. IFNULL lub NZ) w sposób, który można zastosować do zarówno SQL Server i MS Access?

Odpowiedz

6

to będzie działać, ale to niezgrabne:

SELECT Amount 
FROM PaymentsDue 
WHERE Amount IS NOT NULL 
UNION ALL 
SELECT 0 AS Amount 
FROM PaymentsDue 
WHERE Amount IS NULL 

Oczywiście, jeśli masz więcej niż jedną kolumnę, to dostaje się szybko do opanowania.

+1

Część "Ilość = 0" nie działa w programie Access. Powinna wynosić "0 AS". –

+0

Poszedłem z wariantem tego rozwiązania. Moją natychmiastową potrzebą jest wykonanie 'WSTAWU. . . WYBIERZ. . . "i ja po prostu powtarzamy instrukcję dwa razy, raz dla NULL i raz dla innych wierszy. –

5

Nie sądzę, że jest jakaś składnia, która działa tak samo na obu platformach.

Uwaga Nz() jest dostępna tylko w przypadku korzystania z interfejsu użytkownika Access.

Oto kilka sugestii, które mogą być przekształcone do COALESCE dość łatwo, choć powtarzając kolumny jest ból:

Próbka 1:

SELECT IIF([Amount] IS NULL, 0, [Amount]) FROM PaymentsDue; 

Próbka 2:

SELECT SWITCH([Amount] IS NULL, 0, TRUE, [Amount]) FROM PaymentsDue; 
0

I myślę, że nie chcesz pisać parser, który będzie zarządzać tłumaczeniami między Jet SQL i T-SQL ...

Rozwiązaniem, które opracowaliśmy (tak, mieliśmy podobny problem do rozwiązania) jest zdefiniowanie "pseudo-metajęzyka", którego używamy w składni meta-SQL, i mamy rodzaj tłumacza z tego metajęzyka do Jet-SQL lub T-SQL.

Przykład:

myQuery = "SELECT @[email protected]([Amount], 0) FROM PaymentsDue;" 

myQuery = convertFromMeta(myQuery,"T-SQL") 
will give 
    "SELECT COALESCE([Amount], 0) FROM PaymentsDue;" 

myQuery = convertFromMeta(myQuery,"JET-SQL") 
will give 
    "SELECT NZ([Amount], 0) FROM PaymentsDue;" 

Ta sama strategia może być stosowany do symboli wieloznacznych i ogranicznikami:

myQuery = "SELECT [Amount] FROM PaymentsDue WHERE id_client LIKE @[email protected]@[email protected]@[email protected]" 

myQuery = convertFromMeta(myQuery,"T-SQL") 
will give 
    "SELECT [Amount] FROM PaymentsDue WHERE id_client LIKE 'ABC%'" 

myQuery = convertFromMeta(myQuery,"JET-SQL") 
will give 
    "SELECT [Amount] FROM PaymentsDue WHERE id_client LIKE "ABC%"" 

I konw to nie jest tak ładne, ale to jest dość wydajny i czysty. Głównymi punktami są:

  • Nie tłumaczymy między Jet a T-SQL, ale z "meta-składni". Znacznie ułatwia to zadanie.
  • Należy zachować ostrożność, gdy funkcje nie mają tej samej liczby parametrów lub gdy parametry nie są przekazywane w tej samej kolejności. Nadal można to zrobić ...
  • Nasza metastrypcja opiera się na fakcie, że odpowiednie ciągi znaków (np. "@ MojaWildCard @" lub "@ CarSep @") są specyficzne dla naszej składni i nie mogą być używane jako wartości danych (w przeciwnym razie musielibyśmy zarządzać ryzykiem "meta-wtrysku"! ...)
+0

Masz rację, że nie chcę pisać własnego parsera! Myślałem o napisaniu własnego * generatora *, jednak zgodnie z sugestiami (ale działającymi na obiektach, a nie na łańcuchach). W innej części mojej aplikacji wydaje DDL, aby dodać nowe funkcje do bazy danych, które muszą być specyficzne dla silnika; byłoby to korzystne (i stosunkowo łatwe) do korzystania z generatora. Gdybym to zrobił, mógłbym hermetyzować logikę SELECT w różnych widokach dla każdego silnika. Ale to jest w przyszłości, właśnie teraz szukam szybkiego "triku", aby poradzić sobie z tym konkretnym problemem. –

3

Utwórz niestandardową funkcję publiczną w module.

Dodaj do obsługi błędów itp., Ulepszaj.

Teraz można używać funkcji COALESCE w MS Access i SQL.

Powiązane problemy