2016-10-10 1 views
1

나는 많은 테이블을 생성 할 DDL 스크립트를 가지고 있으며, 테스트 사이에 데이터베이스를 정리하기 위해 this script을 사용하고있다.처음 PDO가 전체 구문을 실행하지 않는 이유는 무엇입니까?

이 스크립트를 처음 실행하면 모든 테이블이 만들어집니다. 내가 스크립트를 두 번 실행하려고하면이 가정 된 것처럼 모든 테이블을 삭제하지 않았기 때문에

enter image description here

하지만 어떤 이상한 이유로

CleanMsSQLdb($pdo); 

$ddl = file_get_contents(__DIR__.'/ddl.sql'); 

$pdo->exec($ddl); 

는 오류가 발생합니다.

enter image description here

정말로 나를 방해하는 것은 단순히 두 번 연속 깨끗한 스크립트를 실행하는 경우, 다음은 모든 상품과 잘 작동한다는 것입니다

PHP Fatal error: Uncaught PDOException: SQLSTATE[42S01]: Base table or view already exists: 2714 [Microsoft][ODBC Driver 13 for SQL Server][SQL Server] There is already an object named 'tmpDataRecordSAMPLE' in the database. (SQLExecDirect[2714] at /build/php7.0-41GaEn/php7.0-7.0.8/ext/pdo_odbc/odbc_driver.c:247)

.

CleanMsSQLdb($pdo); 
CleanMsSQLdb($pdo); 

$ddl = file_get_contents(__DIR__.'/ddl.sql'); 

$pdo->exec($ddl); 

첫 번째 패스에서 모든 테이블을 삭제하지 않는 이유는 무엇입니까?

테이블을 삭제하려고 할 때 오류가 발생하지 않습니다.

Microsoft SQL Server Management Studio에서 문을 실행하면 첫 번째 단계에서 모든 테이블이 삭제되므로 PDO가 아닌 이유는 무엇입니까? 내 소개


나는 마이크로 소프트 SQL 서버 2012 (SP3)에 연결 PHP 7.0.8-0ubuntu0.16.04.3 (CLI) (NTS) (KB3072779로 우분투 리눅스 16.04.1를 실행 해요) - 11.0.6020.0 (큰 데이터 덤프

죄송 Microsoft® ODBC Driver 13 (Preview) for SQL Server®

$hostname = 'sql.example.com'; 
$database = 'mydb'; 
$username = 'db_owner'; 
$password = '[email protected]'; 
$driver = 'ODBC Driver 13 for SQL Server'; 

$pdo = new PDO("odbc:Driver=$driver; 
    Server=$hostname; 
    Database=$database", 
    $username, 
    $password 
); 
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

ddl.sql를 사용하여 X64), 그러나 나는이 것 작은 스크립트를 재현 할 수있는, 그래서 일에 대한 호기심 뭔가가있다 특히 테이블.

CREATE TABLE [tmpData] (
    [date] datetime, 
    jpetl_id int IDENTITY PRIMARY KEY 
); 

CREATE TABLE [tmpDataRecord] (
    jpetl_pid int, 
    CONSTRAINT fk_tmpDataRecord 
     FOREIGN KEY (jpetl_pid) 
     REFERENCES [tmpData](jpetl_id), 
    [id] tinyint, 
    jpetl_id int IDENTITY PRIMARY KEY 
); 

CREATE TABLE [tmpDataRecordSAMPLE] (
    jpetl_pid int, 
    CONSTRAINT fk_tmpDataRecordSAMPLE 
     FOREIGN KEY (jpetl_pid) 
     REFERENCES [tmpDataRecord](jpetl_id), 
    [id] tinyint, 
    [created] datetime, 
    [CONTRACT_TERM] varchar(8), 
    [PRICE] decimal(6,3), 
    [ABSTRACT] varchar(100), 
    jpetl_id int IDENTITY PRIMARY KEY 
); 

