【问题标题】:PLSQL missing commaPLSQL 缺少逗号
【发布时间】:2020-05-04 08:08:30
【问题描述】:

我尝试使用 DBMS_SQL.PARSE 解析此插入语句,但我收到“缺少逗号”错误。请帮忙:(

     'insert into ' || '"' || v_materie || '"' || ' ( 
      nume,prenume,nr_matricol,valoare,data_notare) values(' ||
      v_nume || ','||
      v_prenume || ','||
      v_nr_matricol || ','||
      v_nota || ','||
      v_dataNotare || ')'

【问题讨论】:

  • 可以在执行前打印查询吗?
  • 对不起,我是想说解析
  • 您不需要将表名放在双引号之间。即 INSERT 语句的开头可以是:'insert into ' || v_materie || ' (...
  • 我需要 bc 名称中包含空格

标签: sql oracle plsql


【解决方案1】:

实际上生成插入字符串非常糟糕。 无论如何试试这个。

'insert into ' || '"' || v_materie || '"' || ' ( 
nume,prenume,nr_matricol,valoare,data_notare) values(''' ||
v_nume || ''','''||
v_prenume || ''','''||
v_nr_matricol || ''','''||
v_nota || ''','''||
v_dataNotare || ''')'

你应该把值放在'字符中,但是因为你生成字符串你需要转义符号',所以你会得到'''

【讨论】:

    【解决方案2】:

    正如@Giga 指出的那样,将 sql 语句构建为字符串连接是一个非常糟糕的主意。遭受 sql 注入不仅很危险,而且很丑陋,而且完全没有必要。您已经使用 dbms_sql 来验证查询 - 顺便说一句,这是个好主意 - 那么为什么不考虑它来构建查询。因此,您的查询一直使用 dbms_sql:

    -- Setup 
    create table "Mat Val" 
         ( nume        integer
         , prenume     integer
         , nr_matricol integer
         , valoare     integer
         , data_notare integer
         );
    
    
    declare
       k_materie_name varchar2(8) := 'Mat Val';
       k_sql_base varchar2(1000) :=  
         'insert into "v_materie" (nume,prenume,nr_matricol,valoare,data_notare) values(:1,:2,:3,:4,:5)';
    
       l_sql_stmt varchar2(1000);
       l_dbms_cursor_ref integer; 
    
       l_rows_processed integer;
    
       v_nume        integer := 1;
       v_prenume     integer := 2;
       v_nr_matricol integer := 3;
       v_valoare     integer := 4;
       v_data_notare integer := 5;
    
    begin 
      l_sql_stmt := replace(k_sql_base,'v_materie',k_materie_name);
      dbms_output.put_line('Setting up dbms_sql processing for statement:' || chr(10) || l_sql_stmt);  
    
      l_dbms_cursor_ref:= dbms_sql.open_cursor;
      dbms_sql.parse(l_dbms_cursor_ref,l_sql_stmt,DBMS_SQL.native);
    
      -- set up bind variables with local variables
      dbms_sql.bind_variable(l_dbms_cursor_ref, ':1', v_nume);
      dbms_sql.bind_variable(l_dbms_cursor_ref, ':2', v_prenume);
      dbms_sql.bind_variable(l_dbms_cursor_ref, ':3', v_nr_matricol);
      dbms_sql.bind_variable(l_dbms_cursor_ref, ':4', v_valoare);
      dbms_sql.bind_variable(l_dbms_cursor_ref, ':5', v_data_notare);
    
      -- execute dynamic sql
      l_rows_processed := dbms_sql.execute(l_dbms_cursor_ref);
    
      dbms_output.put_line('Rows inserted  to "' || k_materie_name || '" ==> ' || to_char(l_rows_processed)); 
      dbms_sql.close_cursor(l_dbms_cursor_ref);
    end ;
    

    或者只是 dbms_sql 来验证查询然后恢复立即执行:

    declare
       k_materie_name varchar2(8) := 'Mat Val';
       k_sql_base varchar2(1000) :=  
         'insert into "v_materie" (nume,prenume,nr_matricol,valoare,data_notare) values(:1,:2,:3,:4,:5)';
    
       l_sql_stmt varchar2(1000);
       l_dbms_cursor_ref integer; 
    
       l_rows_processed integer;
    
       v_nume        integer := 21;
       v_prenume     integer := 32;
       v_nr_matricol integer := 43;
       v_valoare     integer := 54;
       v_data_notare integer := 65;
    
    begin 
      l_sql_stmt := replace(k_sql_base,'v_materie',k_materie_name);
      dbms_output.put_line('Setting up executee immediate for statement:' || chr(10) || l_sql_stmt);  
    
      l_dbms_cursor_ref:= dbms_sql.open_cursor;
      dbms_sql.parse(l_dbms_cursor_ref,l_sql_stmt,DBMS_SQL.native);
      dbms_sql.close_cursor(l_dbms_cursor_ref);
    
      execute immediate l_sql_stmt 
                  using v_nume      
                      , v_prenume     
                      , v_nr_matricol 
                      , v_valoare     
                      , v_data_notare;
    
      dbms_output.put_line('Rows inserted  to "' || k_materie_name || '" ==> ' || to_char(sql%rowcount)); 
    
    end ;
    

    无论哪种方式永远不要使用字符串连接构建 SQL。规划和使用绑定变量。它更安全,因为它消除了 SQL 注入,而且你的代码更干净,实际上更容易编写(我总是需要先编写一个独立的语句来测试它,然后转换为绑定变量相对简单)。最后,如果相同的语句多次运行,只是值不同,它会更快,因为它避免了硬解析。

    【讨论】:

      猜你喜欢
      • 2019-09-12
      • 1970-01-01
      • 1970-01-01
      • 2015-11-21
      • 2017-06-20
      • 1970-01-01
      • 1970-01-01
      • 2013-10-07
      • 1970-01-01
      相关资源
      最近更新 更多