【发布时间】:2021-02-22 14:38:34
【问题描述】:
我在 $Message 变量中存储了来自 SQL 输出的以下 HL7 消息:
MSH|^~\&|System|System CRM|SYS|System CRM|20210222143236||ADT^A04|CRM001|P|2.4|||AL|NE
EVN||20210222143236
PID||9999999997^^^^NHSN|Ben^Smith^^^Mr||||||12A Cherry Avenue^Middleton^London^Greater London^E170RA^NSP^P|||
PD1|||^Amazing Surgery, Amazing Health Centre, London, E16 0RA|^DR. Fix
PV1|1|O
我正在尝试为其创建 txt 文件的输出:
DECLARE @Message NVARCHAR(MAX)
SET @Message = 'SELECT Message FROM #HL7'
DECLARE @sql VARCHAR(1000);
SELECT @sql = 'bcp ' + @Message + ' queryout "D:\HL7\Test.txt" -c -t|^ , -T -S'+ @@servername
PRINT @sql
EXEC master.dbo.xp_cmdshell @sql
但是,我似乎收到以下错误
' ' is not recognized as an internal or external command,
operable program or batch file.
当删除 |^ 我得到:
Copy direction must be either 'in', 'out' or 'format'.
请有人帮助我认为分隔导致问题
【问题讨论】:
-
这就是 SQL 注入攻击的发生方式以及为什么
xp_cmdshell默认禁用且不应启用的原因。如果@Message包含format c: /u会发生什么?还是del * /s?停止使用xp_cmdsel开始。问题与HL7字符串无关 -
要了解发生了什么,请检查
@sql包含的内容:bcp SELECT Message FROM #HL7 queryout .....。这显然是无效的。应引用查询。如果您使用例如 SQL Server 代理或计划任务,您可以只写一行您需要的命令而没有任何安全风险,甚至使用只能从数据库读取和写入特定文件夹的受限帐户 -
谢谢 我不认为 HL7 消息有问题。它的 BCP 命令。我了解 SQL 注入的风险,您在导出到文件时是否建议使用另一种方法?我确实想到了一个 SSIS 包,但它们创建了数千条这样的消息,并不认为这是最好的选择
-
如果您了解这些问题,为什么要介绍它们?为什么重新启用
xp_cmdshell?该命令默认关闭 15 年,如果不是更长的话。 -
忽略安全问题,要编写动态 tsql 代码,您需要掌握 tsql 技能,并且您需要查看动态代码在执行时发生错误时生成的内容。我建议您首先编写一个静态 BCP 命令行并让它工作。您将看到尝试使用本地临时表注定要失败,因此您需要解决这个问题。或者更好 - 使用(或研究)ETL 工具。或者重新访问为什么需要将其从数据库导出到文件中 - 也许你不需要?
标签: sql sql-server tsql bcp