#sql-server #tsql #if-statement
#sql-сервер #tsql #if-statement
Вопрос:
Я пытаюсь сделать что-то вроде:
IF(@@SERVERNAME = 'SERVER1')
BEGIN
USE Appt
END
IF(@@SERVERNAME = 'SERVER2')
BEGIN
USE ApptDEMO
END
На работе наша база данных для производства "Appt"
, но для тестовой среды "ApptDEMO."
Это одно и то же, но они просто называются по-разному.
Он отлично работает в тестовой среде, потому что оба "Appt"
и "ApptDEMO"
существуют там (он просто не используется "Appt"
). Но в рабочей среде он сообщает мне, что «ApptDEMO» не существует.
Я хочу создать сценарий, который мне не нужно создавать x разных сценариев для разных сред. Возможно ли это?
Комментарии:
1. Насколько я знаю, вы не можете сделать это без выполнения динамического SQL из-за того, как процессы SQL ИСПОЛЬЗУЮТ операторы. Операторы USE также ограничены пакетом, в котором они выполняются. Когда вы говорите «в тесте все работает нормально» — что работает нормально в тесте? Сценарий? Что делают ваши скрипты? Рассматривали ли вы возможность использования других функций SQL (возможно, СИНОНИМЫ могут помочь вам здесь?). Просто пытаюсь понять, есть ли лучший способ для вас достичь того, чего вы хотите…
2. Я согласен с @Charleh. Это звучит как яркий пример использования синонимов. msdn.microsoft.com/en-us/library/ms187552.aspx
3. (Я новичок на этом сайте … ха-ха) Спасибо за быстрый ответ всем! Я собираюсь изучить СИНОНИМЫ и посмотреть, поможет ли это мне!
4. Я не совсем понимаю, как это могло бы мне помочь. Я не хочу ничего жестко кодировать… Я просто хочу, чтобы он выбирал правильную базу данных, которую я использую, в зависимости от используемого сервера. Вероятно, я просто неправильно это понимаю.
5. Мой скрипт пытается настроить клиента с учетной записью. Мы должны протестировать все это в тестовой среде, прежде чем мы сможем запустить его в производство. Когда я сказал, что он отлично работает в тестовой среде, я имел в виду, что, поскольку «Appt» и «ApptDEMO» существуют в тестовой среде, он выполняется полностью. Но в рабочей среде существует только «Appt», поэтому, когда он попадает в строку «Use ApptDEMO» в операторе IF, он выдает ошибку.
Ответ №1:
Попробуйте это (с динамическим SQL):
DECLARE @sql nvarchar(4000)
IF (@@SERVERNAME = 'SERVER1')
BEGIN
SET @sql = N'USE Appt'
END
ELSE IF (@@SERVERNAME = 'SERVER2')
BEGIN
SET @sql = N'USE ApptDEMO'
END
IF (@sql != N'')
BEGIN
EXECUTE sp_executesql @sql
END
Комментарии:
1. Это ограничивает использование только для пакета, выполняемого в
sp_executesql
… вам пришлось бы выполнить больше инструкций в этом пакете, чтобы выполнить какую-либо работу. Это бесполезно, если вы не добавите больше операторов в@sql
переменную2. @Charleh: я фокусирую свой скрипт на выборе базы данных. В переменной sql вы можете поместить другие операторы
Ответ №2:
База данных не может быть изменена динамически ( USE [DB]
), кроме как сделать запрос динамическим.
Приведенный ниже код может прояснить ваше понимание.
SELECT DB_NAME();
-- Master --Default Database
SELECT @@SERVERNAME
-- SERVER1
DECLARE @USEDB NVARCHAR(MAX) =
CASE @@SERVERNAME WHEN 'SERVER1' THEN 'USE [Appt];'
WHEN 'SERVER2' THEN 'USE [ApptDEMO];'
END -- Same as IF statement
EXEC(@USEDB) -- The database [Appt] will be changed within this batch, not outside.
SELECT DB_NAME();
-- Master --Default Database
DECLARE @MyQuery VARCHAR(MAX) = 'Select DB_NAME();'
DECLARE @UseDBWithQuery VARCHAR(MAX) = @USEDB @MyQuery
EXEC(@UseDBWithQuery)
-- Appt