2012-08-14 10 views
7

Długi czas lurker, po raz pierwszy plakat tutaj :)LINQ „Rodzaje powrotne dla następujących procedur składowanych nie może być wykryte” (nie tabele Temp)

zdecydowałem się poprosić tutaj odkąd jest już zmęczony wyszukiwaniem w Google, SO i tym podobnych. Mam przeżywa ten błąd podczas importowania procedury przechowywanej z mojego SQL 2005 DB na mojej stronie (FW 4.0, C#) projekt LINQ: „nie można wykryć Rodzaje powrotne dla następujących procedur składowanych”

Mam dwa zapytania. Chciałbym zauważyć, że nie używam tymczasowych tabel. Te kwerendy zostały edytowane tylko w nazwach zmiennych i na przykład w przypadku środków bezpieczeństwa. Tak czy inaczej, oto ten, który działa:

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 

I oto ten, który nie:

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 

Oto co próbowałem i okazało się, wraz z kilkoma nutami i pytania:

  • Zarówno użytkownicy (LINQ, jak i serwer zdalny) to db_owner.

  • Niedziałająca procedura składowana działa, jeśli zostawiam ją tylko z jednym parametrem (nie ma znaczenia który). Jeśli dodaję nowy, to nie działa.

  • Jeśli zrobię puste SP z prostym wyborem * z dowolnej tabeli i dwoma lub więcej parametrami, to działa (więc to nie ma sensu).

  • Załóżmy, że problem dotyczy programu EXEC. Jeśli tak, to w jaki sposób działa pierwsze SP? Ok, problem nie istnieje wtedy. (tak właśnie brzmi logika, jak sądzę?)

  • Problem nie jest widokiem, ponieważ nie działa, jeśli korzystam z widoku, do którego uzyskuję dostęp w działającym SP.

  • Potrzebuję zrobić to za pomocą podanych zapytań. Nie mogę korzystać z serwerów połączonych lub czegoś podobnego, co musimy zrobić, aby połączyć się z bazami danych 6.5, i nie rozwiązuje ani nie wyjaśnia, dlaczego pierwszy SP działa, a drugi nie, podczas korzystania z tej samej metody.

  • Próbowałem dodać parametr (wzięte z nieprodukcyjnym SP) do SP pracuje i działa, więc to musi być coś z drugim SP, ale nie wiem czego/

  • Okay , jeśli zmodyfikuję drugi SP i usunę parametry w stylu @VAR i zakodowuję je w jedną zmienną @sql, to działa idealnie. Widzę więc, że musi to być coś z włączaniem zmiennych do zapytania dynamicznego (lub czegoś takiego).

Dosłownie odejmuję włosy, więc wszelkie pomysły i sugestie są mile widziane!

Z góry dziękuję! - narzędzia DARKGuy

+0

Czy te bazy danych sql-server? Zamiast kwerend dynamicznych można użyć serwerów połączonych. – jtimperley

+0

Tak, są. Mogłem, ale w tym przypadku nie możemy, ponieważ używamy tego do połączenia się z bazami danych 6.5. Nie o to jednak chodzi, ponieważ miałem problem z zapytaniami do tabel/widoków na tym samym serwerze i DB, ale użyliśmy innego rozwiązania i tym razem miało to związek z tabelami tymczasowymi, tym razem nie robi tego ". t: P – DARKGuy

+0

OK, naprawiłem to, usuwając parametry dynamiczne, kodując je, aby zwrócić niektóre wiersze (również poprzez kodowanie parametrów), a następnie dodając je do LINQ, a następnie edytując SP z powrotem do pierwotnego zapytania dynamicznego z parametrami i takimi. Cholerne, głupie błędy LINQ :( – DARKGuy

Odpowiedz

7

generacji kodu ORM, takich jak te w Linq2Sql importu funkcyjnych zwykle uruchamianie procedur składowanych z ustawieniem SHOWPLAN_ALL włączony, bez faktycznego wykonywania proc, w celu „nosem” zestaw wyników.

Takie podejście ma ograniczenia, jak już stwierdzono, z dynamicznym SQL, a także często są problemy z procami, które używają TempDB lub mają gałęzie, które zwracają dane z różnymi schematami.

Twoje rozwiązanie jest dobre, tj. Zastąpienie rzeczywistego procesu procesem, który jest zakodowany na sztywno, ale który zwraca fałszywe dane, które są reprezentatywne dla rzeczywistych danych.

Edit

Kolejny wzór, który widziałem w celu rozwiązania tego celu jest osadzić zakodowanego „schemat” doprowadzić do powstania stanu uncallable, tak:

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

Szkoda, że ​​nawet gdy używam ['z zestawami wyników'] (https: // msdn.microsoft.com/en-us/library/ms188332.aspx) z moim dynamicznym SQL, Linq2Sql wciąż nie wykrywa zestawu wyników i muszę powtarzać moje kolumny z 'zestawów wyników' również w ten sposób. 'sp_describe_first_result_set' rozumie' z zestawami wyników' po prostu dobrze, ale najwyraźniej Linq2Sql go nie używa. – GSerg

1

ja też miałem takie same kwestia. I rozwiązanie było na http://developwith.net/2012/07/16/unknown-return-type-linq-to-sql/ Sprawdzanie wielu witryn mówi o tych 3 punktach wymienionych w tym łączu, ale nigdzie nie wspomniano o transakcji powodującej problem. W moim przypadku był to sprytny blok z piekła rodem. Po usunięciu LINQ do SQL zachowywał się normalnie. Później wprowadzono próbę odłowu.

1

skorzystać z poniższego formatu zapisu proc ..

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 

Różnica w powyższym formacie jest IF 1=0 BEGIN SET FMTONLY OFF END

który pomaga rozwiązać ten problem i określić typ zwracanej.

Powiązane problemy