日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql sp who_对ASE系统存储过程的剖析-sp_who

發布時間:2023/12/4 数据库 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql sp who_对ASE系统存储过程的剖析-sp_who 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

昨晚有空,把 sybase 系統過程 sp_who , DDL 后分析了一下,全文如下:

-- 以下是 DDL 出來的內容:

-----------------------------------------------------------------------------

-- DDL for Stored procedure 'sybsystemprocs.dbo.sp_who'

-----------------------------------------------------------------------------

-- 以上是注釋

print 'Creating Stored procedure sp_who'

go

-- 上面兩句是顯示一句話, go 是執行(下同)

use sybsystemprocs

go

-- 選擇將要使用的數據庫(存儲過程建在什么數據庫里)

setuser 'dbo'

go

-- 使當前用戶充當 'dbo

-- 以下是存儲過程的實體

/* Sccsid = "%Z% generic/sproc/%M% %I% %G%" */

/* 4.8 1.1 06/14/90 sproc/src/serveroption */

/*

** Messages for "sp_who" 17nnn

**

** 17231, "No login with the specified name exists."

*/

-- 以上是注釋

create procedure sp_who @loginame varchar(30) = NULL as

-- 創建存儲過程 sp_who) 的參數 loginame

declare @low int

declare @high int

declare @spidlow int

declare @spidhigh int

declare @len1 int, @len2 int, @len3 int

-- 申明了若干變量

if @@trancount = 0

--@@ 開頭的都是系統全局變量

--@@trancount 是用來檢查事務嵌套級別的全局變量,批處理中每個 begin transaction 將事務計數加 1

begin

set chained off

-- 用在會話開始和事務結束時使用,指示是否在第一個數據檢索或數據修改語句前開始一個事務(是否在 delte 、 fetch 、 insert 、 open 、 select 、 update 前隱式執行一個 begin transaction 命令)

end

set transaction isolation level 1

-- 設置會話所用的事務隔離級別。當設置此選項后,所有當前或將來的事務都將在些隔離級別上運行

--level 1 的意義:允許對數據使用共享讀取鎖

select @low = @@minsuid, @high = @@maxsuid,

@spidlow = @@minspid, @spidhigh = @@maxspid

-- 給局部變量賦值,四個全局變量的含義:

--@@minsuid :最小服務器用戶 ID

--@@maxsuid :最大服務器用戶 ID

--@@minspid :最小服務器進程 ID

--@@maxspid :最大服務器進程 ID

if @loginame is not NULL

-- 判斷存儲過程的參數是否為空

begin

-- 開始一個新的批

select @low = suser_id(@loginame), @high = suser_id(@loginame)

--suser_id: 系統函數,返回服務器用戶在 syslogins 表中的 ID 號

if @low is NULL

-- 如果參數 @loginame 不正確的話, suser_id 應該返回 NULL

begin

if @loginame like "[0-9]%"

-- 判斷一下 @loginame 是不是數字開頭的字符串

begin

-- 如果是的話把說明參數 @loginame 應該是服務器系統進和 ID

select @spidlow = convert(int, @loginame),

@spidhigh = convert(int, @loginame),

@low = 0, @high = @@maxsuid

-- 把參數 @loginame 轉換成 int 型并賦給 @spidlow 和 @spidhigh

end

else

-- 如果不是數據開頭的字符串,返回錯誤代碼,并返回

begin

/*

** 17231, "No login with the specified name exists."

*/

raiserror 17231

-- 返回的錯誤號是 17231

--raiserror 的作用是返回預定義的錯誤號

return (1)

end

end

end

-- 以上進行的工作是將 @loginame 進行處理,生成下面查詢語言的所需的條件值 @low 、 @high 、 @spidlow 、 @spidhigh

select @len1 = max(datalength(suser_name(suid))),

@len2 = max(datalength(db_name(dbid))),

@len3 = max(datalength(suser_name(origsuid)))

from master..sysprocesses

where suid >= @low and suid <= @high and

spid >= @spidlow and spid <= @spidhigh

--suser_name() :返回當前服務器用戶的名稱或已指定服務器用戶 ID 的用戶

--db_name() :返回已指定 ID 號的數據庫的名稱

--suser_name() :返回當前服務用戶的名稱或已指定服務器用戶 ID 的用戶

--datalength() :返回指定列或字符串的實際長度(以字節表示)

--max() :返回表達式的最大值

-- 以上語句找出 master 庫 sysprocesses 表中 suid 、 dbid 、 origsuid 三列的最大實際長度

-- 以下語句是返回結果

-- 兩個 select 語句的檢索列、 from 、 where 、 order 子句都是一樣的,只是檢索列的字符串長度不一致!(更好看些,呵呵)

-- 兩個 select 語句都是從 master 庫 sysprocesses 表中檢索出符合條件的指定列, 紅色的地方是兩個 select 不一致的地方 。

if (@len1 > 8 or @len2 > 6 or @len3 > 8)

begin

select fid,

spid,

status,

loginame=suser_name(suid),

origname=isnull(suser_name(origsuid), suser_name(suid)),

hostname,

blk_spid=convert(char(5),blocked),

dbname=db_name(dbid),

cmd,

block_xloid

from master..sysprocesses

where suid >= @low and suid <= @high

and spid >= @spidlow and spid <= @spidhigh

order by fid,spid,dbname

end

else

begin

select fid,

spid,

status,

loginame= convert(char(12), suser_name(suid) ) ,

origname= convert(char(12), isnull(suser_name(origsuid), suser_name(suid)) ) ,

hostname,

blk_spid=convert(char(5),blocked),

dbname=convert(char(10),db_name(dbid)),

cmd,

block_xloid

from master..sysprocesses

where suid >= @low and suid <= @high

and spid >= @spidlow and spid <= @spidhigh

order by fid,spid,dbname

end

return (0)

-- 返回

go

Grant Execute on dbo.sp_who to public

-- 向 public 組授予執行 sp_who 的權限

go

setuser

-- 如果在執行 setuser 命令時沒有指定用戶名,則將重新建立數據庫所有者的初始標識

go

-- 我們可以看到,該存儲過程的基本思路是先對傳入的參數進行處理,生成查詢用的條件參數,進而得出查詢結果。

-- 對于該存儲過程為了最終顯示效果而加入的一段代碼的作法,是值得我們學習的。

分析下來,如果你執行一個 sp_who '1sgfadf'

就會發生:

Syntax error during explicit conversion of VARCHAR value '1sgfadf' to a INT field.

的錯誤

呵呵,都是下面這段語句惹的禍:

if @loginame like "[0-9]%"

-- 判斷一下 @loginame 是不是數字開頭的字符串

begin

-- 如果是的話把說明參數 @loginame 應該是服務器系統進和 ID

select @spidlow = convert(int, @loginame),

@spidhigh = convert(int, @loginame),

@low = 0, @high = @@maxsuid

-- 把參數 @loginame 轉換成 int 型并賦給 @spidlow 和 @spidhigh

end

分享至:

總結

以上是生活随笔為你收集整理的mysql sp who_对ASE系统存储过程的剖析-sp_who的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。