筆者之前在一個項目裡面需要調用SQL查詢分析器,並且通過命令行的形式將執行結果返回。於是筆者就采用了 DOS重定位技術進行解決。現在簡單說明一下如何用VC++來進行實現。
命令行調用SQL詢分析器
isqlw 實用工具(SQL 查詢分析器)使您得以輸入 Transact-SQL 語句、系統存儲過程和腳本文件。通過設置快捷方式或創建批處理文件,可以啟動預配置的 SQL 查詢分析器[12]。isqlw.exe的依賴文件如下表:
表6-1
pfclnt80.dll pfuttl80.dll semsfc.dll sqlgui.dll sqlqry.dll
sqlresld.dll sqlsvc.dll sqlunirl.dll OBJMGR.DLL
目錄Resources
目錄1033
isqlw.rll pfclnt80.rll pfuttl80.rll semsfc.rll
sqlgui.rll sqlqry.rll sqlsvc.rll OBJMGR.RLL
目錄2052
isqlw.rll pfclnt80.rll pfuttl80.rll semsfc.rll
sqlgui.rll sqlqry.rll sqlsvc.rll OBJMGR.RLL
Isqlw運行的語法參數如下:
語法
isqlw
[-?] |
[
[-S server_name[\instance_name]]
[-d database]
[-E] [-U user] [-P password]
[{-i input_file} {-o output_file} [-F {U|A|O}]]
[-f file_list]
[-C configuration_file]
[-D scripts_directory]
[-T template_directory]
]
參數
-?
顯示用法信息。
-S server_name[\instance_name]:指定要連接到的 Microsoft SQL Server 2000 實例。
-d database當啟動 isqlw 時,發出一個 USE database 語句。默認值為用戶的默認數據庫。
-E使用信任連接而不請求密碼。
-U user用戶登錄 ID。登錄 ID 區分大小寫。-P password是登錄密碼。默認設置為 NULL。
-i input_file標識包含一批 SQL 語句或存儲過程的文件。必須同時指定 -i 和 -o 選項。如果指定 -i 和 -o 選項,將執行輸入文件中的查詢,並將結果保存到輸出文件中。在查詢執行過程中不顯示用戶接口。當執行完成後,進程退出。-o output_file標識接收來自 isqlw 的輸出的文件。必須同時指定 –i 和 –o 選項。用法同-i。
-F {U|A|O}是輸入文件和輸出文件的格式。值包括 Unicode、ANSI 和 OEM。如果未指定 -F,則使用自動模式(如果文件標為 Unicode 格式,則以 Unicode 格式打開;否則,以 ANSI 格式打開文件)。
-f file_list將列出的文件裝載到 SQL 查詢分析器中。使用 -f 選項,可以裝載一個或多個文件(文件名以單個空格分開)。如果指定了多個文件,則以相同的連接上下文將這些文件打開。文件名可以包含該文件所駐留的目錄路徑。可以使用通配符,如 C: \*.sql 中的星號 (*)。
-C configuration_file使用配置文件中指定的設置。其它在命令提示下顯式指定的參數將重寫相應配置文件中的設置。
-D scripts_directory重寫在注冊表中或在用
–C 指定的配置文件中指定的默認存儲腳本目錄。該值不保留在注冊表或配置文件中。若要在 SQL 查詢分析器中查看該選項的當前值,請單擊"工具"菜單,然後單擊"選項"命令。
-T template_directory重寫在注冊表中或在用 –C 指定的配置文件中指定的默認模板目錄。該值不保留在注冊表或配置文件中。若要在 SQL 查詢分析器中查看該選項的當前值,請單擊"工具"菜單,然後單擊"選項"命令。ISQLW調用方法使用信任連接調用Isqlw格式如下:
isqlw.exe -S "" -d "master" -E
使用SQL認證連接調用Isqlw格式如下:
isqlw.exe -S "" -d "ii" -U "sa" -P ""
用命令行從後台執行Sql腳本
isqlw.exe -S "" -d "ii" -U "sa" -P "" -i "c:\1.sql" -o "c:\output.txt"
參數i是要執行的sql腳本,參數o是輸出執行結果,有了參數i則o不能省略。
特別注意:參數S是大寫,S後的""表示數據庫服務器為本機,參數E是大寫.
6.3.2 使用DOS重定位技術執行isqlw
將上述在命令行使用isqlw的方法在dos下重定位,具體的代碼如下:
[c++]
CString CSQLDebug::ExecSQL()
{ HANDLE hMutex=NULL;
CString TmpStr;
HANDLE hRead=NULL;
CString StrSQLFile,StrSQLResult,CurrPath;
CurrPath=GetBasePath()+"\\"+GetStudentID();
StrSQLFile=CurrPath+"\\"+GetStudentID()+"_P"+GetID()+".sql";//源代碼的路徑
StrSQLResult=CurrPath+"\\"+GetStudentID()+"_P"+GetID()+".txt";//結果路徑
CString Evn=GetBasePath()+"\\sqlDebug\\isqlw";
SetCurrentDirectory(CurrPath);
SetEnvironment();//設置環境變量
ServerName.TrimLeft(" ");
DataBaseName.TrimLeft(" ");
UserPwd.TrimLeft(" ");
UserName.TrimLeft(" ");
CString StrServerName="\""+ServerName+"\"";
CString StrDataBaseName="\""+DataBaseName+"\"";
CString StrUserName="\""+UserName+"\"";
CString StrUserPwd="\""+UserPwd+"\"";
CString StrInput="\""+StrSQLFile+"\"";
CString StrOutput="\""+StrSQLResult+"\"";
CString command;//,TmpStr;
command="Cmd.exe /C isqlw -S "+StrServerName+" -d "+
StrDataBaseName+" -U "+StrUserName+" -P "+
StrUserPwd+" -i "+StrInput+" -o "+StrOutput;
char *cmd=command.GetBuffer(command.GetLength());
SECURITY_ATTRIBUTES sa;
HANDLE hWrite;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&hRead,&hWrite,&sa,0))
{
AfxMessageBox("創建管道失敗!",MB_OK);
return "";
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hWrite; //把創建進程的標准錯誤輸出重定向到管道輸入
si.hStdOutput = hWrite; //把創建進程的標准輸出重定向到管道輸入
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
if (!CreateProcess(NULL, cmd,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
{
CloseHandle(hWrite);
CloseHandle(hRead);
AfxMessageBox("進程創建失敗!\r請嘗試再次編譯!",MB_OK);
return "";
}
CloseHandle(hWrite);
CloseHandle(hRead);
//將結果讀取出來
CString StrOutPut=ReadOutPutFile(StrSQLResult.GetBuffer(StrSQLResult.GetLength()));
SetSaveOutPut(StrOutPut);
return StrOutPut;
}