在开始之前,如果我们有一些原始数据、示例输出以及您尝试过的内容,将会有所帮助。如果没有这些,我会(希望是体面的)猜测数据和数据结构。
对于这个答案,我假设您在一个表中拥有原始数据,每一行代表您在答案中的一行(例如,空间线)。让我们用您的数据调用带有单列“txtField”的平面文件表“LoaderTable”。
现在,回答问题。
您需要循环吗?
没有。
绝对不需要一个循环逐行遍历。
想象一下你有一个函数或某种处理
- 从 LoaderTable 获取一行 (txtField) 并将其保存为变量(例如,@CurrentTxtField)
- 从@CurrentTxtField 计算四个字段
- 丢弃匹配@CurrentTxtField 的行
- 从 LoaderTable 获取下一行到 @CurrentTxtField
代码量不大,但可以替代
- 从 所有 LoaderTable 中的行计算四个字段
您仍然需要相同的逻辑将行拆分为四个新字段;只是在第一个选项(循环)中,您需要多次运行它,并且在它周围有很多代码来支持循环。在第二个选项中,它运行一次,并且不需要所有额外的代码。
如何将单个字段拆分为四列
有很多方法可以做到这一点 - 您可以在此处搜索方法,例如 How to split a comma-separated value to columns(但特别是查看 @Shnugo 对已接受答案的评论)或 Split column based on ascii value
如果您不理解这些并想要一个更简单的答案,您可以使用一些简单的代码来完成。基本上,
- 将源数据复制到带有四个附加字段的临时表中(以防万一)
- 计算第一个字段,并将其从初始字段中删除
- 计算第二个字段,并将其从初始字段中删除
- 对字段 3 和 4 执行相同操作
例如,
CREATE TABLE #TempLoaderTable (
txtField nvarchar(100),
[Lat] nvarchar(25),
[Lon] nvarchar(25),
[Bearing] nvarchar(25),
[Distance] nvarchar(25)
)
INSERT INTO #TempLoaderTable (txtField)
SELECT txtField
FROM LoaderTable
-- Split data assuming commas separate values in txtField
-- Note that the STUFF on txtField is used to remove the saved text from txtField
UPDATE #TempLoaderTable
SET [Lat] = LEFT(txtField, CHARINDEX(',', txtField) - 1),
[txtField] = STUFF(txtfield,1,CHARINDEX(',', txtField),'')
FROM #TempLoaderTable
UPDATE #TempLoaderTable
SET [Lon] = LEFT(txtField, CHARINDEX(',', txtField) - 1),
[txtField] = STUFF(txtfield,1,CHARINDEX(',', txtField),'')
FROM #TempLoaderTable
UPDATE #TempLoaderTable
SET [Bearing] = LEFT(txtField, CHARINDEX(',', txtField) - 1),
[txtField] = STUFF(txtfield,1,CHARINDEX(',', txtField),'')
FROM #TempLoaderTable
UPDATE #TempLoaderTable
SET [Distance] = [txtField],
[txtField] = NULL
FROM #TempLoaderTable
这是一个DB<>fiddle,显示每个步骤的结果。
请注意,以上内容是为简单起见而编写的,并不是最有效的,因为它执行 4 次更新而不是 1 次。通常其中 4 次更新不会成为问题(可能以毫秒为单位)。如果您确实需要更快,上面的链接帖子可以为您指明正确的方向。
如果数据实际上是固定格式的(例如,每一行的值都是相同的长度 - 所以逗号将在相同的列号中),您可以使用您设置的 SUBSTRING 仅使用单个 UPDATE 语句适当的起点和长度,例如如果,
- Lat 和 Lon 各 15 个字符
- 方位为 10 个字符
- 距离为 7 个字符
- 以 1 个字符分隔的所有字段
...您可以使用上面的一个更新,例如,
UPDATE #TempLoaderTable
SET [Lat] = LEFT(txtField, 15),
[Lon] = SUBSTRING(txtField, 17, 15),
[Bearing] = SUBSTRING(txtField, 33, 10),
[Distance] = SUBSTRING(txtField, 44, 7)
(显然,您需要将精确值调整为实际长度)。
这将非常有效地运行。