如何遷移RDS中的加密儲存過程
1. 背景介紹
目前,遷移RDS SQL Server中的資料到其他RDS SQL Server時,使用DTS資料傳輸服務進行遷,無法將加密儲存過程順利遷出。加密的儲存過程,無法script出其定義。
備註:
當您考慮加密資料庫儲存過程之前,建議先做一個備份。
2. 檢視SQL Server中加密儲存過程和函式的方法
1)在儲存過程所在的資料庫下,建立儲存過程sp_decrypt (出自微軟BI開拓者www.windbi.com)。
create PROCEDURE [dbo].[sp_decrypt]
(@procedure sysname = NULL)
AS
SET NOCOUNT ON
BEGIN
DECLARE @intProcSpace bigint, @t bigint, @maxColID smallint,@intEncrypted
tinyint,@procNameLength int
select @maxColID = max(subobjid),@intEncrypted = imageval FROM
sys.sysobjvalues WHERE objid = object_id(@procedure)
GROUP BY imageval
select @procNameLength = datalength(@procedure) + 29
DECLARE @real_01 nvarchar(max)
DECLARE @fake_01 nvarchar(max)
DECLARE @fake_encrypt_01 nvarchar(max)
DECLARE @real_decrypt_01 nvarchar(max),@real_decrypt_01a nvarchar(max)
declare @objtype varchar(2),@ParentName nvarchar(max)
select @real_decrypt_01a = ``
--提取物件的型別如是儲存過程還是函式,如果是觸發器,還要得到其父物件的名稱
select @objtype=type,@parentname=object_name(parent_object_id)
from sys.objects where [object_id]=object_id(@procedure)
-- 從sys.sysobjvalues裡提出加密的imageval記錄
SET @real_01=(SELECT top 1 imageval FROM sys.sysobjvalues WHERE objid =
object_id(@procedure) and valclass = 1 order by subobjid)
--建立一個臨時表
create table #output ( [ident] [int] IDENTITY (1, 1) NOT NULL ,
[real_decrypt] NVARCHAR(MAX) )
--開始一個事務,稍後回滾
BEGIN TRAN
--更改原始的儲存過程,用短橫線替換
if @objtype=`P`
SET @fake_01=`ALTER PROCEDURE `+ @procedure +` WITH ENCRYPTION AS
`+REPLICATE(`-`, 40003 - @procNameLength)
else if @objtype=`FN`
SET @fake_01=`ALTER FUNCTION `+ @procedure +`() RETURNS INT WITH ENCRYPTION AS BEGIN RETURN 1
/*`+REPLICATE(`*`, datalength(@real_01) /2 - @procNameLength)+`*/ END`
else if @objtype=`V`
SET @fake_01=`ALTER view `+ @procedure +` WITH ENCRYPTION AS select 1 as col
/*`+REPLICATE(`*`, datalength(@real_01) /2 - @procNameLength)+`*/`
else if @objtype=`TR`
SET @fake_01=`ALTER trigger `+ @procedure +` ON `+@parentname+`WITH ENCRYPTION AFTER INSERT AS RAISERROR (``N``,16,10)
/*`+REPLICATE(`*`, datalength(@real_01) /2 - @procNameLength)+`*/`
EXECUTE (@fake_01)
--從sys.sysobjvalues裡提出加密的假的
SET @fake_encrypt_01=(SELECT top 1 imageval FROM sys.sysobjvalues WHERE objid =
object_id(@procedure) and valclass = 1 order by subobjid )
if @objtype=`P`
SET @fake_01=`Create PROCEDURE `+ @procedure +` WITH ENCRYPTION AS
`+REPLICATE(`-`, 40003 - @procNameLength)
else if @objtype=`FN`
SET @fake_01=`CREATE FUNCTION `+ @procedure +`() RETURNS INT WITH ENCRYPTION AS BEGIN RETURN 1
/*`+REPLICATE(`*`, datalength(@real_01) /2 - @procNameLength)+`*/ END`
else if @objtype=`V`
SET @fake_01=`Create view `+ @procedure +` WITH ENCRYPTION AS select 1 as col
/*`+REPLICATE(`*`, datalength(@real_01) /2 - @procNameLength)+`*/`
else if @objtype=`TR`
SET @fake_01=`Create trigger `+ @procedure +` ON `+@parentname+`WITH ENCRYPTION AFTER INSERT AS RAISERROR (``N``,16,10)
/*`+REPLICATE(`*`, datalength(@real_01) /2 - @procNameLength)+`*/`
--開始計數
SET @intProcSpace=1
--使用字元填充臨時變數
SET @real_decrypt_01 = replicate(N`A`, (datalength(@real_01) /2 ))
--迴圈設定每一個變數,建立真正的變數
--每次一個位元組
SET @intProcSpace=1
--如有必要,遍歷每個@real_xx變數並解密
WHILE @intProcSpace<=(datalength(@real_01)/2)
BEGIN
--真的和假的和加密的假的進行異或處理
SET @real_decrypt_01 = stuff(@real_decrypt_01, @intProcSpace, 1,
NCHAR(UNICODE(substring(@real_01, @intProcSpace, 1)) ^
(UNICODE(substring(@fake_01, @intProcSpace, 1)) ^
UNICODE(substring(@fake_encrypt_01, @intProcSpace, 1)))))
SET @intProcSpace=@intProcSpace+1
END
--通過sp_helptext邏輯向表#output裡插入變數
insert #output (real_decrypt) select @real_decrypt_01
-- select real_decrypt AS `#output chek` from #output --測試
-- -------------------------------------
--開始從sp_helptext提取
-- -------------------------------------
declare @dbname sysname
,@BlankSpaceAdded int
,@BasePos int
,@CurrentPos int
,@TextLength int
,@LineId int
,@AddOnLen int
,@LFCR int --回車換行的長度
,@DefinedLength int
,@SyscomText nvarchar(4000)
,@Line nvarchar(255)
Select @DefinedLength = 255
SELECT @BlankSpaceAdded = 0 --跟蹤行結束的空格。注意Len函式忽略了多餘的空格
CREATE TABLE #CommentText
(LineId int
,Text nvarchar(255) collate database_default)
--使用#output代替sys.sysobjvalues
DECLARE ms_crs_syscom CURSOR LOCAL
FOR SELECT real_decrypt from #output
ORDER BY ident
FOR READ ONLY
--獲取文字
SELECT @LFCR = 2
SELECT @LineId = 1
OPEN ms_crs_syscom
FETCH NEXT FROM ms_crs_syscom into @SyscomText
WHILE @@fetch_status >= 0
BEGIN
SELECT @BasePos = 1
SELECT @CurrentPos = 1
SELECT @TextLength = LEN(@SyscomText)
WHILE @CurrentPos != 0
BEGIN
--通過回車查詢行的結束
SELECT @CurrentPos = CHARINDEX(char(13)+char(10), @SyscomText,
@BasePos)
--如果找到回車
IF @CurrentPos != 0
BEGIN
--如果@Lines的長度的新值比設定的大就插入@Lines目前的內容並繼續
While (isnull(LEN(@Line),0) + @BlankSpaceAdded +
@CurrentPos-@BasePos + @LFCR) > @DefinedLength
BEGIN
SELECT @AddOnLen = @DefinedLength-(isnull(LEN(@Line),0) +
@BlankSpaceAdded)
INSERT #CommentText VALUES
( @LineId,
isnull(@Line, N``) + isnull(SUBSTRING(@SyscomText,
@BasePos, @AddOnLen), N``))
SELECT @Line = NULL, @LineId = @LineId + 1,
@BasePos = @BasePos + @AddOnLen, @BlankSpaceAdded = 0
END
SELECT @Line = isnull(@Line, N``) +
isnull(SUBSTRING(@SyscomText, @BasePos, @CurrentPos-@BasePos + @LFCR), N``)
SELECT @BasePos = @CurrentPos+2
INSERT #CommentText VALUES( @LineId, @Line )
SELECT @LineId = @LineId + 1
SELECT @Line = NULL
END
ELSE
--如果回車沒找到
BEGIN
IF @BasePos <= @TextLength
BEGIN
--如果@Lines長度的新值大於定義的長度
While (isnull(LEN(@Line),0) + @BlankSpaceAdded +
@TextLength-@BasePos+1 ) > @DefinedLength
BEGIN
SELECT @AddOnLen = @DefinedLength -
(isnull(LEN(@Line),0) + @BlankSpaceAdded)
INSERT #CommentText VALUES
( @LineId,
isnull(@Line, N``) + isnull(SUBSTRING(@SyscomText,
@BasePos, @AddOnLen), N``))
SELECT @Line = NULL, @LineId = @LineId + 1,
@BasePos = @BasePos + @AddOnLen, @BlankSpaceAdded =
0
END
SELECT @Line = isnull(@Line, N``) +
isnull(SUBSTRING(@SyscomText, @BasePos, @TextLength-@BasePos+1 ), N``)
if LEN(@Line) < @DefinedLength and charindex(` `,
@SyscomText, @TextLength+1 ) > 0
BEGIN
SELECT @Line = @Line + ` `, @BlankSpaceAdded = 1
END
END
END
END
FETCH NEXT FROM ms_crs_syscom into @SyscomText
END
IF @Line is NOT NULL
INSERT #CommentText VALUES( @LineId, @Line )
select Text from #CommentText order by LineId
CLOSE ms_crs_syscom
DEALLOCATE ms_crs_syscom
DROP TABLE #CommentText
-- -------------------------------------
--結束從sp_helptext提取
-- -------------------------------------
--刪除用短橫線建立的儲存過程並重建原始的儲存過程
ROLLBACK TRAN
DROP TABLE #output
END
2) DAC連線SQL Server
確認SQL Server例項是否支援DAC連線:
SELECT * FROM sys.configurations where name = `remote admin connections`
--value為1,說明允許DAC連線
--value為0,按照下面方式設定允許DAC連線
USE master
GO
sp_configure `show advanced options`, 1
GO
sp_configure `remote admin connections`, 1
GO
RECONFIGURE WITH OVERRIDE
GO
sqlcmd方式連線例項 :
sqlcmd -A -S servername -E
3)切換到使用者資料庫
Use DBNAME
4)執行解密儲存過程
sp_decrypt EncryptSP
Go
顯示結果
3. 遷移RDS中的儲存過程到本地自建庫和其他RDS例項
RDS上面不支援DAC連線,需要把備份集下載到本地還原,然後使用2中的方法,匯出加密儲存過程的定義。
若是需要RDS之間遷移加密儲存過程,RDS SQL Server 2008 R2之間可以還原備份集,其他版本的RDS SQL Server需要先將備份集還原到本地自建庫,然後使用2中方法解密儲存過程,再將儲存過程定義匯入目的RDS中。
備註:
RDS SQL Server 各個版本,可以在RDS控制檯,備份恢復中下載備份集。
相關文章
- 移動索引的儲存過程索引儲存過程
- 在儲存過程A中呼叫儲存過程B的結果儲存過程
- MySQL儲存過程中如何使用ROLLBACKMySql儲存過程
- Sqlserver中的儲存過程SQLServer儲存過程
- Oracle 儲存過程加密之wrap工具Oracle儲存過程加密
- 使用SQL SERVER儲存過程實現歷史資料遷移SQLServer儲存過程
- 儲存遷移方案
- 儲存過程中巢狀儲存過程的變數執行方式儲存過程巢狀變數
- Sqlserver2014如何解密加密的儲存過程SQLServer解密加密儲存過程
- oracle 加密儲存過程create_wrappedOracle加密儲存過程APP
- [Q]怎麼樣加密儲存過程 zt加密儲存過程
- mysql如何呼叫儲存過程MySql儲存過程
- PB中呼叫儲存過程儲存過程
- 儲存過程中拼接字串儲存過程字串
- java中呼叫儲存過程Java儲存過程
- asm 儲存線上遷移ASM
- mssql 儲存過程呼叫另一個儲存過程中的結果的方法分享SQL儲存過程
- oracle儲存過程中的陣列Oracle儲存過程陣列
- ORACLE儲存過程中建立子過程的測試!Oracle儲存過程
- 從sybase的儲存過程轉向oracle的儲存過程儲存過程Oracle
- MySQL儲存過程詳解 mysql 儲存過程MySql儲存過程
- 儲存過程儲存過程
- vertica 如何實現儲存過程?儲存過程
- jsp中呼叫儲存過程JS儲存過程
- 儲存過程中慎用 execute immediate儲存過程
- java中呼叫ORACLE儲存過程JavaOracle儲存過程
- geoserver資料儲存遷移Server
- 如何刪除名稱相同的儲存過程儲存過程
- oracle的儲存過程Oracle儲存過程
- 修改的儲存過程儲存過程
- mysql的儲存過程MySql儲存過程
- 如何在儲存過程中擁有role的許可權儲存過程
- SQL Server儲存過程中raiserror的使用SQLServer儲存過程AIError
- Oracle 儲存過程中的DDL語句Oracle儲存過程
- MySql儲存過程—2、第一個MySql儲存過程的建立MySql儲存過程
- 儲存過程呼叫其他模式的儲存過程需要注意的地方儲存過程模式
- 在不破壞原加密儲存過程的前提下,解密儲存過程!(補充j9988) (轉)加密儲存過程解密
- SQL 儲存過程裡呼叫另一個儲存過程SQL儲存過程