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 への接続が良好であること。

最後の 3 番目の部分 では、元の質問の前に、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";

データは返されず、エラーはありません???. SSMS から実行すると問題なく動作しますが、SQL は「insert」ステートメントと「exec」ステートメントの間で「GO」を必要としていると思われます。

これも別の方法で考えていました。上記のストアド プロシージャに、int などの入力パラメータが 1 つある場合:

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=?where になり"?" = '@ScreensParam'ます。わからない?

そこで、UDTT を使用する代わりに XML を作成する解決策を見つけました。これは受け入れられます。そして、私はそれを機能させるために十分な時間を費やしてきました。私がやりたいことは、現在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 への接続が良好であること。

最後の 3 番目の部分 では、元の質問の前に、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";

データは返されず、エラーはありません???. SSMS から実行すると問題なく動作しますが、SQL は「insert」ステートメントと「exec」ステートメントの間で「GO」を必要としていると思われます。

これも別の方法で考えていました。上記のストアド プロシージャに、int などの入力パラメータが 1 つある場合:

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=?where になり"?" = '@ScreensParam'ます。わからない?

そこで、UDTT を使用する代わりに XML を作成する解決策を見つけました。これは受け入れられます。そして、私はそれを機能させるために十分な時間を費やしてきました。私がやりたいことは、現在PHPでは実行できないのではないかと、ひそかに疑っています。

誰かが解決策を持っている/見つけた場合は、知りたいです。

助けてくれてありがとうファジーボタン。やってみるのは楽しかったです。

4

2 に答える 2

1

OK、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";
、複数のステートメントが実際に正常に実行できることを確認できます:)

2番...

編集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にロードできる必要があります...
1つの方法: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 に答える