Как я могу использовать транзакции «Use [database]» в операторах IF в SQL?

#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