I want to assign mulitple values into a variable and use that variable in where-clause.
For Ex:
declare
    v_filename varchar2(300) := ''('filename1',开发者_JAVA百科'filename2')'';
    cnt number;
begin
    select count(*) into cnt from table_name
    where filename in v_filename;
end;
Please advise.
Thanks, Deepak
you have basically 2 options. 1. Use dynamic query 2. Use collections
- With dynamic query you dynamically construct the query at runtime and than run it:
DECLARE
  v_filename VARCHAR2(300) := '(''ALL_VIEWS'', ''ALL_TABLES'')'; 
--double quotes inside a string
  cnt NUMBER;
BEGIN
execute immediate 'SELECT COUNT(*) INTO :cnt FROM all_views
   WHERE view_name IN ' || v_filename
   into cnt;
  dbms_output.put_line('counted: ' || cnt);
END;
/
Advantages: easy to write, especially for short queries, fast Disadvanteges: possible SQL INJECTION in cases when you wrongly paste user input in the query string, hard parse everytime you change the filename list
- Use collections. You create a collection type, then fill it and use it as a pseudo table.
create type tt_strings as table of varchar2(30);
declare 
  cnt NUMBER;
  v_condition tt_strings;
begin
  v_condition := tt_strings();
  v_condition.extend;
  v_condition(1) := 'ALL_VIEWS';
  v_condition.extend;
  v_condition(2) := 'ALL_TABLES';
  SELECT COUNT(*)
    INTO cnt
    FROM all_views o, TABLE(v_condition) x
   WHERE x.column_value = o.VIEW_NAME;
  dbms_output.put_line('counted: ' || cnt);
end;
/
Advantages: Safe, maintainable for larger collections with more than just 2 elements Disadvatages: You need to create a type, Harder to code (at first), a bit slower (which in 99% cases doesn't matter)
I would recommend reading Dynamic IN-Lists
EXECUTE IMMEDIATE is also a possibility, but I wouldn't recommend it if you don't check the IN string.
Just wrote on the quick(used the first method presented in "Dynamic IN-Lists"):
CREATE OR REPLACE TYPE t_varchar_tab AS TABLE OF VARCHAR2 (4000);
CREATE OR REPLACE FUNCTION in_list (p_in_list  IN  VARCHAR2) RETURN t_varchar_tab
AS
  l_tab   t_varchar_tab := t_varchar_tab();
  l_text  VARCHAR2(32767) := p_in_list || ',';
  l_idx   NUMBER;
BEGIN
  LOOP
    l_idx := INSTR(l_text, ',');
    EXIT WHEN NVL(l_idx, 0) = 0;
    l_tab.extend;
    l_tab(l_tab.last) := TRIM(SUBSTR(l_text, 1, l_idx - 1));
    l_text := SUBSTR(l_text, l_idx + 1);
  END LOOP;
  RETURN l_tab;
END;
SELECT * FROM TABLE(in_list('filename1,filename2'));
SELECT COUNT(*) INTO cnt FROM table_name WHERE filename IN (SELECT * FROM TABLE(in_list(v_filename)));
You must put the whole query into a string and then execute that string with EXECUTE IMMEDIATE (see the docs).
Alternatively to the "EXECUTE IMMEDIATE", you could use like, e.g.
declare
    v_filename varchar2(300) := '(''filename1'',''filename2'')';
    cnt number;
begin
    select count(*) into cnt from table_name
    where v_filename like '%'''||filename||'''%';
end;
Note that the parenteses and the comma in v_filename are just for human readability. This is by no means a perfect solution, as it presumes that the filenames in your table do not contain some special characters; it's also bad in terms of performance if there is an index on the filename column (which is not used this way).
 
         
                                         
                                         
                                         
                                        ![Interactive visualization of a graph in python [closed]](https://www.devze.com/res/2023/04-10/09/92d32fe8c0d22fb96bd6f6e8b7d1f457.gif) 
                                         
                                         
                                         
                                         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论