2016-10-17 104 views
1

我对写入数据库的SQL代码相当陌生。我一直试图自己编写这段代码,但我没有很多运气。特别是因为我真的不知道如何测试它没有实际写入数据库 我有一个数据库有5个UDF字段。 'UDF1-UDF5'。我的设施中的操作员应该将条码扫描到特定的条码字段中,该条码字段将条码分成五个字段(它们都是字符(30)字段)。不幸的是,他们正在直接扫描UDF1字段,因此整个条形码字符串都在一个字段中。 (我无法控制这个软件)我正在尝试编写一个脚本来解析数据库,将这些字段拆分成单独的变量并更新数据库。我可以使用一点帮助,因为我认为我需要动态SQL来做到这一点,而我对此不太了解。这里是关于系统的更多信息。SQL Server更新字段中连接字符串的字段

BARCODE域看起来是这样的:

%2S12345%1%1%0%10% 

,其中“%”字符开始和结束的条码并连接所有的字符。第一个UDF字段'2'的第一个字符是一个校验位,并且总是相同的。 第一个字段始终为5或6个字符(不包括校验位),其余为1或2位数字。如果条形码只有前三个字段,我还需要代码不会中断。这里没有很多一致性。一些条形码被截断。

问题,

  1. 据我所知,只有这样,才能掰开级联文本串是基于位置(),所以我需要一个额外的5个变量得到各家之长字段和查询该信息的方式。有更容易的方法吗?

  2. 在某些时候,我必须有条件地设置变量,我似乎无法得到设置命令的工作。我明白为什么这样的东西不起作用,但我不知道有任何其他的做法。

DECLARE @BASEID CHAR(30), @LOTID CHAR(30), @SPLITID CHAR(30), @SUBID CHAR(30), @SEQUENCENO CHAR(30), @BASELEN INT 
SET @BASELEN = 
    CASE WHEN(
     SELECT ISNUMERIC(SUBSTRING(R.UDF1,3,1)) 
     FROM VISION17SLITTER.DBO.ROLLINFO R 
     WHERE R.UDF1 LIKE '[%]%' 
     ) = 1 
     THEN 5 
     ELSE 6 
    END 

3.一旦我能得到变量集我认为一个简单的条件update语句会的工作,但如果有别的尝试这个之前,我应该知道我将不胜感激的意见。再次

感谢,

+1

听起来像是你需要一个字符串分离器。这里有几个很棒的选择。 http://sqlperformance.com/2012/07/t-sql-queries/split-strings或者,如果你在SQL服务器2016年有一个很好的新闪亮建成一个。 https://msdn.microsoft.com/en-us/library/mt684588.aspx –

+0

感谢您的链接,不幸的是,我不是数据库管理员(好像这不是显而易见的:)),获得类似实现的东西可能很难。 – mreff555

+0

获取字符串拆分器应该非常简单。特别是如果你与你的DBA交谈并告诉他们另一个选择是使用动态sql循环。如果没有分配器,这将会很糟糕。 –

回答

1

考虑以下几点:

Declare @YourTable table (ID int,BarCode varchar(100)) 
Insert Into @YourTable values 
(1,'%2S12345%1%1%0%10%'), 
(2,'%ABC1234%2%3%4%50%') 

Select A.ID 
     ,A.BarCode 
     ,B.* 
From @YourTable A 
Cross Apply (
       Select Pos1 = xDim.value('/x[1]','varchar(max)') 
         ,Pos2 = xDim.value('/x[2]','varchar(max)') 
         ,Pos3 = xDim.value('/x[3]','varchar(max)') 
         ,Pos4 = xDim.value('/x[4]','varchar(max)') 
         ,Pos5 = xDim.value('/x[5]','varchar(max)') 
         ,Pos6 = xDim.value('/x[6]','varchar(max)') 
         ,Pos7 = xDim.value('/x[7]','varchar(max)') 
         ,Pos8 = xDim.value('/x[8]','varchar(max)') 
         ,Pos9 = xDim.value('/x[9]','varchar(max)') 
       From (Select Cast('<x>' + Replace(A.BarCode,'%','</x><x>')+'</x>' as XML) as xDim) A 

      ) B 

返回

enter image description here

现在,Y你可能会注意到Pos1和Pos7是空白的。这是由于您的字符串以分隔符开头和结尾的事实。如果你想定制CROSS适用,例如:

Select Pos1 = xDim.value('/x[2]','varchar(max)') 
     ,Pos2 = xDim.value('/x[3]','varchar(max)') 
     ,Pos3 = xDim.value('/x[4]','varchar(max)') 
     ,Pos4 = xDim.value('/x[5]','varchar(max)') 
     ,Pos5 = xDim.value('/x[6]','varchar(max)') 
From (Select Cast('<x>' + Replace(A.BarCode,'%','</x><x>')+'</x>' as XML) as xDim) A 

返回

enter image description here

+0

我写了一个非常类似于你在这里的脚本。我能够删除前导字符和尾随字符,并且我已将所有内容都分成1-5位。我的问题是,如何重新将此应用于我的实际DB?我尝试用update语句替换select语句,但我不确定如何访问交叉应用的信息。 – mreff555

+0

@ mreff555查看我的第二个答案刚刚添加 –

1

创建一个函数来分割你的字符串

CREATE FUNCTION [dbo].[fnSplitString] 
( 
    @string NVARCHAR(MAX), 
    @delimiter CHAR(1) 
) 
RETURNS @output TABLE(splitdata NVARCHAR(MAX) 
) 
BEGIN 
    DECLARE @start INT, @end INT 
    SELECT @start = 1, @end = CHARINDEX(@delimiter, @string) 
    WHILE @start < LEN(@string) + 1 BEGIN 
     IF @end = 0 
      SET @end = LEN(@string) + 1 

     INSERT INTO @output (splitdata) 
     VALUES(SUBSTRING(@string, @start, @end - @start)) 
     SET @start = @end + 1 
     SET @end = CHARINDEX(@delimiter, @string, @start) 

    END 
    RETURN 
END 

然后取下前两控制字符和最后一个控制字符并调用这样的功能

0然后
select * from dbo.fnSplitString('S12345%1%1%0%10','%') 

该函数将返回一个表具有以下值:

splitdata 
========= 
S1234 
1 
1 
0 
10 
+0

请参阅Sean Lange的评论和链接。你会看到戏剧性的改进。 sqlperformance.com/2012/07/t-sql-queries/split-strings –

+0

CLR方法可能会更快,但它需要本地访问服务器来安装dll。另一方面,我提供的解决方案不需要数据库管理员的额外权限。 –

+0

谢谢,这个拆分函数按照描述的方式工作,但我很努力去理解如何让数据列表进入这个函数。 – mreff555