2013-11-20 1 views
0

У меня возникают проблемы с использованием USE Database; GO, когда оператор находится в инструкции if..else. Я предполагаю, что USE Database; GO должен был использоваться в начале скрипта или SQL-оператора.SQL Server: проблема с приоритетом базы данных USE

Возможно, кто-то может помочь мне придумать другой способ приблизиться к этому, что я пытаюсь сделать, проверить, существует ли конкретная база данных, если она удаляет определенный пользовательский доступ из этой конкретной базы данных. То, как я думал сделать это следующим образом ...

IF EXISTS(select * from sys.databases where name='MyDB') 
BEGIN 
    USE MyDB 
    GO 
    DROP USER [tester] 
    . 
    . 
    . 
END 
ELSE 
PRINT 'MyDB database is not available' 

Я рубил SQL скрипта для уменьшенной версии, так что я не загромождать этот пост так быть в курсе есть какая-то другая логика, которая была оставлены после DROP USER

Редакции: Я пробовал различные способы, чтобы проверить, существует ли дб, так что каждый знает пробовал

if db_id('MyDB') is not null 
or 
if object_id('MyDB', 'U') 

Но, это всегда идет непосредственно use MyDb первых и I не знаю, почему и как его обойти.

+3

GO [не является оператором T-SQL] (http://technet.microsoft.com/en-us/library/ms188037.aspx). Это всего лишь команда утилиты front-end, которую вы используете, чтобы отправить пакет заявлений, которые вы ввели до этого момента. Вот почему он ломается, если он находится между BEGIN и END - он заканчивает партию в середине блока. –

+0

@MattGibson Я вынул Go, добавил точку с запятой сразу после 'MyDB', и это не сработало. Вот почему я перешел на переполнение стека – Abuelo

+0

Точно, что вы испытываете? Возвращает ли запрос EXISTS() значение true? Что означает «всегда идет прямо на использование MyDb»? – Charleh

ответ

1

Как отмечено в комментариях, вы не можете поставить GO в середине группы операторов SQL, зависящих друг от друга, потому что:

  1. GO указывает конец одного скомпилированного пакета и начало следующего. Большинство контекстов операторов (например, IF..ELSE) не могут охватывать GO. И,

  2. GO не является даже статусом SQL, это команда Management Studio/SQLCMD, поэтому она не будет распознаваться нигде.

Ваша ситуация является общей потребностью, но нет ни одного решения. Для конкретного случая, что вы перечисляете, используя динамический SQL, вероятно, лучший подход:

IF EXISTS(select * from sys.databases where name='MyDB') 
BEGIN 
    EXEC(' 
    USE MyDB 
    EXEC('' 
     DROP USER [tester] 
     . 
     . 
     . 
    '') 
    ') 
END 
ELSE 
PRINT 'MyDB database is not available' 

Это использует тот факт, что динамический SQL exections каждый составляет свою собственную партию как к substitue для GO сек эффекта (начиная новую партию) и изолировать своеобразные взаимодействия USE с компилятором. Конечно, это очень глупо, из-за необходимости «обернуть» вещи после команд USE..GO.

Обратите также внимание на то, что из-за этой двойной обертки любые строки внутри нее должны быть в четыре раза.

+0

Я собираюсь попробовать это, и я обновлю вас. Спасибо, что нашли время, чтобы дать мне голову. – Abuelo

+0

Это сработало! Большое спасибо. Я изменяю свой sql-скрипт, как вы рекомендовали, потому что я не хочу снова видеть эту проблему! – Abuelo

1

Следующие работы ОК для меня (дает все ожидаемые результаты, я также тестировал некоторые операторы выбора после USE, которые отлично работали при обнаружении БД и выдавали ошибку, если БД была вне области видимости)

USE master 
IF EXISTS(select * from sys.databases where name='SomeDatabase') BEGIN 
    USE SomeDatabase 
    print 'Database available' 
END ELSE 
PRINT 'Database is not available' 

Не могли бы вы объяснить, что вы ожидаете и что видите?

Update:

Это также работает отлично:

USE master 
IF EXISTS(select * from sys.databases where name='SomeDatabase') BEGIN 
    USE SomeDatabase 
    print 'Database available' 
    print 'more stuff' 
    print 'even more stuff' 

END ELSE 
PRINT 'Database is not available' 

Однако:

USE master 
IF EXISTS(select * from sys.databases where name='SomeDatabase') BEGIN 
    USE SomeDatabase 
    print 'Database available' 
    print 'more stuff' 
    print 'even more stuff' 

END ELSE 
PRINT 'Database is not available' 
print 'something else when the db is unavail' -- This line will always print regardless 

Обновление: Я также могу это сделать (FYI Я бегу это в 2008 Management Studio)

USE master 
IF EXISTS(select * from sys.databases where name='JMCExpenseService') 
BEGIN 
    USE SomeDatabase  
    select * from SomeTableInSomeDatabase 

    USE AnotherDatabase 
    SELECT * FROM TableInAnotherDatabase  

    USE SomeDatabase  
    select * from SomeOtherTableInSomeDatabase 

END 
ELSE 
PRINT 'MyDB database is not available' 

Я получаю 3 набора результатов с ожидаемыми данными - не уверен, работает ли это в 2005 году, но я не понимаю, почему нет. Как вы выполняете свой запрос?

Edit:

Я вижу, мой вопрос - это умирает, если БД не существует, я использовал USE SomeDatabase2, чтобы проверить его, и так случилось, что у меня на самом деле есть БД называется это. Это полностью задыхается, если БД на самом деле не существует! Я полагаю, что динамический SQL - единственный способ сделать это (я ненавижу динамический SQL)

+0

Простите меня, если я не буду ясен и благодарю вас за ответ. Я мог бы выполнить то, что вы ответили прекрасно, но проблема в том, что у вас есть несколько строк для печати, он жалуется на то, что не нашел. Попробуйте добавить еще один оператор печати, и вы увидите, что я говорю о – Abuelo

+0

Не уверен, о чем вы говорите - я могу печатать столько раз, сколько хочу, без проблем. Вы имеете в виду последнее заявление печати? Я вижу, что это проблема, поскольку она не заключена в блок BEGIN/END, поэтому любые последующие операторы печати всегда будут выполняться, так как они находятся вне любых блоков потока программы. – Charleh

+0

Проблема заключается в том, что команда 'USE' не выполняется, пока * после того, как * скомпилирована пакет sql, который он находится. Таким образом, любые заявления после него в той же партии все еще будут скомпилированы против БД, в котором вы были * до того, как был выполнен «USE», что приводит к появлению странных ошибок. – RBarryYoung

Смежные вопросы