最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

sqlserver另類非遞歸的無限級分類(存儲過程版)

 更新時間:2010年07月19日 23:13:35   作者:  
網(wǎng)絡(luò)上很多無限級的分類,但無非是兩種,一種是遞歸算法,一種是非遞歸算法。。
下面是我統(tǒng)計的幾種方案:

第一種方案(遞歸式):

簡單的表結(jié)構(gòu)為:
CategoryID int(4),
CategoryName nvarchar(50),
ParentID int(4),
Depth int(4)
這樣根據(jù)ParentID一級級的運用遞歸找他的上級目錄。
還有可以為了方便添加CategoryLeft,CategoryRight保存他的上級目錄或下級目錄

第二種方案:
設(shè)置一個varchar類型的CategoryPath字段來保存目錄的完整路徑,將父目錄id用符號分隔開來。比如:1,5,8,10

第三種方案:
每級分類遞增兩位數(shù)字的方法
示例:
一級分類:01,02,03,04...
二級分類:0101,0102,0103,0104...
三級分類:010101,010102,010103...

分析一下,其實第三種方案并不能真正意義上做無限級的分類,而第二種方案,雖然比較容易得到各上級及下級的分類信息。但,添加和轉(zhuǎn)移分類的時候操作將很麻煩。
而且,也完全違反了數(shù)據(jù)庫設(shè)計范式。

其實我也一直在用第二種方案的。為了查找方便,我有時都在新聞表里加上CategoryID和CategoryPath

而我今天要說的算法其實是第二種方案的改進版,一般做分類都是使用一個表格來保存分類信息。
而我這里,要新建兩個表格,一個表格是保存分類信息表,一個保存分類關(guān)系表。

表結(jié)構(gòu)如下:
表1:tomi_Category
CategoryID int(4), '編號
CategoryName nvarchar(50), '分類名稱
Depth int(4), '深度
表2:tomi_CategoryBind
CategoryID int(4),
BindCategoryID int(4),
Depth int(4),

添加,編輯,刪除操作有點麻煩。。我是直接用存儲過程的。。不知道大家能看得懂不。。哈哈。
1、添加分類(Category_Add)
復(fù)制代碼 代碼如下:

CREATE proc [dbo].[Category_Add]
@CategoryName nvarchar(50),
@BindCategoryID int,
@CategoryID int output
as
declare @Success bit
set @Success=1

--生成不重復(fù)的CategoryID
declare @i bit
set @i=0
while @i=0
begin
set @CategoryID=LEFT(10000000 + CONVERT(bigint, ABS(CHECKSUM(NEWID()))), 8)
if(not exists(select CategoryID from tomi_Category where CategoryID=@CategoryID))
set @i=1
end


--得到depth
declare @depth int
set @depth=0
select @depth=depth from tomi_Category where CategoryID=@BindCategoryID
set @depth=@depth+1

--插入
BEGIN TRAN
insert into tomi_Category(categoryID,CategoryName,Depth) values(@CategoryID,@CategoryName,@Depth)
if(@@ERROR<>0)
BEGIN
ROLLBACK TRAN
set @Success=0
END

insert into tomi_CategoryBind(CategoryID,BindCategoryID,Depth) values(@CategoryID,@CategoryID,@Depth)
if(@@ERROR<>0)
BEGIN
ROLLBACK TRAN
set @Success=0
END

insert into tomi_CategoryBind(CategoryID,BindCategoryID,Depth) select @CategoryID,BindCategoryID,Depth from tomi_CategoryBind where CategoryID=@BindCategoryID
if(@@ERROR<>0)
BEGIN
ROLLBACK TRAN
set @Success=0
END
COMMIT TRAN

print @CategoryID

每個分類在tomi_CategoryBind有完整的目錄結(jié)構(gòu)。。一個分類在tomi_CategoryBind的記錄數(shù)等于他在tomi_Category的depth值。

圖片:

2、編輯修改分類(Category_Edit)
復(fù)制代碼 代碼如下:

