Во-первых, тот факт, что вам нужно прибегнуть к динамическому c SQL, указывает на серьезную проблему проектирования базы данных: у вас есть несколько таблиц, в которых хранится одна и та же сущность с некоторыми идентификаторами в имени таблицы.
Принимая ваш Например, если у вас есть таблицы с именами log1
, log2
... logn
, вы должны заменить их одной таблицей с именем log
и иметь этот номер в качестве другого столбца в этой таблице.
Сказав это, я понимаю, что во многих случаях изменение структуры базы данных не вариант - и по этой причине я покажу вам обходной путь для вашей проблемы (кроме изменения структуры базы данных определение обходного пути, а не решения).
Первое, что вы хотите сделать, это использовать sysname
в качестве типа данных для имени таблицы вместо текущего nvarchar(50)
.
sysname
это тип данных, используемый внутренне SQL Сервером для всех идентификаторов.
Второе, что вам нужно, - убедиться, что таблица действительно существует и в ней есть ожидаемые столбцы. Это легко сделать с помощью встроенного системного представления information_schema.columns
.
Далее вы хотите обработать свои параметры как параметры - не объединять их в динамическую строку c SQL, а передавать их в качестве параметров для sp_executeSql
.
И, наконец, вы хотите защитить от фанки символов в имени таблицы, поэтому вы используете QUOTENAME
при объединении его с SQL:
ALTER PROCEDURE [dbo].[InsertIntoTable](
@TableName sysname,
@Actual real,
@Regulated real,
@Supply real,
@Expected real,
@Control_Value real)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @ColumnCount int;
SELECT @ColumnCount = COUNT(*)
FROM Information_schema.Columns
WHERE Table_Name = @TableName
AND COLUMN_NAME IN([Actual],[Regulated],[Supply],[Expected],[Control_Value])
IF @ColumnCount < 5 RETURN;
DECLARE @SQL NVARCHAR(MAX) -- dynamic SQL should always be Unicode
SET @SQL = N'INSERT INTO dbo.' + QUOTENAME(@TableName) + '([Actual],[Regulated],[Supply],[Expected],[Control_Value])
VALUES(@Actual, @Regulated, @Supply, @Expected, @Control_Value)'
EXEC sp_executesql
@sql,
N'@Actual real, @Regulated real, @Supply real, @Expected real, @Control_Value real',
@Actual, @Regulated, @Supply, @Expected, @Control_Value
END
Для более подробного объяснения, посмотрите мой пост в блоге под названием Что нужно и чего не нужно делать динамически c SQL для SQL Сервер .