[SQL] SELECT IN 오라클 매개 변수를 사용하여 문제
SQLSELECT IN 오라클 매개 변수를 사용하여 문제
SQL 쿼리에 숫자의 문자열을 삽입 할 때 나는 문제가
SELECT *
FROM tablename a
WHERE a.flokkurid IN (3857,3858,3863,3285)
ORDER BY sjodategund, rodun
...또는:
SELECT *
FROM tablename a
WHERE a.flokkurid IN (:strManyNumbers)
ORDER BY sjodategund, rodun
...이 코드 :
using (OracleCommand sel = new OracleCommand(SQL, connectionstring)) {
sel.Parameters.Add(":strManyNumbers",
OracleDbType.Varchar2,
"Client",
ParameterDirection.Input);
}
그래서 내가 얻을이 쿼리를 실행하는 경우 :
난 그냥 하나 개의 번호를 삽입하면되지만, 즉 "3857"는이 데이터를 쿼리 OK를 반환합니다.
해결법
-
==============================
1.값 세트를 전달하려면, 당신은 오라클의 테이블 또는 배열 유형을 사용해야합니다.
값 세트를 전달하려면, 당신은 오라클의 테이블 또는 배열 유형을 사용해야합니다.
처음에는 (예를 들어, 번호) 테이블 유형을 작성 :
CREATE TYPE number_table AS TABLE OF NUMBER;
쿼리에 대한 매개 변수를 만들 때, 연관 PL / SQL 배열로 선언 :
OracleParameter param1 = new OracleParameter(); param1.OracleDbType = OracleDbType.Int32; param1.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
그런 다음 몇 가지 값을 지정 :
param1 = new int[] { 3857, 3858, 3863, 3285 };
그리고 당신의 쿼리는 캐스트가 필요합니다 :
SELECT * FROM tablename a where a.flokkurid in (TABLE(CAST(:manyNumbers AS number_table))) order by sjodategund, rodun
-
==============================
2.즉 어떻게 매개 변수의 일이 아니다. 당신은 당신이 문자열의 SQL 쿼리를 조립해야 매개 변수로 "설정"을 지정할 수 없습니다. 그리고 SQL 주입에 대한 조심.
즉 어떻게 매개 변수의 일이 아니다. 당신은 당신이 문자열의 SQL 쿼리를 조립해야 매개 변수로 "설정"을 지정할 수 없습니다. 그리고 SQL 주입에 대한 조심.
또한, 이러한 살펴 할 수 있습니다 :
최신 정보
코도의 대답은 오라클에 대한 매우 흥미로운 접근 방식을 가지고있다. 지금은 그것을 테스트 할 수 없습니다,하지만 확실히 보이는 유망.
매우 비슷한 질문은 여기있다 : @DCookie에 의해 지적 OUT으로 OracleParameter 및 IN 절은. 배열 변경에있는 항목의 유형의 SQL 캐스트는 변경 될 때 때문에 정확한 중복이 아니다.
-
==============================
3.
CREATE OR REPLACE PACKAGE IH_FORMS_TRIAL.STRING_TO_TABLE IS type grs_list_row is record ( varchar_list varchar2(512), int_list number, date_list date ); type grs_list_tab is table of grs_list_row; FUNCTION ft_string_to_table(av2_list varchar2, av2_delimiter varchar2 := ',', av2_list_type varchar2 := 'V', av2_date_mask varchar2 := 'DD-MON-YY') return grs_list_tab PIPELINED; END STRING_TO_TABLE; / CREATE OR REPLACE package body IH_FORMS_TRIAL.STRING_TO_TABLE IS FUNCTION ft_string_to_table(av2_list varchar2, av2_delimiter varchar2 := ',', av2_list_type varchar2 := 'V', av2_date_mask varchar2 := 'DD-MON-YY') return grs_list_tab PIPELINED IS /********************************************************************************************************** http://www.oracle.com/technology/sample_code/tech/pl_sql/htdocs/x/Table_Functions_Cursor_Expressions/Pipelined_Table_Functions.htm http://www.akadia.com/services/ora_pipe_functions.html PIPLELINED TABLE FUNCTION PURPOSE - ------------------ This function takes a string as input and returns a table. The table that is returned will normally be used in an SQL "IN" clause ===================================================================================== ARGUMENTS ------------------ av2_list - this is a comma delimited list of values that will be converted into single rows of a table av2_delimiter - this is a character value and should only be one character long. It is the delimiter that is between valid values in the av2_list The default value is a comma ',' av2_list_type - This function can return various types of lists or tables For this parameter A value of 'V' will return a table of varchar2 A value of 'I' will return a table of integers A value of 'D' will return a table of dates av2_date_mask - This is required if the value of av2_list_type is 'D' for date The date mask will be used by the Oracle built-in TO_DATE function A default value of 'DD-MON-YY' is used ===================================================================================== RETURNS Table of values for input to an IN portion of a WHERE clause ===================================================================================== EXAMPLES SELECT * FROM <TABLE> WHERE <VARCHAR_COLUMN> IN (select varchar_list from table (ih_core_owner.core.ft_string_to_table.ft_string_to_table('has986, abc454'))); SELECT * FROM <TABLE> WHERE <INTEGER_COLUMN> IN (select int_list from table (ih_core_owner.core.ft_string_to_table.ft_string_to_table('1,2,3,4,5,6,7,8,9', ',', 'I'))); SELECT * FROM <TABLE> WHERE <DATE_COLUMN> IN (select date_list from table (ih_core_owner.core.ft_string_to_table.ft_string_to_table('2010-03-04, 2010-03-05', ',', 'D', 'YYYY-MM-DD'))); ===================================================================================== TEST CASES select varchar_list from table (ih_core_owner.core.ft_string_to_table.ft_string_to_table('has986, abc454', ',', 'V')); select int_list from table (ih_core_owner.core.ft_string_to_table.ft_string_to_table('1,2,3,4,5,6,7,8,9', ',', 'I')); select date_list from table (ih_core_owner.core.ft_string_to_table.ft_string_to_table('04-mar-10, 05-mar-10', ',', 'D')); select date_list from table (ih_core_owner.core.ft_string_to_table.ft_string_to_table('2010-03-04, 2010-03-05', ',', 'D', 'YYYY-MM-DD')); test using and invalid list type Use Y instead of V, I or D Should produce an error select varchar_list from table (ih_core_owner.core.ft_string_to_table.ft_string_to_table('has986, abc454', ',', 'Y')); test using a date format that does not match the date format passed Should produce an error select date_list from table (ih_core_owner.core.ft_string_to_table.ft_string_to_table('2010-03-04, 2010-03-05', ',', 'D', 'YYYY-MON-DD')); select date_list from table (ih_core_owner.core.ft_string_to_table.ft_string_to_table('2010-MAR-04, 2010-MAR-05', ',', 'D', 'YYYY-MM-DD')); ---------- ===================================================================================== REVISION HISTORY Called by misc systems ---------------------------------------------------------------- Modification History Date User Description ------------ -------------- ---------------------------------- 2006-03-03 HarvS Initial Release 2010-04-09 HarvS Translated from SQL Server to ORACLE Combined functions that returned lists of varchar, integer, and date into one function with optional parameters REVISION HISTORY ---------------- Build Version - 11.02.01.001 Build Date - 08-June-2010 Modified By - has986 Description - Created ******************************************************************************/ --local variable of type grs_list_row lrs_row grs_list_row; E_INVALID_LIST_TYPE EXCEPTION; li_delimiter_position int; li_previous_delimiter_position int; lv2_value varchar2(512); BEGIN if av2_list_type not in ('V', 'I', 'D') THEN raise E_INVALID_LIST_TYPE; end if; li_delimiter_position := 1; li_previous_delimiter_position := 1; li_delimiter_position := INSTR(av2_list, av2_delimiter, li_delimiter_position); while li_delimiter_position > 0 loop lv2_value := substr(av2_list, li_previous_delimiter_position, (li_delimiter_position - li_previous_delimiter_position)); --Trim the value lv2_value := RTRIM(LTRIM(lv2_value)); if length(lv2_value) > 0 THEN if av2_list_type = 'V' then --varchar lrs_row.varchar_list := lv2_value; elsif av2_list_type = 'I' then --integer lrs_row.int_list := to_number(lv2_value); elsif av2_list_type = 'D' then --date lrs_row.date_list := to_date(lv2_value, av2_date_mask); end if; pipe row ( lrs_row ); END IF; --set the new delimiter positions li_previous_delimiter_position := li_delimiter_position + 1; li_delimiter_position := INSTR(av2_list, av2_delimiter, li_delimiter_position + 1); END loop; --Get the last value lv2_value := SUBSTR(av2_list, li_previous_delimiter_position, length(av2_list)); --Trim the value lv2_value := RTRIM(LTRIM(lv2_value)); if length(lv2_value) > 0 THEN --Insert the value into the in memory table if av2_list_type = 'V' then --varchar lrs_row.varchar_list := lv2_value; elsif av2_list_type = 'I' then --integer lrs_row.int_list := to_number(lv2_value); elsif av2_list_type = 'D' then --date lrs_row.date_list := to_date(lv2_value, av2_date_mask); end if; pipe row ( lrs_row ); END IF; return; EXCEPTION WHEN E_INVALID_LIST_TYPE then /* The developer should be notified of this error during the development phase. */ raise_application_error (-20001, av2_list_type || ' is not a valid type. Valid types are (V, I, or D)' ); WHEN OTHERS THEN RAISE; END ft_string_to_table; end string_to_table; / select * FROM table( string_to_table.ft_string_to_table('1, 2, 3', ',', 'I')); select * FROM table( string_to_table.ft_string_to_table('fred, wilma, betty, barney', ',', 'V')); select * FROM table( string_to_table.ft_string_to_table('2011-5-1, 1950-1-1, 1960-1-2, 2023-12-1', ',', 'D', 'yyyy-mm-dd'));
당신을 위해이 작품을 바랍니다. 나는뿐만 아니라이 작업을 수행 다른 코드를 보았다. 어떻게 그 가치를 들어,이 마이크로 소프트 SQL 서버에서 수행하는 것이 훨씬 쉽다
할브 SATHER
from https://stackoverflow.com/questions/6155146/problem-using-oracle-parameters-in-select-in by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 하나의 테이블 컬럼에 다중 비트 값을 저장 (0) | 2020.05.16 |
---|---|
[SQL] SQLite는 아이폰에서 열처럼 ROWNUM을 얻는 방법 (0) | 2020.05.16 |
[SQL] SQL Server 2005의 쿼리 성능 (0) | 2020.05.16 |
[SQL] 결과는 SQL 전치하는 하나의 열은 복수 열로 이동되도록 (0) | 2020.05.16 |
[SQL] 두 테이블 구조의 차이점 (0) | 2020.05.16 |