문제

얼마전에 제가 찾고 있던 것이 isql을 통해 텍스트 필드에 값을 삽입하는 방법그리고 결국 나에게 맞는 로드 명령을 찾았습니다.

Perl에서 실행하려고 하면 작동하지 않습니다.구문 오류가 발생합니다.나는 두 가지 별도의 방법을 시도했지만 둘 다 지금까지 작동하지 않습니다.

각 루프 주기가 끝날 때 SQL 문 변수를 인쇄하여 구문이 정확하다는 것을 알지만 올바르게 전달되지는 않습니다.

제가 테스트한 최신 코드는 다음과 같습니다.

foreach(@files)
{

$STMT = <<EOF;
load from $_ insert into some_table
EOF

$sth = $db1->prepare($STMT);
$sth->execute;

}

@files 요소가 파이프로 구분된 텍스트 파일의 전체 경로/위치인 배열입니다(예:/home/xx/xx/xx/something.txt)

테이블의 열 수가 텍스트 파일의 필드 수와 일치하고 유형 검사가 양호합니다. (테스트 파일은 실패 없이 수동으로 로드했습니다.)

내가받는 오류는 다음과 같습니다.

DBD::Informix::db prepare failed: SQL: -201: A syntax error has occurred.

이 문제의 원인이 무엇인지 아시나요?


RET 및 Petr의 답변 편집

$STMT = "'LOAD FROM $_ INSERT INTO table'";
    system("echo $STMT | isql $db")

die 명령이 부자연스러운 죽음을 강요하고 명령문을 작은따옴표로 묶어야 했기 때문에 이것을 이렇게 변경해야 했습니다.

도움이 되었습니까?

해결책

Petr의 말이 맞습니다. LOAD 문은 ISQL 또는 DB-Access 확장이므로 DBI를 통해 실행할 수 없습니다.매뉴얼을 보면 SPL, ESQL/C 등에 대한 구문도 유효하지 않다는 것을 알 수 있습니다.

스크립트를 실행하기 위해 Perl을 사용해야 하는지, 아니면 Perl이 단지 SQL을 생성하는 편리한 방법인지는 확실하지 않습니다.

전자이고 순수한 Perl 방법을 원한다면 INSERT 문을 준비하고(겉으로 보기에는 테이블이 하나뿐인 걸까요?) 다음을 사용하여 파일 전체를 후루룩 읽어야 합니다. split 열로 나누고 준비된 삽입을 실행합니다.

그렇지 않으면 Perl을 사용하여 SQL을 생성하고 DB-Access를 통해 직접 실행할 수 있습니다. system 또는 둘 다 쉘 스크립트나 DOS 배치 파일로 래핑하여 수행할 수 있습니다.

시스템 호출 버전

foreach (@files) {
    my $stmt = "LOAD FROM $_ INSERT INTO table;\n";
    system("echo $stmt | dbaccess $database")
            || die "Statement $stmt failed: $!\n";
}

배치 스크립트 버전에서는 모든 SQL을 단일 스크립트로 작성할 수 있습니다. 즉:

perl -e 'while(@ARGV){shift; print "LOAD FROM '$_' INSERT INTO table;\n"}' file1 [ file2 ... ] > loadfiles.sql
isql database loadfiles.sql

주의, 파일 이름에 대한 따옴표에 대한 설명은 파일 이름에 공백이나 메타 문자가 포함된 경우에만 관련이 있습니다. 이는 일반적인 문제입니다.

또한 isql과 dbaccess 사이의 주요 동작 차이점 중 하나는 이러한 방식으로 실행될 때 dbaccess는 오류 시 중지되지 않지만 isql은 중지된다는 것입니다.오류 발생 시 dbaccess 처리를 중지하려면 환경에서 DBACCNOIGN=1을 설정하십시오.

도움이 되었기를 바랍니다.

다른 팁

쿼리가 SQL 쿼리가 아니기 때문에 ISQL에게 입력 파일을 구문 분석하고 삽입 문을 생성하도록 ISQL 명령입니다.

당신이 그것에 대해 생각한다면, 서버는 완전히 다른 컴퓨터에있을 수 있으며 어떤 파일에 대해 이야기하고 있는지, 어떻게 액세스하는지 전혀 모릅니다.

따라서 기본적으로 두 가지 옵션이 있습니다.

  1. ISQL을 호출하고로드 명령을 파이프로 파이프 - 매우 추악한
  2. 파일을 직접 구문 분석하고 삽입 문을 생성하십시오

파일에 유의하십시오 Notes/load.unload DBD :: Informix와 함께 배포되며 Perl, DBI 및 DBD :: Informix를 사용하여 언로드 작업을 처리하는 방법에 대한 지침이 포함되어 있습니다. 내 chagrin에 대해서는 부하 섹션에 대해 "TBD"(다소)라고 말합니다.

다른 사람들이 언급했듯이로드 및 언로드 명령문은 다양한 클라이언트 측 도구로 가짜 SQL 문처럼 보이지만 Informix 서버는 주로 클라이언트 시스템에서 파일을 가져 오는 문제로 인해 자체를 지원하지 않습니다 (아마도 PC) 서버 시스템 (아마도 Solaris 기계)에.

로드 명령문을 시뮬레이션하려면 분석해야합니다. INSERT INTO Table 부분. 열을 나열하는 경우 (INSERT INTO Table(Col03, Col05, Col09)),로드 데이터 파일에서 세 가지 값을 기대할 수 있으며이 세 열로 들어갑니다. 당신은 진술을 준비 할 것입니다 'SELECT Col03, Col05, Col09 FROM Table'열의 유형을 얻기 위해. 그렇지 않으면 진술을 준비해야합니다.SELECT * FROM Table'열의 전체 열 목록 (및 해당 유형)을 얻으려면. 열 이름과 열 수가 주어지면 적절한 삽입문을 작성하고 준비 할 수 있습니다. 'INSERT INTO Table(Col03, Col05, Col09) VALUES(?,?,?)' 또는 'INSERT INTO Table VALUES(?,?,?,?,?,?,?,?,?)'. 두 번째 이름에 열 이름을 포함시킬 수 있습니다.

그 준비가되면 이제 언로드 된 데이터를 구문 분석했습니다. SQLCMD 프로그램에서 사용할 수있는 문서가 있습니다. IIUG 소프트웨어 아카이브 (같은 이름의 Microsoft의 신생 프로그램보다 훨씬 길었습니다). 그것은 하역 형식을 상당히 상세하게 설명합니다. Perl은 Informix가 사용하는 모든 것을 처리 할 수있는 기능이 있습니다. load.unload DBD :: Informix로 배포 된 파일.

빠른 인터넷 검색 부하에 대한 구문이 있음을 보여주었습니다 파일 이름에 인용 표시를 넣습니다. 당신이 당신의 진술을 바꾸면 :

load from '$_' insert into some_table

당신의 진술은 장소 홀더를 사용하지 않기 때문에 DBI 인용 기능을 사용하는 것과는 달리 인용문을 직접 넣어야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top