亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

sqlsrv_query 是否限制一個查詢中可以執行的語句數?

sqlsrv_query 是否限制一個查詢中可以執行的語句數?

PHP
慕村9548890 2023-04-28 15:16:00
insert我在 PHP循環中生成 SQL語句for。生成的 SQL 字符串是大量單獨的 SQL 語句,如下所示:INSERT INTO tbl VALUES(1,2,3);INSERT INTO tbl VALUES(4,5,6);INSERT INTO tbl VALUES(7,8,9);ETC...然后我執行:$InsertResult = sqlsrv_query($conn, $InsertSQL);問題是只有前 312 條語句被執行,而不是完整的 2082 行(只有 312 行被插入到表中)。當我將$InsertSQL變量輸出到 JavaScript 控制臺,然后在 SSMS 中手動執行它時,它完美地工作并插入了所有 2082 行。只有當我運行$InsertSQL變量時sqlsrv_query它才不會完成。我也沒有收到任何錯誤,并且查詢結果返回 true,如下行所示:if(!$InsertResult) die('Problem with Insert query: ' . $InsertSQL);當我搜索此問題的解決方案時,我看到(盡管 PHP 手冊站點中未提及)sqlsrv_query顯然對變量有字符串字符限制$SQL(大約 65k 個字符)。請在此處查看另一篇 StackOverflow 文章: sqlsrv_query 上的 sql 變量的長度限制?我認為這是問題所在,因此創建了一個較短版本的字符串(通過僅添加我實際想要導入的列值)。然而,這個短得多的版本仍然只插入前 312 行!所以現在看來這與最大字符串長度無關。事實上,如果是的話,我應該只得到大約 250 行(在 250 條語句之后我大約有 65k 個字符)。我也可以insert單獨執行每個語句,但這當然需要更長的時間。在我的測試中,這樣做需要 90 秒左右,而在 SMSS 中手動運行組合語句只需要大約 40 秒。請注意,我還查看了 SQL Server 的批量插入,但是我無法將文件發送到安裝了 SQL Server 的機器(SQL Server 和 Web 服務器位于不同的計算機上)。據我了解,這消除了這種可能性。非常感謝任何幫助,因為我什至無法弄清楚是什么限制了我,更不用說修復它了,我不想一次只執行一行。
查看完整描述

1 回答

?
慕虎7371278

TA貢獻1802條經驗 獲得超4個贊

說明:

提供的解決方案的一部分是以下解釋:

