Динамическое создание таблиц с помощью цикла while - PullRequest
0 голосов
/ 24 мая 2019

Я создаю таблицы динамически с циклом while.Будет создано несколько таблиц.Тем не менее, я получаю эту ошибку при запуске кода.

'Преобразование не удалось при преобразовании значения varchar'

Не знаю почему, потому что, если я жестко закодирую имя таблицы, она работает нормально.

СТАРЫЙ КОД -

DECLARE @Count INT = (SELECT COUNT(*) FROM PayComponents) --This is how many 
times im going to loop.
DECLARE @Pcomp INT = '1' --starting at 1
DECLARE @Table VARCHAR(10) = 'Pcomp' --Part of the table name
DECLARE @TableNo VARCHAR(10) --declaring for adding onto table name.
DECLARE @TableName VARCHAR(10) --declare to hold full table name

 WHILE @Pcomp <= @Count --while 1 is less than or = to 61 loop
  BEGIN 
  DECLARE @str VARCHAR(MAX)
  SET @TableNo = CAST(@Pcomp AS VARCHAR(10))
  SET @TableName = @Table + @TableNo --Full table name... Pcomp1, Pcomp2, 
  Pcomp3, Pcomp4 etc


   SET @str = 'IF OBJECT_ID(''dbo.' + @TableName + ''', ''U'') IS NOT NULL //This is where i am getting the conversion error
   Drop Table ' + @TableName + '

   CREATE TABLE ' + @TableName + '
   (
   EeID INT,
   EeRef VARCHAR(10),
   Name VARCHAR(50),
   PayCompID SMALLINT,
   PayCompDesc VARCHAR(50),
   RateLastMonth MONEY,
   RateThisMonth MONEY
   )

   INSERT INTO ' + @TableName + ' (EeID, EeRef, Name, PayCompID, 
   PayCompDesc, 
   RateLastMonth)
   SELECT
   ed.EeID,
   ed.EeRef,
   CONCAT(Forename, '' '', Surname) AS ''Name'',
   eec.PCompID,
   eec.PCDescr,
   eec.Rate
   FROM EeDetails ed
   INNER JOIN UnityEeComponents eec ON eec.EeRef = ed.EeRef
   CROSS JOIN PayrollRuns pr
   WHERE eec.PCompID = ' + @Pcomp + ' AND pr.RunID = (SELECT RunID FROM 
   PayrollRuns WHERE RunDate = ''2019-04-30'')
   ORDER BY ed.EeID

   UPDATE ' + @TableName + '
   SET 
   ' + @TableName + '.RateThisMonth = EeComponents.ECRate
   FROM ' + @TableName + '
   INNER JOIN 
   EeComponents
   ON 
   ' + @TableName +'.EeID = EeComponents.EeID
   WHERE EeComponents.PCompID = ' + @Pcomp + ' AND EeComponents.RunID = 
   (SELECT RunID FROM PayrollRuns WHERE RunDate = ''2019-02-08'')

   SET ' + @Pcomp + ' = ' + @Pcomp + ' + 1;'
   END;

НОВЫЙ КОД - Указывает, что «Запятые завершены успешно»

Таблицы не созданы.

DECLARE @Count INT = (SELECT COUNT(*) FROM PayComponents) --This is how many 
times im going to loop
DECLARE @Pcomp INT = '1' --starting at 1
DECLARE @Table VARCHAR(10) = 'PComp' --Part of the table name
DECLARE @TableName VARCHAR(10) --declare to hold full table name

WHILE @Pcomp <= @Count --while 1 is less than or = to 61 loop
BEGIN
DECLARE @str VARCHAR(MAX)

SET @str = '
SET ' + @TableName + ' = CONCAT('+@Table+', '+CAST(@Pcomp AS VARCHAR(10))+')
IF OBJECT_ID(''dbo.' + QUOTENAME(@TableName) + ''', ''U'') IS NOT NULL
Drop Table ' + QUOTENAME(@TableName) + '

CREATE TABLE ' + QUOTENAME(@TableName) + '
(
EeID INT,
EeRef VARCHAR(10),
Name VARCHAR(50),
PayCompID SMALLINT,
PayCompDesc VARCHAR(50),
RateLastMonth MONEY,
RateThisMonth MONEY
)

INSERT INTO ' + QUOTENAME(@TableName) + ' (EeID, EeRef, Name, PayCompID, 
PayCompDesc, RateLastMonth, RateThisMonth)
SELECT
ed.EeID,
ed.EeRef,
CONCAT(Forename, '' '', Surname),
eec.PCompID,
eec.PCDescr,
eec.Rate,
''0.00''
FROM EeDetails ed
INNER JOIN UnityEeComponents eec ON eec.EeRef = ed.EeRef
CROSS JOIN PayrollRuns pr
WHERE eec.PCompID = ' + QUOTENAME(@Pcomp) + ' AND pr.RunID = (SELECT RunID 
FROM PayrollRuns WHERE RunDate = ''2019-04-30'')
ORDER BY ed.EeID

UPDATE ' + QUOTENAME(@TableName) + '
SET 
' + QUOTENAME(@TableName) + '.RateThisMonth = EeComponents.ECRate
FROM ' + QUOTENAME(@TableName) + '
INNER JOIN 
EeComponents
ON 
' + QUOTENAME(@TableName) +'.EeID = EeComponents.EeID
WHERE EeComponents.PCompID = ' + CAST(@Pcomp AS VARCHAR(10)) + ' AND 
EeComponents.RunID = (SELECT RunID FROM PayrollRuns WHERE RunDate = ''2019- 
02-08'');'

EXEC (@str)
SET @Pcomp = CAST(@Pcomp AS VARCHAR(10)) + 1;
END;

Любая помощь или предложения будут с благодарностью.

1 Ответ

0 голосов
/ 24 мая 2019

Оператор + делает разные вещи в зависимости от типов данных значений, к которым он применяется. Он либо выполняет числовую операцию (добавление), либо объединяет строки. У вас есть (фрагмент)

'....SET ' + @Pcomp + ' = ' + @Pcomp + ' + 1;'

@ Pcomp является инт. Другое значение - это строка. Что просходит? Чтобы оценить результат, значения должны быть преобразованы в один тип данных, чтобы определить, что делать. Итак, какой тип данных выбран? Существуют правила , когда ваш код явно не указывает, что использовать - и строки имеют почти самый низкий приоритет. В этом случае движок пытается преобразовать ваши строковые литералы в целые, что не удается.

Хотя это решает вашу непосредственную проблему, у вас есть гораздо большие проблемы. Ваш цикл бесконечен, потому что вы не увеличиваете счетчик циклов. Фактически, вы не выполняете динамический запрос, который вы генерируете. Все поправимо - но главный вопрос - почему!

Зачем вам нужно создавать отдельные таблицы здесь? У вас есть проблема нормализации, которую вы должны пересмотреть.

Наконец, вы жестко закодировали очень конкретную дату в логике запроса. Хотя сейчас это может сработать, я не могу понять, как это будет работать в общем, постоянном режиме.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...