2009-08-26 2 views
0

프로젝트 용으로 ColdFusion을 사용하고 있으며 저장 프로 시저를 사용하여 더 빠를 수 있다고 생각되는 쿼리를 작성했지만 T-SQL 담당자가 아닙니다. 비교할 방법을 모르겠습니다.스토어드 프로 시저/ColdFusion의 Select 쿼리를 기반으로 테이블 업데이트

동적으로 생성 된 cfquery를 기반으로하는 테이블에서 여러 필드를 선택하는 초기 쿼리를 실행하고 있습니다. 이 쿼리를 SQL Server 저장 프로 시저로 변환하는 방법을 알고 있다고 생각합니다.

그러나 그 직후에 나는 그 쿼리의 모든 기본 키 ID를 가져 와서 해당 ID로 레코드를 "잠급니다"별도의 테이블에 대해 다른 쿼리를 실행합니다. 잠금은 시스템에이 레코드가 "체크 아웃"되었음을 알리는 두 번째 테이블의 비트 필드 (플래그)입니다. 난 단위로 실행되도록 cftransaction에 두 쿼리를 래핑했습니다.

코드 개요 :

<cftransaction> 
    <cfquery name="selectQuery"> 
     SELECT id, field2, field3 
     FROM table1 
     WHERE (bunch of conditions here) 
    </cfquery> 

    <cfquery name="updateQuery"> 
     UPDATE table2 
     SET lockField = 1 
     WHERE table2.id IN (#ValueList(selectQuery.id#) 
    </cfquery> 
</cftransaction> 

나는 다음 몇 가지 데이터를 출력을 위해 그것을 사용하는 내 응용 프로그램에 selectQuery 결과 집합을 반환합니다. cfstoredproc을 사용하여 호출 할 수있는 단일 SQL Server 2008 저장 프로 시저에서 동일한 작업을 수행하는 방법은 무엇입니까?

다시 CF로 결과 집합을 검색 한 다음 다른 쿼리를 다시 DB에 호출해야하므로 원래의 CF 방식 (cfquery)이 저장 프로 시저만큼 효율적이지 않다고 생각합니다. 단일 저장 프로시 저는 DB에서 모든 작업을 수행 한 다음 원래 쿼리 결과 집합을 반환합니다.

아이디어가 있으십니까?

답변

0

첫 번째 쿼리를 하위 쿼리로 만든 다음 별도의 문을 사용하여 결과를 반환하면 한 쿼리에서 업데이트 할 수 있습니다. 모든 것은 하나의 저장 프로 시저 일 수 있습니다 :

CREATE PROCEDURE myUpdate 
     @Variable [datatype], etc... 
    AS 
    BEGIN 
    UPDATE table2 
    SET lockField = 1 
    WHERE table2.id IN (
     SELECT id 
     FROM table1 
     WHERE (bunch of conditions here) 
    ) 
    SELECT id, field2, field3 
    FROM table1 
    WHERE (bunch of conditions here) 
    END 

매개 변수를 전달해야 할 수도 있지만 저장 프로 시저의 기본 구조입니다. 그런 다음 ColdFusion에서 다음과 같이 호출 할 수 있습니다.

<cfstoredproc procedure="myUpdate"> 
    <cfprocparam type="[CF SQL Type]" value="[CF Variable]"> 
    etc... 
    <cfprocresult name="selectQuery" resultSet="1"> 
</cfstoredproc> 

이전에 사용한 것과 같은 쿼리 결과를 사용할 수 있습니다.

+0

좋아,이 대답에 대한 온 전성 검사가 필요합니다. table1 데이터는 일정한 플럭스에 있습니다 ... 본질적으로 대기열입니다. 이것은 하나의 storedproc 안에 있기 때문에 본질적으로 단일 트랜잭션 권한으로 실행됩니다. 의미는, 내가 테이블 1에서 두 번 SELECT를 실행하기 때문에, 나는 같은 결과를 두 번 다시 얻고 있음을 보장해야합니다. 많은 사용자가이 기능을 정기적으로 사용하기 때문에 잠금 기능이 제대로 작동하는지 확인해야합니다. –

+0

아니요, 단일 트랜잭션으로 실행되고 있지 않습니다. 업데이트를 실행하기 전에 출력용 데이터가 필요한 경우 다른 방법으로 수행해야합니다. 나는 당신의 질문에 전체 잠금 장치를 잡지 않았다. –

1

"여기에 조건이 있습니다"라는 문제가 있습니다. 그 조건들은 항상 정적입니까? 항상 그렇습니다 : (FOO = @x AND BAR = @y)? 아니면 가끔 FOO가 전혀 존재하지 않는 조건부인가?

FOO가 항상 존재하지 않는 경우 저장 프로 시저에 문제가 있습니다. T-SQL은 동적 쿼리 작성을 수행 할 수 없으며 실제로는 SQL을 컴파일하고 사전 최적화하는 proc의 요점을 무효로 만들 수도 있습니다. 물론 할 수 있지만, 결국 proc 본문 안에 SQL 문자열을 작성한 다음 끝에 실행해야합니다. cfqueryparams로 CFQuery를 사용하는 것이 훨씬 낫습니다. 실제로 이것을 대신 생각한 적이 있습니까?

<cfquery name="updateQuery"> 
     UPDATE table2 
     SET lockField = 1 
     WHERE table2.id IN (SELECT id 
          FROM table1 
          WHERE (bunch of conditions here)) 
    </cfquery> 
+0

문제점은 table2를 업데이트하는 것이 아니라 table1에서 select 문의 결과 세트를 리턴해야한다는 것입니다. –

1

당신은 업데이트 된 레코드의 id의를 캡처하고 테이블 변수/임시 테이블에 삽입하는 UPDATE 문에 OUTPUT 절을 추가 할 수 있습니다. 그런 다음 결과 세트를 리턴하기 위해 table1에 다시 조인하십시오.

DECLARE @UpdatedRecords TABLE (ID INT) 

UPDATE t2 
SET  t2.lockField = 1 
OUTPUT Inserted.ID INTO @UpdatedRecords (ID) 
FROM table2 t2 INNER JOIN table1 t1 ON t2.id = t1.id 
WHERE (bunch of conditions for table1 here) 

SELECT t1.id, t1.field2, t1.field3 
FROM table1 t1 INNER JOIN @UpdatedRecords u ON t1.id = u.id 

표가 유동적 인 경우, 다른 값 ("FIELD2"와 "FIELD3은")는 UPDATE가 발생했을 당시이 보장되지 않습니다 있음을 유의하십시오.하지만 당신의 현재 방법도 그 문제에 취약하다고 생각합니다.

0

SPROC이 필요 없습니다.

UPDATE table2 
SET table2.lockField = 1 
FROM table1 
WHERE table1.id = table2.id 
    AND table1.field2 = <cfqueryparam ....> 
    AND table1.field3 = <cfqueryparam ....> 
+0

단지 이것이 중요한 질문의 묘법이라는 것을 깨달았다. : - / – Shawn

관련 문제