似乎在執行大量 SQL 語句時,Microsoft SQL Server 可能會在執行批處理中的所有語句之前停止處理該批處理。處理批處理的結果時,SQL Server 使用批處理創建的結果集填充連接的輸出緩沖區。這些結果集必須由客戶端應用程序處理。如果您正在執行具有多個結果集的大型批處理,SQL Server 會填充該輸出緩沖區,直到它達到內部限制并且無法繼續處理更多結果集。那時,控制權返回給客戶端。此行為是設計使然??蛻舳藨贸绦驊⑿滤写幚淼慕Y果集。一旦所有掛起的結果集都被客戶端使用,SQL Server 就會完成批處理的執行??蛻舳藨贸绦蚩梢哉{用 sqlsrv_next_result() 直到它返回 NULL。

因此,我認為 SQL 語句的長度沒有限制,只有 PHP 字符串變量($InsertSQL在您的情況下)的大小被限制為允許的最大 PHP 內存限制。這種意外行為的實際原因是,對于SET NOCOUNT OFF(默認情況下)和大量的單個INSERT語句,SQL Server 將受影響的行數作為結果集返回(例如(1 row affected))。

解決方案:

我能夠重現此問題(使用 SQL Server 2012、PHP 7.1.12 和適用于 SQL Server 4.3.0+9904 的 PHP 驅動程序)并且您可以使用以下選項來解決此問題:

  • 使用 刷新掛起的結果集sqlsrv_next_result()。

  • 在復雜的 T-SQL 語句中作為第一行執行SET NOCOUNT ON,以停止 SQL Server 將受影響的行數作為結果集返回。

  • 使用參數化語句使用sqlsrv_prepare()\sqlsrv_execute()

桌子:

CREATE?TABLE?MyTable?(
????Column1?int,
????Column2?int,
????Column3?int)

一個復雜的語句(使用sqlsrv_query()and?sqlsrv_next_result()):

<?php?


// Connection info

$server = 'server\instance';

$database = 'database';

$username = 'username';

$password = 'password';

$cinfo = array(

? ? "Database" => $database,

? ? "UID" => $username,

? ? "PWD" => $password

);


// Statement with sqlsrv_query

$sql = "";

for ($i = 1; $i <= 1000; $i++) {

? ? $sql .= "INSERT INTO MyTable (Column1, Column2, Column3) VALUES (".$i.", 0, 0);";

}

$stmt = sqlsrv_query($con, $sql);

if ($stmt === false) {

? ? echo "Error (sqlsrv_query): ".print_r(sqlsrv_errors(), true);

? ? exit;

}


// Clean the buffer

while (sqlsrv_next_result($stmt) != null){};


// End

sqlsrv_free_stmt($stmt);

sqlsrv_close($con);

echo "OK";

?>

一個復雜的語句(使用sqlsrv_query()and SET NOCOUNT ON):


<?php?


// Connection info

$server = 'server\instance';

$database = 'database';

$username = 'username';

$password = 'password';

$cinfo = array(

? ? "Database" => $database,

? ? "UID" => $username,

? ? "PWD" => $password

);


// Connection

$con = sqlsrv_connect($server, $cinfo);

if ($con === false) {

? ? echo "Error (sqlsrv_connect): ".print_r(sqlsrv_errors(), true);

? ? exit;

}


// Statement with sqlsrv_query

$sql = "SET NOCOUNT ON;";

for ($i = 1; $i <= 1000; $i++) {

? ? $sql .= "INSERT INTO MyTable (Column1, Column2, Column3) VALUES (".$i.", 0, 0);";

}

$stmt = sqlsrv_query($con, $sql);

if ($stmt === false) {

? ? echo "Error (sqlsrv_query): ".print_r(sqlsrv_errors(), true);

? ? exit;

}


// End

sqlsrv_free_stmt($stmt);

sqlsrv_close($con);

echo "OK";

?>

參數化語句(使用sqlsrv_prepare()and sqlsrv_execute()):


<?php?


// Connection info

$server = 'server\instance';

$database = 'database';

$username = 'username';

$password = 'password';

$cinfo = array(

? ? "Database" => $database,

? ? "UID" => $username,

? ? "PWD" => $password

);


// Connection

$con = sqlsrv_connect($server, $cinfo);

if ($con === false) {

? ? echo "Error (sqlsrv_connect): ".print_r(sqlsrv_errors(), true);

? ? exit;

}


$sql = "INSERT INTO MyTable (Column1, Column2, Column3) VALUES (?, ?, ?);";

$value1 = 0;??

$value2 = 0;??

$value3 = 0;??

$params = array(&$value1, &$value2, &$value3);

$stmt = sqlsrv_prepare($con, $sql, $params);

if ($stmt === false ) {

? ? echo "Error (sqlsrv_prepare): ".print_r(sqlsrv_errors(), true);

? ? exit;

}

for ($i = 1; $i <= 1000; $i++) {

? ? $value1 = $i;??

? ? $value2 = 0;??

? ? $value3 = 0;??

? ? $result = sqlsrv_execute($stmt);

? ? if ($result === false) {

? ? ? ? echo "Error (sqlsrv_execute): ".print_r(sqlsrv_errors(), true);

? ? ? ? exit;

? ? }

}


// End

sqlsrv_free_stmt($stmt);

sqlsrv_close($con);

echo "OK";

?>



查看完整回答
反對 回復 2023-04-28
  • 1 回答
  • 0 關注
  • 185 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號