2012-08-14 16 views
7

長時間リードオンリーメンバー、ここでは、初めてのポスター:)LINQ「次のストアド・プロシージャの戻り値の型が検出されなかった」(NOT一時テーブル)

私がきたので、私はここに頼むことにしましたGoogleやSOなどで検索するのに飽き足りました。

「次のストアド・プロシージャの戻り値の型が検出されなかった」:私は私のSQL 2005 DBの私のウェブサイトへ(FW 4.0、C#)LINQプロジェクトからストアドプロシージャをインポートするときに、このエラーが発生しています

私は2つのクエリを持っています。 私は一時テーブルを使用していないことに注意したいと思います。これらのクエリは、セキュリティ対策のためにのみ、変数名などで編集されています。とにかく、ここでを動作するものがあります:

ALTER PROCEDURE [dbo].[spMyWorkingProc] 
@OS numeric 
AS 
BEGIN 
SET NOCOUNT ON; 

DECLARE @sql varchar(5000) 

set @sql = ' 
     SELECT 
     * 
     FROM MYDB.dbo.MYVIEW 
     WHERE OS = ' + CONVERT(varchar, @OS) 

EXEC(' 
SET NOCOUNT ON 
SELECT * FROM 
OPENROWSET(''SQLOLEDB'', ''MYDB''; ''user''; ''password'', ''' + @sql + ''')') 

END 

そして、ここでは、ないものです:

ALTER PROCEDURE [dbo].[spNotWorking] 
@IDCLIENT int, 
@PPNO char(10) 
AS 
BEGIN 
SET NOCOUNT ON; 

DECLARE @sql varchar(5000) 

set @sql = ' 
     SELECT 
     * 
     FROM MYDB.dbo.MYOTHERVIEW 
     WHERE ID = ' + CONVERT(VARCHAR, @IDCLIENT) + ' AND PASSPORTNO = ' + @PPNO + ' ORDER BY AGE' 

EXEC(' 
SET NOCOUNT ON 
SELECT * FROM 
OPENROWSET(''SQLOLEDB'', ''MYDB''; ''user''; ''password'', ''' + @sql + ''')') 

END 

ここではいくつかのノートと一緒に、私が試したし、見つけたものだと質問:

  • 両方のユーザー(LINQとリモートサーバー)はdb_ownerです。

  • 私がそれを1つのパラメータだけで残しておけば、動作していないストアドプロシージャが機能します。私が新しいものを追加すると、うまくいきません。

  • テーブルから単純なselect *を使用して空のSPを作成し、2つ以上のパラメータを使用するとうまくいく(意味がない)。

  • 問題がEXECにあるとします。もしそうなら、どのように最初のSPが動作するのですか?さて、問題はそこにはありません。

  • 私は現役SPで私がアクセスしたビューを使用すると問題はありません。

  • 提供されたクエリを使用してこれを行う必要があります。 6.5データベースに接続するために必要なリンクサーバーなどを使用することはできません。また、同じ方法を使用している間に最初のSPが動作する理由と2番目のSPが動作しない理由については説明しません。

  • は、私が働いてSPに(非作業SPから取られた)パラメータを追加しようとしましたが、それは動作しますので、それは、第二のSPとなるものでなければなりませんが、私は何を知らない:/

  • オーケーを私が2番目のSPを修正し、@ VARのスタイルでパラメータを削除し、それらを単一の@sql変数にハードコードすると、完全に動作します。だから、私は動的なクエリ(または何か)に変数を含めるものでなければならないことがわかります。

私は文字通り自分の髪を引っ張っているので、アイデアや提案は大歓迎です!

ありがとうございます! - DARKGuy

+0

これらのSQL Serverデータベースはありますか?動的クエリの代わりにリンクサーバーを使用できます。 – jtimperley

+0

そうです。私は可能ですが、この場合、6.5データベースに接続する際には使用できません。しかし、問題は同じサーバーやDB内のテーブルやビューに対して行われた問題に起こりましたが、別の回避策を使用しましたが、その時点では一時テーブルと関係がありましたが、今度は、 t:P – DARKGuy

+0

さて、ダイナミックパラメータを削除し、ハードコーディングしていくつかの行を返すように修正しました(パラメータをハードコーディングすることによって)、それをLINQに追加して、SPをパラメータなどで元の動的クエリに戻して編集しました。愚かなLINQのバグ:( – DARKGuy

答えて

7

Linq2Sql機能の輸入のものとORMのコード生成ツールは、通常SHOWPLAN_ALL設定で、あなたのストアドプロシージャを実行するには、「スニフ」結果セットのために、実際にPROCを実行せず、オン。

このアプローチには、動的SQLでは制限があります。また、多くの場合、TempDBを使用するprocsや、異なるスキーマでデータを返すブランチを持つ問題があります。

解決策は良いものです。つまり、実際のprocをハードコードされたものに置き換えますが、実際のデータを表す模擬データを返します。

編集

私はこれがuncallable状態になり、ハードコーディングされた「スキーマ」を埋め込むことで対処するように見てきたもう一つのパターン、そのよう:

ALTER PROCEDURE [dbo].[someProc] 
AS 
BEGIN 
    SET NOCOUNT ON; 
    IF (1 = 0) 
    BEGIN 
     -- "Cheat" the ORM resultset sniffing by returning an example of the schema. 
     -- Casting and name aliasing to ensure the ORM derives the correct types 
     SELECT CAST('Hello' AS NVARCHAR(50)) AS Name, CAST (1 AS BIT) AS IsOnline, ... 
     RETURN; 
    END 
    .. rest of the REAL proc goes here 
+0

[[with with result sets'](https:// msdn.microsoft.com/en-us/library/ms188332.aspx)を動的SQLと組み合わせても、Linq2Sqlはまだ結果セットを検出できず、この方法で列を '結果セット 'から繰り返す必要があります。 'sp_describe_first_result_set'は'結果セット 'を使って理解できますが、明らかにLinq2Sqlはそれを使用していません。 – GSerg

1

私も同じでした問題。そして解決策はhttp://developwith.net/2012/07/16/unknown-return-type-linq-to-sql/にありました。多くのサイトをチェックすると、このリンクで言及されている3つのポイントについては言いますが、問題の原因となっているトランザクションについては何も言及していません。私の場合、それは地獄を上げる試みブロックでした。それを削除した後、LINQ to SQLは正常に動作しました。後でtry catch backを導入しました。書き込みprocのためのフォーマット以下

1

使用..上記の形式で

CREATE PROCEDURE PROC_NAME 
@variableName nvarchar(150) 
AS 
IF 1=0 BEGIN 
SET FMTONLY OFF 
END 
BEGIN 
SET NOCOUNT ON; 
DECLARE @Sql nvarchar(MAX) 
SET @Sql = 'SELECT Column1, Column2, Column3 FROM' ; 
EXEC sp_executesql @Sql 
END 

違いは、この問題を解決し、戻り値の型を決定するのに役立ちます IF 1=0 BEGIN SET FMTONLY OFF END

です。

関連する問題