请你帮我改写下面的CP,这样当它从文件中读取时除去除了数字之外的任何其他字符: 它的作用是读取一个文件,例如block.txt,并将每一行加到表中。
USE [db_Test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[Cp_ImportBlackList]
AS
BEGIN
BEGIN TRY
BEGIN TRANSACTION Acbc
DECLARE @command nvarchar(max)
DECLARE @delcommand varchar(200)
DECLARE @txtfile nvarchar(200)
DECLARE @line nvarchar(2)
DECLARE @andreas nvarchar(200)
set @line='\n'
DECLARE @isExists INT
DECLARE @tempcol int
DECLARE MyCursor cursor fast_forward for
Select Users_ID from Prj_Users
open MyCursor
fetch next from MyCursor
into @tempcol
while @@fetch_status = 0
begin
set @txtfile = 'c:\BlackList\ ' + LTRIM(RTRIM(str(@tempcol))) + '.txt'
exec master.dbo.xp_fileexist @txtfile,
@isExists OUTPUT
if (@isExists =1)
begin
BEGIN TRY
BEGIN TRANSACTION ad
set @command=' BULK INSERT Prj_TempBlackList FROM ''' + @txtfile + ''''
set @command += ' WITH( ROWTERMINATOR = '''+ @line +''' )'
print @command
EXECUTE(@command)
delete Prj_TempBlackList where Tell in(select [BLList_TEll] from prj_BlackList where [BLList_UserID] = @tempcol)
insert into prj_BlackList select DISTINCT Tell,@tempcol from Prj_TempBlackList where Tell not in(select [BLList_TEll] from prj_BlackList where [BLList_UserID] = @tempcol)
delete from Prj_TempBlackList
set @delcommand ='del ' + @txtfile
exec xp_cmdshell @delcommand
print 'end'
COMMIT TRANSACTION ad
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION ad
SELECT ERROR_Message() AS ErrorNumber;
END CATCH
end
else
print 'no'
fetch next from MyCursor
into @tempcol
end
close MyCursor
deallocate MyCursor
set @txtfile = 'c:\BlackList\block.txt'
exec master.dbo.xp_fileexist @txtfile,
@isExists OUTPUT
if (@isExists =1)
begin
BEGIN TRY
BEGIN TRANSACTION ada
set @command=' BULK INSERT Prj_TempBlackList FROM ''' + @txtfile + ''''
set @command += ' WITH( ROWTERMINATOR = '''+@line+''' )'
EXECUTE(@command)
delete Prj_TempBlackList where Tell in(
select [BLList_TEll] from prj_BlackList where [BLList_UserID] is null)
insert into prj_BlackList SELECT DISTINCT Tell,null from
Prj_TempBlackList where Tell not in(
select [BLList_TEll] from prj_BlackList where [BLList_UserID] is null)
delete from Prj_TempBlackList
set @delcommand ='del ' + @txtfile
exec xp_cmdshell @delcommand
print 'yes'
COMMIT TRANSACTION ada
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION ada
SELECT ERROR_Message() AS ErrorNumber;
END CATCH
end
COMMIT TRANSACTION Acbc
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION Acbc
END CATCH
END
答案 0 :(得分:0)
尽量避免使用CURSOR和LOOP!
这种方法动态,但你真的应该考虑TSQL是否是正确的工具......
DECLARE @tbl TABLE(ID INT IDENTITY, EvilString NVARCHAR(100));
INSERT INTO @tbl(EvilString) VALUES('ab23cd56jkl'),(' adfhasd l h45 hagf 78 l 9');
WITH RunningNumbers AS
(
SELECT ROW_NUMBER() OVER(ORDER BY A) AS Nmbr
FROM (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS tblA(A)
,(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS tblB(B)
,(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS tblC(C)
,(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS tblD(D)
,(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS tblE(E)
,(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS tblF(F)
)
,SingleChars AS
(
SELECT tbl.ID,rn.Nmbr,SUBSTRING(tbl.EvilString,rn.Nmbr,1) AS Chr
FROM @tbl AS tbl
CROSS APPLY (SELECT TOP(LEN(tbl.EvilString)) Nmbr FROM RunningNumbers) AS rn
)
SELECT ID,EvilString
,(
SELECT '' + Chr
FROM SingleChars AS sc
WHERE sc.ID=tbl.ID AND ASCII(Chr) BETWEEN 48 AND 57
ORDER BY sc.Nmbr
FOR XML PATH('')
) AS GoodString
FROM @tbl As tbl
结果
ID EvilString GoodString
1 ab23cd56jkl 2356
2 adfhasd l h45 hagf 78 l 9 45789