CREATE proc [dbo].[Category_Edit]
@CategoryID int,
@CategoryName nvarchar(50),
@BindCategoryID int
as
--更新
BEGIN TRAN
update tomi_Category set CategoryName=@CategoryName where CategoryID=@CategoryID
IF @@ERROR<>0
BEGIN
ROLLBACK TRAN
return 0
END
COMMIT TRAN
--檢測是否更改了上級目錄
declare @is bit
set @is=0
if(exists(select CategoryID from tomi_CategoryBind where CategoryID=@CategoryID and BindCategoryID=@BindCategoryID and Depth=(select Depth-1 from tomi_Category where CategoryID=@CategoryID)))
set @is=1
print @is
--更改了深度
if(@is=0)
BEGIN
--得到上級目錄的depth
declare @depth int
set @depth=0
select @depth=depth from tomi_Category where CategoryID=@BindCategoryID
set @depth=@depth+1
--print @depth
--更改子目錄
declare @i int
declare @sCategoryID int
declare @sBindCategoryID int
declare @tCategoryIDList Table
(
CategoryID int,
FlagID tinyint
)
insert @tCategoryIDList select c.CategoryID,0 from tomi_Category c left join tomi_CategoryBind b on c.CategoryID=b.CategoryID where b.BindCategoryID=@CategoryID order by c.Depth
set @i=1
set @sBindCategoryID=@BindCategoryID
declare @errs int
set @errs=0
BEGIN TRAN
while(@i>=1)
BEGIN
select @sCategoryID=0
select Top 1 @sCategoryID=CategoryID from @tCategoryIDList where FlagID=0
set @i=@@RowCount
--print @sCategoryID
if @sCategoryID>0
BEGIN
--刪除,更新
delete from tomi_CategoryBind where CategoryID=@sCategoryID
set @errs=@errs+@@error
update tomi_Category set depth=@depth where CategoryID=@sCategoryID
set @errs=@errs+@@error
--插入
insert into tomi_CategoryBind(CategoryID,BindCategoryID,Depth) values(@sCategoryID,@sCategoryID,@Depth)
set @errs=@errs+@@error
insert into tomi_CategoryBind(CategoryID,BindCategoryID,Depth) select @sCategoryID,BindCategoryID,Depth from tomi_CategoryBind where CategoryID=@sBindCategoryID
set @errs=@errs+@@error
set @sBindCategoryID=@sCategoryID
set @Depth=@Depth+1
--print @sCategoryID
--print @sBindCategoryID
--print @Depth
--print '--'
END
update @tCategoryIDList set FlagID=1 where CategoryID=@sCategoryID
END
if(@errs>0)
BEGIN
ROLLBACK TRAN
return 0
END
else
COMMIT TRAN
END


3、刪除分類(Category_Del) 會直接刪除子分類
復(fù)制代碼 代碼如下:

create proc Category_Del
@CategoryID int
as
BEGIN TRAN
delete from tomi_Category where CategoryID in (select CategoryID from tomi_CategoryBind where CategoryID=@CategoryID or BindCategoryID=@CategoryID)
if(@@ERROR<>0)
BEGIN
ROLLBACK TRAN
return 0
END
delete from tomi_CategoryBind where CategoryID in (select CategoryID from tomi_CategoryBind where CategoryID=@CategoryID or BindCategoryID=@CategoryID)
if(@@ERROR<>0)
BEGIN
ROLLBACK TRAN
return 0
END
COMMIT TRAN

4、分類列表,顯示分類(Category_List)

復(fù)制代碼 代碼如下:

CREATE proc Category_List
as
select c.* from tomi_Category c left join tomi_CategoryBind b on c.CategoryID=b.CategoryID where b.Depth=1 order by b.BindCategoryID,c.Depth

GO

exec Category_List 可以直接讓分類等級查詢出來。而且顯示全部的話,一次查詢即可,只需判斷depth就行。
圖片:

5、上級子分類列表 (Category_upTree)
復(fù)制代碼 代碼如下:

Create Proc Category_UpTree
@CategoryID int
as
select c.* from tomi_Category c left join tomi_CategoryBind b on c.CategoryID=b.BindCategoryID where b.CategoryID=@CategoryID order by c.Depth
GO

exec Category_UpTree 63919523 這樣就可以得到一個分類的完整子目錄集,方便吧,只要一條sql.
圖片:

6、下級子分類列表(Category_downTree)
復(fù)制代碼 代碼如下:

Create Proc Category_DownTree
@CategoryID int
as
select c.* from tomi_Category c left join tomi_CategoryBind b on c.CategoryID=b.CategoryID where b.BindCategoryID=@CategoryID order by c.Depth
GO

