sql-server - 使用平面文件作为存储过程的动态值
问题描述
我正在寻找一种使用存储过程将数据从平面文件导入 SQL Server 的方法。平面文件中的数据由位置、方位和距离组成。
存储过程使用此数据在 SQL Server 中生成空间线。导入后可以丢弃平面文件中的原始源数据。
存储过程具有以下语法
exec dbo.Getline <Lat>,<Lon>,<Bearing>,<Distance>
我正在考虑使用循环来遍历平面文件的行,但是我不太确定这是最好的解决方案。不幸的是我不能使用 SSIS。
有人可以帮帮我吗?
解决方案
在开始之前,如果我们有一些原始数据、示例输出以及您尝试过的内容,将会有所帮助。如果没有这些,我将对数据和数据结构进行(希望是体面的)猜测。
对于这个答案,我假设您将原始数据放在一个表中,每一行代表您想要的结果作为答案中的一行(例如,空间线)。让我们用您的数据将单列“txtField”称为平面文件表“LoaderTable”。
现在,开始回答。
你需要一个循环吗?
不。
绝对不需要逐行遍历循环。
想象一下,你有一个函数或某种处理
- 从 LoaderTable 获取一行 (txtField) 并将其保存为变量(例如,@CurrentTxtField)
- 从@CurrentTxtField 计算四个字段
- 丢弃匹配 @CurrentTxtField 的行
- 从 LoaderTable 获取下一行到 @CurrentTxtField
不是大量的代码,但替代方案是
- 计算LoaderTable 中所有行的四个字段
您仍然需要相同的逻辑将行拆分为四个新字段;只是在第一个选项(循环)中,您需要多次运行它,并且围绕它有很多代码来支持循环。在第二个选项中,它运行一次,并且不需要所有额外的代码。
如何将单个字段拆分为四列
有很多方法可以做到这一点 - 您可以在此处搜索方法,例如,如何将逗号分隔的值拆分为列(但特别是查看@Shnugo 对已接受答案的评论)或基于 ascii 值拆分列
如果您不理解这些并想要一个更简单的答案,您可以使用一些简单的代码来完成。基本上,
- 将源数据复制到带有四个附加字段的临时表中(以防万一)
- 计算第一个字段,并将其从初始字段中删除
- 计算第二个字段,并将其从初始字段中删除
- 对字段 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)
(显然,您需要将精确值调整为实际长度)。
这将非常有效地运行。
推荐阅读
- c++ - void * 从 C 到 CPP 的分配
- php - 如果类别中没有产品,如何从类别下拉列表中删除类别
- sql - 将 CSV 文件从 URL 导入 SQL Fiddle Postgres 9.6 引擎
- javascript - javascript:使用reduce来集体添加某些字段?
- c# - 在 CheckedListBox C# 中搜索项目
- python - 我的代码运行但没有输出任何东西,为什么?
- android - Parcel 0x799b1b22d0:以 96 容量释放 Oppo 设备中的日志消息
- python - 有没有办法从python中的数据框中删除行,列中有某个单词?
- excel - 我的 Vlookup 公式有问题吗?
- python - 使 new-alias 运行特定的 python 文件