CREATE TABLE [tmpDataRecordSAMPLEADMIN_DEP] (
    jpetl_pid int, 
    CONSTRAINT fk_tmpDataRecordSAMPLEADMIN_DEP 
     FOREIGN KEY (jpetl_pid) 
     REFERENCES [tmpDataRecordSAMPLE](jpetl_id), 
    [id] bigint, 
    [primaryKey] varchar(10), 
    [DEP] varchar(10), 
    jpetl_id int IDENTITY PRIMARY KEY 
); 

CREATE TABLE [tmpDataRecordSAMPLESUPP_DEP] (
    jpetl_pid int, 
    CONSTRAINT fk_tmpDataRecordSAMPLESUPP_DEP 
     FOREIGN KEY (jpetl_pid) 
     REFERENCES [tmpDataRecordSAMPLE](jpetl_id), 
    [id] bigint, 
    [primaryKey] varchar(19), 
    jpetl_id int IDENTITY PRIMARY KEY 
); 

CREATE TABLE [tmpDataRecordSAMPLESUPP_DEPDEP] (
    jpetl_pid int, 
    CONSTRAINT fk_tmpDataRecordSAMPLESUPP_DEPDEP 
     FOREIGN KEY (jpetl_pid) 
     REFERENCES [tmpDataRecordSAMPLESUPP_DEP](jpetl_id), 
    [DEP] varchar(19), 
    jpetl_id int IDENTITY PRIMARY KEY 
); 

CREATE TABLE [tmpDataRecordSAMPLETITLE] (
    jpetl_pid int, 
    CONSTRAINT fk_tmpDataRecordSAMPLETITLE 
     FOREIGN KEY (jpetl_pid) 
     REFERENCES [tmpDataRecordSAMPLE](jpetl_id), 
    [TITLE] varchar(19), 
    jpetl_id int IDENTITY PRIMARY KEY 
); 

CREATE TABLE [tmpDataRecordSAMPLESAMPLE_AUTH] (
    jpetl_pid int, 
    CONSTRAINT fk_tmpDataRecordSAMPLESAMPLE_AUTH 
     FOREIGN KEY (jpetl_pid) 
     REFERENCES [tmpDataRecordSAMPLE](jpetl_id), 
    [id] tinyint, 
    [FACULTY_NAME] smallint, 
    [FACULTY_NAMEfid] smallint, 
    [FNAME] varchar(4), 
    [MNAME] varchar(100), 
    [LNAME] varchar(3), 
    [ISSTUDENT] varchar(100), 
    [DISPLAY] varchar(2), 
    [INITIATION] datetime, 
    jpetl_id int IDENTITY PRIMARY KEY 
); 

CREATE TABLE [tmpDataRecordSAMPLESAMPLE_EDITOR] (
    jpetl_pid int, 
    CONSTRAINT fk_tmpDataRecordSAMPLESAMPLE_EDITOR 
     FOREIGN KEY (jpetl_pid) 
     REFERENCES [tmpDataRecordSAMPLE](jpetl_id), 
    [id] tinyint, 
    [FACULTY_NAME] varchar(100), 
    [FNAME] varchar(100), 
    [MNAME] varchar(100), 
    [LNAME] varchar(100), 
    [DISPLAY] varchar(100), 
    jpetl_id int IDENTITY PRIMARY KEY 
); 

CREATE TABLE [Data] (
    [date] datetime, 
    jpetl_id int PRIMARY KEY 
); 

CREATE TABLE [DataRecord] (
    jpetl_pid int, 
    CONSTRAINT fk_DataRecord 
     FOREIGN KEY (jpetl_pid) 
     REFERENCES [Data](jpetl_id), 
    [id] tinyint, 
    jpetl_id int PRIMARY KEY 
); 

