移動節點處理的通用儲存過程 sql

2022-02-11 20:23:16 字數 4856 閱讀 8459

create proc p_move_copycode

@tablename  sysname,        --調整編碼規則的表名

@fieldname  sysname,        --編碼欄位名

@coderule   varchar(50),    --以逗號分隔的編碼規則,每層編碼的長度,比如1,2,3,表示有三層編碼,第一層長度為1,第二層長度為2,第三層長度為3

@code      varchar(50),     --要複製或者移動的節點編碼

@parentcode varchar(50),    --移動到該編碼的節點下

@iscopy    bit=0            --0為移動處理,否則為複製處理

as--引數檢查

if isnull(objectproperty(object_id(@tablename),n'isusertable'),0)=0

begin

raiserror(n'"%s"不存在,或者不是使用者表',1,16,@tablename)

return

endif not exists(select * from syscolumns where id=object_id(@tablename) and name=@fieldname)

begin

raiserror(n'列名"%s"在使用者表"%s"中無效',1,16,@fieldname,@tablename)

return    

endif isnull(@coderule,'')=''

begin

raiserror(n'必須編碼規則字串',1,16)

return    

endif patindex(n'%[^0-9^,]%',@coderule)>0

begin

raiserror(n'編碼規則字串"%s"中只能包含數字和逗號(,)',1,16,@coderule)

return    

endif isnull(@code,'')='' return

--生成編碼規則修改字串

declare @codelen int,@codelens varchar(10),@pos varchar(10),

@old_coderule varchar(50),@new_coderule varchar(50),

@s nvarchar(4000),

@code1 varchar(100),@code2 varchar(100)

if isnull(@parentcode,'')=''

select @parentcode=n'',

@new_coderule=@coderule

set @codelens=0

while charindex(n',',@coderule)>0

begin

set @codelen=left(@coderule,charindex(n',',@coderule)-1)

if @codelens+@codelen=len(@code)

begin

select @old_coderule=@coderule,

@pos=@codelens

if @new_coderule>'' goto lb_calccodelens

endselect @coderule=stuff(@coderule,1,charindex(n',',@coderule),n''),

@codelens=@codelens+@codelen

if @codelens=len(@parentcode)

begin

set @new_coderule=@coderule

if @old_coderule>'' goto lb_calccodelens

endend

if @old_coderule is null and cast(@codelens as int)+@coderule=len(@code)

select @old_coderule=@coderule,

@pos=@codelens

if @new_coderule is null and cast(@codelens as int)+@coderule=len(@parentcode)

begin

raiserror(n'移動編碼"%s"到編碼"%s"下導致編碼長度溢位編碼規則允許的長度',1,16,@code,@parentcode)

return

endlb_calccodelens:

set @s=n'set @codelens=@codelens+'+replace(@coderule,n',',n'+')

exec sp_executesql @s,n'@codelens int output',@codelens output

if @old_coderule is null

begin

raiserror(n'編碼"%s"不符合指定的編碼規則',1,16,@code)

return

endif @new_coderule is null

begin

raiserror(n'編碼"%s"不符合指定的編碼規則',1,16,@parentcode)

return

enddeclare @parent_chk nvarchar(4000),@delete_old nvarchar(4000),@where nvarchar(4000)

select @tablename=quotename(@tablename),

@fieldname=quotename(@fieldname),

@s=case

when @old_coderule=@new_coderule then n'new_no'

else dbo.f_changecoderule(@old_coderule,@new_coderule,'',0,n'new_no')

end,

@code1=quotename(@code+n'%',n''''),

@code2=quotename(@code,n''''),

@parentcode=quotename(@parentcode,n''''),

@parent_chk=case

when @parentcode=n'''''' then n''

else 'if not exists(select * from '+@tablename

+n' where '+@fieldname+n'='+@parentcode+n')

begin

raiserror(n''編碼"%s"不存在'',1,16,'+@parentcode+n')

rollback tran

return

end' end,

@delete_old=case

when @iscopy=0

then n'delete a from '+@tablename

+n' a,# b where a.'+@fieldname+n'=b.old_no'

else n'' end,

@where=case

when @iscopy=0 then n'and old_no<>a.old_no'

else n'' end

--檢查並完成刪除處理

exec(n'begin tran

'+@parent_chk+n'

--將處理後的編碼與處理前的編碼儲存到臨時表

select old_no,new_no='+@parentcode+n'+'+@s+n'

into # from(

select old_no='+@fieldname+n',

new_no=stuff('+@fieldname+n',1,'+@pos+n','''')

from '+@tablename+n' with(xlock,tablock)

where '+@fieldname+n' like '+@code1+n')a

--編碼重複檢測

select err=n''超過編碼規則能處理的長度'',* into #1 from # where len(new_no)>'+@codelens+n'

union all

select err=n''轉換後編碼重複'',* from # a

where exists(

select * from # where new_no=a.new_no and old_no<>a.old_no)

union all

select err=n''轉換後與表中現有的編碼重複'',* from # a

where exists(

select * from '+@tablename+n'

where '+@fieldname+n'=a.new_no '+@where+n')

if @@rowcount>0

select * from #1 order by err,new_no

else

begin

--移動編碼

select a.* into #2

from '+@tablename+n' a,# b

where a.'+@fieldname+n'=b.old_no

update a set '+@fieldname+n'=b.new_no

from #2 a,# b

where a.'+@fieldname+n'=b.old_no

'+@delete_old+n' --如果是移動,先進行刪除處理

insert '+@tablename+n' select * from #2

endcommit tran')

移動sq 資料庫物理檔案儲存過程

use master godeclare dbname sysname,destpath varchar 256 declare dbtable name sysname,physical name sysname begin tryselect dbname ff input database n...

通用的分頁儲存過程

alter procedure dbo p splitpage sql nvarchar 4000 要執行的sql語句 page int 1,要顯示的頁碼 pagesize int,每頁的大小 pagecount int 0 out,總頁數 recordcount int 0 out,總記錄數 se...

通用的分頁儲存過程

找了個通用的分頁儲存過程,速度很快 create procedure pagination3 tblname varchar 255 表名 strgetfields varchar 1000 需要返回的列 fldname varchar 255 排序的欄位名 pagesize int 10,頁尺寸 ...