2016-11-11 6 views
2

私はCREATE TABLEのスクリプトを持っています。 コマンドラインで実行すると、NULL可能な列は作成されません。私がを手動で実行すると、SQL Serverのクエリブラウザ経由でが実行されます。私は何が欠けていますか?コマンドラインを介してなぜSQL Serverはこの同じSQLを異なる方法で扱いますか?

私はSQL Serverの2014年に私のスキーマを作成するために、教義2のコマンドラインスキーマツールを使用しようとしてる

(1)。 SQL Serverが受信SQL Serverプロファイラによると、

# dump the SQL Doctrine will use 
vendor/bin/doctrine-module orm:schema-tool:create --dump-sql 
CREATE TABLE company (
    id INT IDENTITY NOT NULL, 
    address_1 NVARCHAR(255) NOT NULL, 

    address_2 NVARCHAR(255), <-- it should be optional 

    city NVARCHAR(31) NOT NULL, 
    email NVARCHAR(255), 
    name NVARCHAR(255) NOT NULL, 
    phone NVARCHAR(12), 
    state NVARCHAR(2) NOT NULL, 
    zip NVARCHAR(5) NOT NULL, 
    PRIMARY KEY (id) 
); 

# execute the command 
vendor/bin/doctrine-module orm:schema-tool:create 

:ここ

は、それが私のエンティティの注釈から作成するSQLは、(2)(注、address_2がNULL可能である)(間隔と矢印は私です)ですしかし

set textsize 20971520 
go 
set textsize 2147483647 
set quoted_identifier on 

go 
SET ANSI_WARNINGS ON 
go 
SET ANSI_PADDING ON 
go 
SET ANSI_NULLS ON 
go 
SET QUOTED_IDENTIFIER ON 
go 
SET CONCAT_NULL_YIELDS_NULL ON 
go 
CREATE TABLE company (
    id INT IDENTITY NOT NULL, 
    address_1 NVARCHAR(255) NOT NULL, 

    address_2 NVARCHAR(255), <-- it should be optional 

    city NVARCHAR(31) NOT NULL, 
    email NVARCHAR(255), 
    name NVARCHAR(255) NOT NULL, 
    phone NVARCHAR(12), 
    state NVARCHAR(2) NOT NULL, 
    zip NVARCHAR(5) NOT NULL, 
    PRIMARY KEY (id) 
) 
go 

、あなたが作成したテーブルを検査する際、address_2がです:コマンド(ノート、address_2はまだNULL可能でなければなりません)(間隔と矢印は私です)、次0。

はここ(間隔と矢印は私です)テーブルブラウザのスクリーンショットだけでなく、SQL Server's equivalent to MySQL's SHOW CREATE TABLEの出力です:

Table created via command line

USE [mydatabase] 
GO 

/****** Object: Table [dbo].[company] Script Date: 11/11/2016 9:47:03 AM ******/ 
SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

