2011-05-24 1 views
0

Nous avons une interface héritée qui insère dans la table T1 les valeurs "BODY_TEXT" (varcharmax), "BODY_BIN"(varbinarymax). Il insère actuellement juste à l'une des colonnes, et laisse l'autre NULL. Maintenant, nous avons implémenté une nouvelle interface - la table T2 qui a seulement la colonne "BODY"(varbinarymax).Colonnes doubles dans une vue SQL

Je dois créer une vue V1 qui devrait remplacer T1, ce qui signifie

CREATE VIEW V1 AS 
SELECT 
T2.UNIQUE_ID AS UNIQUE_ID, 

etc ...

Maintenant, je ne sais pas comment traiter T2.BODY colonne ... Je dois faire quelque chose comme T2.BODY AS (whatever is not null(BODY_BIN, BODY_TEXT)) . Il doit également supporter varcharmax vs varbinarymax. J'ai essayé d'implémenter COALESCE ce qui signifie T2.BODY AS COALESCE(BODY_BIN, BODY_TEXT) mais cela ne fonctionne pas. ne Refait

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

- Dans le tableau de l'héritage que nous avait T1 avec deux colonnes - BODY_BIN et BODY_TEXT. L'utilisateur a inséré une valeur et laissé l'autre vide, puisque le corps est binaire ou textuel mais pas les deux. La nouvelle interface a une table T2 qui n'a qu'une colonne, BODY (varbinarymax), et on m'a demandé de supprimer la table T1 et de créer une vue avec le même nom. Signification afin de préserver la comparabilité vers l'arrière, ils devraient toujours être en mesure d'effectuer "insérer dans T1 valeurs X, Y" (X est DATA_BIN ou NULL, et Y est DATA_TEXT ou NULL), mais le contenu (tiré de X ou Y) devrait être traduit en une colonne dans la table T2 - BODY. Je n'ai aucune idée de comment tirer celui-ci.

Pouvez-vous m'aider?

Merci,

Nili

+0

Je ne suis pas sûr de comprendre. COALESCE (, ) devrait fonctionner. –

+0

Oui, mais notez que la direction est différente - généralement vous "mappez" la table à afficher, ce qui signifie COALESCE (DATA_BIN, DATA_TEXT) comme T.BODY, mais j'ai besoin de mapper une valeur maximale de la vue, ce qui signifie T2.BODY AS COALESCE (DATA_BIN, DATA_TEXT), ou quelque chose comme ça ... – Nili

+0

Suis-je en train de lire ceci correctement: vous voulez changer le nom de la colonne en fonction du type de données retourné? – tobias86

Répondre

1

En premier lieu, cela est une mauvaise conception. Rejoindre un champ varchar(max) ou varbinary(max) est une mauvaise idée car ils ne peuvent pas être indexés. Préparez-vous pour les scans de table!

Vous avez des types de données incohérents dans la même colonne, ce qui constitue un problème.

Essayez:

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

+0

Mais j'ai besoin de mapper la valeur T2 dans la valeur non nulle, ce qui signifie que j'ai besoin de quelque chose comme: T2.Body AS CAST ((COALESCE (BODY_BIN, BODY_TEXT)) comme varchar (max)), mais cela ne fonctionne pas. – Nili

+0

@Nili: 'COALESCE (CAST (BODY_BIN comme varchar (max)), BODY_TEXT))'? –

2

varbinary varchar (notez l'ordre) sera implicitement converti. Donc, cela fonctionne parce que ISNULL prend le premier type de données

ISNULL(varchar, varbinary) 

COALESCE échoue parce qu'il prend le type de données la plus haute priorité (ce qui est varbinary). La distribution implicite n'est pas autorisée. ISNULL(varbinary, varchar) échouerait trop

Vous avez besoin d'un CAST explicite

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 

ou

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

Edit: Je comprends la question maintenant ...peut-être

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: quelque chose comme ça (pas testé) pour maintenir la même interface d'écriture. Normalement, je maintiens seulement une interface de lecture d'où la confusion ...

+0

Je ne sais toujours pas si une distribution simple fonctionnerait, je suis toujours un pas en arrière car je ne sais pas comment lier une colonne "physique" de la table T2 à non-null-value-out-of-two -colonnes de V1 ... – Nili

+0

@Nili: Je vous ai donné la preuve que * ça * marche dans mon script ci-dessus – gbn

+0

Ok merci mais comment le lier de T2.BODY à V1 ...? – Nili

Questions connexes