EF4 - 선택한 저장 프로시저가 열을 반환하지 않습니다.
저장 프로시저에서 동적 SQL로 연결된 서버를 호출하는 쿼리가 있습니다.EF가 그것을 좋아하지 않는 것으로 알고 있기 때문에, 저는 반품될 모든 칼럼을 구체적으로 열거했습니다.하지만, 그것은 여전히 그것을 좋아하지 않습니다.내가 여기서 뭘 잘못하고 있는 거지?저장 프로시저에서 반환된 열을 EF가 감지하여 필요한 클래스를 만들 수 있기를 바랍니다.
저장 프로시저의 마지막 줄을 구성하는 다음 코드를 참조하십시오.
SELECT
#TempMain.ID,
#TempMain.Class_Data,
#TempMain.Web_Store_Class1,
#TempMain.Web_Store_Class2,
#TempMain.Web_Store_Status,
#TempMain.Cur_1pc_Cat51_Price,
#TempMain.Cur_1pc_Cat52_Price,
#TempMain.Cur_1pc_Cat61_Price,
#TempMain.Cur_1pc_Cat62_Price,
#TempMain.Cur_1pc_Cat63_Price,
#TempMain.Flat_Length,
#TempMain.Flat_Width,
#TempMain.Item_Height,
#TempMain.Item_Weight,
#TempMain.Um,
#TempMain.Lead_Time_Code,
#TempMain.Wp_Image_Nme,
#TempMain.Wp_Mod_Dte,
#TempMain.Catalog_Price_Chg_Dt,
#TempMain.Description,
#TempMain.Supersede_Ctl,
#TempMain.Supersede_Pn,
TempDesc.Cust_Desc,
TempMfgr.Mfgr_Item_Nbr,
TempMfgr.Mfgr_Name,
TempMfgr.Vendor_ID
FROM
#TempMain
LEFT JOIN TempDesc ON #TempMain.ID = TempDesc.ID
LEFT JOIN TempMfgr ON #TempMain.ID = TempMfgr.ID
EF는 다음에서 결과 집합을 빌드하는 저장 프로시저 가져오기를 지원하지 않습니다.
- 동적 쿼리
- 임시 테이블
그 이유는 프로시저를 가져오기 위해서는 EF가 이를 실행해야 하기 때문입니다.이러한 작업은 데이터베이스에서 일부 변경사항을 트리거할 수 있으므로 위험할 수 있습니다.따라서 EF는 저장 프로시저를 실행하기 전에 특수 SQL 명령을 사용합니다.
SET FMTONLY ON
이 명령 저장 프로시저를 실행하면 결과 집합의 열에 대한 "메타데이터"만 반환되고 논리는 실행되지 않습니다.그러나 논리가 실행되지 않았기 때문에 임시 테이블(또는 빌드된 동적 쿼리)이 없으므로 메타데이터에는 아무것도 포함되지 않습니다.
이러한 기능을 사용하지 않으려면 저장 프로시저를 다시 작성해야 하는 옵션을 제외하고 다음 두 가지를 선택할 수 있습니다.
- 반환된 복합 유형을 수동으로 정의합니다(작동해야 할 것 같습니다).
- the storage 에 있는 저장 프로시저를 합니다.
SET FMTONLY OFF
이렇게 하면 SP의 나머지 코드가 정상적인 방식으로 실행될 수 있습니다.SP가 데이터를 수정하지 않는지 확인하십시오. 이러한 수정 사항은 가져오기 중에 실행됩니다.가져오기가 성공하면 해당 해킹을 제거합니다.
이 비논리적 코드 블록을 추가하면 문제가 해결되었습니다.절대 부딪치지 않을지라도
IF 1=0 BEGIN
SET FMTONLY OFF
END
입력한 데이터 집합이 임시 테이블을 좋아하지 않는 이유는 무엇입니까?
또는 사용자 정의 테이블 유형을 생성하여 반환할 수 있습니다.
CREATE TYPE T1 AS TABLE
( ID bigint NOT NULL
,Field1 varchar(max) COLLATE Latin1_General_CI_AI NOT NULL
,Field2 bit NOT NULL
,Field3 varchar(500) NOT NULL
);
GO
그런 다음 절차에서:
DECLARE @tempTable dbo.T1
INSERT @tempTable (ID, Field1, Field2, Field3)
SELECT .....
....
SELECT * FROM @tempTable
이제 EF는 반환된 열 유형을 인식할 수 있어야 합니다.
다른 사람들이 언급했듯이, 절차가 실제로 실행되는지 확인합니다.특히 저의 경우 SQL Server Management Studio에서 관리자 권한으로 로그인한 것을 완전히 잊고 오류 없이 행복하게 절차를 실행하고 있었습니다.응용 프로그램의 주 사용자를 사용하여 절차를 실행하려고 하자 쿼리에 해당 사용자에게 액세스 권한이 없는 테이블이 있습니다.
흥미로운 측면 참고:처음에 Temp Tables(가져오기 전용)가 아닌 Table Variables(테이블 변수)를 사용하여 해결한 것과 동일한 문제가 있었습니다.제가 처음 두 SProcs를 관찰했을 때는 그다지 직관적이지 않았습니다. 하나는 Temp tables를 사용하고 다른 하나는 Table variables를 사용하는 것이었습니다.
(SET FMONLY OFF는 저를 위해 작동한 적이 없기 때문에, 저는 단지 FYI로서 EF 쪽의 해킹을 신경쓰지 않고 열 정보를 얻기 위해 일시적으로 SProcs를 변경했을 뿐입니다.)
저의 최선의 선택은 정말로 복잡한 유형을 수동으로 만들고 함수 가져오기를 매핑하는 것이었습니다.잘 작동했고, 마지막으로 유일한 차이점은 특성을 만드는 추가 공장 방법이 디자이너에 포함되었다는 것입니다.
추가할 내용은 다음과 같습니다.
저장 프로시저에 매개 변수가 있고 기본 매개 변수 값에 대해 설정된 결과가 없으면 가져오기도 실패합니다.
저장 프로시저에는 2개의 float 매개 변수가 있으며 두 매개 변수가 모두 0이면 아무것도 반환하지 않습니다.
따라서 이 저장 프로시저를 엔터티 모델에 추가하기 위해 저장 프로시저에서 이러한 매개 변수의 값을 설정하여 매개 변수가 실제로 무엇이든 간에 일부 행을 반환하도록 보장합니다.
그런 다음 이 저장 프로시저를 엔티티 모델에 추가한 후 변경을 취소했습니다.
두 가지 해결책: 1- 반환되는 복잡한 유형을 수동으로 정의합니다(작동해야 할 것 같습니다). 2- 해킹을 사용하여 시작할 때 저장 프로시저를 추가하기만 하면 됩니다(SET FMONLY OFF.
어떤 절차에서 나와 함께 일하지 않았지만 다른 절차에서는 작동했습니다!
내 절차는 다음 행으로 끝납니다.
SELECT machineId, production [AProduction]
, (select production FROM #ShiftBFinalProd WHERE machineId = #ShiftAFinalProd.machineId) [BProduction]
, (select production FROM #ShiftCFinalProd WHERE machineId = #ShiftAFinalProd.machineId) [CProduction]
FROM #ShiftAFinalProd
ORDER BY machineId
감사해요.
@tmanthley가 말한 것 외에도 저장 프로시저가 SSMS에서 먼저 실행함으로써 실제로 작동하는지 확인합니다.저장 프로시저를 몇 개 가져왔는데 종속 스칼라 함수 몇 개를 잊어버려서 EF가 프로시저에서 열을 반환하지 않았다고 판단했습니다.제가 좀 더 일찍 잡아야 할 실수인 것 같은데, 그런 경우 EF는 당신에게 오류 메시지를 주지 않습니다.
Entity Framework는 저장 프로시저를 실행하여 모든 인수에 NULL을 전달하여 열을 가져옵니다.
모든 상황에서 저장 프로시저가 무언가를 반환하는지 확인하십시오.Entity Framework가 NULL과 반대로 인수에 대한 기본값으로 저장된 proc를 실행하는 것이 더 현명했을 수 있습니다.
ER은 다음 작업을 수행하여 테이블의 메타데이터를 가져옵니다.
FM만 설정
이렇게 하면 특히 임시 테이블을 사용하는 경우 다양한 상황에서 저장 프로시저가 손상됩니다.
복잡한 유형으로 결과를 얻으려면 다음을 추가하십시오.
FM만 끄십시오.
이것은 나에게 효과가 있었습니다. 당신에게도 효과가 있기를 바랍니다.
https://social.msdn.microsoft.com/Forums/en-US/e7f598a2-6827-4b27-a09d-aefe733b48e6/entity-model-add-function-import-stored-procedure-returns-no-columns?forum=adodotnetentityframework 에서 참조.
경우에는 의나경추가우를 추가합니다.SET NOCOUNT ON;
절차의 맨 위에서 문제를 해결했습니다.어쨌든 최선의 방법입니다.
저의 경우 SET FMONLY OFF가 작동하지 않았습니다.제가 수행한 방법은 원래 저장 프로시저의 백업을 수행하고 아래 쿼리와 같이 열 이름으로만 교체하는 것입니다.
Select Convert(max,'') as Id,Convert(max,'') as Name
이 변경 후 엔티티 프레임워크에 새 함수 가져오기, 복잡한 유형을 만듭니다.함수 가져오기 및 복합 유형이 생성되면 위 쿼리를 원래 저장 프로시저로 대체합니다.
SET FMTONLY OFF
한 절차는 저를 위해 일했지만 다른 절차는 실패했습니다.다음 단계는 문제를 해결하는 데 도움이 됩니다.
저장 프로시저 내에서 동일한 열 유형의 임시 테이블을 만들고 동적 쿼리에 의해 반환된 모든 데이터를 임시 테이블에 삽입했습니다.온도 테이블 데이터를 선택했습니다.
Create table #temp ( -- columns with same types as dynamic query ) EXEC sp_executeSQL @sql insert into #temp Select * from #temp drop table #temp
이전 저장 프로시저에 대한 기존 복합 유형, 가져오기 함수 및 저장 프로시저 인스턴스를 삭제하고 현재 새 프로시저에 대한 엔티티 모델을 업데이트했습니다.
원하는 복합 유형에 대해 가져온 함수의 도면요소 모달을 편집하면 이전 저장 프로시저에서 얻지 못한 모든 열 정보를 얻을 수 있습니다.
형식 작성을 완료한 후 저장 프로시저에서 임시 테이블을 삭제한 다음 Entity Framework를 새로 고칠 수 있습니다.
엔티티 프레임워크에서 sql은 열 정보를 가져오는 동안 매개 변수에 null 값을 전달하는 절차를 실행합니다.따라서 필요한 모든 열이 포함된 임시 테이블을 만들고 null이 절차에 전달될 때 값이 없는 모든 열을 반환하여 null 대소문자를 다르게 처리했습니다.
제 절차에는 동적 쿼리가 있었습니다.
declare @category_id int
set @category_id = (SELECT CATEGORY_ID FROM CORE_USER where USER_ID = @USER_ID)
declare @tableName varchar(15)
declare @sql VARCHAR(max)
declare @USER_IDT varchar(100)
declare @SESSION_IDT varchar(10)
IF (@category_id = 3)
set @tableName = 'STUD_STUDENT'
else if(@category_id = 4)
set @tableName = 'STUD_GUARDIAN'
if isnull(@tableName,'')<>''
begin
set @sql = 'SELECT [USER_ID], [FIRST_NAME], SCHOOL_NAME, SOCIETY_NAME, SCHOOL_ID,
SESSION_ID, [START_DATE], [END_DATE]
from @tableName
....
EXECUTE (@sql)
END
ELSE
BEGIN
SELECT * from #UserPrfTemp
END
설정된 FMONLY OFF 트릭을 사용한 후 제 경우 컬럼 정보를 받지 못했습니다.
이것은 제가 빈 데이터를 얻기 위해 만든 임시 테이블입니다.이제 열 정보를 받는 중입니다.
Create table #UserPrfTemp
(
[USER_ID] bigint,
[FIRST_NAME] nvarchar(60),
SCHOOL_NAME nvarchar(60),
SOCIETY_NAME nvarchar(200)
.....
}
저는 테이블 변수를 만든 다음 테이블 변수에서 돌아오는 이 문제를 해결했습니다.
DECLARE @VarTable TABLE (
NeededColumn1 VARCHAR(100),
NeededColumn2 INT,
NeededColumn3 VARCHAR(100)
)
...
--Fetch Data from Linked server here
...
INSERT INTO @VarTable (NeededColumn1,NeededColumn2,NeededColumn3)
SELECT Column1, Column2, Column3
FROM #TempTable
SELECT * FROM @VarTable.
그런 식으로 SP 결과는 EF가 액세스할 수 있는 테이블 변수로 제한됩니다.
저는 무슨 일이 일어나든 대부분의 사람들을 도울 수 있는 방법을 발견했습니다.
즐겨찾는 SQL 클라이언트를 풀업하고 모든 매개 변수 = null로 업데이트하려는 proc를 실행합니다.Visual Studio는 문자 그대로 다음과 같은 작업을 수행하려고 합니다.SET FMTONLY ON
추적합니다.두고 보세요.
오류가 발생하거나 예상치 못한 데이터가 출력될 수 있습니다.그것을 고치면 문제가 해결됩니다.
저의 경우 JSON에서 읽었던 함수가 JSON 문자열이 비어 있어서 실패했습니다.
저는 그냥 다음과 같은 것을 넣었습니다.
IF(@FooJSON IS NULL)
BEGIN
SELECT 1 VAR1, 2 VAR2;
END
ELSE
--OTHER LOGIC
그것은 아마도 추악한 해결책일 것입니다. 하지만 저는 이 난장판을 물려받았고 우리는 레이븐홀름에 가지 않습니다.
SQL EXPRESSION을 사용하여 #Temp 테이블 변경
언급URL : https://stackoverflow.com/questions/7128747/ef4-the-selected-stored-procedure-returns-no-columns
'programing' 카테고리의 다른 글
데이터베이스 공급자 유형당 허용 가능한 최대 매개 변수 수는 몇 개입니까? (0) | 2023.06.24 |
---|---|
이름이 MKMapView인 클래스를 인스턴스화할 수 없습니다. (0) | 2023.06.24 |
IIS 7에서 하위 도메인을 설정하는 방법 (0) | 2023.06.24 |
유형 스크립트에서 콜백 함수 내의 '이것'에 액세스하는 방법은 무엇입니까? (0) | 2023.06.19 |
ORA-01031 가져오기: ORA-00942 대신 테이블을 쿼리하는 동안 권한이 부족합니다. 테이블 또는 보기가 없습니다. (0) | 2023.06.19 |