0

我们有一个遗留接口插入到表 T1 中,它的值是"BODY_TEXT" (varcharmax), "BODY_BIN"(varbinarymax)。它当前只插入其中一列,而将另一列保留为 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

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

你能帮助我吗?

谢谢,

尼力

4

2 回答 2

2

varbinary 到 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
于 2011-05-24T11:29:59.843 回答
1

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

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

尝试:

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

于 2011-05-24T10:58:33.297 回答