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;
";
下面的 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;
";