SQL视图中的双列

时间:2011-05-24 09:39:18

标签: sql tsql view sql-view

我们有一个遗留接口,可插入到表格T1中,其值为"BODY_TEXT" (varcharmax)"BODY_BIN"(varbinarymax)。 它目前只插入其中一列,而另一列则为NULL。 现在我们实现了一个新的接口 - 表T2只有"BODY"(varbinarymax)列。

我需要创建一个应该替换T1的视图V1,意思是

CREATE VIEW V1 AS
SELECT 
T2.UNIQUE_ID AS UNIQUE_ID,

等...

现在我不知道如何对待T2.BODY列...我需要做类似的事情 T2.BODY AS (whatever is not null(BODY_BIN, BODY_TEXT))。它还必须支持varcharmax与varbinarymax。 我尝试实现COALESCE意味着T2.BODY AS COALESCE(BODY_BIN, BODY_TEXT),但它不起作用。

也没有
COALESCE(BODY_BIN, BODY_TEXT) AS BODY
T2.BODY AS BODY

再次 - 在遗留表中,我们有T1有两列 - BODY_BIN和BODY_TEXT。用户插入一个值并将另一个值保留为null,因为正文是二进制或文本而不是两者。新接口有一个表T2只有一列BODY(varbinarymax),我被要求删除表T1并创建一个具有相同名称的视图。意思是为了保持向后的可比性,他们仍然应该能够执行“插入T1值X,Y”(X是DATA_BIN或NULL,Y是DATA_TEXT或NULL),但内容(取自X或Y)应该被翻译成T2表中的一列 - BODY。 我不知道如何把它拉出来。

你能帮助我吗?

谢谢,

尼里

2 个答案:

答案 0 :(得分:2)

varbinary to varchar(注意顺序)将隐式转换。所以这是有效的,因为ISNULL采用第一种数据类型

ISNULL(varchar, varbinary)

COALESCE失败,因为它采用最高优先级数据类型(varbinary)。不允许隐式演员表。 ISNULL(varbinary, varchar)也会失败

您需要明确的CAST

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

答案 1 :(得分:1)

首先,这是一个糟糕的设计。加入varchar(max)varbinary(max)字段是一个坏主意,因为它们无法编入索引。准备桌面扫描!

同一列中的数据类型不一致,这是一个问题。

尝试:

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