SQL (sqlsrv) 从 PHP 执行时游标未完成

SQL (sqlsrv) Cursor not finishing when execute from PHP

下面的 SQL 代码在 MSSQL 中运行良好,但当通过 php 调用时,它只输出大约一半的结果。我试过将它放在一个存储过程中并从 php 执行,但这也会产生相同的结果。

它应该插入 150 行,但我只得到 77,有时是 78,但它始终是这两个数字之一,这让我相信它每次都会在接近一半的位置停止...


error_reporting(0);   //turn off error reporting

session_start();

if ($_SESSION['id']) {

require('../config.php');

$connectionInfo = array( "Database"=>$database, "UID"=>$user, "PWD"=>$password);
$conn = sqlsrv_connect( $host, $connectionInfo);

$sql = "INSERT INTO [RP].[dbo].[RP_UniqueOffers] (offertype)
Select distinct(offertype) from [RP].[dbo].[Offers] t2
where convert(date,[RedeemedDate]) >= convert(date,getdate()-30)
and not exists (Select distinct(offertype) from [RP].[dbo].[RP_UniqueOffers] t1 where t1.OfferType = t2.offertype )

truncate table [RP].[dbo].[RP_Last30days]

DECLARE @id INT
DECLARE @OfferType NVARCHAR(100)
DECLARE @getid CURSOR
Declare @counter int
Declare @nextDate as Date

SET @getid = CURSOR FOR
SELECT [RP].[dbo].[RP_UniqueOffers].ID,
       [RP].[dbo].[RP_UniqueOffers].OfferType
FROM   [RP].[dbo].[RP_UniqueOffers]


OPEN @getid
FETCH NEXT
FROM @getid INTO @id, @OfferType
WHILE @@FETCH_STATUS = 0
BEGIN
    --print @offertype


    Set @counter = 1
    WHILE (@counter < 31 ) 
    begin
    Set @nextDate = convert(varchar,getdate() -30 + @counter,101)
    insert into [RP].[dbo].[Last30Days] ([Date],[OfferType])
    Select Convert(varchar,@nextDate,101), @OfferType
    Set @counter = @counter + 1
    END


    FETCH NEXT
    FROM @getid INTO @id, @OfferType
END

CLOSE @getid
DEALLOCATE @getid";

$params = array();
$options =  array( "Scrollable" => SQLSRV_CURSOR_KEYSET );
$stmt = sqlsrv_query( $conn, $sql , $params, $options );
if ($stmt === False) {
    echo "Faild to worked!";
} else {
   // echo "Should have worked... ";
}

sqlsrv_free_stmt($stmt);

}

?>```

感谢@SalmanA

我需要在脚本顶部添加 SET NOCOUNT ON 以及使用 sqlsrv_prepare 和 sqlsrv_execute 代替 sqlsrv_query。

供您考虑:失去光标。这可以是 set-based.

$sql = "INSERT INTO [RP].[dbo].[RP_UniqueOffers] (offertype)
Select distinct(offertype) from [RP].[dbo].[Offers] t2
where convert(date,[RedeemedDate]) >= convert(date,getdate()-30)
and not exists (Select distinct(offertype) from [RP].[dbo].[RP_UniqueOffers] t1 where t1.OfferType = t2.offertype )

truncate table [RP].[dbo].[RP_Last30days];

WITH ThirtyDays
AS (
   SELECT top(30)
          DATEADD(DAY,ROW_NUMBER() OVER (ORDER BY object_id)*-1,GETDATE()) as nextDate
     FROM sys.columns
)
INSERT [RP].[dbo].[Last30Days] ([Date],[OfferType])
SELECT CONVERT(char(10),ThirtyDays.nextDate,101)
     , RP_UniqueOffers.OfferType
  from [RP].[dbo].[RP_UniqueOffers]
CROSS JOIN ThirtyDays;
";