CREATE TABLE [DataRecordSAMPLE] (
    jpetl_pid int, 
    CONSTRAINT fk_DataRecordSAMPLE 
     FOREIGN KEY (jpetl_pid) 
     REFERENCES [DataRecord](jpetl_id), 
    [id] tinyint, 
    [created] datetime, 
    [CONTRACT_TERM] varchar(8), 
    [PRICE] decimal(6,3), 
    [ABSTRACT] varchar(100), 
    jpetl_id int PRIMARY KEY 
); 

CREATE TABLE [DataRecordSAMPLEADMIN_DEP] (
    jpetl_pid int, 
    CONSTRAINT fk_DataRecordSAMPLEADMIN_DEP 
     FOREIGN KEY (jpetl_pid) 
     REFERENCES [DataRecordSAMPLE](jpetl_id), 
    [id] bigint, 
    [primaryKey] varchar(10), 
    [DEP] varchar(10), 
    jpetl_id int PRIMARY KEY 
); 

CREATE TABLE [DataRecordSAMPLESUPP_DEP] (
    jpetl_pid int, 
    CONSTRAINT fk_DataRecordSAMPLESUPP_DEP 
     FOREIGN KEY (jpetl_pid) 
     REFERENCES [DataRecordSAMPLE](jpetl_id), 
    [id] bigint, 
    [primaryKey] varchar(19), 
    jpetl_id int PRIMARY KEY 
); 

CREATE TABLE [DataRecordSAMPLESUPP_DEPDEP] (
    jpetl_pid int, 
    CONSTRAINT fk_DataRecordSAMPLESUPP_DEPDEP 
     FOREIGN KEY (jpetl_pid) 
     REFERENCES [DataRecordSAMPLESUPP_DEP](jpetl_id), 
    [DEP] varchar(19), 
    jpetl_id int PRIMARY KEY 
); 

CREATE TABLE [DataRecordSAMPLETITLE] (
    jpetl_pid int, 
    CONSTRAINT fk_DataRecordSAMPLETITLE 
     FOREIGN KEY (jpetl_pid) 
     REFERENCES [DataRecordSAMPLE](jpetl_id), 
    [TITLE] varchar(19), 
    jpetl_id int PRIMARY KEY 
); 

CREATE TABLE [DataRecordSAMPLESAMPLE_AUTH] (
    jpetl_pid int, 
    CONSTRAINT fk_DataRecordSAMPLESAMPLE_AUTH 
     FOREIGN KEY (jpetl_pid) 
     REFERENCES [DataRecordSAMPLE](jpetl_id), 
    [id] tinyint, 
    [FACULTY_NAME] smallint, 
    [FACULTY_NAMEfid] smallint, 
    [FNAME] varchar(4), 
    [MNAME] varchar(100), 
    [LNAME] varchar(3), 
    [ISSTUDENT] varchar(100), 
    [DISPLAY] varchar(2), 
    [INITIATION] datetime, 
    jpetl_id int PRIMARY KEY 
); 

CREATE TABLE [DataRecordSAMPLESAMPLE_EDITOR] (
    jpetl_pid int, 
    CONSTRAINT fk_DataRecordSAMPLESAMPLE_EDITOR 
     FOREIGN KEY (jpetl_pid) 
     REFERENCES [DataRecordSAMPLE](jpetl_id), 
    [id] tinyint, 
    [FACULTY_NAME] varchar(100), 
    [FNAME] varchar(100), 
    [MNAME] varchar(100), 
    [LNAME] varchar(100), 
    [DISPLAY] varchar(100), 
    jpetl_id int PRIMARY KEY 
); 

CleanMsSQLdb

이 커서 방해했다 exec

