Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 将包含信息的Varchar拆分到表中_Sql_Sql Server_Tsql - Fatal编程技术网

Sql 将包含信息的Varchar拆分到表中

Sql 将包含信息的Varchar拆分到表中,sql,sql-server,tsql,Sql,Sql Server,Tsql,我正在处理一个问题,我有一个长的varchar,其中包含不同类型的信息。我正试着把它分成一张桌子,这样我就可以处理它了。项目类型信息由4个空格分隔。这个系统已经是这样建立起来的,所以我需要找到一种方法来对付这种瓦查尔人 DECLARE @V AS VARCHAR(MAX) = 'Price Updated. Previous Value: 20.20 New Value: 30.20 by UsernameA Item Name Updated. Previous Value: XBOX

我正在处理一个问题,我有一个长的varchar,其中包含不同类型的信息。我正试着把它分成一张桌子,这样我就可以处理它了。项目类型信息由4个空格分隔。这个系统已经是这样建立起来的,所以我需要找到一种方法来对付这种瓦查尔人

DECLARE @V AS VARCHAR(MAX) = 'Price Updated. Previous Value: 20.20 New Value: 30.20 by UsernameA    Item Name Updated. Previous Value: XBOX New Value: XBOX2 by UsernameB    Item Colour Updated. Previous Value: Black New Value: Silver by UsernameC'
我创建了以下临时表,用于保存数据:

DECLARE @info AS TABLE
(
    Name VARCHAR(500),
    Previous_Value NUMERIC(8, 2) ,
    New_Value NUMERIC(8, 2) ,
    User_By VARCHAR(500)
)
我正在尝试将内容拆分为下表:

-- Name                 Previous_Value      New_Value   User_By
-- Price Updated.       20.20               30.20       UsernameA
-- Item Name Updated.   XBOX                XBOX2       UsernameB
-- Item Colour Updated. Black               Silver      UsernameC

有人能帮我怎么做吗?我正在寻找一种性能方法,因为我正在处理很多这样的问题。

SQL Server不太擅长字符串操作。但如果必须在数据库中执行操作,则可以:

select s.value,
       left(s.value, charindex(' Previous Value:', s.value)) as name,
       left(v.prev, charindex(' New Value:', v.prev)) as prev_value,
       left(v.new_val, charindex(' by ', v.new_val)) as new_value,
       stuff(v.new_val, 1, charindex(' by ', v.new_val) + 3, '') as user_by
from string_split(replace(@v, '    ', '|'), '|') s cross apply
     (values (substring(s.value, charindex(' Previous Value:', s.value) + 17, 1000),
              substring(s.value, charindex(' New Value:', s.value) + 12, 1000)
             )
     ) v(prev, new_val);
我建议使用更合适的工具(如Python)将数据转换为分隔文件,然后将其加载到数据库中


SQL Server不太擅长字符串操作。但如果必须在数据库中执行操作,则可以:

select s.value,
       left(s.value, charindex(' Previous Value:', s.value)) as name,
       left(v.prev, charindex(' New Value:', v.prev)) as prev_value,
       left(v.new_val, charindex(' by ', v.new_val)) as new_value,
       stuff(v.new_val, 1, charindex(' by ', v.new_val) + 3, '') as user_by
from string_split(replace(@v, '    ', '|'), '|') s cross apply
     (values (substring(s.value, charindex(' Previous Value:', s.value) + 17, 1000),
              substring(s.value, charindex(' New Value:', s.value) + 12, 1000)
             )
     ) v(prev, new_val);
我建议使用更合适的工具(如Python)将数据转换为分隔文件,然后将其加载到数据库中


是一个dbfiddle。

我相信Gordon的是一个性能更高的+1,但这里有另一个使用JSON的选项

范例

结果


我相信Gordon's是一个性能更好的+1,但这里有另一个使用JSON的选项

范例

结果


多亏了@John Cappelletti的JSON思想,使用XML实现了类似的功能

将@V声明为VARCHARMAX='价格已更新。以前的值:20.20新值:30.20按用户名更新项目名称。以前的值:XBOX新值:XBOX 2按用户名b项目颜色更新。以前的值:黑色新值:UsernameC的银色' 声明@V_XML= 选择c.value'/@value[1]','varchar50'作为名称, c、 值“/@Previous_value[1]”,将“varchar50”作为Prev_值, c、 值“/@New_value[1]”,'varchar50'作为新_值, c、 值“/@by[1]”,'varchar50'由人指定 从@V_XML.nodes'root/Name'作为tc 名称 前值 新价值 个人 价格更新。 20.20 30.20 用户名 项目名称已更新。 XBOX XBOX2 用户名b 项目颜色更新。 黑色 银 用户名
多亏了@John Cappelletti的JSON思想,使用XML实现了类似的功能

将@V声明为VARCHARMAX='价格已更新。以前的值:20.20新值:30.20按用户名更新项目名称。以前的值:XBOX新值:XBOX 2按用户名b项目颜色更新。以前的值:黑色新值:UsernameC的银色' 声明@V_XML= 选择c.value'/@value[1]','varchar50'作为名称, c、 值“/@Previous_value[1]”,将“varchar50”作为Prev_值, c、 值“/@New_value[1]”,'varchar50'作为新_值, c、 值“/@by[1]”,'varchar50'由人指定 从@V_XML.nodes'root/Name'作为tc 名称 前值 新价值 个人 价格更新。 20.20 30.20 用户名 项目名称已更新。 XBOX XBOX2 用户名b 项目颜色更新。 黑色 银 用户名
很好的解决方案。花了一段时间才弄明白。我以前从未使用过字符串分割函数和交叉应用。很好的解决方案。花了一段时间才弄明白。我以前从未使用过string_split函数和cross apply。作为将来的参考:根据问题指南,请展示您尝试了什么,并告诉我们您在本网站或其他地方发现了什么,以及为什么它不能满足您的需要。作为将来的参考:根据问题指南,请展示您的尝试,并告诉我们您在本网站或其他地方发现了什么,以及为什么它不能满足您的需求。
Name                     Prev_Value     New_Value   User_By
Price Updated.           20.20          30.20       UsernameA
Item Name Updated.       XBOX           XBOX2       UsernameB
Item Colour Updated.     Black          Silver      UsernameC