2012-11-28 3 views
0

프로젝트에서 사용하는 일부 SQL 코드를 매개 변수를 사용하여 변환하려고합니다. 삽입 작업이 정상적으로 작동합니다.쿼리의 값을 매개 변수로 가져 오기

with SQLDataSet do begin 
    Close; 
    SQL.Text := 'INSERT INTO testtable (keyname, waarde) VALUES (:keyname,:waarde)'; 
    Prepare; 
    for i := 1 to 10000 do begin 
    ParamByName('waarde').AsInteger := i; 
    ParamByName('keyname').AsString := 'Testa'+IntToStr(i); 
    ExecSql; 
    end; 
end; 

잘 작동하고 빠릅니다.

그러나, 나는 그것이 SELECT 문에서 작동하지 않습니다.

with SQLDataSet do begin 
    SQL.Clear; 
    SQL.Text := 'SELECT :waarde = waarde FROM testtable WHERE keyname = :keyname'; 
    Prepare; 
    for i := 1 to 10000 do begin 
    ParamByName('keyname').AsString := 'Testa'+IntToStr(i); 
    ExecSQL; 
    k[i] := ParamByName('waarde').AsInteger; 
    Close; 
    end; 
end; 

하지만 K의 값 [내가] 단지 공의로 채워집니다 : 은 먼저 다음은 작동하는 것 같다. 구식 방식을 계속 선택하고, 쿼리를 실행하고, 결과 집합을 열고 가로 지르거나, 매개 변수 값을 올바르게 선택하기 위해 한 행만있는 쿼리가있는 방법이 있습니까?

+0

사용중인 데이터 집합의 유형을 알려주십시오. 예 : TDataset, TADODataset, TClientDataset 등 ... – MikeT

+1

where 블록에는 매개 변수가 있지만 매개 변수화 할 수 없습니다. –

+0

@MikeT 순간에는 ODBC Express DataSet입니다.하지만 ADO로도 마이그레이션 중이지만 마이그레이션 중입니다. –

답변

2

짧은 대답을 (테스트되지 않음) :는 당신이 지금 할 방법을 수행하십시오. 매개 변수를 사용하여 쿼리 결과를 가져올 이유가 없습니다.

긴 대답 : 당신이 저장 프로 시저를 실행할 수있는 유사한 방법으로

SELECT 
    YourField 
INTO 
    :YourParam 
FROM 
    YourTable 
WHERE 
    ID = 1 

: 당신은 ADOCommand합니다 (ODBCExpess에 해당이 무엇인지 확실하지)를 사용하고 SELECT INTO 쿼리를 실행할 수 있습니다

.

그러나 매개 변수를 사용하는 것은 주로 입력이 유효하고 특정 유형으로 취급되도록하기 위해 수행됩니다. 또한 데이터베이스가 쿼리를 한 번 캐시하고 매개 변수를 가변적으로 볼 수 있으므로 더 나은 캐싱을 사용할 수 있습니다.

출력 (리턴 필드) 용

이 소용된다. 쿼리는 이미 일반 열로도 캐시됩니다. 이제 쿼리를 실행하고 필드를 읽습니다. 매개 변수를 사용할 수는 있지만 어떤 이점도없이 더 많은 복잡성과 제한 만 추가합니다. 이러한 종류의 매개 변수는 저장 프로 시저 및 프로그램 블록의 출력을 읽는 데 특히 유용합니다.

특정 경우에 많은 필드를 검색하고 싶습니까? (아마도 모두?)이 경우 단일 쿼리를 실행하고 결과를 반복하는 것이 현재와 같이 1000 개의 작은 쿼리를 실행하는 것보다 낫습니다. . 각 쿼리는 초기화에 약간의 오버 헤드가 있으며 필요한 모든 데이터를 한 번에 쿼리하는 경우 해당 오버 헤드를 1000 번 저장합니다. 또한 여러 가지 데이터 레코드를 가져 오는 경우 해당 결과를 매개 변수로 가져올 방법이 없으므로 매개 변수가 제한되는 이유 중 하나이며 따라서 입력에 매개 변수를 사용할 수있는 또 다른 이유가 있습니다. .

귀하의 결과 : 당신이 매개 변수 값을 설정하지 않기 때문에

당신이 0을 얻고있는 이유입니다. 따라서이 값은 NULL로 유지됩니다. AsInteger을 사용하여 값을 요청하기 때문에이 값은 정수로 변환되므로 0을 반환합니다.

쿼리에서 반환 된 값 (반환되는 한 필드)은 아마도 0 일 것입니다. 실제 표현식 X = Y을 쿼리합니다. 여기서 X는 매개 변수의 값이고 Y는 필드의 값입니다. 매개 변수의 값이 NULL이기 때문에 표현식은 항상 false로 평가됩니다 (NULL 값에 대한 일반 비교 연산자를 사용하면 사용하는 연산자 나 다른 값이 무엇이든 관계없이 항상 false를 반환합니다). true 및 false는 보통 0/1의 작은 int 필드로 표현되므로 필드 값은 아마도 0을 반환합니다. 그러나 게시 된 코드에서이 값을 사용하지 마십시오.

+0

처음에'0'을 얻는 이유를 설명하는 단락이나 두개를 추가했습니다. – GolezTrol

+0

이것이 최선의 대답이라고 생각합니다. 때로는 어떤 방식으로도 할 수 없거나해야 할 일이 있다는 말을해야합니다. –

+0

@GolezTrol, SQLQuery에도 동일하게 적용 할 수 있습니까? into SQLQuery와 구문 오류가 발생했습니다. SQLQuery와 비슷한 방식으로 수행하고 있습니까? –

1

열 이름을 매개 변수화 할 수 없습니다. waarde는 테이블의 열 이름이어야합니다. 코드를 이와 같이 변경해야합니다.

with SQLDataSet do begin 
    SQL.Clear; 
    SQL.Text := 'SELECT waarde FROM testtable WHERE keyname = :keyname'; 
    Prepare; 
    for i := 1 to 10000 do begin 
    ParamByName('keyname').AsString := 'Testa'+IntToStr(i); 
    ExecSQL; 
    k[i] := SQLDataSet['waarde']; 
    Close; 
    end; 
end; 
+0

당신은'SQLDataSet [ 'waarde']'do가 아닌'FieldByName [ 'waarde']'를 사용 했습니까? – TLama

+0

글쎄, 그렇다면'Fields [0] .AsInteger' 같은가? 더 빠르고 더 유형 증명. –

+0

@TLama 이렇게하는 데 익숙합니다. SQLDataSet [ 'waarde'] – slotomo

관련 문제