[英]PHP pdo_odbc SQL Server Stored Procedure Unexpected Error
I'm having a problem with PHP and a stored procedure in SQL Server 2005. I haven't really touched stored procedures before and haven't used them with php. 我在SQL Server 2005中使用PHP和存储过程时遇到了问题。之前我还没有真正接触过存储过程,也没有在php中使用它们。 I can't retrieve a value from a table that I know is definitely there. 我无法从我肯定存在的表中检索值。 I have a simple login table, what I want the stored procedure to do is to take a username as an input and then output that user's password salt. 我有一个简单的登录表,我希望存储过程要做的是将用户名作为输入,然后输出该用户的密码盐。 I want the stored procedure to use parameterised values to avoid SQL injection. 我希望存储过程使用参数化的值来避免SQL注入。 What happens at the moment is when the php page is run, nothing is returned and the SQL Profiler displays the following error: 目前发生的情况是,当运行php页面时,未返回任何内容,并且SQL Profiler显示以下错误:
User Error Message: Incorrect Syntax near '@Username'.
While this error message should tell me something is wrong, I can't for the life of me see where the incorrect syntax is. 虽然此错误消息应该告诉我出了什么问题,但我终生无法看到错误的语法在哪里。
Copy of the Php: Php副本:
$user = "usercm";
$password ="cmuserpassword";
try{$conn = new PDO("odbc:DRIVER={SQL Server Native Client 10.0};SERVER=TestingServer;DATABASE=TestingDatebase;",$user,$password);}
catch(PDOException $e){echo "oh no";}
$username = "sdct";
$prepusp = $conn->prepare("EXEC uspReturnSalt(?,?)");
$prepusp->bindParam(1, $username, PDO::PARAM_STR);
$prepusp->bindParam(2, $usersalt, PDO::PARAM_STR, 450);
$prepusp->execute();
Copy of the Stored Procedure: 存储过程的副本:
ALTER PROCEDURE [dbo].[uspReturnSalt]
@Username NVARCHAR(100),
@Usersalt NVARCHAR(450) OUTPUT
AS
BEGIN
DECLARE @sqlcmd NVARCHAR(MAX);
DECLARE @params NVARCHAR(MAX);
SET @sqlcmd = N'SELECT @Usersaltone = salt FROM CMUsers WHERE username = @Usernameone';
SET @params = N'@Usernameone NVARCHAR(100), @Usersaltone NVARCHAR(450) OUTPUT';
EXECUTE sp_executesql @sqlcmd, @params, @Usernameone = @Username, @Usersaltone = @Usersalt OUTPUT;
END
To clarify, the server this is on runs Windows 2003 so I cannot use the sqlsrv drivers as they require SQL Server Native Client 2012 which is incompatible. 为了明确起见,该服务器运行Windows 2003,因此我无法使用sqlsrv驱动程序,因为它们需要不兼容的SQL Server Native Client 2012。 It is impossible to upgrade the operating system (server isn't mine) so I can't use any php drivers that require SQL Server Native Client 2012. 无法升级操作系统(服务器不是我的),所以我不能使用任何需要SQL Server Native Client 2012的php驱动程序。
If anyone could help I would be eternally grateful. 如果有人能帮助我,我将永远感激不已。
EDIT1: 编辑1:
Here is the sql profiler messages before and after that error: 这是该错误前后的SQL事件探查器消息:
RPC:Completed | exec [sys].sp_sproc_columns_90 N'uspReturnSalt' ,@ODBCVer=3
RPC:Starting | declare @p1 int
set @p1 =NULL
exec sp_prepare @p1 output,N'@Username nvarchar(100),@P2 text OUTPUT' ,N'EXEC uspReturnSalt(@Username,@P2 OUTPUT)' ,1
select @p1
Exception | Error: 102, Severity: 15, State: 1
User Error Message | Incorrect syntax near '@Username'.
SP:CacheMiss | (@Username nvarchar(100),@P2 text OUTPUT)EXEC uspReturnSalt(@Username,@P2 OUTPUT)
Exception | Error: 8180, Severity: 16, State: 1
User Error Message | Statement(s) could not be prepared
RPC:Completed | declare @p1 int
set @p1=NULL
exec sp_prepare @p1 output, N'@Username nvarchar(100),@P2 text OUTPUT' ,N'EXEC uspReturnSalt(@Username,@P2 OUTPUT)',1
select @p1
$prepusp = $conn->prepare("EXEC uspReturnSalt(?,?)"); $ prepusp = $ conn-> prepare(“ EXEC uspReturnSalt(?,?)”); Needs to be changed to: $prepusp = $conn->prepare("{CALL uspReturnSalt(?,?)}"); 需要更改为:$ prepusp = $ conn-> prepare(“ {CALL uspReturnSalt(?,?)}”));
They are both actually supposed to work. 他们实际上都应该工作。 Even the {} around the EXEC statement doesn't work. 甚至EXEC语句周围的{}也无效。 Only CALL will work. 只有CALL会起作用。
how about changing these lines 如何更改这些行
$prepusp = $conn->prepare("EXEC uspReturnSalt(?,?)");
$prepusp->bindParam(1, $username, PDO::PARAM_STR);
$prepusp->bindParam(2, $usersalt, PDO::PARAM_STR, 450);
$prepusp->execute();
to 至
$prepusp = $conn->prepare("EXEC uspReturnSalt(:username,:usersalt)");
$prepusp->bindParam(":username", $username, PDO::PARAM_STR);
$prepusp->bindParam(":usersalt", $usersalt, PDO::PARAM_STR, 450);
$prepusp->execute();
and then try 然后尝试
Long shot but worth a try, try change 远射但值得一试,尝试改变
ALTER PROCEDURE [dbo].[uspReturnSalt]
@Username NVARCHAR(100),
@Usersalt NVARCHAR(450) OUTPUT
AS
to 至
ALTER PROCEDURE [dbo].[uspReturnSalt]
(
@Username NVARCHAR(100),
@Usersalt NVARCHAR(450) OUTPUT
)
AS
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.