exec Category_DownTree 21779652 這樣可以得到一個分類完整下級目錄。比如得到某個分類和其分類的子分類下的所有產(chǎn)品用這個就好。。方便,一條sql.
圖片:

以上是初稿,只是隨意的測試了幾次。。。有錯誤的,還請大家指出。。

呵呵。轉(zhuǎn)載請注明鏈接,博客園首發(fā),多謝。
作者:TomiWong
時間:2010.07.18

相關(guān)文章

  • 詳解SQL Server的簡單查詢語句

    詳解SQL Server的簡單查詢語句

    本篇文章詳細講解了SQL ServerSQL的簡單查詢語句。圖文并茂,方便大家理解與學(xué)習(xí)。有興趣的朋友可以看下
    2016-12-12
  • SQL Server實現(xiàn)分頁方法介紹

    SQL Server實現(xiàn)分頁方法介紹

    這篇文章介紹了SQL Server實現(xiàn)分頁的方法,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • 什么是數(shù)據(jù)庫 SQL Execution Plan(簡單介紹)

    什么是數(shù)據(jù)庫 SQL Execution Plan(簡單介紹)

    SQL Execution PlanSQL 執(zhí)行計劃是數(shù)據(jù)庫管理系統(tǒng)在執(zhí)行SQL語句時,對如何高效檢索數(shù)據(jù)進行的一系列優(yōu)化步驟的描述,這篇文章主要介紹了什么是數(shù)據(jù)庫 SQL Execution Plan,需要的朋友可以參考下
    2024-03-03
  • SqlServer中查看當(dāng)前Open的Cursor方法

    SqlServer中查看當(dāng)前Open的Cursor方法

    這篇文章主要介紹了SqlServer中查看當(dāng)前Open的Cursor方法,本文為了解決A cursor with thename ' ' already exists總結(jié)的幾個方法,需要的朋友可以參考下
    2015-07-07
  • SQL Server如何保證可空字段中非空值唯一

    SQL Server如何保證可空字段中非空值唯一

    今天同學(xué)向我提了一個問題,我覺得蠻有意思,現(xiàn)記錄下來大家探討下。問題是:在一個表里面,有一個允許為空的字段,空是可以重復(fù)的,但是不為空的值需要唯一。
    2011-03-03
  • SQL中Exists的用法

    SQL中Exists的用法

    這篇文章主要介紹了SQL中Exists的用法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-02-02
  • 存儲過程實現(xiàn)訂單號,流水單號(8位)的詳細思路

    存儲過程實現(xiàn)訂單號,流水單號(8位)的詳細思路

    存儲過程實現(xiàn)訂單號,流水單號是一個比較不錯的功能,在處理訂單方面起到一個不錯的作用;此文章是借鑒園中的各位大神的,本人只是略作修改。有不好的地方,歡迎吐槽
    2013-01-01
  • Spark SQL的整體實現(xiàn)邏輯解析

    Spark SQL的整體實現(xiàn)邏輯解析

    使用sparkSQL是為了解決一般用sql不能解決的復(fù)雜邏輯,使用編程語言的優(yōu)勢來解決問題,今天通過本文給大家分享Spark SQL的整體實現(xiàn)邏輯,需要的朋友參考下吧
    2021-07-07
  • SQL Server一個字符串拆分多行顯示或者多行數(shù)據(jù)合并成一個字符串

    SQL Server一個字符串拆分多行顯示或者多行數(shù)據(jù)合并成一個字符串

    這篇文章介紹了SQL Server一個字符串拆分多行顯示或者多行數(shù)據(jù)合并成一個字符串的方法,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • CPQuery 解決拼接SQL的新方法

    CPQuery 解決拼接SQL的新方法

    這篇博客不是寫給ORM用戶的,而是寫給所有喜歡寫SQL語句的朋友
    2012-09-09

最新評論

克山县| 麦盖提县| 环江| 肥乡县| 股票| 黄石市| 陇西县| 荆州市| 香港 | 兴城市| 怀仁县| 称多县| 汨罗市| 二手房| 明光市| 新密市| 贵州省| 扎囊县| 温泉县| 东乌| 丰原市| 漳浦县| 紫金县| 稻城县| 望谟县| 金川县| 民权县| 阜南县| 西贡区| 宾川县| 嘉峪关市| 吉木萨尔县| 蒲江县| 漠河县| 张家口市| 西青区| 邵阳市| 南乐县| 大兴区| 镇远县| 宁河县|