【解決方法】ストアドプロシージャでVB6レコードセットが開かない

[ad_1]

一時テーブルを作成し、最終結果を返すストアド プロシージャを作成しました。

SSMSでテストすると、単一のレコードセットが返され、正常に動作します。VBで実行すると、すべてを渡した後、レコードセットは開かれませんが、VBまたはADODBではエラーは返されません。

ストアド プロシージャ

SQL
USE [MainDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SYS_Purchasing_CDOrder] @PONo as varchar(10) AS
BEGIN
	DECLARE @HeaderID int
	DECLARE @FrameID int
	DECLARE @RowOn int = 1
	DECLARE @RowCount int
	DECLARE @tmpParts TABLE(HeaderID int, FrameID int, SetCode varchar(3), PCode varchar(99))
	DECLARE @tmpPurchase TABLE(LineID int IDENTITY(1,1) NOT NULL, CustRef varchar(99), HeaderID int, FrameID int, PONo varchar(10), Width int, Height int, Qty int, OrdDate DATE, DelDate DATE, CDPart varchar(99), LB varchar(3), Opener varchar(99), Handed varchar(99))
	
	INSERT INTO @tmpPurchase SELECT JobNo+'_'+CustRef, HeaderID, FrameID, PONo, Width, Height, Qty, CAST(OrdDate AS DATE), CAST(DelDate AS DATE), null, null, null, null FROM SYS_Purchasing WHERE PONo = @PONo AND PartType = 'CDOOR'
	SET @RowCount = (SELECT MAX(LineID) FROM @tmpPurchase)
	WHILE @RowOn <=@RowCount
	BEGIN
		SET @HeaderID = (SELECT HeaderID FROM @tmpPurchase WHERE LineID = @RowOn)
		SET @FrameID = (SELECT FrameID FROM @tmpPurchase WHERE LineID = @RowOn)
		INSERT INTO @tmpParts SELECT HEADER_ID, FRAME_ID, SetCode, PCode FROM PARTS WHERE (HEADER_ID = @HeaderID AND FRAME_ID = @FrameID) AND (SetCode = 'CDR' OR SetCode = 'LB')
		UPDATE @tmpPurchase SET CDPart = (SELECT PCODE FROM @tmpParts WHERE HeaderID = @HeaderID AND FrameID = @FrameID AND SetCode = 'CDR') WHERE LineID = @RowOn
		UPDATE @tmpPurchase SET LB = (SELECT SETCODE FROM @tmpParts WHERE HeaderID = @HeaderID AND FrameID = @FrameID AND SetCode = 'LB') WHERE LineID = @RowOn
		UPDATE @tmpPurchase SET OPENER = (SELECT SASHPCODE FROM SASHES WHERE Header_ID = @HeaderID AND Frame_ID = @FrameID AND SASHPCODE LIKE 'CDS%') WHERE LineID = @RowOn
		UPDATE @tmpPurchase SET Handed = (SELECT SASHType FROM SASHES WHERE Header_ID = @HeaderID AND Frame_ID = @FrameID AND SASHPCODE LIKE 'CDS%') WHERE LineID = @RowOn
		SET @RowOn += 1
	END
	SELECT CustRef, HeaderID, FrameID, PONo, Width, Height, Qty, OrdDate, DelDate, CDPart, LB, Opener, Handed, SupplierCode, ColourExt, ColourInt, Cassette, SpecialRequirements  FROM @tmpPurchase LEFT JOIN SYS_PURCHASING_CDMatrix ON CDPart = SYS_PURCHASING_CDMatrix.WDProdCode 
END

VB コード

VB
Set Cmd1 = New ADODB.Command
Set rs = New ADODB.Recordset
Set sqlServer = New ADODB.Connection
'extra code here to open the connection, this opens ok
sqlServer.Open
Cmd1.ActiveConnection = sqlServer
Cmd1.CommandType = adCmdStoredProc
Cmd1.CommandText = "[SYS_Purchasing_CDOrder]"
Set Parm1 = Cmd1.CreateParameter("@PONo", adVarChar, adParamInput, 10, OrderNo)
Cmd1.Parameters.Append Parm1
rs.Open Cmd1
Debug.Print rs.State 'This always returns 0

テーブルから直接データを返すようにストアド プロシージャを変更すると、問題なく動作しますが、一時テーブルを使用すると、失敗して終了します。

このようにする理由は、Parts テーブルに 1,100 万を超えるレコード (5 GB を超えるデータ) があり、処理が遅くなる可能性があるためです。

前もって感謝します

レイ

解決策 1

いくつかのアイデア:

  • 角かっこなしでコマンドを作成します。 Cmd1.CommandText = "SYS_Purchasing_CDOrder"
  • 「at」なしでパラメーターを作成します。 Cmd1.CreateParameter("PONo", ...
  • 手順の上部近くで、 SET NOCOUNT ON; これが役立つことを時々見てきました。
  • アリサボートの設定を確認してください。

また、SQL プロファイラーを使用できる場合 (つまり、SQL Express を使用していない場合)、実際に実行される SQL コードは何ですか?
ところで、手順を最適化することもできます。 すべてのソースを結合するクエリで同じ結果を得るようにしてください。

お役に立てれば、

パブロ。

解決策 4

いくつかのビューとストアド プロシージャをリンクして、これを並べ替えました。

よろしく

レイ

解決策 5

ストアド プロシージャの最終選択で「#TempTable から何とか何とか何とか * を選択」し、レコードセットを返すと、VB6 に戻ったときにレコードセットが空になることがわかりました。 この手順は 100% 機能し、目的の結果を正確に返します。 しかし、VB6 で呼び出すと、空になり、レコードセットが開かれません。

しかし !!

通常のテーブルを使用するようにストアド プロシージャを変更すると、それは機能し、VB6 は結果に満足しています。

解決策 3

パブロ、返信ありがとう。

それらをすべて実行してもまだ運がありません。すでに nocount を入れていましたが、変更しても表示されません。

テーブルの 1 つに 1,100 万件を超えるレコードが含まれているため、結合されたテーブルとしてこれを実行すると時間がかかることを投稿で述べました。そのため、必要なものだけを返します。

よろしく

レイ

[ad_2]

コメント

タイトルとURLをコピーしました