【问题标题】:PHP with MSSQL Insert NULL errorPHP与MSSQL插入NULL错误
【发布时间】:2012-04-25 15:23:26
【问题描述】:

我正在尝试将 PHP 与 Microsoft SQL Server 2008 R2 一起使用,这让我想死。我有一个存储过程,可以通过我在 Mac 上的终端中运行的 FreeTDS 完美运行,在 Visual Studio 中完美运行,并通过 FrontPage 服务器上的 ASP.NET 完美运行。然而,它在 Ubuntu Web 服务器上通过 PHP 5.3.2 失败了。在这个过程中,我设置了一些临时表,并从一个巨大的表中插入到它们中,该表总是到处都包含一些空值。我得到的错误是

Cannot insert the value NULL into column 'Notes', table 'tempdb.dbo.#termtable1__00000000BE0B'; column does not allow nulls. INSERT fails.

只有十亿多下划线。有人将此作为错误here 发布,但并没有引起太多关注。我最好的尝试是在每个临时表的每一列上指定一个 NULL 约束,但这没有帮助。也试过SET ANSI_NULLS ON。就补丁和驱动程序而言,我没有太多访问这些服务器的权限,我也没有太多访问权限的人。我不认为他们会想要做太多的事情来帮助我,但如果有人有一个非常好的想法,我会尽力完成它。哦,而且,应该注意的是,SquirrelSQL 中的相同过程(通过 Microsoft JDBC 驱动程序)给出了奇怪的、半正确的结果。谢谢。


编辑:

我修复了链接,实际上只是复制并粘贴了错误的 URL。这是声明临时表的 T-SQL。我尝试在每个数据类型之后加上NULL。有五个就是这样的。

    CREATE TABLE #termtable1
        (SerialNumber varchar(50), SR varchar(50), LeaseTag varchar(50), Component varchar(50), 
        Fund int, Org int, Program varchar(50), FirstName varchar(80), LastName varchar(30), 
        Department varchar(50), Location varchar(50), UserID nvarchar(20), Notes nvarchar(MAX), 
        Manufacturer varchar(50), Model varchar(50), Maintenance bit, OrderNumber varchar(50), 
        ContractNumber varchar(50), ParentTag varchar(50));

它们是通过动态 SQL 插入的,这就是为什么我不能使用表变量来代替(范围问题):

DECLARE @sqlstring nvarchar(MAX);
DECLARE @params nvarchar(200) = N'@term1 varchar(100), @term2 varchar(100), @term3 varchar(100), @term4 varchar(100), @term5 varchar(100)';
DECLARE qryCursor CURSOR FOR SELECT * FROM @terms;
OPEN qryCursor;
FETCH NEXT FROM qryCursor INTO @term1, @term2, @term3, @term4, @term5;
DECLARE @termrow int = 1;
WHILE (@@FETCH_STATUS = 0)
BEGIN
    SET @sqlstring = N'INSERT INTO #termtable' + CAST(@termrow AS varchar) + N' SELECT * FROM dbo.NewUserInfo WHERE ';
    DECLARE @i int = 1;
    WHILE (@i <= 5)
    BEGIN
        SET @sqlstring = @sqlstring +
        N'(SerialNumber LIKE @term' + CAST(@i AS varchar) + N' OR ' +
         N'SR LIKE @term' + CAST(@i AS varchar) + N' OR ' +
         N'LeaseTag LIKE @term' + CAST(@i AS varchar) + N' OR ' +
         N'Component LIKE @term' + CAST(@i AS varchar) + N' OR ' +
         N'Fund LIKE @term' + CAST(@i AS varchar) + N' OR ' +
         N'Org LIKE @term' + CAST(@i AS varchar) + N' OR ' +
         N'Program LIKE @term' + CAST(@i AS varchar) + N' OR ' +
         N'FirstName LIKE @term' + CAST(@i AS varchar) + N' OR ' +
         N'LastName LIKE @term' + CAST(@i AS varchar) + N' OR ' +
         N'Department LIKE @term' + CAST(@i AS varchar) + N' OR ' +
         N'Location LIKE @term' + CAST(@i AS varchar) + N' OR ' +
         N'Notes LIKE @term' + CAST(@i AS varchar) + N' OR ' +
         N'Manufacturer LIKE @term' + CAST(@i AS varchar) + N' OR ' +
         N'Model LIKE @term' + CAST(@i AS varchar) + N' OR ' +
         N'Maintenance LIKE @term' + CAST(@i AS varchar) + N' OR ' +
         N'OrderNumber LIKE @term' + CAST(@i AS varchar) + N' OR ' +
         N'ContractNumber LIKE @term' + CAST(@i AS varchar) + N' OR ' +
         N'ParentTag LIKE @term' + CAST(@i AS varchar) + N') OR ';
        SET @i = @i + 1;
    END
    SET @sqlstring = @sqlstring + N'(0 = 1)';
    EXECUTE sp_executesql @sqlstring, @params, @term1=@term1, @term2=@term2, @term3=@term3, @term4=@term4, @term5=@term5;
    SET @termrow = @termrow + 1;
    FETCH NEXT FROM qryCursor INTO @term1, @term2, @term3, @term4, @term5;
END

PHP 很简单。 $result = mssql_query("EXEC QuickSearch '" . $search . "';"); 它只在 NewUserInfo 表中找到 NULL 时给出错误。经常出现在“笔记”中。

【问题讨论】:

  • 如果您需要输入,您需要显示存储过程的代码(至少是创建和填充#termtable1 的部分)以及如何从 PHP 调用该过程。您可能还想详细说明“奇怪的,半正确的结果”的意思(尽管可能在不同的问题中)。听起来你有不止一个问题。
  • 您的链接受密码保护。无论如何,如果没有一行代码(PHP 或 T-SQL)就很难提供帮助。
  • 听起来你需要破解 - 是否可以不使用临时表?
  • 更新了大量代码和更多细节。谢谢大家。

标签: php sql sql-server database tsql


【解决方案1】:

好吧,伙计们,我很抱歉。将NULL 放在每个数据类型确实 工作之后。当我第一次尝试时,我一定错过了一对。表声明应该是这样的:

CREATE TABLE #termtable1
        (SerialNumber varchar(50) NULL, SR varchar(50) NULL, LeaseTag varchar(50) NULL, Component varchar(50) NULL, 
        Fund int NULL, Org int NULL, Program varchar(50) NULL, FirstName varchar(80) NULL, LastName varchar(30) NULL, 
        Department varchar(50) NULL, Location varchar(50) NULL, UserID varchar(20) NULL, Notes varchar(MAX) NULL, 
        Manufacturer varchar(50) NULL, Model varchar(50) NULL, Maintenance bit NULL, OrderNumber varchar(50) NULL, 
        ContractNumber varchar(50) NULL, ParentTag varchar(50) NULL);

【讨论】:

    【解决方案2】:

    如果您创建临时表将使用 SELECT ... INTO 语句,那么您可以确保它会匹配 NewUserInfo 表的列,即使您迟到对该表进行更改

     SET @sqlstring = N'SELECT * FROM dbo.NewUserInfo INTO #termtable' + CAST(@termrow AS varchar) + N' WHERE 1=0';
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-18
      • 2012-11-19
      相关资源
      最近更新 更多