2

ストアド プロシージャの結果セットを一時テーブルに格納する必要があります (SQL Server 2000 を使用)。私が読んだことから、これ(不十分に構築された例)は機能するはずです:

create table #tempTable (TempId int primary key, Column1 varchar(100), 
Column2 varchar(100), DateCreated datetime)

insert into #tempTable (TempId, Column1, Column2, DateCreated)
exec sproc_Select_Stuff_By_DateCreated @Date1 = '1/1/2009', @Date2 = '1/2/2009'

しかし、「挿入エラー: 列名または指定された値の数がテーブル定義と一致しません。」

手順を調べると(編集できません)、次のことがわかります。

CREATE PROCEDURE sproc_Select_Stuff_By_DateCreated

@Date1 datetime,
@Date2 datetime
AS

BEGIN

SELECT TempId, Column1, Column2, DateCreated
FROM ReallyHugeMessOfJoinsAndCalculatedColumns
WHERE DateCreated between @Date1 and @Date2

SELECT @Date1 as Date1, @Date2 as Date2

END

したがって、実際には、渡されたパラメーターを 2 番目の結果セットとしてエコー バックしています。(理由はわかりません。プロシージャを呼び出すものは、渡されたデータを知っていると思います。)

私のテストでは、SQL が結果セットを結合しようとして失敗したように、2 番目の結果セットが挿入エラーの原因であると考えるようになりました。

一時テーブルに保存された最初の結果セットだけが必要です。どうやってやるの?

編集

CLR ストアド プロシージャを指摘していただきありがとうございます。ただし、その機能は SQL 2005 で導入されました。2000 では機能しません。

他の唯一の答えは「できません」のように見えるので、私にとっては製図板に戻っていると思います.

4

4 に答える 4

2

ストアド プロシージャは変更できないため、次の 2 つのオプションしかありません。

  • 両方の結果セットを取得できる CLR を使用し、必要な結果セットのみを返します。
  • 独自のプロシージャまたはビューで必要なクエリを複製します。これは本当のハックであり、CLR が推奨されます。ただし、多くの選択肢はありません。
于 2009-10-08T17:43:33.057 に答える
1

通常、プレーン SQL ではこれは不可能です。Brannon のリンクは、CLR を使用した可能な回避策を提供します。

一方、リファクタリングがオプションである場合は、最初のクエリを独自のストアド プロシージャでアトミックにすることを検討してください。次に、既存のストアド プロシージャとその他のコードの両方から呼び出すことができます。コードはまだ 1 か所にあるだけで、何も壊れておらず、純粋な SQL からより簡単に使用できるものを取得できます。機能によっては、SP の最初の部分がインライン テーブル値関数の候補となる場合もあります (これらはパフォーマンスが高く、柔軟であることがわかりました)。次に、出力を一時テーブルにキャプチャして、他の処理を行うテーブルとして使用する必要さえありません(ただし、何度か使用したい場合は必要になるかもしれません)。

于 2009-10-08T16:37:31.770 に答える
0

以下は、あなたが話していることの完全で実用的な(SQL 2005の)例です。

悪いニュースは、あなたがやろうとしていることをする方法がないと私は信じているということです。ごめん。SPライターがそれを不可能にしたようです。

誰かがこの作品を作るための創造的な方法を思いついたら、素晴らしいです!

IF OBJECT_ID('tempdb..#tempTable') IS NOT NULL
    DROP TABLE #tempTable
GO
IF EXISTS (SELECT * FROM sys.procedures WHERE name = 'sproc_Select_Stuff_By_DateCreated')
    DROP PROCEDURE dbo.sproc_Select_Stuff_By_DateCreated
GO
CREATE PROCEDURE dbo.sproc_Select_Stuff_By_DateCreated
    @Date1 datetime,
    @Date2 datetime
AS BEGIN
    ;WITH t AS (
        SELECT
            1                       AS TempId,
            'Column1-val1'          AS Column1,
            'Column2-val1'          AS Column2,
            '2009-01-01 10:00:00'   AS DateCreated
        UNION ALL
        SELECT
            2,
            'Column1-val2',
            'Column2-val2',
            '2009-01-01 11:00:00'
    )
    SELECT
        TempId,
        Column1,
        Column2,
        DateCreated
    FROM t -- ReallyHugeMessOfJoinsAndCalculatedColumns
    WHERE DateCreated between @Date1 and @Date2

    SELECT @Date1 as Date1, @Date2 as Date2
END
GO

create table #tempTable (
    TempId int primary key,
    Column1 varchar(100),
    Column2 varchar(100),
    DateCreated datetime
)

insert into #tempTable (TempId, Column1, Column2, DateCreated)
exec dbo.sproc_Select_Stuff_By_DateCreated
    @Date1 = '1/1/2009',
    @Date2 = '1/2/2009'

--SELECT * FROM #tempTable

----------------------------------------

Msg 213, Level 16, State 7, Procedure sproc_Select_Stuff_By_DateCreated, Line 26
Insert Error: Column name or number of supplied values does not match table definition.
于 2009-10-08T16:16:27.163 に答える
-1

Microsoft T-SQL リファレンスから

INSERT EmployeeSales 
EXECUTE uspGetEmployeeSales;
GO
于 2009-10-08T18:00:17.857 に答える