我有一个 SQLCLR 程序集,它创建一个带有条码扫描器的 Telnet 接口,并将它接收到的任何东西放在一个表中。有时,它会因错误而崩溃:
以用户身份执行:NT AUTHORITY\SYSTEM。 执行用户定义的例程期间发生 .NET Framework 错误 或聚合“fnBarcodeScanner”: System.Data.SqlClient.SqlException:子查询返回超过 1 个值。 当子查询跟随 =、!=、、>= 或 当子查询用作表达式时。 System.Data.SqlClient.SqlException: 在 System.Data.SqlClient.SqlConnection.OnError( SqlException 异常,布尔型 breakConnection) 在 System.Data.SqlClient.SqlInternalConnection.OnError( SqlException 异常,布尔型 breakConnection) 在 System.Data.SqlClient.SqlInternalConnectionSmi.EventSink.DispatchMessages( 布尔忽略非致命消息) 在 Microsoft.SqlServer.Server.SmiEventSink_Default.DispatchMessages( 布尔忽略非致命消息) 在 System.Data.SqlClient.SqlCommand.RunExecuteNonQuerySmi( 布尔 sendToPipe) 在 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery( DbAsyncResult 结果、String methodName、Boolean sendToPipe) 在 System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 在 MinimalisticTelnet.Program.Connect(String ip) 。 [SQLSTATE 42000](错误 6522)语句已终止。 [SQLSTATE 01000](错误 3621)。步骤失败。
我理解错误的含义,但我不确定在这种情况下它是如何引起的。程序集中唯一的 SQL 是一个插入语句,它将一个字符串插入到表中。不应该有任何方法具有多个值。这是程序集的 C# 代码(为简洁起见,省略了):
namespace MinimalisticTelnet
{
public class Program
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void Main(string[] args)
{
}
public static void Connect(String ip)
{
String lastCode = null;
TelnetConnection tc = new TelnetConnection(ip, 23);
using (SqlConnection conn = new SqlConnection("context connection=true"))
{
SqlCommand InsertID = new SqlCommand();
InsertID.Connection = conn;
SqlParameter IDCodeParam = new SqlParameter("@Barcode", SqlDbType.VarChar);
conn.Open();
while (tc.IsConnected)
{
String barcode = tc.Read();
if (!((barcode).Length == 0))
{
barcode = barcode.Substring(0,barcode.IndexOf("\n") - 1);
if (!(barcode == lastCode))
{
lastCode = barcode;
SqlString sqlBarcode = barcode;
IDCodeParam.Value = sqlBarcode;
InsertID.Parameters.Add(IDCodeParam);
InsertID.CommandText = "INSERT INTO dbo.tbl_Barcode (Barcode)" +
" Values(@Barcode)";
InsertID.ExecuteNonQuery();
InsertID.Parameters.Clear();
}
}
}
conn.Close();
}
}
}
}
这是 fnBarcodeScanner 的代码:
CREATE PROCEDURE [dbo].[fnBarcodeScanner]
@ip [nvarchar](20)
WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [Telnet].[MinimalisticTelnet.Program].[Connect]
GO
这是触发器:
ALTER TRIGGER [dbo].[trg_Barcode]
ON [dbo].[tbl_Barcode]
AFTER INSERT
AS
BEGIN
DECLARE @MVID INT,
@P VARCHAR(25),
@NewLane VARCHAR(10),
@TC INT,
@DID INT,
@AD DATE,
@AT VARCHAR(18),
@TrayCount INT,
@DivertCount INT,
@ScanID VARCHAR(50),
@PID INT,
@cDivert VARCHAR(8)
SET @ScanID = (SELECT Barcode
FROM tbl_Barcode)--Barcode Value
SET @MVID = (SELECT MVID
FROM tbl_Divert
WHERE Barcode = @ScanID)--JOT Version ID
SET @P = (SELECT PalletNbr
FROM tbl_Divert
WHERE Barcode = @ScanID)--Pallet Number
SET @PID = (SELECT PalletID
FROM tbl_Pallet_Verification
INNER JOIN tbl_Pallet_Mailing
ON tbl_Pallet_Verification.MailingID = tbl_Pallet_Mailing.MailingID
WHERE tbl_Pallet_Mailing.MVID = @MVID
AND tbl_Pallet_Verification.PalletNum = @P)--PAT Pallet ID
SET @AD = ( Cast(CONVERT(VARCHAR(10), Getdate(), 110) AS DATE) )--Today's Date
SET @AT = CONVERT(TIME, Getdate())--Current Time
SET @cDivert = (SELECT Divert
FROM tbl_Divert
WHERE Barcode = @ScanID)
SET @NewLane = (SELECT TOP 1 ID
FROM tbl_Tray_Lanes
WHERE LaneActive = -1
AND ID NOT IN(SELECT Divert
FROM tbl_Pallet_Lanes
WHERE DateCompleted IS NULL))--Find Open Lane
SET @TC = (SELECT Count(TrackerID)
FROM tbl_Divert
WHERE MVID = @MVID
AND PalletNbr = @P)--Tray Count
SET @TrayCount = (SELECT Count(TrackerID)
FROM tbl_Divert
WHERE Barcode = @ScanID)--Is Tray Found in Divert Table
SET @DivertCount = (SELECT Count(TrackerID)
FROM tbl_Divert
WHERE Barcode = @ScanID
AND Divert IS NOT NULL)--Verify Tray has not been scanned
--Add Date/Time to Tray Record. This will mark tray as scanned
SELECT TrackerID
FROM tbl_Divert
WHERE Barcode = @ScanID
AND Divert IS NULL
IF @@ROWCOUNT > 0
BEGIN
SET NOCOUNT ON;
IF @NewLane IS NOT NULL
BEGIN --Add Available lane to Lane Table and give tray record the LaneID
IF @TrayCount > 0 --Verify tray record exist
BEGIN
--IF @DivertCount = 0 --If not previously scanned
--Begin--Insert Lane Record
INSERT INTO tbl_Pallet_Lanes
(MVID,
PalletID,
PalletNbr,
Divert,
TrayCount,
DateStarted,
TimeStarted)
SELECT @MVID,
@PID,
@P,
@NewLane,
@TC,
@AD,
@AT
--Get LaneID
SET @DID = (SELECT ID
FROM tbl_Pallet_Lanes
WHERE MVID = @MVID
AND PalletNBR = @P)
--Add LaneID to tray record
UPDATE tbl_Divert
SET Divert = @NewLane,
DivertID = @DID
WHERE MVID = @MVID
AND PalletNbr = @P
--END
END
END
IF @NewLane IS NULL
BEGIN --If there is no open lane assign Lane 16. This will send the tray to end of tray tracker for
--manual pallet load.
UPDATE tbl_Divert
SET Divert = 16,
DivertID = 0
WHERE MVID = @MVID
AND Barcode = @ScanID
END
END
DELETE FROM tbl_Barcode --Clear barcode table
UPDATE tbl_Divert
SET Scanned = @AD,
ScanStatus = 1 --Scan Status Flags which Reader
WHERE Barcode = @ScanID
END
谢谢你的帮助。