我在处理XMLHttpRequest时遇到问题。基本上,HTML按钮会调用deleteItem函数,然后再调用另一个函数。这两个函数的每一个都使XHR成为php页面,以便从两个不同的数据库表中删除元组。
这是代码(变量重命名为泛型):
JS:
//remove first item from first table
function deleteItem() {
var conn = new XMLHttpRequest();
var query = "DELETE FROM MyTable WHERE ID = " + arrayOfObjects[i][0] + ";";
conn.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
deleteWorkflowProcess(arrayOfObjects[i][1], conn.responseText);
}
}
conn.open("GET","../../db_query/sql.php?q=" + query + "&p=DELETE", true);
conn.send();
}
//remove other items from other table
function deleteWorkflowProcess(s, r) {
var conn = new XMLHttpRequest();
var query = "DELETE FROM MyOtherTable WHERE FOREIGN_KEY = '" + s + "';";
if (r == "Deletion succeeded.") {
conn.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var response = conn.responseText;
alert(response);
window.location.replace("thissamepage.php");
}
}
conn.open("GET","../../db_query/sql.php?q=" + query + "&p=DELETE", true);
conn.send();
} else {
alert(r);
}
}
这是PHP页面,它需要两次调用:
//set up connection
$serverName = "SERVER\MSSQLINSTANCE";
$connectionInfo = array("Database"=>"DATABASE");
if (isset($_REQUEST['q'])) {
//establish connection
$conn = sqlsrv_connect($serverName, $connectionInfo);
if ($conn) {
//delete data
if ($_REQUEST['p'] == "DELETE") {
$result = sqlsrv_query($conn, $_REQUEST['q']);
if ($result) {
echo "Deletion succeeded.";
} else {
echo "Deletion failed: " . explode("]",sqlsrv_errors()[0]['message'])[3];
}
}
//do some other stuff based on 'p' value
//e.g. insert, update, etc.
}
sqlsrv_close($conn);
}
这是我确定的东西:
我的问题是:为什么第一个功能可以正常工作,而第二个功能却不能正常工作?
编辑: $ _REQUEST ['q']等于SQL查询,在这种情况下为“从MyOtherTable中删除,其中FOREIGN_KEY ='asdf';”
$ _ REQUEST ['p']是我正在使用的SQL命令,在本例中为“ DELETE”。
sqlsrv_errors()不返回任何内容,因为它从未被调用。据我所知,查询成功执行了,只是没有任何反应。我怎么知道的:
在Zhorov的建议下,我放入了sqlsrv_rows_affected()来确定正在发生的事情。似乎每次报告的受影响的行数都是相同的,无论有多少行与SQL语句中的条件匹配,或者即使有任何行要受影响。仅在Internet Explorer中会发生此行为。在Chrome中,这两个功能均应正常运行。
主要修改: 看来此问题的范围已更改。通过暂时禁用IE中的缓存,我已经能够按预期运行两个文件,而没有任何错误。我不确定为什么IE决定缓存它,但是现在的问题已经变成该程序在禁用或解决IE中的缓存方面可以做什么?我几乎不能指望每个用户都可以这样做这本身。
答案 0 :(得分:0)
我会建议一些可能对您有所帮助的东西。您的DELETE语句将执行,但不会删除行,因为没有匹配WHERE条件的行。 尚不清楚您的表定义是什么,实际数据是什么(我想'asdf'只是一个例子),但是我有类似的测试用例,这是一个解决方案。
检查由sqlsrv_rows_affected()
执行的最后一条语句修改的行数。
只需在脚本中添加一行:
...
$result = sqlsrv_query($conn, $_REQUEST['q']);
if ($result) {
echo 'Rows affected: '.sqlsrv_rows_affected($result).'</br>';
echo "Deletion succeeded.";
} else {
echo "Deletion failed: " . explode("]",sqlsrv_errors()[0]['message'])[3];
}
...
因此,如果执行该语句时没有错误并且受影响的行为0,则可能的一个原因可能是事实,即FOREIGN_KEY列的类型似乎为varchar / nvarchar / text。 如果FOREIGN_KEY列中的值包含任何特殊字符,则在传递此DELETE语句时必须考虑编码问题。
这也将解释一个事实,第一个功能正常工作,而第二个功能失败。 第一个函数删除基于数字列值的WHERE条件的记录,而第二个函数删除基于文本列值的WHERE条件的记录。
如何测试该语句:
使用SQL Server Management Studio并查看结果和受影响的行。
使用您的代码,只需将INSERT语句放在DELETE语句之前,然后再次检查sqlsrv_rows_affected()
。
...
$sql = "INSERT MyOtherTable (FOREIGN_KEY) VALUES ('asdf');";
$sql = $sql + $_REQUEST['q'];
$result = sqlsrv_query($conn, $sql);
if ($result) {
echo 'Rows affected: '.sqlsrv_rows_affected($result).'</br>';
echo "Deletion succeeded.";
} else {
echo "Deletion failed: " . explode("]",sqlsrv_errors()[0]['message'])[3];
}
...
有关sqlsrv_rows_affected()
的信息可以在here中找到。
更新:
来自php.net的用户信息:
如果sql包含INSERT,UPDATE或DELETE语句,则必须消耗受影响的行数。 sqlsrv_query返回一个SQL游标,如果结果为非false,则必须读取该游标以完成事务。 这对于sqlsrv_execute有效。在这种情况下,还必须使用准备好的语句句柄来读取游标。
...
$result = sqlsrv_query($conn, $_REQUEST['q']);
if ($result) {
while ($row = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)) {
}
echo 'Rows affected: '.sqlsrv_rows_affected($result).'</br>';
echo "Deletion succeeded.";
} else {
echo "Deletion failed: " . explode("]",sqlsrv_errors()[0]['message'])[3];
}
...
另一种解决方案是将SET NOCOUNT ON置于sqlsrv语句以及所有调用的过程,函数和触发器的顶部。
...
$sql = "SET NOCOUNT ON;";
$sql = $sql + $_REQUEST['q'];
$result = sqlsrv_query($conn, $sql);
if ($result) {
echo 'Rows affected: '.sqlsrv_rows_affected($result).'</br>';
echo "Deletion succeeded.";
} else {
echo "Deletion failed: " . explode("]",sqlsrv_errors()[0]['message'])[3];
}
...