2016-02-26 49 views
0

我動態構造與名稱的user_data在PL/SQL程序字符串,單引號(')和形式WHERE IN條件不通過附加的用戶名接受字符串值

'abc123','xyz456','pqr789' 

的逗號(,)但是,當我通過這個字符串凡在SELECT語句

SELECT * FROM table_name WHERE USERNAME IN (user_data) 

它拋出一個NO_DATA_FOUND異常的情況。

另一方面,如果我的字符串只包含一個沒有引號的用戶,它就能夠找到該用戶並顯示所需的輸出。

的數據類型USER_DATA是VARCHAR2。

+3

的可能的複製[參數化子句的SQL](http://stackoverflow.com/questions/337704/parameterize-an-sql-in-clause) –

+0

或這個http://stackoverflow.com/questions/6155146/problem-using-oracle-parameters-in-select-in/6155215#6155215 –

+0

在這兩種情況下,你可以打印和發佈你的字符串'user_data'的內容,工作不工作? – Aleksej

回答

0

這不是那樣的工作。您的表達等於

SELECT * FROM table_name WHERE USERNAME = '''abc123'', ''xyz456'', ''pqr789'''; 

這就是爲什麼沒有結果。

你可以做這樣的事情,才達到慾望的效果:

SELECT * FROM table_name WHERE user_data like '%''' || USERNAME || '''%'; 

,但它不會是相同的,但。

3

您可以使用集合做到這一點:

CREATE TYPE VARCHAR2s_Table IS TABLE OF VARCHAR2(100); 
/

然後輸入你的數據是這樣的:

SELECT * 
FROM table_name 
WHERE user_data MEMBER OF VARCHAR2s_Table('abc123','xyz456','pqr789'); 

或者

您可以創建一個函數來分割數據並生成集合:

CREATE TYPE VARCHAR2_TABLE AS TABLE OF VARCHAR2(4000); 
/

CREATE OR REPLACE FUNCTION split_String(
    i_str IN VARCHAR2, 
    i_delim IN VARCHAR2 DEFAULT ',' 
) RETURN VARCHAR2_TABLE DETERMINISTIC 
AS 
    p_result  VARCHAR2_TABLE := VARCHAR2_TABLE(); 
    p_start  NUMBER(5) := 1; 
    p_end   NUMBER(5); 
    c_len CONSTANT NUMBER(5) := LENGTH(i_str); 
    c_ld CONSTANT NUMBER(5) := LENGTH(i_delim); 
BEGIN 
    IF c_len > 0 THEN 
    p_end := INSTR(i_str, i_delim, p_start); 
    WHILE p_end > 0 LOOP 
     p_result.EXTEND; 
     p_result(p_result.COUNT) := SUBSTR(i_str, p_start, p_end - p_start); 
     p_start := p_end + c_ld; 
     p_end := INSTR(i_str, i_delim, p_start); 
    END LOOP; 
    IF p_start <= c_len + 1 THEN 
     p_result.EXTEND; 
     p_result(p_result.COUNT) := SUBSTR(i_str, p_start, c_len - p_start + 1); 
    END IF; 
    END IF; 
    RETURN p_result; 
END; 
/

然後,你可以這樣做:

SELECT * 
FROM table_name 
WHERE user_data MEMBER OF split_String('abc123,xyz456,pqr789', ','); 

或:

SELECT * 
FROM table_name 
WHERE user_data MEMBER OF split_String(TRIM('''' FROM '''abc123'',''xyz456'',''pqr789'''), ''','''); 
0

你可以在你IN第一個動態的字符串是這樣的:

SQL> declare 
    2  user_data varchar2(1000); 
    3  vSQL  varchar2(2000); 
    4  type  tabUser is table of varchar2(16); 
    5  outData tabUser; 
    6 begin 
    7  user_data := '''abc'', ''123'', ''zzz'''; 
    8  -- 
    9  vSQL := 'select userName from table_name where username in (' || user_data || ')'; 
10  -- 
11  execute immediate vSQL bulk collect into outData; 
12  -- 
13  dbms_output.put_line('user_data: ' || user_data); 
14  for i in outData.first .. outData.last loop 
15   dbms_output.put_line('User: ' || outData(i)); 
16  end loop; 
17 end; 
18/
user_data: 'abc', '123', 'zzz' 
User: abc 
User: 123 

PL/SQL procedure successfully completed. 

SQL> select * from table_name; 

USERNAME 
---------------- 
abc 
ABC 
123 

在這種情況下,你無論您是否有一個或多個用戶名,都必須在字符串中使用帶引號的名稱。

0

你的SELECT語句

SELECT * FROM table_name WHERE USERNAME IN (user_data)

將被視爲

SELECT * FROM table_name WHERE USERNAME = 'abc123','xyz456','pqr789'

這是不正確的。

一個替代方案是

SELECT * FROM table_name WHERE INSTR(user_data, USERNAME) > 0