0

使用 PHP v. 5.4,我正在尝试连接到 SQL 2008 数据库并插入并返回 SQL 用户定义的表类型中的数据。

SQL表数据类型定义如下:
create type ScreensTableType as table(ElementCode decimal(6,2), ElementYear int, MinimumValue float, MaximumValue float, AndOr bit)

我的 PHP 代码的精简版是:

<?php
$sqlStr='';
$serverName = "Server"; //serverName\instanceName
$connectionInfo = array( "Database"=>"Db");
$conn = sqlsrv_connect( $serverName, $connectionInfo);

if(!$conn ) {
     echo "Connection could not be established.<br />";
     die( print_r( sqlsrv_errors(), true));
}    
$sqlStr="declare @ScreensParam [ScreensTableType] insert @ScreensParam values (5101.00,2011,0,100,1),(5103.00,2011,0,100,1) select * from @ScreensParam";
  // print $sqlStr;
$getFormData=sqlsrv_query($conn, $sqlStr);

if( $getFormData === false )
{
      if( ($errors = sqlsrv_errors() ) != null)
      {
         foreach( $errors as $error)
         {
            echo "SQLSTATE: ".$error[ 'SQLSTATE']."\n";
            echo "code: ".$error[ 'code']."\n";
            echo "message: ".$error[ 'message']."\n";
         }
      }
}

     while( $row = sqlsrv_fetch_array( $getFormData, SQLSRV_FETCH_ASSOC) ) {
       print '####'.$row['ElementCode'];

     }
?>

连接正常,没有返回错误。然而,什么都没有返回。如果我在 Management Studio 中打印并运行 $sqlStr ,它可以正常工作。如果我将 $sqlStr 更改为"select top 10 * from someExistingDbTable"然后我会返回数据。

有人对如何做到这一点或我可能做错了什么有任何想法吗?

非常感谢,

第 2 部分
这是我正在尝试做的 - sp 从 Web 表单返回请求的财务数据。用户从表单中选择以下选项:

"financial item", "financial year", "minimum value", "maximum value", "and/or"  
Revenue, 2010, 1000000, 10000000, 'and'  
EPS, 2011, 0.5, 1.5, 'or'  

根据用户的要求,可能有 1 行或 50 行。我想将这些项目加载到 UDTT 中。在存储过程中,我创建了一个动态查询。游标遍历 UDTT 的行并在动态查询的 where 子句中创建条件。然后返回数据。

我遇到的问题是,当我使用 UDTT 时,我似乎无法让 PHP 返回任何结果。我只是使用上面的简化示例来查看是否有人可以返回数据。

我应该补充一点,当我打印从 PHP 传递到 SQL 的“真实”字符串时,存储过程确实会返回数据。而且我与 SQL 的连接很好。

第三部分也是最后一部分 我应该在原始问题的开头说我是 PHP 的新手。不过在 SQL 方面还不错。

好的,这是我尝试过的:

没有 UDTT 的 SQL

drop procedure testUDTT

go

create PROCEDURE [testUDTT]
as
SET NOCOUNT ON
select XmlRequest = '###Data Returned###'

go

如果我运行以下 PHP 代码,则返回数据:

$select="exec testUDTT";
$sqlResponse=sqlsrv_query($conn, $select);
while( $row = sqlsrv_fetch_array( $sqlResponse, SQLSRV_FETCH_ASSOC) ) {
  print '####'.$row['XmlRequest'];
  }

如果我将 $select 更改为:

$select="declare @ScreensParam [ScreensTableType] exec testUDTT";

返回数据。

但是,如果我将 $select 更改为:

$select="declare @ScreensParam [ScreensTableType] insert @ScreensParam values (5101.00,2011,0,100,1),(5103.00,2011,0,100,1) exec testUDTT";

没有数据返回,也没有错误???。我怀疑 SQL 希望在“insert”和“exec”语句之间有一个“GO”,尽管当我从 SSMS 运行时这工作正常。

我也在考虑另一种方式。如果上述存储过程有一个像 int 这样的输入参数,例如:

create PROCEDURE [testUDTT]
@InputInt int
as
SET NOCOUNT ON
if @InputInt > 0
  select XmlRequest = '###Data Returned###'

我的 PHP 代码可能类似于:

$inputInt=1;
$select="exec testUDTT @InputInt=?";
$params = array(
  array($inputInt, SQLSRV_PARAM_IN)
  );
$sqlResponse=sqlsrv_query($conn, $select, $params);

现在,如果我有这个使用 UDTT 的存储过程:

create PROCEDURE [testUDTT]
@ScreensParam ScreensTableType READONLY
as
SET NOCOUNT ON
select XmlRequest = '###Data Returned###'
from @ScreensParam

go

我尝试将 PHP 对 sql 的调用分成两部分(不确定这是否正确,但试了一下):

