String 使用SSI将列中的字符串拆分为多个列

String 使用SSI将列中的字符串拆分为多个列,string,ssis,split,String,Ssis,Split,我在SQLServer表中有一列,其中服务器名称是数据。我需要将服务器名称拆分为两列。主机名进入一列,实例名进入另一列。任何帮助都将不胜感激 希望为此目的使用SSI 例如:- Input Expected Output column1 Column2 Column3 ServerName Hostname InstanceName w

我在SQLServer表中有一列,其中服务器名称是数据。我需要将服务器名称拆分为两列。主机名进入一列,实例名进入另一列。任何帮助都将不胜感激

希望为此目的使用SSI

例如:-

Input                      Expected Output

column1                     Column2            Column3

ServerName                  Hostname           InstanceName

wsql1005x\Express           wsql1005x           Express

您可以选择两条路线。您可以使用脚本组件,也可以使用派生列任务及其表达式。此解决方案使用这种方法

您可以在一个派生列转换中完成所有这些逻辑,但我不希望维护噩梦发生在我最坏的敌人身上。相反,可以自由地使用派生列,这样您就有机会调试它

此解决方案不处理拆分可能为空的列。由于源数据不允许这样做,我不想使解决方案进一步复杂化。这种方法确实处理默认的未命名实例

nvarchar(最大值) 您已选择将服务器名称和实例存储在nvarchar(max)字段中。除非您有理由需要4000多个字符,否则您不仅会浪费空间和弄乱优化器,而且会让SSI感到痛苦

SSIS的功能来自于对内存中的数据进行操作。它根据给定列的最大大小分配内存。除大型对象类型LOB外,LOB由数据类型DT_TEXT、DT_NTEXT、DT_IMAGE标识。引擎无法为这些数据分配足够的内存,因此在内存中携带指向磁盘上表示此数据的文件的指针。磁盘速度很慢,所以如果您想获得良好的性能,现在就知道为什么无法获得它

然后,诀窍是将数据从LOB类型中提取出来,并转换为合理的类型。计算机名的最大长度是多少?那么,完全限定域名的上限是255字节,而实例名称的上限是16字节。无需访问math.stackexchange.com查看您超出最大长度的10倍

我一直热衷于让我的源系统来完成这项工作,所以在我最初的提取查询中

SELECT 'wsql1005x\Express' AS ServerName
UNION ALL
SELECT 'localhost'
UNION ALL
SELECT @@ServerName;
我会把它写得尽可能长

SELECT
    (D.ServerName AS nvarchar(542)) AS ServerName
FROM
(
    SELECT 'wsql1005x\Express' AS ServerName
    UNION ALL
    SELECT 'localhost'
    UNION ALL
    SELECT @@ServerName
) D(ServerName);
一些关于该主题的有用问题

  • 寻找标记位置
继续演出

寻找标记位置 此组件的目的是查找令牌的位置。由于
\
字符也是转义字符,因此我们必须使用双反斜杠,因为实际上只有一个

在英语中,此表达式查看ServerName列中是否存在反斜杠。如果有,那么我们将把位置存储在一个名为
TokenLocation
的新列中。如果它不存在,那么我们将指示标记是字符串的最终位置。如果没有连接实例,这将允许我们切掉服务器名称

标记定位

FINDSTRING(ServerName,"\\",1) > 0 ? FINDSTRING(ServerName,"\\",1) : LEN(ServerName)
德内多弗斯特沃德酒店 这里我们将确定第一个单词的结束边界和第二个单词的开始边界。如果标记位置的值与字符串的总长度匹配,那么我们知道字符串中没有反斜杠标记。然后,我们查看令牌左侧和右侧的一个字符位置,以确定停止和开始边界。对于没有标记的单词,我们将把这两个位置都设置到单词的末尾

Endofirstword

(TokenLocation != LEN(ServerName)) ? TokenLocation - 1 : LEN(ServerName)
BeginOfSecondWord

(TokenLocation != LEN(ServerName)) ? TokenLocation + 1 : LEN(ServerName)
生成新列 在这一点上,我们知道

  • 其中我们的令牌是
    TokenLocation
  • 第一个单词的起始位置(位置
    1
  • 第一个单词的结尾(
    endofirstword
  • 第二个单词的开头(
    BeginOfSecondWord
  • 第二个单词的结尾(
    LEN(TokenLocation)
因此,这就成了一个简单的问题,切片我们的专栏

主机名

SUBSTRING(ServerName,1,EndOfFirstWord)
实例名

SUBSTRING(ServerName,BeginOfSecondWord,LEN(ServerName) - TokenLocation)

感谢您提供的解决方案。下面是我收到的错误消息标题:Microsoft Visual Studio-----------------数据流任务[派生列[39]]处出错:函数“FINDSTRING”不支持参数编号1的数据类型“DT_NTEXT”。无法将参数的类型隐式转换为函数的兼容类型。要执行此操作,需要使用转换运算符显式转换操作数。源表中的数据类型是什么。请使用源表定义编辑您的问题。使用我的源查询,它是否会产生预期的结果?源表数据类型为nvarchar(max)您正在将服务器名称和实例存储在定义为nvarchar(max)的列中?您是否遇到过超过4000个字符的服务器名称和实例?