CREATE TABLE [dbo].[company](
    [id] [int] IDENTITY(1,1) NOT NULL, 
    [address_1] [nvarchar](255) NOT NULL, 

    [address_2] [nvarchar](255) NOT NULL, <-- it's not optional! 

    [city] [nvarchar](31) NOT NULL, 
    [email] [nvarchar](255) NOT NULL, 
    [name] [nvarchar](255) NOT NULL, 
    [phone] [nvarchar](12) NOT NULL, 
    [state] [nvarchar](2) NOT NULL, 
    [zip] [nvarchar](5) NOT NULL, 
PRIMARY KEY CLUSTERED 
(
    [id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

クエリブラウザ今

を経由して、ここで楽しい部分が来る。あなたは、SQL ServerがSQL Serverのクエリブラウザに(SQL Serverプロファイラによる)受信まったく同じコマンドを実行する場合

(間隔と矢印はわたしのもの):

set textsize 20971520 
go 
set textsize 2147483647 
set quoted_identifier on 

go 
SET ANSI_WARNINGS ON 
go 
SET ANSI_PADDING ON 
go 
SET ANSI_NULLS ON 
go 
SET QUOTED_IDENTIFIER ON 
go 
SET CONCAT_NULL_YIELDS_NULL ON 
go 
CREATE TABLE company (
    id INT IDENTITY NOT NULL, 
    address_1 NVARCHAR(255) NOT NULL, 

    address_2 NVARCHAR(255), <-- it should be optional 

    city NVARCHAR(31) NOT NULL, 
    email NVARCHAR(255), 
    name NVARCHAR(255) NOT NULL, 
    phone NVARCHAR(12), 
    state NVARCHAR(2) NOT NULL, 
    zip NVARCHAR(5) NOT NULL, 
    PRIMARY KEY (id) 
) 
go 

address_2フィールドがNULLです:

Table created via query browser

USE [mydatabase] 
GO 

/****** Object: Table [dbo].[company] Script Date: 11/11/2016 9:49:41 AM ******/ 
SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

CREATE TABLE [dbo].[company](
    [id] [int] IDENTITY(1,1) NOT NULL, 
    [address_1] [nvarchar](255) NOT NULL, 

    [address_2] [nvarchar](255) NULL, <-- it's optional! 

    [city] [nvarchar](31) NOT NULL, 
    [email] [nvarchar](255) NULL, 
    [name] [nvarchar](255) NOT NULL, 
    [phone] [nvarchar](12) NULL, 
    [state] [nvarchar](2) NOT NULL, 
    [zip] [nvarchar](5) NOT NULL, 
PRIMARY KEY CLUSTERED 
(
    [id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

結論

何が起こっているのですか? どうすれば同じのSQLスクリプトが生成異なる結果?

私はウェブでヘルプを検索しましたが、問題の説明や解決策が見つからないようです。どんな助けでも大歓迎です!私の心の中で

:クエリは彼らとSQL Serverのクエリブラウザで動作するため、

  • SETフラグは、問題ではないはず。さらに、私はそれらを調べましたが、T-SQLの動作をオプションの列に変更するようなものはありません。
  • * nixマシンからDoctrineをSQL Serverに接続するために飛び越したジャンプ(SQL Serverプロファイラに示されているように)SQL Serverに到達するコマンドがクエリブラウザで機能するため、問題ではありません(1)。

脚注

  1. 私はCentOSのマシンからSQL Serverへの教義を接続しています。 FreeTDSを使用してSQLサーバーに接続しています。私はサードパーティのDBlib Doctrine Driverを使用しています。私はそれが渦巻いていることを知っている。
  2. エンティティが含まれていないため、私はそれが役に立たないと考えています。 Doctrineによって生成されたSQLは正しいです。
+4

['SET ANSI_NULL_DFLT_ON'](https://msdn.microsoft.com/library/ms187375)。そして今、なぜあなたはいつも明白にすべきであると知っています。 –

+0

Jeroenからのコメントにスポット:)。小さな疑問:「SQL Server Query Browser」と言えば、「SQL Server Management Studio」ですか? –

+0

@JeroenMostertあなたは私のヒーローです!私は作成されたSQL Doctrineを変更できませんでした。しかし、データベースでグローバルオプションを設定しています(右クリックデータベース>プロパティ>オプション> ANSI NULLデフォルトをtrueに設定)、それを修正しました!学んだ教訓! _comment_を_answer_として追加することができますので、私はそれを受け入れることができますか? – Jack

答えて

2

あなたは明示的に列があなたのCREATE TABLENULLNOT NULLであるかどうかを指定しない場合は、物事は複雑になります。必然的に、あなたは言うかもしれません。

  • (セッションレベル)の場合:自分の知恵で

    (または、よりおそらく、後方互換性に応えるために)SQL Serverのの開発者は、これは劣らず3以上の選択肢に支配持つようにフィット見てオプションANSI_NULL_DFLT_ONONの場合、未指定の列はNULL可能です。

  • (セッション・レベル)オプションANSI_NULL_DFLT_OFFONの場合、未指定の列はNULL可能ではありません。
  • これらのオプションは排他的です。したがって、両方をONにすることはできません。しかし、どちらもOFFです。値がNULLの場合、null許容度はデータベースレベルのオプションANSI_NULL_DEFAULTによって制御されます。ON(未指定の列はNULL可能)またはOFF(未指定の列はNULL可能ではありません)のいずれかになります。

クライアントの大半は、(結局、それは何のためにANSIと呼ばれていない)ANSI_NULL_DFLT_ONを設定し、両方のだろうODBCまたはOLE DB、を介して接続します。これは、何も指定されていなければ、ほとんどの "現代的な"クライアントは常にヌル可能な列を取得することを意味します。しかし、(古代の)DB-Libraryを介して接続するクライアントや、この特定のセットアップではFreeTDSも、これらのオプションを指定していないため、データベースの設定が有効になります。

データベースの作成時に、設定はmodelデータベースから取得され、documentedです。下位互換性を重視しており、新たに作成されたデータベースの場合はがデフォルトでOFFになります。しかし、ここで、少なくともあなたはそれがこれを行うには良いアイデアかどうかは、

ALTER DATABASE [db] SET ANSI_NULL_DEFAULT ON 

で、ステップや物事を変更する機会を持って、あなたの設定に依存します。可能であれば、ANSI_NULL_DLFT_ONオプションを設定しているドライバに接続するか、自分で明示的に実行する必要があります。データベースのデフォルトを設定する(またはすべてのデータベースが継承するようにmodelに設定する)ことは、一貫性を保証するか、または古いクライアントを壊すので悪いことかもしれません。

Books Online wisely notes on this subject通り:

異なるNULL可能設定で データベースで使用されたTransact-SQLスクリプトのより信頼性の高い動作のために、CREATE TABLEALTER TABLE文で NULLまたはNOT NULLを指定することをお勧めします。

Doctrineの作者がこれを行っていれば、上記のテキストをすべて忘れている可能性があります。


FreeTDSのはまだ人気がありますが、私は、Microsoftが最近ではその以前は思い詰めクロスプラットフォームのODBCサポートに多くのリソースを犯したことを指摘したいと思います。 Microsoft ODBC Driver for SQL Server on Linuxは、機能と互換性の面でLinuxに最適な接続オプションを書いている時点であり、予期せぬ古くなったデフォルトのオプションの問題を回避する必要があります。あなたのソフトウェアがODBCをサポートしている場合は、検討する価値があります。

+0

私の友人の笑の上に!ありがとうございました。 – Jack

関連する問題