2016-11-04 75 views
1

我创建了一个包含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; 
/

这是不是很多,但它的工作。

+3

你可以很容易地使用REPLACE来“解决”这个问题。我会建议尽管如果你有一个有400万插入语句的表,你正在做一些可怕的错误。这听起来像是需要存储过程而不是像这样存储查询的情况。 –

+0

您是否需要修复已经生成的语句,或者您是否需要修复语句生成代码? –

+1

作为我之前的评论的后续。想想如果你改变你的一张桌子,你的生活将会变得多么荒谬。您必须更新400万个插入语句,而不是单个存储过程。 –

回答

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选中。

+0

感谢您的回复。我通过在Oracle中创建一个虚拟永久表并用双引号更新撇号,然后在SQL Server中加载SQL插入语句来解决此问题。它成功执行。 –