$add='declare @ScreensParam [ScreensTableType] insert @ScreensParam values (5101.00,2011,0,100,1),(5103.00,2011,0,100,1)';
$select='exec testUDTT @ScreensParam='.$screensParam;

sqlsrv_query($conn, $add);
$sqlResponse=sqlsrv_query($conn, $select);

我收到以下错误:SQLSTATE: 42000 code: 137 message: [Microsoft][SQL Server Native Client 11.0][SQL Server]Must declare the scalar variable "@ScreensParam".因为我猜 UDTT 不在范围内。另外我想知道在数组中传递 @ScreensParam 的 PHP 语法应该是什么?$select 会变成exec testUDTT @ScreensParam=?where "?" = '@ScreensParam'。不知道?

所以我找到了一个创建 XML 而不是使用 UDTT 的解决方案,这是可以接受的。我已经花了足够多的时间试图让它发挥作用。我有一个偷偷摸摸的怀疑,我想做的事情目前不能用 PHP 完成。

如果有人有/找到解决方案,我很想知道。

感谢模糊按钮的帮助。尝试很有趣。

使用 PHP v. 5.4,我正在尝试连接到 SQL 2008 数据库并插入并返回 SQL 用户定义的表类型中的数据。

SQL表数据类型定义如下:
create type ScreensTableType as table(ElementCode decimal(6,2), ElementYear int, MinimumValue float, MaximumValue float, AndOr bit)

我的 PHP 代码的精简版是:

<?php
$sqlStr='';
$serverName = "Server"; //serverName\instanceName
$connectionInfo = array( "Database"=>"Db");
$conn = sqlsrv_connect( $serverName, $connectionInfo);

if(!$conn ) {
     echo "Connection could not be established.<br />";
     die( print_r( sqlsrv_errors(), true));
}    
$sqlStr="declare @ScreensParam [ScreensTableType] insert @ScreensParam values (5101.00,2011,0,100,1),(5103.00,2011,0,100,1) select * from @ScreensParam";
  // print $sqlStr;
$getFormData=sqlsrv_query($conn, $sqlStr);

if( $getFormData === false )
{
      if( ($errors = sqlsrv_errors() ) != null)
      {
         foreach( $errors as $error)
         {
            echo "SQLSTATE: ".$error[ 'SQLSTATE']."\n";
            echo "code: ".$error[ 'code']."\n";
            echo "message: ".$error[ 'message']."\n";
         }
      }
}

     while( $row = sqlsrv_fetch_array( $getFormData, SQLSRV_FETCH_ASSOC) ) {
       print '####'.$row['ElementCode'];

     }
?>

连接正常,没有返回错误。然而,什么都没有返回。如果我在 Management Studio 中打印并运行 $sqlStr ,它可以正常工作。如果我将 $sqlStr 更改为"select top 10 * from someExistingDbTable"然后我会返回数据。

有人对如何做到这一点或我可能做错了什么有任何想法吗?

非常感谢,

第 2 部分
这是我正在尝试做的 - sp 从 Web 表单返回请求的财务数据。用户从表单中选择以下选项:

"financial item", "financial year", "minimum value", "maximum value", "and/or"  
Revenue, 2010, 1000000, 10000000, 'and'  
EPS, 2011, 0.5, 1.5, 'or'  

根据用户的要求,可能有 1 行或 50 行。我想将这些项目加载到 UDTT 中。在存储过程中,我创建了一个动态查询。游标遍历 UDTT 的行并在动态查询的 where 子句中创建条件。然后返回数据。

我遇到的问题是,当我使用 UDTT 时,我似乎无法让 PHP 返回任何结果。我只是使用上面的简化示例来查看是否有人可以返回数据。

我应该补充一点,当我打印从 PHP 传递到 SQL 的“真实”字符串时,存储过程确实会返回数据。而且我与 SQL 的连接很好。

第三部分也是最后一部分 我应该在原始问题的开头说我是 PHP 的新手。不过在 SQL 方面还不错。

好的,这是我尝试过的:

没有 UDTT 的 SQL

drop procedure testUDTT

go

create PROCEDURE [testUDTT]
as
SET NOCOUNT ON
select XmlRequest = '###Data Returned###'

go

如果我运行以下 PHP 代码,则返回数据:

$select="exec testUDTT";
$sqlResponse=sqlsrv_query($conn, $select);
while( $row = sqlsrv_fetch_array( $sqlResponse, SQLSRV_FETCH_ASSOC) ) {
  print '####'.$row['XmlRequest'];
  }

如果我将 $select 更改为:

$select="declare @ScreensParam [ScreensTableType] exec testUDTT";

返回数据。

但是,如果我将 $select 更改为:

$select="declare @ScreensParam [ScreensTableType] insert @ScreensParam values (5101.00,2011,0,100,1),(5103.00,2011,0,100,1) exec testUDTT";

没有数据返回,也没有错误???。我怀疑 SQL 希望在“insert”和“exec”语句之间有一个“GO”,尽管当我从 SSMS 运行时这工作正常。

