Benötigen Sie einen effizienten path, um die gegebene SQL-Abfrage in SQL server, gespeicherte Prozedur durchzuführen

Ich habe ein Problem, wo ich Tabellen auf Basis der Anzahl der Parameter, die in der gespeicherten Prozedur wie folgt:

----when there is one column 'CREATE TABLE [dbo].['+@table_name+'] ( ['+@colname1+'] [VARCHAR](200) ) ' ----when there are two column 'CREATE TABLE [dbo].['+@table_name+'] ( ['+@colname1+'] [VARCHAR](200), ['+@colname2+'] [VARCHAR](200) ) ;' ----when there are three column 'CREATE TABLE [dbo].['+@table_name+'] ( ['+@colname1+'] [VARCHAR](200), ['+@colname2+'] [VARCHAR](200), ['+@colname3+'] [VARCHAR](200) ) ' 

Eine Möglichkeit, dass ich das weiß, ist:

 ----when there is one column If ((@colname1 IS NOT NULL AND LEN(@colname1) !=0)) BEGIN 'CREATE TABLE [dbo].['+@table_name+'] ( ['+@colname1+'] [VARCHAR](200) )' END ----when there are two column If ((@colname1 IS NOT NULL AND LEN(@colname1) !=0) AND (@colname2 IS NOT NULL AND LEN(@colname2) !=0)) BEGIN Drop table [dbo].['+@table_name+'] 'CREATE TABLE [dbo].['+@table_name+'] ( ['+@colname1+'] [VARCHAR](200), ['+@colname2+'] [VARCHAR](200) )' END ----when there are three column If ((@colname1 IS NOT NULL AND LEN(@colname1) !=0) AND (@colname2 IS NOT NULL AND LEN(@colname2) !=0) AND (@colname3 IS NOT NULL AND LEN(@colname3) !=0)) BEGIN Drop table [dbo].['+@table_name+'] 'CREATE TABLE [dbo].['+@table_name+'] ( ['+@colname1+'] [VARCHAR](200), ['+@colname2+'] [VARCHAR](200), ['+@colname3+'] [VARCHAR](200) ) ' END 

Auf diese Weise wird mein Code sehr langwierig. Gibt es einen anderen effizienten path, dies zu tun. Wenn anstatt Werte für @ colname1, @ colname2, @ colname3 separat zu übergeben, gebe ich Werte in einem einzigen parmaeter @colname als @colname = 'col1, col2, col3', wie kann ich das machen?

Es ist möglich, dynamische sql und einen durch Kommas getrennten Parameter für Spaltennamen zu verwenden, obwohl, wie ich in meinem Kommentar schrieb, das eine schlechte Idee ist, und ich empfehle Ihnen dringend, diesen Ansatz neu zu überdenken. mit der "xml Split-String-Technik" und QUOTENAME zu minimieren SQL-Injektion Hazard:

 CREATE PROCEDURE stpCreateTableDynamically ( @Table_Name sysname, @Column_Names nvarchar(max) ) AS DECLARE @Sql nvarchar(max) SELECT @Sql = 'CREATE TABLE [dbo].' + QUOTENAME('zzz_'+ @Table_Name) +' (' SELECT @Sql = @Sql + QUOTENAME(split.a.value('.', 'VARCHAR(100)')) + ' [VARCHAR](200),' FROM (SELECT Cast ('<M>' + Replace(@Column_Names, ',', '</M><M>')+ '</M>' AS XML) AS Data) AS A CROSS apply data.nodes ('/M') AS Split(a); SELECT @Sql = LEFT(@Sql, LEN(@Sql) - 1) + ') ON [ZZZ_FG];' PRINT @Sql --EXEC(@Sql) GO 

Verwendung:

 EXEC stpCreateTableDynamically 'MyTable', 'Column1,Col2,Col3' 

Ausgabe:

 CREATE TABLE [dbo].[zzz_MyTable] ([Column1] [VARCHAR](200),[Col2] [VARCHAR](200),[Col3] [VARCHAR](200)) ON [ZZZ_FG]; 

Sobald Sie sehen, dass die Ausgabe in Ordnung ist, können Sie die exec Zeile nicht exec und die print löschen.

Du kannst so versuchen,

  DECLARE @SQL NVARCHAR(max) = '' ,@table_name NVARCHAR(255) = 'Table1' ,@colname1 NVARCHAR(255) = 'c1' ,@colname2 NVARCHAR(255) = 'c2' ,@colname3 NVARCHAR(255) = 'c3' ,@cols NVARCHAR(max) = '' SET @cols = CASE WHEN @colname1 IS NOT NULL AND len(@colname1) > 0 THEN ',[' + @colname1 + '] [VARCHAR](200)' ELSE '' END + CASE WHEN @colname2 IS NOT NULL AND len(@colname2) > 0 THEN ',[' + @colname2 + '] [VARCHAR](200)' ELSE '' END + CASE WHEN @colname3 IS NOT NULL AND len(@colname3) > 0 THEN ',[' + @colname3 + '] [VARCHAR](200)' ELSE '' END SET @cols = stuff(@cols, 1, 1, '') SET @SQL = 'Drop table [dbo].[zzz_' + @table_name + '] CREATE TABLE [dbo].[zzz_' + @table_name + '] ( ' + @cols + ' ) ON [ZZZ_FG];' PRINT @sql --EXEC sp_executesql @sql