【问题标题】:Passing date as input parameter to mssql stored procedure through PHP通过PHP将日期作为输入参数传递给mssql存储过程
【发布时间】:2012-07-26 13:49:26
【问题描述】:

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

//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

【问题讨论】:

  • 我对MS SQL不是很熟悉,但是你为什么使用SQLFLT8作为日期的数据类型?

标签: php sql-server stored-procedures


【解决方案1】:

信不信由你,将 DATETIME 字段设置为 VARCHAR 然后传入日期时间格式 'Y-m-d H:i:s' 是正确的方法。您还只需要确保它后面的字段( @Installed_To_Standards) 在传递时有一个大写的“T”,因为它区分大小写。

【讨论】:

    【解决方案2】:

    我讨厌在 SQL Server 中处理日期对象。我为解决这个问题所做的工作是为存储过程中的每个日期输入设置 2 个参数。

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

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

    这是我用来将 PHP 时间戳转换为 VARCHAR (19) 参数的格式化字符串: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
    

    【讨论】:

    • 好的,我没有权限修改存储过程,我只是定义了存储过程,并且必须传递所需的信息
    【解决方案3】:

    您正在使用 h 的 12 小时格式。您需要 H 以获取 24 小时格式。可能不是您的唯一问题。但它是其中之一。

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

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

    【讨论】:

    • 我尝试了几种不同的输入类型,SQLVARCHAR SQLDATETIME 等。它们似乎都不起作用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-19
    • 2010-10-19
    相关资源
    最近更新 更多