#sql #sql-server #common-table-expression #sql-server-2019
Вопрос:
мне нужна помощь , пожалуйста, я застрял на этом уже 3 дня, я бесконечно гуглил, но, похоже, не могу это исправить, может кто-нибудь, пожалуйста, помогите мне исправить это и объяснить, что я сделал не так?
я продолжаю получать столбец «Нет», указанный для ошибки C1, и когда я пытаюсь его выполнить, я продолжаю получать
Msg 4112, Уровень 15, Состояние 1, Процедура XXX, Строка 27 [Строка запуска пакета 7] Функция «НОМЕР СТРОКИ» должна иметь предложение OVER с ПОРЯДКОМ ПО.
SELECT TOP 1 @DataIndex = DataIndex,
@ChannelDescription = Description,
@UserConfigurationData = UserConfigurationData
FROM DevicesCW WHERE Id = @DTSourceRecId
SELECT @DataIndex DataIndex,Column_Id ChannelID, value ChannelName INTO #CName FROM dbo.[fn_split_string_to_column] (@ChannelDescription,@delimiter)
SELECT @DataIndex DataIndex,Column_Id ChannelID, value ChannelNumber INTO #CNumber FROM dbo.[fn_split_string_to_column] (@UserConfigurationData,@delimiter);
--Test Code--
--Channel 1
With C1 AS (SELECT @ReoDeviceId,CN.ChannelNumber,C.ChannelID,D.Totaliser1Units TotaliserUnits, C.ChannelName, 'CW', @DTSourceRecId,'B', C.ChannelName,
RN = ROW_NUMBER() OVER(PARTITION BY @DTSourceRecId)
FROM DevicesCW D
JOIN #CName C
ON D.DataIndex = C.DataIndex AND C.ChannelID = 1
JOIN #CNumber CN
ON D.DataIndex = C.DataIndex AND C.ChannelID = 1
LEFT JOIN ReoDeviceMeter RDM
ON D.DataIndex = RDM.DeviceIndex AND RDM.ChannelNumber = 1
WHERE D.Id = @DTSourceRecId AND RDM.ReoMeterId IS NULL)
INSERT INTO ReoMeter(ReoDeviceId, MeterNumber, ChannelNumber, ChanUnitOfMeasure, Description, DtSource, DtSourceRecId, MeterType, SourceDescription)
SELECT @ReoDeviceId,ChannelNumber,ChannelID,TotaliserUnits,ChannelName,'CW',@DTSourceRecId,'B',ChannelName
FROM C1
WHERE RN = 1
Group BY @ReoDeviceId,ChannelNumber,ChannelID,TotaliserUnits,ChannelName,'CW',@DTSourceRecId,'B',ChannelName
-- Test Code---
Я пытаюсь пойти по вышеуказанному пути, чтобы решить проблему, когда код удара дублирует данные в базе данных для каждого канала. если у меня есть 2 канала, он вставляет данные 2 раза для CH1 и CH2 вместо того, чтобы просто вставлять данные для каждого канала
--Channel1
INSERT INTO ReoMeter(ReoDeviceId, MeterNumber, ChannelNumber, ChanUnitOfMeasure, Description, DtSource, DtSourceRecId, MeterType, SourceDescription)
SELECT @ReoDeviceId,CN.ChannelNumber,C.ChannelID,D.Totaliser1Units, C.ChannelName, 'CW', @DTSourceRecId,'B', C.ChannelName
FROM DevicesCW D
JOIN #CName C
ON D.DataIndex = C.DataIndex AND C.ChannelID = 1
JOIN #CNumber CN
ON D.DataIndex = C.DataIndex AND C.ChannelID = 1
LEFT JOIN ReoDeviceMeter RDM
ON D.DataIndex = RDM.DeviceIndex AND RDM.ChannelNumber = 1
WHERE D.Id = @DTSourceRecId AND RDM.ReoMeterId IS NULL
--Channel2
INSERT INTO ReoMeter(ReoDeviceId, MeterNumber, ChannelNumber, ChanUnitOfMeasure, Description, DtSource, DtSourceRecId, MeterType, SourceDescription)
SELECT @ReoDeviceId,CN.ChannelNumber,C.ChannelID,D.Totaliser2Units, C.ChannelName, 'CW', @DTSourceRecId, 'B', C.ChannelName
FROM DevicesCW D
JOIN #CName C
ON D.DataIndex = C.DataIndex AND C.ChannelID = 2
JOIN #CNumber CN
ON D.DataIndex = C.DataIndex AND C.ChannelID = 2
LEFT JOIN ReoDeviceMeter RDM
ON D.DataIndex = RDM.DeviceIndex AND RDM.ChannelNumber = 2
WHERE D.Id = @DTSourceRecId AND RDM.ReoMeterId IS NULL
Комментарии:
1. Приведенный выше код относится к конкретному продукту. Какие СУБД вы используете?
2. вам нужно присвоить псевдоним этим выражениям в вашем CTE
C1
3. MSSQL Server 2019 с SQL Server Management Studio V18.9.2
4. Я знаю, что мне нужно назначить псевдоним выражению, которое я получил в результате поиска переполнения стека, я просто не знаю, как и где мне нужно его назначить, я, кажется, не могу это понять.
5. Ошибка говорит вам о проблеме.
SELECT @ReoDeviceId,CN.ChannelNumber
. Где имя/псевдоним столбца, в котором указано значение переменной/параметра@ReoDeviceId
? Есть и другие столбцы с той же проблемой.
Ответ №1:
Вам нужно указать Alea для всех столбцов C1, чтобы устранить проблему.
SELECT TOP 1 @DataIndex = dataindex,
@ChannelDescription = description,
@UserConfigurationData = userconfigurationdata
FROM devicescw
WHERE id = @DTSourceRecId
SELECT @DataIndex DataIndex,
column_id ChannelID,
value ChannelName
INTO #cname
FROM dbo.[Fn_split_string_to_column] (@ChannelDescription, @delimiter)
SELECT @DataIndex DataIndex,
column_id ChannelID,
value ChannelNumber
INTO #cnumber
FROM dbo.[Fn_split_string_to_column] (@UserConfigurationData, @delimiter);
--Test Code--
--Channel 1
WITH c1
AS (SELECT @ReoDeviceId AS ReoDeviceId,
CN.channelnumber,
C.channelid,
D.totaliser1units TotaliserUnits,
C.channelname,
'CW' AS CW,
@DTSourceRecId AS DTSourceRecId,
'B' AS B,
C.channelname,
RN = Row_number()
OVER(
partition BY @DTSourceRecId)
FROM devicescw D
JOIN #cname C
ON D.dataindex = C.dataindex
AND C.channelid = 1
JOIN #cnumber CN
ON D.dataindex = C.dataindex
AND C.channelid = 1
LEFT JOIN reodevicemeter RDM
ON D.dataindex = RDM.deviceindex
AND RDM.channelnumber = 1
WHERE D.id = @DTSourceRecId
AND RDM.reometerid IS NULL)
INSERT INTO reometer
(reodeviceid,
meternumber,
channelnumber,
chanunitofmeasure,
description,
dtsource,
dtsourcerecid,
metertype,
sourcedescription)
SELECT reodeviceid,
channelnumber,
channelid,
totaliserunits,
channelname,
cw,
dtsourcerecid,
b,
channelname
FROM c1
WHERE rn = 1
GROUP BY reodeviceid,
channelnumber,
channelid,
totaliserunits,
channelname,
cw,
dtsourcerecid,
b,
channelname
Комментарии:
1. В определении CTE также есть другие столбцы без имен (псевдонимов).
2. Почему вы добавили a
GROUP BY
, когда у вас нет агрегации?3. Просто скопируйте вставку вышеуказанного кода с идентификацией проблемы и сгруппируйте по, чтобы избежать дублирования, о котором говорится во второй части вопроса.
4. Спасибо, да, теперь у меня ошибка в col 6, так что мне нужно указывать псевдонимы для каждого из столбцов
5. Да, конечно, пожалуйста, примите ответ и откажитесь от голоса, если бы это вам помогло..