SQL 视图中的双列

发布于 2024-11-09 12:49:02 字数 976 浏览 0 评论 0原文

我们有一个旧接口,可将值 "BODY_TEXT" (varcharmax)"BODY_BIN"(varbinarymax) 插入到表 T1 中。 当前它仅插入到其中一列,并将另一列保留为 NULL。 现在我们实现了一个新的接口 - 表 T2,它只有 "BODY"(varbinarymax) 列。

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

CREATE VIEW V1 AS
SELECT 
T2.UNIQUE_ID AS UNIQUE_ID,

等等…

现在我不知道如何处理 T2.BODY 列…我需要做类似的事情 T2.BODY AS(不为 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。用户插入一个值并将另一个值保留为空,因为正文要么是二进制的,要么是文本的,但不能同时是两者。新界面有一个表 T2,只有一列 BODY (varbinarymax),我被要求删除表 T1 并创建一个同名的视图。这意味着为了保持向后可比性,它们仍然应该能够执行“插入 T1 值 X,Y”(X 是 DATA_BIN 或 NULL,Y 是 DATA_TEXT 或 NULL),但内容(取自 X 或 Y)应该被转换为 T2 表中的一列 - BODY。 我不知道如何把这个拉起来。

你能帮助我吗?

谢谢,

尼利

We have a legacy interface that inserts into table T1 that values "BODY_TEXT" (varcharmax), "BODY_BIN"(varbinarymax).
It currently inserts just to one of the columns, and leave the other one NULL.
Now we implemented a new interface - table T2 that has only "BODY"(varbinarymax) column.

I need to create a view V1 that should replace T1, meaning

CREATE VIEW V1 AS
SELECT 
T2.UNIQUE_ID AS UNIQUE_ID,

etc…

Now I don't know how to treat T2.BODY column… I need to do something like
T2.BODY AS (whatever is not null(BODY_BIN, BODY_TEXT)). It must also support varcharmax vs. varbinarymax.
I tried implementing COALESCE meaning T2.BODY AS COALESCE(BODY_BIN, BODY_TEXT) but it doesn't work.
Nor does

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

Again - In the legacy table we had T1 with two columns - BODY_BIN and BODY_TEXT. The user inserted one value and left the other one null, since body is either binary or textual but not both. The new interface has a table T2 that has only one column, BODY (varbinarymax), and I was asked to delete table T1 and create a view with the same name. Meaning in order to preserve backward comparability they should still be able to perform "insert into T1 values X,Y" (X is DATA_BIN or NULL, and Y is DATA_TEXT or NULL), but the content (taken from either X or Y) should be translated into ONE column in the T2 table - BODY.
I have no idea how to pull this one up.

Can you help me?

Thanks,

Nili

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

入画浅相思 2024-11-16 12:49:02

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

varbinary to varchar (note the order) will cast implicitly. So this works because ISNULL takes the first datatype

ISNULL(varchar, varbinary)

COALESCE fails because it takes the highest precedence datatype (which is varbinary). The implicit cast is not allowed. ISNULL(varbinary, varchar) would fail too

You need an explicit 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

or

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

Edit: I understand the question now... maybe

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: something like this (not tested) to maintain the same write interface. Normally, I'd only maintain a read interface hence the confusion...

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
尘世孤行 2024-11-16 12:49:02

首先,这是一个糟糕的设计。连接 varchar(max)varbinary(max) 字段不是一个好主意,因为它们无法建立索引。准备表扫描!

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

尝试:

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

First, this is a bad design. Joining on a varchar(max) or varbinary(max) field is a bad idea since they can't be indexed. Prepare for table scans!

You have inconsistent data types in the same column, which is a problem.

Try:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文