由于我无法创建任何函数或过程,因此在编写sql查询时遇到了一些问题。这就是我当前的查询样子
SELECT ProductData.Customer_ID, ProductData.Product_Type
CASE
WHEN ProductData.Product_Title = 'A_Title' THEN 'A_Title' ELSE 'R_Title' END AS R_Title
CASE
WHEN ProductData.Product_Title = 'A_Title' AND ProductData.Product_Category != 'A_Category' THEN **(REMOVE Non-alphanumeric Character)**
WHEN ProductData.Product_Category = 'A_Category' THEN 'A_Category' ELSE 'R_Category' END AS R_Category,
FROM ProductData
由于上面(删除非字母数字字符)中第二个CASE WHEN的第一行,我希望能够使用以下代码,但仍然没有找到一种方法来实现工作。
while @@rowcount > 0
update ProductData
set Product_Category = replace(Product_Category, substring(Product_Category, patindex('%[^a-zA-Z ]%', Product_Category), 1), '')
非常感谢您提供建议。
答案 0 :(得分:2)
承接了艾伦·伯斯坦(Alan Burstein)的强大功能PatExclude8K,我在此处包括了该功能
CREATE FUNCTION dbo.PatExclude8K
(
@String VARCHAR(8000),
@Pattern VARCHAR(50)
)
/*******************************************************************************
Purpose:
Given a string (@String) and a pattern (@Pattern) of characters to remove,
remove the patterned characters from the string.
Usage:
--===== Basic Syntax Example
SELECT CleanedString
FROM dbo.PatExclude8K(@String,@Pattern);
--===== Remove all but Alpha characters
SELECT CleanedString
FROM dbo.SomeTable st
CROSS APPLY dbo.PatExclude8K(st.SomeString,'%[^A-Za-z]%');
--===== Remove all but Numeric digits
SELECT CleanedString
FROM dbo.SomeTable st
CROSS APPLY dbo.PatExclude8K(st.SomeString,'%[^0-9]%');
Programmer Notes:
1. @Pattern is not case sensitive (the function can be easily modified to make it so)
2. There is no need to include the "%" before and/or after your pattern since since we
are evaluating each character individually
Revision History:
Rev 00 - 10/27/2014 Initial Development - Alan Burstein
Rev 01 - 10/29/2014 Mar 2007 - Alan Burstein
- Redesigned based on the dbo.STRIP_NUM_EE by Eirikur Eiriksson
(see: http://www.sqlservercentral.com/Forums/Topic1585850-391-2.aspx)
- change how the cte tally table is created
- put the include/exclude logic in a CASE statement instead of a WHERE clause
- Added Latin1_General_BIN Colation
- Add code to use the pattern as a parameter.
Rev 02 - 11/6/2014
- Added final performane enhancement (more cudo's to Eirikur Eiriksson)
- Put 0 = PATINDEX filter logic into the WHERE clause
Rev 03 - 5/16/2015
- Updated code to deal with special XML characters
*******************************************************************************/
RETURNS TABLE WITH SCHEMABINDING AS
RETURN
WITH
E1(N) AS (SELECT N FROM (VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) AS X(N)),
itally(N) AS
(
SELECT TOP(CONVERT(INT,LEN(@String),0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM E1 T1 CROSS JOIN E1 T2 CROSS JOIN E1 T3 CROSS JOIN E1 T4
)
SELECT NewString =
((
SELECT SUBSTRING(@String,N,1)
FROM iTally
WHERE 0 = PATINDEX(@Pattern,SUBSTRING(@String COLLATE Latin1_General_BIN,N,1))
FOR XML PATH(''),TYPE
).value('.[1]','varchar(8000)'));
GO
这是您可以使用的改编。
WITH E1(N) AS (
SELECT N FROM (VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) AS X(N)
)
SELECT ProductData.Customer_ID,
CASE
WHEN ProductData.Product_Title = 'A_Title' AND ProductData.Product_Category != 'A_Category' THEN x.NewString
WHEN ProductData.Product_Category = 'A_Category' THEN 'A_Category'
ELSE 'R_Category' END AS R_Category
FROM ProductData
CROSS APPLY (SELECT NewString =((SELECT SUBSTRING(Product_Category,N,1)
FROM (
SELECT TOP(CONVERT(INT,LEN(Product_Category),0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM E1 T1, E1 T2, E1 T3, E1 T4) AS iTally(N)
WHERE 0 = PATINDEX('%[^a-zA-Z ]%',SUBSTRING(Product_Category COLLATE Latin1_General_BIN,N,1))
FOR XML PATH(''),TYPE).value('.[1]','varchar(8000)'))) AS x;
正如肖恩(Sean)以及其他人所提到的,您应该永久清除数据,而不是每次使用数据时都要清除数据。先前的SELECT语句可以轻松转换为UPDATE。
WITH E1(N) AS (
SELECT N FROM (VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) AS X(N)
)
UPDATE ProductData SET
Product_Category = CASE
WHEN ProductData.Product_Title = 'A_Title' AND ProductData.Product_Category != 'A_Category' THEN x.NewString
WHEN ProductData.Product_Category = 'A_Category' THEN 'A_Category'
ELSE 'R_Category' END
FROM ProductData
CROSS APPLY (SELECT NewString =((SELECT SUBSTRING(Product_Category,N,1)
FROM (
SELECT TOP(CONVERT(INT,LEN(Product_Category),0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM E1 T1, E1 T2, E1 T3, E1 T4) AS iTally(N)
WHERE 0 = PATINDEX('%[^a-zA-Z ]%',SUBSTRING(Product_Category COLLATE Latin1_General_BIN,N,1))
FOR XML PATH(''),TYPE).value('.[1]','varchar(8000)'))) AS x;
SELECT * FROM ProductData;
答案 1 :(得分:1)
您的更新代码运行正常,您只需要处理如下循环:
declare @i int
set @i = 1
while @i is not null
begin
declare @ids table (id int);
delete from @ids
set @i = null
update tb
set val = replace(val, substring(val, patindex('%[^a-zA-Z ]%', val), 1), '')
OUTPUT INSERTED.id INTO @ids
where patindex('%[^a-zA-Z ]%', val) > 0
select top 1 @i = id
from @ids
end