以下是我正在运行的查询。我的问题似乎在下面的INSERT声明中。我有一个FeatureKeys列表,我使用ROW_NUMBER()逐个遍历此列表,以便一次输入每个FeatureKey。问题是前几个FeatureKeys输入正确没问题但是在列表末尾它说我试图将NULL值插入FeatureKey列。作为一个例子,我有一个4个FeatureKeys的列表,然后我尝试逐个输入每个FeatureKey,前两个正确插入,最后说我试图将NULL值插入FeatureKey列。我已经尝试将FeatureKey值打印到循环的不同部分的控制台,并且很好地逐个打印出所有值。只有当我尝试执行INSERT语句时,无论出于何种原因,FeatureKey变量都是NULL。
DECLARE @Count INT, @RowFeature INT, @MaxParts INT, @TotalNewFeatures INT, @InspectionKey INT, @FeatureKey INT
SET @InspectionKey =
(SELECT Inspection_Key FROM ATI_FeatureInspection.dbo.Inspection WHERE Op_Key = 562634);
SET @TotalNewFeatures =
(SELECT COUNT(Features.Feature_Key)
FROM ATI_FeatureInspection.dbo.Features
WHERE NOT EXISTS(
SELECT *
FROM ATI_FeatureInspection.dbo.Position
WHERE Features.Feature_Key = Position.Feature_Key
AND Inspection_Key_FK =
(SELECT Inspection.Inspection_Key
FROM ATI_FeatureInspection.dbo.Inspection
WHERE Op_Key = 562634))
AND Part_Number_FK =
(SELECT Part_Number
FROM ATI_FeatureInspection.dbo.Operation
WHERE Op_Key = 562634)
AND Operation_Number_FK =
(SELECT Operation_Number
FROM ATI_FeatureInspection.dbo.Operation
WHERE Op_Key = 562634));
SET @Count = 0;
SET @RowFeature = 0
SET @MaxParts = 13
WHILE(@RowFeature < @TotalNewFeatures)
BEGIN
SET @RowFeature = @RowFeature + 1;
SET @FeatureKey =
(SELECT Feature_Key
FROM (
SELECT ROW_NUMBER() OVER(ORDER BY Features.Feature_Key ASC) AS RowNumber, Features.Feature_Key
FROM ATI_FeatureInspection.dbo.Features
WHERE NOT EXISTS(
SELECT *
FROM ATI_FeatureInspection.dbo.Position
WHERE Features.Feature_Key = Position.Feature_Key
AND Inspection_Key_FK =
(SELECT Inspection.Inspection_Key
FROM ATI_FeatureInspection.dbo.Inspection
WHERE Op_Key = 562634))
AND Part_Number_FK =
(SELECT Part_Number
FROM ATI_FeatureInspection.dbo.Operation
WHERE Op_Key = 562634)
AND Operation_Number_FK =
(SELECT Operation_Number
FROM ATI_FeatureInspection.dbo.Operation
WHERE Op_Key = 562634)) AS foo
WHERE RowNumber = @RowFeature);
WHILE(@Count < @MaxParts)
BEGIN
INSERT INTO ATI_FeatureInspection.dbo.Position(Inspection_Key_FK, Piece_ID, Feature_Key)
VALUES(@InspectionKey, @Count + 1, @FeatureKey)
SET @Count = @Count + 1
END
SET @Count = 0
END
下面是我的数据库图表。有一个WinForms程序,用户输入一个OpKey和一个LotSize。 OpKey属于特定的部件号和操作号对,并且多个OpKey可以具有相同的部件和操作号。用户可以将功能添加到部件和操作编号对(NOT AN OPKEY),使2个不同或更多的OpKey可以使用相同的功能,而无需为每个OpKey添加功能。我在这里要做的是为用户想要检查的每个部分插入功能,这也是LotSize。作为示例,用户将3个特征添加到PartNumber = 386022和OperationNumber = 150的组合中。具有该组合的大约7个不同的OpKeys。我们将使用其中两个。使用LotSize = 10时,用户使用OpKey = 26266进行打孔。因此,此查询创建10个部分,其中3个要素与每个部分关联。如果我然后打入OpKey = 468753和LotSize = 6,它与相同的零件和操作编号相关联,则此查询将插入6个零件,每个零件具有相同的3个特征。现在,此查询还将检测事后是否添加了任何新功能,并相应地添加这些功能。因此,如果用户在上面的相同部件和操作编号组合中添加了新功能,当用户进入OpKey = 26266时,用户将无法再选择批量,因为它已经创建并将新功能添加到每个部件中那次检查。所以基本上只是添加创建具有必要功能的部件,以便在Position表中进行检查。
[DataBaseDiagramImage] [1] [1]:https://i.stack.imgur.com/svbgJ.png
答案 0 :(得分:0)
您的问题在这里:
WHERE RowNumber = @RowFeature
您正在向要查询的其中一个表中添加行,用于从返回的信息中排除项目。您还在递增@RowFeature值。组合工作如下:
Position
表 Position
表添加了第一个功能,因此在阅读下一个功能时不会返回第一个功能 Position
表 鉴于此结构,解决方案是将WHERE RowNumber = @RowFeature
替换为WHERE RowNumber = 1
然而,更好的处理方法是使这个代码更加基于集合,而不是逐行处理数据行(RBAR)。如果我们创建一个小数字表,例如:
,这将更容易CREATE TABLE Nums(num int primary key clustered)
INSERT INTO Nums(num)
SELECT TOP 10000 ROW_NUMBER() OVER(ORDER BY t1.number) AS N
FROM master..spt_values t1
CROSS JOIN master..spt_values t2
在您的情况下,您可以在一个命令中插入所有@maxParts
行。
这样的事情应该有效:
WITH foo as (
SELECT ROW_NUMBER() OVER(ORDER BY Features.Feature_Key ASC) AS RowNumber,
Features.Feature_Key
FROM ATI_FeatureInspection.dbo.Features
WHERE NOT EXISTS(
SELECT *
FROM ATI_FeatureInspection.dbo.Position
WHERE Features.Feature_Key = Position.Feature_Key
AND Inspection_Key_FK = (
SELECT Inspection.Inspection_Key
FROM ATI_FeatureInspection.dbo.Inspection
WHERE Op_Key = 562634
)
)
AND Part_Number_FK = (
SELECT Part_Number
FROM ATI_FeatureInspection.dbo.Operation
WHERE Op_Key = 562634
)
AND Operation_Number_FK = (
SELECT Operation_Number
FROM ATI_FeatureInspection.dbo.Operation
WHERE Op_Key = 562634
)
)
INSERT INTO ATI_FeatureInspection.dbo.Position(Inspection_Key_FK, Piece_ID, Feature_Key)
SELECT @InspectionKey, Nums(num), foo.Feature_Key,
FROM foo
CROSS JOIN Nums
WHERE num <= @maxParts