Diviser une table principale en plusieurs tables à l'aide du server SQL

Salut, j'essaie de créer plusieurs tables sur une table principale dans le server SQL. par exemple

La table principale ressemble à

A 1 A 2 A 3 B 4 B 5 B 6 

La sortie devrait ressembler à:

Tableau A:

 A 1 A 2 A 3 

Tableau B:

 B 4 B 5 B 6 

La table principale est mise à jour chaque semaine, donc peut avoir des alphabets différents. Je veux donc créer une requête dynamic qui divise automatiquement la table principale en 'n' différentes tables en fonction du nombre de n différents et qui nomme également la table en fonction de la nième valeur.

Oui c'est réalisable, mais la malédiction et la bénédiction SQL dynamic par Erland Sommarskog

CREATE TABLE @tbl

Le désir ici est de créer une table dont le nom est déterminé à l'exécution.

Si nous regardons simplement les arguments contre l'utilisation de SQL dynamic dans les procédures stockées, peu d'entre eux sont vraiment applicables ici. Si une procédure stockée contient une table CREATE TABLE statique, l'user qui exécute la procédure doit disposer des permissions pour créer des tables, de sorte que SQL dynamic ne changera rien. Plan cache n'a évidemment rien à voir avec ça. Etc.

Néanless: Pourquoi? Pourquoi voudriez-vous faire cela? Si vous créez des arrays à la volée dans votre application, vous avez manqué certains principes de base concernant la design de database. Dans une database relationnelle, l'set des tables et des colonnes est supposé être constant. Ils peuvent changer avec l'installation de nouvelles versions, mais pas pendant l'exécution.

Parfois, lorsque les gens font cela, il semble qu'ils veulent build des noms uniques pour les tables temporaires. Ceci est totalement inutile, car il s'agit d'une fonctionnalité embeddede dans SQL Server. Si tu le dis:

CREATE TABLE #nisse (un int NOT NULL)

alors le nom réel derrière les scènes sera quelque chose de beaucoup plus long, et aucune autre connection ne pourra voir cette instance de #nisse.

Si vous voulez créer une table permanente unique pour un user, mais que vous ne voulez pas restr connecté et que vous ne pouvez pas utiliser de tables temporaires, il peut être préférable de créer une table que tous les clients peuvent partager, mais où la première colonne est une key qui est privée au client. Je discute de cette méthode un peu plus près dans mon article Comment partager des données entre procédures stockées.

Solution possible à l'aide de la fonction de table paramétrée en ligne (vous pouvez utiliser la procédure stockée si nécessaire):

 CREATE FUNCTION dbo.fxnExample (@Parameter1 NVARCHAR(1)) RETURNS TABLE AS RETURN ( SELECT id, value FROM TableName WHERE id = @Parameter1 ) -- Usage Example SELECT * FROM dbo.fxnExample('A') -- only data from 'A' SELECT * FROM dbo.fxnExample('B') -- only data from 'B' 

MODIFIER

Vous pouvez utiliser la vue pour cela et les transmettre aux users. Si vous voulez toujours que les tables se sentent libres de changer de code, vous devriez avoir l'idée. Pourquoi les vues, parce que la table est toujours une et vous obtenez une vue dynamic qui peut imiter vos tables multiples. En outre, lorsque datatables seront mises à jour dans la table principale, toutes les vues seront traitées immédiatement, pas besoin de mettre à jour / insert.

SqlFiddleDemo

DBFiddle Demo (mise à jour)

 CREATE TABLE main_tab(suffix NVARCHAR(10) NOT NULL, val INT); INSERT INTO main_tab(suffix, val) VALUES ('A', 1), ('A', 2), ('A', 3), ('B', 4), ('B', 5), ('B', 6), ('C', 7), ('C', 8), ('C', 9); /* Get list of suffixes */ SELECT suffix, [row_id] = ROW_NUMBER() OVER(ORDER BY suffix) INTO #temp FROM main_tab GROUP BY suffix; DECLARE @name_suffix NVARCHAR(100), @sql NVARCHAR(MAX), @view_name NVARCHAR(MAX), @index INT = 1, @total INT = (SELECT COUNT(*) FROM #temp); /* I used simple while loop but you can change to CURSOR if needed */ WHILE (@index <= @total) BEGIN SELECT @name_suffix = suffix FROM #temp WHERE row_id = @index; SELECT @sql = N'CREATE VIEW [dbo].[View@name_suffix] AS SELECT t.suffix, t.val FROM [dbo].[main_tab] t WHERE t.suffix = ''@name_suffix'' WITH CHECK OPTION' SELECT @view_name = REPLACE('[dbo].[View@name]', '@name', @name_suffix) ,@sql = REPLACE(@sql, '@name_suffix', @name_suffix) /* Check if view exists, if not create one */ /* Instead of EXEC you can use EXEC [dbo].[sp_executesql] and pass params explicitly */ IF OBJECT_ID(@view_name, 'V') IS NULL EXEC(@sql) SET @index += 1; END /* Check if you can query views */ SELECT * FROM ViewA; SELECT * FROM ViewB; SELECT * FROM ViewC;