通过PHP将日期作为输入参数传递给mssql存储过程


Passing date as input parameter to mssql stored procedure through PHP

我正在尝试运行一个mssql存储过程,该过程传递一些用户输入的数据。我直接运行存储过程,它运行得很好,但当我尝试使用附加的代码运行它时,我没有得到任何错误,也没有任何更新。我认为这与传入的日期有关。数据库中的日期字段定义为"datetime"。它可能是其他东西,但在该系统上以相同方式运行的其他存储过程运行良好。

//initiate function
    $proc = mssql_init('usp_Update_Certificate_Customer_Details', $msdb); 
    //define parameters
    $telId = $_POST['telId'];
    $certNumber = $_POST['certNumber'];
    $custTel = $_POST['main_tel'];
    $instRef = $_POST['install_ref'];
    //$commDate = $_POST['comm_date'];
    $standards = $_POST['standards'];
    $commDate = date('Y-m-d h:i:s');
    echo 'telid: '.$telId.' certNumber: '.$certNumber.' custTel: '.$custTel.' instRef: '.$instRef.' commDate: '.$commDate.' standards: '.$standards;
    mssql_bind($proc, '@Telephone_ID', $telId, SQLINT4, false, false, 10);
    mssql_bind($proc, '@Certificate_Number', $certNumber, SQLINT4, false, false, 10);
    mssql_bind($proc, '@Customer_Telephone', $custTel, SQLVARCHAR, false, false, 10);
    mssql_bind($proc, '@Installers_Reference', $instRef, SQLVARCHAR, false, false, 10);
    mssql_bind($proc, '@Commisioned_Date', $commDate, SQLDATETIME, false, false, 10);
    mssql_bind($proc, '@Installed_to_Standards', $standards, SQLVARCHAR, false, false, 10);
    //Execute Procedure 
    $result = mssql_execute($proc); 
    //Free Memory 
    mssql_free_statement($proc); 

当我如上所述运行并将字段设置为"SQLDATETIME"时,我会得到一个php警告

    Warning: mssql_bind() expects parameter 4 to be long, string given

如果我在字段设置为"SQLVARCHAR"的情况下运行它,我不会得到错误,但数据库中不会发生更新

我已经粘贴在下面运行的存储过程中:

    SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:        Phil Yeomn
-- Create date: 19-04-2008
-- Description:   Update Customer Details
-- =============================================
ALTER PROCEDURE [dbo].[usp_Update_Certificate_Customer_Details](
@Telephone_ID INT,
@Certificate_Number Int,
@Customer_Telephone Varchar(50),
@Installers_Reference Varchar(50),
@Commisioned_Date Datetime,
@Installed_To_Standards Varchar(50)
)

AS
BEGIN
SET NOCOUNT ON;

IF @Telephone_ID <> 0 AND @Customer_Telephone IS NULL
BEGIN
      DELETE FROM ssaib.dbo.Telephone_T
      WHERE Telephone_ID = @Telephone_ID

      SET @Telephone_ID = NULL
END

IF @Telephone_ID = 0 AND @Customer_Telephone IS NOT NULL
BEGIN
INSERT INTO       ssaib.dbo.Telephone_T (Telephone_Number_VC, Last_Update_DT)
VALUES               (@Customer_Telephone, GETDATE())

SET @Telephone_ID = SCOPE_IDENTITY()
END

IF @Telephone_ID = 0
BEGIN
SET @Telephone_ID = NULL
END

UPDATE      ssaib.dbo.Certificate_Returns_T
SET         Customer_Telephone_ID = @Telephone_ID,
            Installers_Reference_VC = @Installers_Reference,
            Commisioned_Date_DT = @Commisioned_Date,
            Installed_To_Standards_VC = @Installed_To_Standards
WHERE  (Certificate_Return_ID = @Certificate_Number)


END

我在下面粘贴了完整的错误,第一行是传递到存储过程中的值,只是显示为一个字符串,以检查它们是否都在那里。

telid: 61529 certNumber: 1262789 custTel: 01423 734002 instRef: /3548 commDate: 2012-05-05 00:00:00 standards: PD 6662 and DD 243
Warning: mssql_bind() expects parameter 4 to be long, string given in /home/ssaibuk/public_html/common/modules/supplier/certificates-direct.php on line 111
Warning: mssql_execute() [function.mssql-execute]: message: Procedure or function 'usp_Update_Certificate_Customer_Details' expects parameter '@Commisioned_Date', which was not supplied. (severity 16) in /home/ssaibuk/public_html/common/modules/supplier/certificates-direct.php on line 116
Warning: mssql_execute() [function.mssql-execute]: General SQL Server error: Check messages from the SQL Server (severity 16) in /home/ssaibuk/public_html/common/modules/supplier/certificates-direct.php on line 116
Warning: mssql_execute() [function.mssql-execute]: stored procedure execution failed in /home/ssaibuk/public_html/common/modules/supplier/certificates-direct.php on line 116
信不信由你,将DATETIME字段设置为VARCHAR,然后传递日期时间格式"Y-m-d H:i:s"是正确的方法(@Installed_To_Standards)在通过时有一个大写"T",因为它区分大小写。

我讨厌在SQL Server中处理日期对象。为了解决这个问题,我在存储过程中为每个日期输入了2个参数。

基本上,一个是VARCHAR(19),只是一个日期字符串。另一个是一个实际的DATETIME对象,默认情况下设置为NULL。

我检查了一下DATETIME对象是否为NULL;如果是,我将VARCHAR(19)参数转换为DATETIME对象。

这是我用来将PHP时间戳转换为VARCHAR(19)param:date("Y-m-d H:i:s",$timestamp); 的格式化字符串的方法

以下是如何在存储过程中将VARCHAR(19)转换为DATETIME的方法:SET @dateObject = CONVERT(VARCHAR(19),@dateString,120)

以下是存储过程示例:

CREATE PROCEDURE [dbo].[WorkingWithDateObjects] 
-- Add the parameters for the stored procedure here
@dateString [varchar] (19) = null, -- ex: '2009-07-01 00:00:00.000'
@dateObject [datetime] = null -- computed in sp from @dateString
AS
BEGIN
SET NOCOUNT ON;
SET @dateObject = CONVERT(VARCHAR(19),@dateString,120)
    SELECT *
    FROM SomeTable
    WHERE DateField >= @dateObject
  END

您使用的是h的12小时格式。24小时格式需要H。可能不是您唯一的问题。但这是其中之一。

$commDate = date('Y-m-d H:i:s');

我认为根本问题是使用SQLFLT8作为日期参数类型。它应该反映datetime数据。