簡體   English   中英

使用PHP v.5.4從SQL Server 2008用戶定義的表類型返回數據

[英]Returning data from SQL server 2008 User defined table types using PHP v. 5.4

使用PHP 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希望在“插入”和“ 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

並且我嘗試將對sql的PHP調用分為2個部分(不知道這是否正確,但可以嘗試一下):

$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=? 在哪里"?" = '@ScreensParam' "?" = '@ScreensParam' 不知道嗎

因此,我找到了一個創建XML而不是使用UDTT的解決方案。 而且我花了太多的時間嘗試使其工作。 我暗中懷疑我現在想用PHP無法完成的工作。

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

感謝您的幫助模糊按鈕。 嘗試很有趣。

使用PHP 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希望在“插入”和“ 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

並且我嘗試將對sql的PHP調用分為2個部分(不知道這是否正確,但可以嘗試一下):

$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=? 在哪里"?" = '@ScreensParam' "?" = '@ScreensParam' 不知道嗎

因此,我找到了一個創建XML而不是使用UDTT的解決方案。 而且我花了太多的時間嘗試使其工作。 我暗中懷疑我現在想用PHP無法完成的工作。

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

感謝您的幫助模糊按鈕。 嘗試很有趣。

我一直在考慮這個問題。

首先,我玩過
$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

切換到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));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM