2017-10-20 56 views
0

Si je veux faire quelque chose de relativement compliqué - quelque chose d'habitude fait par une procédure stockée. Est-il possible de le rendre automatique en utilisant un VIEW?utilisez INSERT dans la définition de VIEW: CREATE VIEW AS INSERT IN

Mon cas particulier:

Je veux tableau output = table d'entrée A + une table de saisie de lignes B. Dans une procédure stockée, je peux faire une copie du tableau A, puis INSERT INTO, mais ce n'est pas autorisé dans une vue.

exemple simplifié:

table d'entrée

est [test_album], et une table de sortie = table d'entrée + chanteur Prince.

--create test data 
IF OBJECT_ID('[dbo].[test_album]', 'U') IS NOT NULL 
    DROP TABLE [dbo].[test_album] 

CREATE TABLE [test_album] ( 
    id int not null identity(1, 1) primary key, 
    singer VARCHAR(50) NULL, 
    album_title VARCHAR(100) NULL 
    ) 

INSERT INTO [test_album] (singer, album_title) 
    VALUES ('Adale', '19'), 
     ('Michael Jaskson', 'Thriller') 

--this can be executed as sql code or in stored proc 
SELECT * 
INTO [result_table] 
FROM [test_album] 

INSERT INTO [result_table] ([singer]) 
    VALUES ('Prince') 

select * 
from [result_table] 
--id singer album_title 
--1 Adale 19 
--2 Michael Jaskson Thriller 
--3 Prince NULL 
----as expected 

Mais je peux le faire INSERT INTO l'intérieur d'une vue.

cas réel:

chanteurs supplémentaires sont dans une table [extra_singers]

[test_album] peut avoir beaucoup d'autres colonnes (ou schéma peut changer) il est donc pas idéal pour saisir toutes les colonnes noms dans le code.

--create test data 
IF OBJECT_ID('[dbo].[test_album]', 'U') IS NOT NULL 
    DROP TABLE [dbo].[test_album] 
IF OBJECT_ID('[dbo].[extra_singers]', 'U') IS NOT NULL 
    DROP TABLE [dbo].[extra_singers] 
IF OBJECT_ID('[dbo].[result_table]', 'U') IS NOT NULL 
    DROP TABLE [dbo].[result_table]   

CREATE TABLE [test_album] ( 
    id int not null identity(1, 1) primary key, 
    singer VARCHAR(50) NULL, 
    album_title VARCHAR(100) NULL, 
    many_other_columns VARCHAR(100) NULL 
    ) 

INSERT INTO [test_album] (singer, album_title) 
    VALUES ('Adale', '19'), 
     ('Michael Jaskson', 'Thriller') 


CREATE TABLE [extra_singers] ( 
    [id] int not null identity(1, 1) primary key, 
    [name] VARCHAR(50) NULL) 

INSERT INTO [extra_singers] ([name]) 
    VALUES ('Prince'), 
     ('Taylor Swift') 


--append [extra_singers] to [test_album] 
--this can be executed as sql code or in stored proc 
SELECT * 
INTO [result_table] 
FROM [test_album] 

INSERT INTO [result_table] ([singer]) 
    SELECT [name] 
    FROM [extra_singers] 

Existe-t-il une alternative à cela (c'est automatique)? toute aide est appréciée. Merci u-


une solution partielle je peux penser:

create view test_view as 

    select * 
    from [test_album] 

    union all 

    select 3 as id, 
     'Prince' as singer, 
     NULL as album_title 

mais vous devez connaître tous les noms de colonnes dans [test_album] et vous ne pouvez pas laisser la colonne [id] faire auto -increment

+1

Cela n'a aucun sens. Pouvez-vous clarifier? – SqlZim

+2

Les vues sont censées afficher les données sous-jacentes. L'insertion ne serait pas vraiment appropriée pour cela. Une procédure stockée serait mieux adaptée à ce que vous essayez de faire si vous ne voulez pas insérer les données directement. – indiri

+0

@SqlZim Je dois ajouter une ligne à une table chaque fois que je l'utilise. J'essaie d'automatiser ceci en utilisant 'VIEW'. Donc, la vue devrait = table d'entrée + une ligne supplémentaire –

Répondre

3

Vous risquez donc d'avoir une mauvaise compréhension de ce qu'est un view ou de ce qu'est un insert. Une vue est simplement un wrapper autour d'une seule requête select. Il contient exactement une instruction select et rien d'autre. Un insert ajoute définitivement une ligne de données à une table persistante. L'exemple que vous avez donné où vous venez d'union la rangée que vous voulez semble assez valide. Et certainement si c'est la même ligne que vous voulez à chaque fois, vous ne voudriez pas insérer (ou même essayer d'insérer) cette ligne dans la table sous-jacente à chaque fois

Cela soulève cependant quelques questions.

  • Si vous êtes toujours en train d'unir la même rangée à chaque fois, pourquoi ne pas ajouter cette ligne à la table?
  • Si, disons, vous ne voulez pas que cette ligne dans la table sous-jacente, cool. Mais si c'est toujours les mêmes valeurs statiques, pourquoi devez-vous l'inclure dans la vue? Ne peut-on pas supposer que c'est là?
  • Si l'on ne peut pas toujours supposer que c'est la même chose, vous ne voulez certainement pas changer le corps VIEW chaque fois que vous en avez besoin pour changer.Donc si est va changer et vous ne voulez pas l'insérer dans la table de base, peut-être faire une deuxième table contenant les valeurs que vous voulez ajouter à la table de base dans la vue. Puis, fusionnez la table de base et la table "valeurs supplémentaires" au lieu d'un seul constructeur de ligne codé en dur.
+0

merci @Xedni - beaucoup clarifié pour moi! Mon cas réel est 'output table' = entrée' table A' + quelques lignes supplémentaires basées sur 'table B'. Mes collègues peuvent mettre à jour la table A et la table B, et j'essayais de la rendre automatique, donc je n'ai pas besoin de l'ajouter de temps en temps. –