2013-06-26 84 views
0

我通過批處理文件自動執行各種EXE,包括調用現有的批處理文件,然後通過OSQL.exe執行各種TSQL語句。從批處理文件調用的批處理文件中調用OSQL中的TSQL語句失敗

現有的批處理文件正常工作。但是,當我的批處理文件調用時,調用osql.exe失敗,導致批處理文件退出。

:check_user_privs 

%OSQLPATH% %CONNECTSTRING% -S "%SERVER_INSTANCE%" -d "%DBNAME%" -Q "DECLARE @userName varchar(100) ; set @userName = user_name() ; IF IS_SRVROLEMEMBER ('sysadmin') != 1 RAISERROR ('This user ''%s'' is not a member of the ''sysadmin'' group.' , 16 , 127 , @userName)" > /nul 
if errorlevel 1 (
    echo ** ERROR - The user is NOT a sysadmin member on "%SERVER_INSTANCE%" - Exiting ** 1 
    echo. 
    pause 
    exit 
) 

不用說,發生錯誤。隨着ECHO ON,即第一行變成了:

"C:\Program Files\Microsoft SQL Server\100\Tools\Binn\OSQL.EXE" -U"ADMIN" -P"PASSWORD" -S "SQL_SRVR10" -d "DB01" -Q "DECLARE @userName varchar(100) ; set @userName = user_name() ; IF IS_SRVROLEMEMBER ('sysadmin') != 1 RAISERROR ('This user ''ADMIN'' is not a member of the ''sysadmin'' group.' , 16 , 127 , @userName)" > /nul 

此行是相同的,當我直接在命令行或從我自己的批處理文件調用腳本。

我手動捕獲了從批處理文件調用此批處理文件時設置的環境變量。然後我在命令行手動設置它們,然後手動運行該批處理文件。沒有repro。

我改變了TSQL語句,只是輸出函數IS_SRVROLEMEMBER()的返回值。無論從我的腳本和命令行調用,輸出是相同的 - 「1」:

"C:\Program Files\Microsoft SQL Server\100\Tools\Binn\OSQL.EXE" -U"ADMIN" -P"PASSWORD" -S "SQL_SRVR10" -d "DB01" -Q "SELECT IS_SRVROLEMEMBER ('sysadmin')" 

回答

1

那麼,我花了一些時間在這個,我注意到,如果我使用CMD.EXE/C或START/B/WAIT來調用其他腳本沒有發生錯誤。所以這肯定是關於導致問題的CMD.EXE過程的狀態。

另外,我決定將ECHO的每一行都寫入一個文本文件。而且我注意到,有一個細微的差別:

ECHO "C:\Program Files\Microsoft SQL Server\100\Tools\Binn\OSQL.EXE" -U"ADMIN" -P"PASSWORD" -S "SQL_SRVR10" -d "DB01" -Q "DECLARE @userName varchar(100) ; set @userName = user_name() ; IF IS_SRVROLEMEMBER ('sysadmin') != 1 RAISERROR ('This user ''ADMIN'' is not a member of the ''sysadmin'' group.' , 16 , 127 , @userName)" > out.txt 

當你看out.txt,它包含:

"C:\Program Files\Microsoft SQL Server\100\Tools\Binn\OSQL.EXE" -U"ADMIN" -P"PASSWORD" -S "SQL_SRVR10" -d "DB01" -Q "DECLARE @userName varchar(100) ; set @userName = user_name() ; IF IS_SRVROLEMEMBER ('sysadmin') = 1 RAISERROR ('This user ''ADMIN'' is not a member of the ''sysadmin'' group.' , 16 , 127 , @userName)" 

不同的是,驚歎號字符已經消失(!)。這就解釋了爲什麼比較總是評估爲錯誤,因爲比較與你所期望的完全相反。

我最終發現所發生的事情是調用該腳本的CMD.EXE當前處於延遲環境變量擴展模式,這是由於先前執行了SETLOCAL ENABLEDELAYEDEXPANSION。當CMD.EXE處理該行時,!字符標誌着擴展的開始,所以它會自動將其刪除。但是,下一個字符是等號字符(=),這是環境變量中不允許的,所以處理立即取消變量擴展,而是處理該字符。所以只有=字符被設置爲OSQL.EXE的參數。

正確的解決方案是在調用腳本之前立即執行SETLOCAL DISABLEDELAYEDEXPANSION,然後執行ENDLOCAL。

+0

我認爲你是對的'延遲擴展'。總是一個好主意,沒有它的工作,因爲副作用,我這樣做 – Endoro

+0

但它是*所以*有用!:-) –

0

我會改變EXITEXIT /B

EXIT終止CMD會議。

exit /b optionalerrorlevelnumber終止當前批處理,可選地返回一個錯誤級別。

+0

彼得 - 你是對的,當錯誤發生時,它會導致整個過程。一個腳本我沒有任何直接的控制 –

1

另外,在運行osql/sqlcmd的批處理中,您可能會遇到使用「LIKE'%mytext%'」語法的問題,因爲您需要在這些討厭的百分號上加倍! 但是,當您在命令提示符下測試它時,它當然會起作用。 我花了大約一個小時試圖調試今天早些時候。 爲什麼我沒有立即看到並理解這個問題? 不幸的是,我的記憶越來越像我媽媽的每一天...老年癡呆症在家庭中運行;-(

相關問題