0

"BODY_TEXT" (varcharmax)テーブル T1 に値,を挿入する従来のインターフェイスがあります"BODY_BIN"(varbinarymax)。現在、列の 1 つだけに挿入し、もう 1 つの列は NULL のままにします。ここで、"BODY"(varbinarymax)列のみを持つテーブル T2 という新しいインターフェイスを実装しました。

T1 を置き換えるビュー V1 を作成する必要があります。つまり、

CREATE VIEW V1 AS
SELECT 
T2.UNIQUE_ID AS UNIQUE_ID,

など…</p>

列の扱い方がわからないT2.BODY…みたいなことをする必要があります T2.BODY AS (whatever is not null(BODY_BIN, BODY_TEXT))varcharmaxvs. varbinarymaxもサポートする必要があります。COALESCE意味 を実装しようとしT2.BODY AS COALESCE(BODY_BIN, BODY_TEXT)ましたが、うまくいきません。そうでもない

COALESCE(BODY_BIN, BODY_TEXT) AS BODY
T2.BODY AS BODY

繰り返しますが、従来のテーブルには、BODY_BIN と BODY_TEXT の 2 つの列を持つ T1 がありました。本文はバイナリまたはテキストのいずれかであり、両方ではないため、ユーザーは 1 つの値を挿入し、もう 1 つの値を null のままにしました。新しいインターフェイスには、BODY (varbinarymax) という 1 つの列しかないテーブル T2 があり、テーブル T1 を削除して同じ名前のビューを作成するように求められました。つまり、下位比較可能性を維持するために、「T1 値 X、Y への挿入」(X は DATA_BIN または NULL、Y は DATA_TEXT または NULL) を引き続き実行できる必要がありますが、コンテンツ (X または Y から取得) はT2 テーブルの 1 つの列 - BODY に変換されます。これを引き上げる方法がわかりません。

手伝って頂けますか?

ありがとう、

ニリ

4

2 に答える 2

2

varbinary から varchar (順序に注意) は暗黙的にキャストされます。ISNULL は最初のデータ型を取るため、これは機能します

ISNULL(varchar, varbinary)

COALESCE は、最も優先順位の高いデータ型 (varbinary) を使用するため失敗します。暗黙のキャストは許可されていません。ISNULL(varbinary, varchar)あまりにも失敗するだろう

明示的なキャストが必要です

DECLARE @foo TABLE (ID int IDENTITY (1,1), charmax varchar(MAX) NULL, binmax varbinary(MAX) NULL)

INSERT @foo (charmax, binmax) VALUES ('text', NULL)
INSERT @foo (charmax, binmax) VALUES (NULL, 0x303131)
INSERT @foo (charmax, binmax) VALUES ('Moretext', NULL)
INSERT @foo (charmax, binmax) VALUES (NULL, 0x414243454647)

SELECT ISNULL(binmax, CONVERT(varbinary(MAX), charmax))
FROM @foo

また

SELECT COALESCE(binmax, CONVERT(varbinary(MAX), charmax))
FROM @foo

編集:私は今質問を理解しています...多分

DECLARE @foo2 TABLE (ID int IDENTITY (1,1), BODY varbinary(MAX) NULL)

INSERT @foo2 (BODY) VALUES (CAST('text' AS varbinary(MAX)))
INSERT @foo2 (BODY) VALUES (0x303132)
INSERT @foo2 (BODY) VALUES (CAST('Moretext' AS varbinary(MAX)))
INSERT @foo2 (BODY) VALUES (0x414243454647)
SELECT
    BODY AS BODY_BIN,
    CAST(BODY AS varchar(MAX)) AS BOY_TEXT
FROM
    @foo2

Edit2:同じ書き込みインターフェースを維持するために、このようなもの (テストされていません)。通常、私は読み取りインターフェースのみを維持するため、混乱します...

CREATE VIEW OldFoo
AS
SELECT
    ID,
    BODY AS BODY_BIN,
    CAST(BODY AS varchar(MAX)) AS BOY_TEXT
FROM
    newFoo
GO
CREATE TRIGGER ON OldFoo INSTEAD OF INSERT
AS
SET NOCOUNT ON
INSERT newFoo (BODY)
SELECT ISNULL(binmax, CONVERT(varbinary(MAX), charmax))
FROM INSERTED
GO
于 2011-05-24T11:29:59.843 に答える
1

まず、これは悪い設計です。varchar(max)またはフィールドに結合するvarbinary(max)ことは、インデックスを作成できないため、悪い考えです。テーブルスキャンの準備を!

同じ列に一貫性のないデータ型があり、これが問題です。

試す:

CAST((COALESCE(BODY_BIN, BODY_TEXT)) as varchar(max))

于 2011-05-24T10:58:33.297 に答える