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