Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Data Bases > Pgsql Sql > bcp.exe Fix Tri...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 1 of 2 Topic 3490 of 3799
Post > Topic >>

bcp.exe Fix Triggers

by yazicivo@[EMAIL PROTECTED] ("yazicivo") Jun 2, 2008 at 11:25 AM

This is a multi-part message in MIME format.

------_=_NextPart_001_01C8C48A.2ABE01F3
Content-Type: text/plain;
	charset="ISO-8859-1"
Content-Transfer-Encoding: quoted-printable

Hi,

I'm trying to im****t some relatively huge (~300GiB) set of data from
Microsoft SQL Server database to PostgreSQL. For this purpose, I use
bcp.exe (bulk copy utility) comes with MSSQL. Despite there are command
line arguments which you can specify batch size, escape characters, null
fields, etc.; %90 of these arguments are unsuprisingly ignored by
bcp.exe. The problem is, bcp.exe

- Uses nothing to specify null fields, which is equivalent to

    COPY ... WITH NULL AS ''

  in PostgreSQL.

- Uses \x00 character to specify empty strings.

(Sorry not any single part of this mess is configurable.) To
successfully accept such an input during "COPY ... FROM ..." in
PostgreSQL, I decided to write middleware triggers to tables including
columns of type character varying. Below is the procedure I come up with

  CREATE OR REPLACE FUNCTION create_bcp_fix_triggers (_table_schema =
text)
  RETURNS void AS $$
  DECLARE
      _table       record;
      _column      record;
      _create_stmt text;
  BEGIN
      SET standard_conforming_strings TO off;
      SET escape_string_warning TO off;
      -- Find every table having a column of type 'character varying'.
      FOR _table
       IN SELECT table_name
            FROM information_schema.columns
           WHERE table_schema =3D _table_schema AND
                 data_type =3D 'character varying'
        GROUP BY table_name
        ORDER BY table_name
     LOOP _create_stmt =3D 'BEGIN;\n' ||
                         'CREATE OR REPLACE\n' ||
                         'FUNCTION ' || _table.table_name || '_bcp_fix =
()\n' ||
                         'RETURNS "trigger" AS $bcp-fix$\n' ||
                         'BEGIN\n';
          -- Create appropriate bcp.exe fix clauses for every found =
column.
          FOR _column
           IN SELECT column_name
                FROM information_schema.columns
               WHERE table_schema =3D _table_schema AND
                     table_name   =3D _table.table_name
         LOOP _create_stmt =3D _create_stmt ||
                             '    IF NEW.' || _column.column_name || ' =
=3D E''\0'' THEN\n' ||
                             '        NEW.' || _column.column_name || ' =