我也在考虑另一种方式。如果上述存储过程有一个像 int 这样的输入参数,例如:

create PROCEDURE [testUDTT]
@InputInt int
as
SET NOCOUNT ON
if @InputInt > 0
  select XmlRequest = '###Data Returned###'

我的 PHP 代码可能类似于:

$inputInt=1;
$select="exec testUDTT @InputInt=?";
$params = array(
  array($inputInt, SQLSRV_PARAM_IN)
  );
$sqlResponse=sqlsrv_query($conn, $select, $params);

现在,如果我有这个使用 UDTT 的存储过程:

create PROCEDURE [testUDTT]
@ScreensParam ScreensTableType READONLY
as
SET NOCOUNT ON
select XmlRequest = '###Data Returned###'
from @ScreensParam

go

我尝试将 PHP 对 sql 的调用分成两部分(不确定这是否正确,但试了一下):

$add='declare @ScreensParam [ScreensTableType] insert @ScreensParam values (5101.00,2011,0,100,1),(5103.00,2011,0,100,1)';
$select='exec testUDTT @ScreensParam='.$screensParam;

sqlsrv_query($conn, $add);
$sqlResponse=sqlsrv_query($conn, $select);

我收到以下错误:SQLSTATE: 42000 code: 137 message: [Microsoft][SQL Server Native Client 11.0][SQL Server]Must declare the scalar variable "@ScreensParam".因为我猜 UDTT 不在范围内。另外我想知道在数组中传递 @ScreensParam 的 PHP 语法应该是什么?$select 会变成exec testUDTT @ScreensParam=?where "?" = '@ScreensParam'。不知道?

所以我找到了一个创建 XML 而不是使用 UDTT 的解决方案,这是可以接受的。我已经花了足够多的时间试图让它发挥作用。我有一个偷偷摸摸的怀疑,我想做的事情目前不能用 PHP 完成。

如果有人有/找到解决方案,我很想知道。

感谢模糊按钮的帮助。尝试很有趣。

4

2 回答 2

1

好的,在切换到 XML 解决方案后,我正在寻找如何在 PHP 中做其他事情,并且偶然发现了一个关于在 PHP 中使用 SQL 临时表的问题,并且响应使用了 sqlsrv_next_result() 函数。所以这现在很好用:

$sqlStr=
  <<<SQL
    declare @ScreensParam [ScreensTableType]
    insert @ScreensParam values (5101.00,2011,-1000,1000,1),(5103.00,2011,0,100,1)
    exec xml_testIndustry '1,2', 2009, 2011, @ScreensParam
  SQL;

$getFormData=sqlsrv_query($conn, $sqlStr);
echo "Rows affected: " . sqlsrv_rows_affected($getFormData).'<br/>';

$next_result = sqlsrv_next_result($getFormData);
if( $next_result ) {
   while( $row = sqlsrv_fetch_array( $getFormData, SQLSRV_FETCH_ASSOC)){
      echo $row['XmlRequest'].": <br />"; 
   }
} elseif( is_null($next_result)) {
     echo "No more results.<br />";
} else {
     die(print_r(sqlsrv_errors(), true));
}
于 2013-03-13T14:24:49.950 回答
0

我一直在考虑这个。

首先,我玩过
$sqlStr="DECLARE @test varchar(max) SET @test='123' SELECT * from table";
并且可以确认多个语句确实可以运行正常:)

第二...

编辑在http://sqlfiddle.com/#!3/b1596/73
中播放更多内容,您似乎可以将值表作为定义的表类型传递给 SQL 命令,并使用临时表作为参数执行 SP。 .. (进行了大量的实验,但我最终发现 sqlfiddle 对分号非常挑剔,有时不会将注释视为注释!)

create type ScreensTableType1 as table
 (ElementCode decimal(6,2), ElementYear int, MinimumValue float,
  MaximumValue float, AndOr bit);

一个用于演示表参数的 SP,它输出传入的内容:

CREATE PROCEDURE testSP
  ( @ParamTab ScreensTableType1 Readonly )
AS 
begin
  SELECT * FROM @ParamTab
end;

应该能够在 PHP 中将多行数据加载到 SP...
一种方法:使用 CTE:

DECLARE @S1 as ScreensTableType1
With data_in as
(
 SELECT
   5101.00 as ElementCode, 2011 as ElementYear,
   0 as MinimumValue, 100 as MaximumValue, 1 as AndOr
 UNION ALL 
 SELECT 5103.00,2011,0,100,1
)
INSERT @S1 SELECT * from data_in
Exec testSP @S1

.. 或多个 INSERT:

DECLARE @S2 as ScreensTableType1
insert @S2 values (5199.00,2011,0,100,1)
insert @S2 values (5177.00,2011,0,100,1)
EXEC testSP @S2
于 2013-02-27T10:34:11.777 回答