在动态创建的插入语句中替换撇号

时间:2016-11-04 16:17:23

标签: sql sql-server tsql

我创建了一个包含Insert语句的查找表。值中的某些值包含撇号。

值如下所示

'SCRW, PAN-HD PHIL, THR'D: 8-32. L: 3/8""'

整个陈述是:

INSERT INTO PARTS_BOMD (BOM_ID, ITEM_REV, ITEM_CN, ITEM_NUMBER, ITEMNUMBER, FINDNUM, QTY, ITEMDESCRIPTION, ITEMREV, ITEMSIZE, REFDES, BOMTEXT02, ITEMLIST21, SUMMARYCOMPLIANCE, BOMMULTITEXT30, BOMNOTES, ITEMLIST10, BOMLIST01, BOMLIST03, BOMLIST02, ITEMTEXT22, ITEMTEXT23, ITEMLIFECYCLEPHASE, ITEMP2MULTILIST05, ITEMTEXT15, RNUM) VALUES (2009034062,'31','ECO05447','1472096','1422042','100','4','SCRW, PAN-HD PHIL, THR'D: 8-32. L: 3/8""','A0 MPL03682','PC','PC','','6 out of 6 Compliant','Missing Info','Missing Info','','ZHLB','','','X','','','AREL','Yes','0.10220',582272);

此表有超过400万条记录,大多数时间都会出现此问题。

我有什么方法可以将这个撇号改为两个单引号。

我正在使用SQL Server 2014。

生成这些插入语句的Oracle脚本:

set serveroutput on size 100000
set feedback off

declare
  v_table_name      varchar2(30) := 'PARTS_BOMD';  -- Your Tablename
  v_column_list     varchar2(2000);
  v_insert_list     varchar2(2000);
  v_ref_cur_columns varchar2(4000);
  v_ref_cur_query   varchar2(2000);
  v_ref_cur_output  varchar2(2000);
  v_column_name     varchar2(2000);
  cursor c1 is select column_name, data_type from user_tab_columns where table_name = v_table_name order by column_id;
  refcur            sys_refcursor; 
begin
  for i in c1 loop
     v_column_list := v_column_list||','||i.column_name;
     if i.data_type = 'NUMBER' then
        v_column_name := i.column_name;
     elsif i.data_type = 'DATE' then
        v_column_name := chr(39)||'to_date('||chr(39)||'||chr(39)'||'||to_char('||i.column_name||','||chr(39)||'dd/mm/yyyy hh:mi:ss'||chr(39)||')||chr(39)||'||chr(39)||', '||chr(39)||'||chr(39)||'||chr(39)||'dd/mm/rrrr hh:mi:ss'||chr(39)||'||chr(39)||'||chr(39)||')'||chr(39);
     elsif i.data_type = 'VARCHAR2' then
        v_column_name := 'chr(39)||'||i.column_name||'||chr(39)';
     end if;
     v_ref_cur_columns := v_ref_cur_columns||'||'||chr(39)||','||chr(39)||'||'||v_column_name;
  end loop; 
  v_column_list     := ltrim(v_column_list,',');
  v_ref_cur_columns := substr(v_ref_cur_columns,8);

  v_insert_list     := 'INSERT INTO '||v_table_name||' ('||v_column_list||') VALUES ';
  v_ref_cur_query   := 'SELECT '||v_ref_cur_columns||' FROM '||v_table_name;

  open refcur for v_ref_cur_query;
  loop
  fetch refcur into v_ref_cur_output; 
  exit when refcur%notfound;
    v_ref_cur_output := '('||v_ref_cur_output||');'; 
    v_ref_cur_output := replace(v_ref_cur_output,',,',',null,');
    v_ref_cur_output := replace(v_ref_cur_output,'(,','(null,');
    v_ref_cur_output := replace(v_ref_cur_output,',,)',',null)');
    v_ref_cur_output := replace(v_ref_cur_output,'null,)','null,null)');
    v_ref_cur_output := v_insert_list||v_ref_cur_output; 
    --dbms_output.put_line (v_ref_cur_output); 
    INSERT INTO BOM_INS_LOOKUP(LOOKUP_STATMENT)
    VALUES (v_ref_cur_output);
    COMMIT;
  end loop; 
end;
/

它并不多,但它确实起到了作用。

1 个答案:

答案 0 :(得分:1)

通常没有一种简单的方法可以解决这个问题。您将如何处理像这样的值列表?:'A',',','B'是一个还是两个或三个值?并且有两种方法将其拆分为两个值。

通过对格式做出一些假设,您可以采取以下方法。

declare @pos int;
declare @s varchar(1024);

declare myCursor for select <COLUMN> from T;
open myCursor;

while @@fetch_status = 0
begin 

    fetch next from myCursor into @s;

    set @pos = charindex(@s, '''', @pos);
    while @pos > 0
    begin
        /* if apostrophe is followed by comma plus apostrophe
           then assume this is the delimiter */
        if substring(@s +',''', @pos + 1, 2) <> ','''
            set @s = stuff(@s, @pos, 1, '''''');
        else
            set @pos = @pos + 2;
       set @pos = charindex(@s, '''', @pos);
    end

    update T set <COLUMN> = @s where current of myCursor;
end

close myCursor;
deallocate myCursor;

最好通过在生成INSERT查询时正确引用值来避免问题。从Oracle导出数据的方法有很多种,可以通过SQL Server轻松获取。