Функция COALESCE, IFNULL или NZ (), которую можно использовать в SQL Server и MS Access - PullRequest
9 голосов
/ 27 октября 2011

У меня есть проект, который может использовать SQL Server или MS Access в качестве хранилища данных. В одном операторе SELECT я должен выполнить операцию COALESCE для одного столбца и одного значения, например:

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

Я хотел бы написать одну инструкцию SQL, которая будет правильно выполняться как в SQL Server, так и в MS Access. Версия SQL Server, которая представляет непосредственный интерес, - это 2008 год, хотя было бы предпочтительным решение, применимое к различным версиям.

Ранее сегодня кто-то смог показать мне трюк SQL , который позволил мне использовать один оператор SELECT для эффективного CAST DATETIME to DATE. Мне было интересно, есть ли у кого-нибудь подобный прием для выполнения COALESCE (например, IFNULL или NZ) способом, который можно применить к и SQL Server и MS Access?

Ответы [ 4 ]

7 голосов
/ 27 октября 2011

Я не думаю, что существует какой-либо синтаксис, который функционирует одинаково на обеих платформах.

Примечание Nz() доступно только при использовании пользовательского интерфейса Access.

Вот несколько советов, которые довольно легко можно преобразовать в COALESCE, хотя повторение столбца затруднительно:

Образец 1:

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

Образец 2:

SELECT SWITCH([Amount] IS NULL, 0, TRUE, [Amount]) FROM PaymentsDue;
6 голосов
/ 27 октября 2011

Это будет работать, но неуклюже:

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

Очевидно, что если у вас есть более одного столбца, это становится быстро неуправляемым.

4 голосов
/ 18 августа 2012

Создание пользовательской общедоступной функции в модуле.

Public Function COALESCE(InputValue, ValueIfNull)
   COALESCE = nz(InputValue, ValueIfNull)
End Function

Добавляйте обработку ошибок и т. Д., Вносите улучшения.

Теперь вы сможете использовать функцию COALESCE в MS Access и SQL.

0 голосов
/ 28 октября 2011

И я думаю, вы не хотите писать парсер, который будет управлять переводами между Jet SQL и T-SQL ...

Решение, которое мы разработали (да, у нас была похожая проблема, которую нужно решить)состоит в том, чтобы определить некоторый «псевдо-метаязык», который мы используем в нашем синтаксисе мета-SQL, и у нас есть своего рода переводчик с этого мета-языка в Jet SQL или T-SQL.

Пример:

myQuery = "SELECT @MyCoalesceFunction@([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;"

Та же стратегия может быть использована для подстановочных знаков и разделителей:

myQuery = "SELECT [Amount] FROM PaymentsDue WHERE id_client LIKE @CarSep@ABC@MyWildCard@@CarSep@"

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%""

Я знаю, что это не так хорошо, но это довольно эффективно ичистый.Основные моменты:

  • Мы не переводим между Jet и T-SQL, а используем мета-синтаксис.Это намного упрощает
  • Следует быть очень осторожным, когда функции не имеют одинаковое количество параметров или когда параметры не передаются в одном и том же порядке.Это все еще можно сделать ...
  • Наш метасинтаксис основан на том факте, что соответствующие строки (например, '@ MyWildCard @' или '@ CarSep @') являются специфическими для нашего синтаксиса и не могут использоватьсяв качестве значений данных (в противном случае нам пришлось бы управлять некоторыми рисками мета-инъекций! ...)
...