DDL(대략) 변환 스크립트(PostgreSQL→SQLServer)

수요는 거의 없다고 생각합니다만, PostgreSQL의 DDL을 SQLServer용의 DDL로 변환할 필요가 발생했을 때에 귀찮았기 때문에 작성한 스크립트입니다.

참고: 완벽한 변환이 아닙니다.
#!/usr/bin/perl
#
# Convert dumped PostgreSQL ddl to MS SQLServer ddl.
#

use strict;
use warnings;

use File::Basename;

my $targetFile = shift @ARGV;

my @converted;

open SRCDDL, "<:encoding(utf-8)", './'.$targetFile or die "[Error] Failed to open input file";
    my $row = 0;
    while (my $line = <SRCDDL>) {
       $row++;

       $line =~ s/\r//g;
       $line =~ s/\n//g;

       #
       # Type of Strings
       #

       if ($line =~ /varchar|character varying/i) {
           $line =~ s/varchar|character varying/nvarchar/gi;
           print "[$row]:Convert varchar to nvarchar.\n";
       }

       if ($line =~ /character|char/i) {
           # Nothing TODO.
       }

       if ($line =~ /\s{1}text/i) {
           $line =~ s/\s{1}text/ nvarchar(max) /gi;
           print "[$row]:Convert text to nvarchar(max).\n";
       }

       #
       # Type of numerics
       #

       if ($line =~ /\s{1}int2|smallint/i) {
           $line =~ s/\s{1}int2/ smallint/gi;
           print "[$row]:Convert int2 to smallint.\n";
       }

       if ($line =~ /\s{1}int4|integer/i) {
           $line =~ s/\s{1}int4| integer/ int/gi;
           print "[$row]:Convert int4|integer to int.\n";
       }

       if ($line =~ /\s{1}int8|bigint/i) {
           $line =~ s/\s{1}int8/ bigint/gi;
           print "[$row]:Convert int8 to bigint.\n";
       }

       #
       # Type of serials
       #

       if ($line =~ /smallserial|\s{1}serial2/i) {
           $line =~ s/smallserial|\s{1}serial2/ smallint/gi;
           print "[$row]:Convert smallserial|serial2 to smallint.\n";
       }

       if ($line =~ /bigserial|\s{1}serial8/i) {
           $line =~ s/bigserial|\s{1}serial8/ bigint/gi;
           print "[$row]:Convert bigserial|serial8 to bigint.\n";
       }

       if ($line =~ /\s{1}(serial)[\s|,]/i) {
           $line =~ s/\s{1}(serial)([\s|,])/ int$2/gi;
           print "[$row]:Convert serial to int.\n";
       }

       #
       # Type of float
       #

       if ($line =~ /decimal|numeric/i) {
           # Nothing TODO.
       }

       if ($line =~ /float4/i) {
           $line =~ s/float4/real/gi;
           print "[$row]:Convert float4 to real.\n";
       }

       if ($line =~ /double precision|float8/i) {
           $line =~ s/double precision|float8/float\(25\)/gi;
           print "[$row]:Convert double precision|float8 to float(25).\n";
       }

       #
       # Type of dates
       #

       if ($line =~ /timestamp/i) {
           # remove time zone option
           $line =~ s/with time zone//gi;
           $line =~ s/without time zone//gi;

           $line =~ s/timestamp\(\d\)+/datetime2\(6\)/gi;
           $line =~ s/timestamp/datetime2\(6\)/gi;

           # change call function
           $line =~ s/now\(\)/getdate\(\)/gi;

           print "[$row]:Convert timestamp.\n";
       }

       #
       # Type others
       #

       if ($line =~ /boolean/i) {
           $line =~ s/true/1/gi;
           $line =~ s/false/0/gi;

           $line =~ s/boolean/bit/gi;

           print "[$row]:Convert boolean to bit.\n";
       }

       #
       # Convert "CONSTRAINT"
       #

       if ($line =~ /alter table only/i) {
           $line =~ s/only//gi;
           print "[$row]:Remove 'only' from ALTER TABLE.\n";
       }

       push(@{converted}, $line);

    }
close SRCDDL;

my $outFile = $targetFile . ".mssql";
open OUTPUT, ">:encoding(utf-8)", $outFile or die "[Error] False open output file ($outFile)";
    print OUTPUT join "\n", @{converted};
close OUTPUT;

사용방법



Convert 원본 PostgreSQL DDL을 Dump



pg_dump -h localhost -d testdb -U testuser --schema-only --no-owner --file={path to}/ddl_postgres.dump

덤프 된 파일을 지정하여 실행



예:

$perl convert_ddl.pl ddl_postgres_test.dump

ddl_postgres_test.dump.mssql 생성

비고


  • Serial 형은 Integer로 변환하고 있습니다 (INDENTITY로 변환하는 등은 하지 않습니다)
  • 기타 목적에 따라 사용자 정의하십시오



  • 좋은 웹페이지 즐겨찾기