我正在使用PHP PDO和ODBC驱动程序连接到MSSQL数据库。我有一个名为“uspGetLoginUserInformation”的存储过程。我试着像这样称呼它:
$username = 'my@email.com';
$password = 'test';
$stmt = $odbc->prepare("CALL dbo.uspGetLoginUserInformation(:username, :password)");
$stmt->bindParam(':username', $username);
$stmt->bindParam(':password', $password);
$stmt->execute();
我一直收到这个错误:
致命错误:带有消息'SQLSTATE [42000]的未捕获异常'PDOException':语法错误或访问冲突:102 [Microsoft] [SQL Server的ODBC驱动程序11] [SQL Server]'。'附近的语法不正确。 (第28行的C:\ wamp \ www \ plugin.php中的分机号码[102]在ext \ pdo_odbc \ odbc_stmt.c:254)'
有什么想法吗?我知道这是一个语法错误,但即使我删除了“dbo”。我仍然在语法错误'@ P1'附近语法不正确。
谢谢!
答案 0 :(得分:1)
使用了错误的语法。准备线看起来像这样:
$stmt = $odbc->prepare("Exec uspGetLoginUserInformation @Username=:username, @Password=:password");
答案 1 :(得分:1)
我之前尝试使用PDO时遇到类似的错误,并希望将流程记录到某个地方的解决方案,以便任何有相同问题的人都可以找到这个解决方案。
转换旧的sql_srv代码以在PHP中使用PDO。原始代码:
$params = array(array($date, SQLSRV_PARAM_IN),array($location, SQLSRV_PARAM_IN),array(3, SQLSRV_PARAM_IN));
$result = sqlsrv_query($sqldb, "{call Some_Stored_Procedure ( @base_date=?,@location=?,@plusdays=? )}", $params);
新代码V1:
$q = "{call Some_Stored_Procedure ( @base_date=?,@location=?,@plusdays=? )}";
$params = array(array($date, SQLSRV_PARAM_IN),array($location, SQLSRV_PARAM_IN),array(3, SQLSRV_PARAM_IN));
$stmt = $CONN->prepare($q);
$stmt->execute($params);
投掷了:未捕获的异常' PDOException'消息' SQLSTATE [42000]:[Microsoft] [SQL Server的ODBC驱动程序11] [SQL Server]无法找到存储过程' Some_Stored_Procedure'。'
通过在以下位置指定数据库来解决此错误:
$q = "{call Database.dbo.Some_Stored_Procedure ( @base_date=?,@location=?,@plusdays=? )}";
$params = array(array($date, SQLSRV_PARAM_IN),array($location, SQLSRV_PARAM_IN),array(3, SQLSRV_PARAM_IN));
$stmt = $CONN->prepare($q);
$stmt->execute($params);
但是这引入了一个新的错误,这就是这个问题存在的原因:未捕获的异常' PDOException' with message' SQLSTATE [42000]:[Microsoft] [SQL Server的ODBC驱动程序11] [SQL Server]将数据类型nvarchar转换为datetime时出错。'
试图解决这个错误导致许多其他错误(没有一个指向实际问题!),包括作者'致命错误:未捕获的异常' PDOException' with message' SQLSTATE [42000]:[Microsoft] [SQL Server的ODBC驱动程序11] [SQL Server]' @ P1'附近的语法不正确。'
最终解决方案(与作者相同):
$stmt = $CONN->prepare("Exec Database.dbo.Some_Stored_Procedure ?, ?, 3");
$stmt->execute(array($date, $location));
差异(我觉得作者没有压力)是调用存储过程的格式。而不是:
CALL Some_Stored_Procedure(Param1, Param2, ...);
是
EXEC Some_Stored_Procedure Param1, Param2, ...;
使用EXEC而不是CALL(存在一些差异)并且不在参数周围使用括号。