我使用insert into将数据从一个表移动到另一个表。在选择位需要从具有字符和数字的列转移到另一个只有数字。原始列采用varchar格式。
原始栏目 -
ABC100
XYZ:200
DD2000
通缉专栏 100 200 2000
无法编写函数,因为在插入
时,不能在side select语句中使用函数使用MS SQL
答案 0 :(得分:3)
答案 1 :(得分:0)
你可以用正则表达式替换来做到这一点。此语法取决于您的数据库软件(您尚未指定)。
您应该能够在SELECT语句中执行函数调用,即使您正在使用它来INSERT INTO。
答案 2 :(得分:0)
如果您的数据是固定格式的,我会执行类似
的操作INSERT INTO SOME_TABLE(COLUMN1, COLUMN2, COLUMN3)
SELECT TO_NUMBER(SUBSTR(SOURCE_COLUMN, 4, 3)),
TO_NUMBER(SUBSTR(SOURCE_COLUMN, 12, 3)),
TO_NUMBER(SUBSTR(SOURCE_COLUMN, 18, 4))
FROM SOME_OTHER_TABLE
WHERE <conditions>;
以上代码适用于Oracle。根据您使用的数据库,您可能需要做一些不同的事情。
我希望这会有所帮助。
答案 3 :(得分:0)
在INSERT期间,你当然可以在SELECT语句中有一个函数:
INSERT INTO CleanTable (CleanColumn)
SELECT dbo.udf_CleanString(DirtyColumn)
FROM DirtyTable
你的主要问题是让功能正确(the one the G Mastros linked to is pretty good)并使其正常运行。如果你只说几千行,这应该没问题。如果你在谈论数百万行,你可能需要一个不同的策略。
答案 4 :(得分:0)
编写UDF是我过去解决这个问题的方法。但是,我开始思考是否存在基于集合的解决方案。这就是我所拥有的:
首先,我使用Red Gate的数据生成器填充了一堆随机字母数字值:
Create Table MixedValues (
Id int not null identity(1,1) Primary Key
, AlphaValue varchar(50)
)
接下来,我使用CTE动态建立了一个Tally表,但通常我有一个固定的表。 Tally表只是一个序列表。
;With Tally As
(
Select ROW_NUMBER() OVER ( ORDER BY object_id ) As Num
From sys.columns
)
, IndividualChars As
(
Select MX.Id, Substring(MX.AlphaValue, Num, 1) As CharValue, Num
From Tally
Cross Join MixedValues As MX
Where Num Between 1 And Len(MX.AlphaValue)
)
Select MX.Id, MX.AlphaValue
, Replace(
(
Select '' + CharValue
From IndividualChars As IC
Where IC.Id = MX.Id
And PATINDEX('[ 0-9]', CharValue) > 0
Order By Num
For Xml Path('')
)
, ' ', ' ') As NewValue
From MixedValues As MX
从顶层开始,这里的想法是将字符串拆分为每个字符一行,测试所需的模式类型,然后重新构建它。
请注意,我的sys.columns表只包含500个奇数行。如果您的字符串大于500个字符,则可以简单地将sys.columns连接到自身并获得500 ^ 2行。另外,对于Xml Path,返回一个空格转义的字符串(注意我的模式索引[0-9]中的空格,它告诉系统包含空格。)所以我使用replace函数来反转转义。
编辑:顺便说一下,由于我使用了CTE,因此只能在SQL 2005+中使用。如果你想要一个SQL 2000解决方案,你需要将CTE分解为单独的表创建调用(例如Temp表),但它仍然可以完成。
编辑:我在IndividualChars CTE中添加了Num列,并在结尾处向NewValue查询添加了Order By。虽然它可能会按顺序重新组合字符串,但我希望通过明确地对结果进行排序来确保它。