function CleanMsSQLdb(PDO $pdo){ 
    $sql = " 
     /* Drop all non-system stored procs */ 
     DECLARE @name VARCHAR(128) 
     DECLARE @SQL VARCHAR(254) 

     SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'P' AND category = 0 ORDER BY [name]) 

     WHILE @name is not null 
     BEGIN 
      SELECT @SQL = 'DROP PROCEDURE [dbo].[' + RTRIM(@name) +']' 
      EXEC (@SQL) 
      PRINT 'Dropped Procedure: ' + @name 
      SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'P' AND category = 0 AND [name] > @name ORDER BY [name]) 
     END 
    "; 
    $pdo->exec($sql); 

    $sql = " 
     /* Drop all views */ 
     DECLARE @name VARCHAR(128) 
     DECLARE @SQL VARCHAR(254) 

     SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'V' AND category = 0 ORDER BY [name]) 

     WHILE @name IS NOT NULL 
     BEGIN 
      SELECT @SQL = 'DROP VIEW [dbo].[' + RTRIM(@name) +']' 
      EXEC (@SQL) 
      PRINT 'Dropped View: ' + @name 
      SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'V' AND category = 0 AND [name] > @name ORDER BY [name]) 
     END 
    "; 
    $pdo->exec($sql); 

    $sql = " 
     /* Drop all functions */ 
     DECLARE @name VARCHAR(128) 
     DECLARE @SQL VARCHAR(254) 

     SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] IN (N'FN', N'IF', N'TF', N'FS', N'FT') AND category = 0 ORDER BY [name]) 

     WHILE @name IS NOT NULL 
     BEGIN 
      SELECT @SQL = 'DROP FUNCTION [dbo].[' + RTRIM(@name) +']' 
      EXEC (@SQL) 
      PRINT 'Dropped Function: ' + @name 
      SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] IN (N'FN', N'IF', N'TF', N'FS', N'FT') AND category = 0 AND [name] > @name ORDER BY [name]) 
     END 
    "; 
    $pdo->exec($sql); 

    $sql = " 
     /* Drop all Foreign Key constraints */ 
     DECLARE @name VARCHAR(128) 
     DECLARE @constraint VARCHAR(254) 
     DECLARE @SQL VARCHAR(254) 

     SELECT @name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY' ORDER BY TABLE_NAME) 

     WHILE @name is not null 
     BEGIN 
      SELECT @constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY' AND TABLE_NAME = @name ORDER BY CONSTRAINT_NAME) 
      WHILE @constraint IS NOT NULL 
      BEGIN 
       SELECT @SQL = 'ALTER TABLE [dbo].[' + RTRIM(@name) +'] DROP CONSTRAINT [' + RTRIM(@constraint) +']' 
       EXEC (@SQL) 
       PRINT 'Dropped FK Constraint: ' + @constraint + ' on ' + @name 
       SELECT @constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY' AND CONSTRAINT_NAME <> @constraint AND TABLE_NAME = @name ORDER BY CONSTRAINT_NAME) 
      END 
     SELECT @name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY' ORDER BY TABLE_NAME) 
     END 
    "; 
    $pdo->exec($sql); 

    $sql = " 
     /* Drop all Primary Key constraints */ 
     DECLARE @name VARCHAR(128) 
     DECLARE @constraint VARCHAR(254) 
     DECLARE @SQL VARCHAR(254) 

     SELECT @name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' ORDER BY TABLE_NAME) 

     WHILE @name IS NOT NULL 
     BEGIN 
      SELECT @constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' AND TABLE_NAME = @name ORDER BY CONSTRAINT_NAME) 
      WHILE @constraint is not null 
      BEGIN 
       SELECT @SQL = 'ALTER TABLE [dbo].[' + RTRIM(@name) +'] DROP CONSTRAINT [' + RTRIM(@constraint)+']' 
       EXEC (@SQL) 
       PRINT 'Dropped PK Constraint: ' + @constraint + ' on ' + @name 
       SELECT @constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' AND CONSTRAINT_NAME <> @constraint AND TABLE_NAME = @name ORDER BY CONSTRAINT_NAME) 
      END 
     SELECT @name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' ORDER BY TABLE_NAME) 
     END 
    "; 
    $pdo->exec($sql); 

    $sql = " 
     /* Drop all tables */ 
     DECLARE @name VARCHAR(128) 
     DECLARE @SQL VARCHAR(254) 

     SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'U' AND category = 0 ORDER BY [name]) 

     WHILE @name IS NOT NULL 
     BEGIN 
      SELECT @SQL = 'DROP TABLE [dbo].[' + RTRIM(@name) +']' 
      EXEC (@SQL) 
      PRINT 'Dropped Table: ' + @name 
      SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'U' AND category = 0 AND [name] > @name ORDER BY [name]) 
     END 
    "; 
    $pdo->exec($sql); 
} 
+0

