как использовать для цикла в хранимой процедуре SQL Server 2005 - PullRequest
3 голосов
/ 08 февраля 2011

Я новичок в SQL-сервере.мое требование - я должен взять тысячи записей из c # в виде файла XML, и из этого файла я беру данные из временной таблицы.И из таблицы я должен проверить запись одну за другой, если она присутствует, затем обновить еще вставить.Итак, я написал хранимую процедуру, но она дает мне следующую ошибку

Сообщение 102, Уровень 15, Состояние 1, Процедура InsertIntoMyTable, Строка 13
Неверный синтаксис рядом с «cast».
Сообщение 102, Уровень 15, Состояние 1, Процедура InsertIntoMyTable, Строка 18
Неверный синтаксис рядом с 'LOOP'.
Сообщение 156, Уровень 15, Состояние 1, Процедура InsertIntoMyTable, Строка 25
Неверный синтаксис рядом сКлючевое слово 'END'.

Хранимая процедура:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE InsertIntoMyTable
    @mytable xml 
 AS
BEGIN
    SELECT 
    cast(colx.query('data(PointsliceId) ') as int) as PointSliceId,
    cast(colx.query('data(Pt_timestamp) ') as datetime)     as Point_timestamp
    cast(colx.query('data(FloatValue) ') as float)     as Float_Value
INTo #TMP FROM @mytable.nodes('DocumentElement/mytable') AS Tabx(Colx)


For IDX in (select * from TMP)
LOOP
if((select count(*) from PointValue_Float where PointSliceId=IDX.PointSliceId and Pt_timeStamp=IDX.Pt_timeStamp)>0 )            
          update PointValue_Float set FloatValue=t.FloatValue from #TMP t  where t.PointSliceId=PointValue_Float.PointSliceId and t.Pt_timeStamp=PointValue_Float.Pt_timeStamp 
else
        insert into PointValue_Float(PointSliceId,Pt_timeStamp,FloatValue) SELECT PointSliceId,Pt_timeStamp,FloatValue FROM #TMP
END LOOP

END
GO
  • Имя моей таблицы: pointvalue_float, где я должен проверить, присутствуют данные или нет, если они есть, тогда обновите, иначе вставьте

Ответы [ 2 ]

4 голосов
/ 08 февраля 2011

Создание ручного цикла в процедуре SQL Server - всегда плохая идея - SQL Server работает с наборами данных - и ваш оператор также должен быть ориентирован на множество.

В вашем случае я бы сделал следующее:

  • уничтожить XML во временную таблицу (как вы уже сделали)
  • затем обновить существующие значения на основе условия объединения
  • удалить эти строки, обновленные из временной таблицы
  • остальные строки должны быть вставлены

То есть ваш код будет выглядеть примерно так:

CREATE PROCEDURE InsertIntoMyTable @mytable xml 
AS BEGIN
   SELECT 
      colx.value('(PointsliceId)[1]', 'INT') AS PointSliceId,
      colx.value('(Pt_timestamp)[1]', 'DATETIME') AS Point_timestamp
      colx.value('(FloatValue)[1]', 'FLAOT') AS Float_Value
   INTO #TMP 
   FROM @mytable.nodes('DocumentElement/mytable') AS Tabx(Colx)

-- udpate the existing rows
UPDATE dbo.PointValue_Float
SET FloatValue = t.FloatValue 
FROM #TMP t  
WHERE t.PointSliceId = PointValue_Float.PointSliceId 
  AND t.Pt_timeStamp = PointValue_Float.Pt_timeStamp 

-- remove those from the #TMP table
DELETE FROM #TMP
WHERE EXISTS
  (SELECT * FROM dbo.PointValue_Float 
   WHERE PointSliceId = #TMP.PointSliceId AND Pt_timeStamp = #TMP.Pt_timeStamp)

-- INSERT the remaining rows    
INSERT INTO 
    dbo.PointValue_Float(PointSliceId, Pt_timeStamp, FloatValue) 
  SELECT 
     PointSliceId, Pt_timeStamp, FloatValue 
  FROM #TMP
END
0 голосов
/ 08 февраля 2011
  1. Вам не хватает запятой во второй строке (case case) в конце. Поля выбора всегда должны быть разделены запятой. В вашем случае второй оператор case, запятая в конце строки отсутствует.
  2. Вы должны использовать BEGIN и END для начала и окончания цикла WHILE . WHILE лучше использовать в хранимых процедурах вместо FOR. Не уверен, что в хранимых процедурах SQL Server есть что-то вроде FOR.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...