11

今日、これに似たコードに出くわしました。

SELECT AuditDomain, 
    ObjectId,
    AuditSubdomain = CONVERT(VARCHAR(50), NULL),
    SubDomainObjectId = CONVERT(INT, NULL)
FROM Audit

データ型情報をNULL値に関連付けることができることを意味しているようです。これは、指定されたデータ型としてそれを識別するNULL値にメタデータを添付しますか?

この投稿では、SQL Serverでデータ型を見つける方法について詳しく説明していますが、次の行を試してみると、NULLとして返されます。

SELECT CAST(SQL_VARIANT_PROPERTY(CONVERT(INT, NULL), 'BaseType') AS VARCHAR(20))
4

5 に答える 5

16

SQL Serverでは、これNULLINT私が考えることができるすべてのシナリオのデフォルトです。これは、次のコードで判別できます。

SELECT x = NULL INTO #x;
EXEC tempdb..sp_columns '#x';

結果:

TABLE_QUALIFIER TABLE_OWNER TABLE_NAME COLUMN_NAME DATA_TYPE TYPE_NAME
--------------- ----------- ---------- ----------- --------- ---------
tempdb          dbo         #x___...   x           4         int

テーブルに配置する前、またはコンテキストメタデータに関連付ける前に、何を購入しますか?それはどのような違いがありますINTDATETIME?その情報をどうしますか?

SQL_VARIANT_PROPERTY意味のあるメタデータと値のNULL両方が必要なように見えるため、が返されます。観察する(単にそれを混ぜるために別のタイプを使用する):

SELECT SQL_VARIANT_PROPERTY(NULL, 'BaseType');

DECLARE @x DATE;

SELECT SQL_VARIANT_PROPERTY(@x, 'BaseType');

DECLARE @y DATE = SYSDATETIME();

SELECT SQL_VARIANT_PROPERTY(@y, 'BaseType');

結果:

NULL

NULL

date

したがって、基本タイプを正確に判別するには、タイプ値の両方が必要なようです。

このように機能する正確な理由については、肩をすくめてください。ソースコードにアクセスできる人に聞いてみる必要があります。

基本タイプを採用する必要があるのは、SQL Serverの手を強制した場合のみであることに注意してください。つまりNULL、それに基づいてテーブルを作成しました。この状況(実際には、意味するデータ型を推測する必要がある多くの状況)でSQLServerがエラーを返す場合が非常によくあります。これを回避する方法は、SQL Serverが推測しなければならない状況を作成しないことです(これが、私が尋ねた理由です。この情報をどのように処理しますか?)。

于 2013-03-26T21:24:57.297 に答える
0

Nullにはデータ型がありません。nullの目的は、値とタイプの両方で「不明」を表すことです。

ISNULL()は、データ型が提示された最初の引数のデータ型を返します。

http://msdn.microsoft.com/en-us/library/ms187928.aspx

于 2013-03-26T21:47:28.727 に答える
0

すでにいくつかの良い答えがあることは知っていますが、SQL_VARIANT_PROPERTYは誤解されていると思います。

SQL_Variant_Propertyを列とともに使用し、次にそのメタデータプロパティに必要なものを示します。ただし、nullの場合は、あまりわかりません。

例えば:

declare 
    @Start date = getdate()
,   @End datetime= getdate()
,   @Int int = 1
,   @DateNull date
;


select 
    sql_variant_property(@Start, 'BaseType')
,   sql_variant_property(@End, 'BaseType')
,   sql_variant_property(@Int, 'BaseType')
,   sql_variant_property(@DateNull, 'BaseType')

3つのデータ型とnullを返します。NULLの処理はSQLの重要な部分です。私を含め、非常に多くの人々が、nullを表す値でnullを処理したい場合もあれば、気にしない場合もあります。SQLバリアントは、引数'BaseType'が設定された値に対してのみ機能します。それ以外の場合は、nullを返します。私の知る限り、これはSQLが次のように言っているためです。「ここにはデータがなく、メモリ使用量を決定するものは何もありません。」

一般に、整数を操作する場合はisnull(@thing、0)を指定しますが、データセットに未知数のゼロを明示的に含める必要があります。また、nullが発生したことで、レポートに対して他のisnull(@thing、'not present')が発生したことをユーザーに知らせたい場合もあります。さらに別の場合は、基本的に一連の可能性の合体に合体を使用できます(@thing、@ otherthing、@ yetotherthing、'不明')。

私はあなたが本当にそのようなことをする必要がある場所がわからないときに誰かが何かを変換しているのを目撃しているコードであると思います。テーブル内の列のデータ型は、必要なものが維持され、NULLの場合、SQLはその列にメモリを格納しません。したがって、それを変更する必要性は恣意的な私見のようです。SQL 2008で導入されたSPARSEオプションを使用すると、より多くのnullを期待できる場合に、より良いメモリ消費を処理できることを私は知っています。

于 2013-03-26T22:09:29.187 に答える
0

当然のことながら、NULLにはデータ型があります。次のコードを試して確認してください:

SELECT 
  CAST(NULL AS date) AS c1,
  CAST(NULL AS time) AS c2
INTO #x;
EXEC tempdb..sp_columns '#x';

また、SQL_VARIANTの実装には、NULL型に関する情報が失われるため、バグがあると思います。残念な!

于 2016-03-17T15:07:37.347 に答える
0

@aaron-bertrandに同意しません。デフォルトでは、SQlサーバーは整数データ型の列を作成してNULL値を格納するため、NullはInt、Datetime、Date、Varcharの他の列に挿入できます。

SELECT x = NULLINTO#xでテーブルにNullを挿入する場合。

SQlサーバーは、整数列にNullを挿入できるため、デフォルトで整数型の列を作成しました。

したがって、「SELECT x = NULLINTO#x;」と記述したクエリの性質が原因である可能性があります。これにより、列が整数になり、NULL値が入力されます。

于 2017-07-20T14:06:38.823 に答える