=3D ''''\n' ||
                             '    END IF;\n';
          END LOOP;
          _create_stmt =3D _create_stmt ||
                         '    RETURN NEW;\n' ||
                         'END;' ||
                         '$bcp-fix$ LANGUAGE plpgsql;\n' ||
                         'CREATE TRIGGER ' || _table.table_name || =
'_bcp_fix\n' ||
                         '    BEFORE INSERT ON ' || _table.table_name || =
'\n' ||
                         '    FOR EACH ROW EXECUTE ' ||
                         '    PROCEDURE ' || _table.table_name || =
'_bcp_fix();\n' ||
                         'COMMIT;';
          EXECUTE _create_stmt;
      END LOOP;
  END;
  $$ LANGUAGE plpgsql;

But executing this procedure fails for some reason I couldn't
understand.

  > SELECT public.create_bcp_fix_triggers('commsrv');
  ERROR:  syntax error at or near "AS $"
  LINE 4: RETURNS "trigger" AS $bcp-fix$
                            ^
  QUERY:  BEGIN;
  CREATE OR REPLACE
  FUNCTION xyz_bcp_fix ()
  RETURNS "trigger" AS $bcp-fix$
  BEGIN
      IF NEW.foo =3D E'        NEW.foo =3D ''
      END IF;
      IF NEW.bar =3D E'        NEW.bar =3D ''
      END IF;
      RETURN NEW;
  END;$bcp-fix$ LANGUAGE plpgsql;
  CREATE TRIGGER xyz_bcp_fix
      BEFORE INSERT ON xyz
      FOR EACH ROW EXECUTE     PROCEDURE xyz_bcp_fix();
  COMMIT;
  CONTEXT:  PL/pgSQL function "create_bcp_fix_triggers" line 41 at
  EXECUTE statement

Can anybody help me to spot the problem?


Regards.

P.S. For data transfer during migratition, I first considered using "EMS
     Data Ex****t for SQL Server" tool, but it lacks of performance.
     (~1000rows/sec) Namely, I'm open to any bcp.exe alternatives.

------_=_NextPart_001_01C8C48A.2ABE01F3
Content-Type: text/html;
	charset="ISO-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; =
charset=3Diso-8859-1">
<META NAME=3D"Generator" CONTENT=3D"MS Exchange Server version =
6.5.7652.24">
<TITLE>bcp.exe Fix Triggers</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/plain format -->

<P><FONT SIZE=3D2>Hi,<BR>
<BR>
I'm trying to im****t some relatively huge (~300GiB) set of data from<BR>
Microsoft SQL Server database to PostgreSQL. For this purpose, I use<BR>
bcp.exe (bulk copy utility) comes with MSSQL. Despite there are =
command<BR>
line arguments which you can specify batch size, escape characters, =
null<BR>
fields, etc.; %90 of these arguments are unsuprisingly ignored by<BR>
bcp.exe. The problem is, bcp.exe<BR>
<BR>
- Uses nothing to specify null fields, which is equivalent to<BR>
<BR>
&nbsp;&nbsp;&nbsp; COPY ... WITH NULL AS ''<BR>
<BR>
&nbsp; in PostgreSQL.<BR>
<BR>
- Uses \x00 character to specify empty strings.<BR>
<BR>
(Sorry not any single part of this mess is configurable.) To<BR>
successfully accept such an input during &quot;COPY ... FROM ...&quot; =
in<BR>
PostgreSQL, I decided to write middleware triggers to tables =
including<BR>
columns of type character varying. Below is the procedure I come up =
with<BR>
<BR>
&nbsp; CREATE OR REPLACE FUNCTION create_bcp_fix_triggers (_table_schema =
text)<BR>
&nbsp; RETURNS void AS $$<BR>
&nbsp; DECLARE<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
_table&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; record;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _column&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
record;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _create_stmt text;<BR>
&nbsp; BEGIN<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SET standard_conforming_strings TO =
off;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SET escape_string_warning TO off;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- Find every table having a column of =
type 'character varying'.<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FOR _table<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IN SELECT table_name<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FROM =
information_schema.columns<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHERE =
table_schema =3D _table_schema AND<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp; data_type =3D 'character varying'<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GROUP BY table_name<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ORDER BY table_name<BR>
&nbsp;&nbsp;&nbsp;&nbsp; LOOP _create_stmt =3D 'BEGIN;\n' ||<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
'CREATE OR REPLACE\n' ||<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
'FUNCTION ' || _table.table_name || '_bcp_fix ()\n' ||<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
'RETURNS &quot;trigger&quot; AS $bcp-fix$\n' ||<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
'BEGIN\n';<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- Create =
appropriate bcp.exe fix clauses for every found column.<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FOR _column<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IN SELECT =
column_name<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp; FROM information_schema.columns<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp; WHERE table_schema =3D _table_schema AND<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table_name&nbsp;&nbsp; =
=3D _table.table_name<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LOOP _create_stmt =3D =
_create_stmt ||<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp; '&nbsp;&nbsp;&nbsp; IF NEW.' || =
_column.column_name || ' =3D E''\0'' THEN\n' ||<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp; '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NEW.' =
|| _column.column_name || ' =3D ''''\n' ||<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp; '&nbsp;&nbsp;&nbsp; END IF;\n';<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; END LOOP;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _create_stmt =3D =
_create_stmt ||<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
'&nbsp;&nbsp;&nbsp; RETURN NEW;\n' ||<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
'END;' ||<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
'$bcp-fix$ LANGUAGE plpgsql;\n' ||<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
'CREATE TRIGGER ' || _table.table_name || '_bcp_fix\n' ||<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
'&nbsp;&nbsp;&nbsp; BEFORE INSERT ON ' || _table.table_name || '\n' =
||<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
'&nbsp;&nbsp;&nbsp; FOR EACH ROW EXECUTE ' ||<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
'&nbsp;&nbsp;&nbsp; PROCEDURE ' || _table.table_name || '_bcp_fix();\n' =
||<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
'COMMIT;';<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EXECUTE =
_create_stmt;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; END LOOP;<BR>
&nbsp; END;<BR>
&nbsp; $$ LANGUAGE plpgsql;<BR>
<BR>
But executing this procedure fails for some reason I couldn't<BR>
understand.<BR>
<BR>
&nbsp; &gt; SELECT public.create_bcp_fix_triggers('commsrv');<BR>
&nbsp; ERROR:&nbsp; syntax error at or near &quot;AS $&quot;<BR>
&nbsp; LINE 4: RETURNS &quot;trigger&quot; AS $bcp-fix$<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp; ^<BR>
&nbsp; QUERY:&nbsp; BEGIN;<BR>
&nbsp; CREATE OR REPLACE<BR>
&nbsp; FUNCTION xyz_bcp_fix ()<BR>
&nbsp; RETURNS &quot;trigger&quot; AS $bcp-fix$<BR>
&nbsp; BEGIN<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IF NEW.foo =3D =
E'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NEW.foo =3D ''<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; END IF;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IF NEW.bar =3D =
E'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NEW.bar =3D ''<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; END IF;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RETURN NEW;<BR>
&nbsp; END;$bcp-fix$ LANGUAGE plpgsql;<BR>
&nbsp; CREATE TRIGGER xyz_bcp_fix<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BEFORE INSERT ON xyz<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FOR EACH ROW =
EXECUTE&nbsp;&nbsp;&nbsp;&nbsp; PROCEDURE xyz_bcp_fix();<BR>
&nbsp; COMMIT;<BR>
&nbsp; CONTEXT:&nbsp; PL/pgSQL function =
&quot;create_bcp_fix_triggers&quot; line 41 at<BR>
&nbsp; EXECUTE statement<BR>
<BR>
Can anybody help me to spot the problem?<BR>
<BR>
<BR>
Regards.<BR>
<BR>
P.S. For data transfer during migratition, I first considered using =
&quot;EMS<BR>
&nbsp;&nbsp;&nbsp;&nbsp; Data Ex****t for SQL Server&quot; tool, but it =
lacks of performance.<BR>
&nbsp;&nbsp;&nbsp;&nbsp; (~1000rows/sec) Namely, I'm open to any bcp.exe =
alternatives.</FONT>
</P>

</BODY>
</HTML>
------_=_NextPart_001_01C8C48A.2ABE01F3--
 




 2 Posts in Topic:
bcp.exe Fix Triggers
yazicivo@[EMAIL PROTECTED  2008-06-02 11:25:08 
Re: bcp.exe Fix Triggers
dev@[EMAIL PROTECTED] (J  2008-06-02 08:36:17 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Tue Dec 2 21:33:15 CST 2008.