我们有一个遗留接口,可插入到表格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。 我不知道如何把它拉出来。
你能帮助我吗?
谢谢,
尼里
答案 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))