시도와 오류 메시지 :

이는 execute documentation에 도움이 메모를 발견하는 나를 이끌었다 https://phpdelusions.net/pdo#multiquery - 그것은해야 (그리고 실패한 정리 프로세스 중에 오류가있을 경우) 오류를보고하십시오. –

+0

@YourCommonSense 입력 해 주셔서 감사하지만 가능한 모든 방법을 적용하려고했지만 내 문장 중 하나도 결과 집합을 반환하지 않아'$ stmt-> fetchAll()'을 호출하면 오류가 발생합니다. 잘못된 커서 상태 SQLFetchScroll [0]' –

+0

물론 fetchall은 당연히 여기서는 이해가되지 않습니다. 여러 개의 쿼리 결과를 반환 할 때 설명 부분을 읽으시기 바랍니다. –

답변

0

이 모든 PRINT 문을 전원 만 켜 다중으로 배치를 GO 문을 나누는 this script에서 꽤 많이 복사 - 붙여 넣기입니다 , 외래 키 드랍에만 해당합니다.

PRINT 문 또는 close the cursor 문을 모두 삭제하십시오.일괄 문 각각 한 박사

,

$pdo->query($sql)->closeCursor(); 

TL :

$pdo->exec($sql); 

조회하고 가까운 커서 :

는 후자를 사용하여, 나는 모든 간부 라인을 변경 결과 집합을 반복하여 다음과 같은 오류 메시지를 확인했습니다.

$stmt = $pdo->prepare($sql); 
$stmt->execute(); 
do { 
    var_dump($stmt->errorInfo()); 
} while ($stmt->nextRowset()); 

그리고 나는 흥미로운 결과를 얻었습니다. 첫째, 나는 3 가지를 얻습니다. 왜냐하면 저는 procs, views, 또는 functions가 없기 때문에 말이됩니다.

array(4) { 
    [0] => 
    string(5) "00000" 
    [1] => 
    int(0) 
    [2] => 
    string(24) " ((null)[0] at (null):0)" 
    [3] => 
    string(0) "" 
} 

그런 다음이 중 16 개를 얻습니다. 18 개의 테이블 중에서 16 개 테이블에 외래 키가 있으므로이 또한 의미가 있습니다. 루프의 각 반복에 대해 반복되는 루프의 마지막 인쇄 문 (나는 fk_DataRecord이 마지막으로 삭제 될 것으로 예상됩니다)이 왜 궁금합니다. 16 개의 fk_constraints가 삭제 될 때마다 print 서술문이 달라질 것으로 예상됩니다.

array(4) { 
    [0] => 
    string(5) "01000" 
    [1] => 
    int(0) 
    [2] => 
    string(186) "[Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Dropped FK Constraint: fk_DataRecord on Da 
taRecord (SQLExecute[0] at /build/php7.0-41GaEn/php7.0-7.0.8/ext/pdo_odbc/odbc_stmt.c:256)" 
    [3] => 
    string(5) "01000" 
} 

그런데 문제가 더 이상 존재하지 않는다고 당황했습니다. 여기에 설명 된대로 결과를 반복 할

Note:
Some drivers require to close cursor before executing next statement.

관련 문제