MSSQL之十一 數據庫高級編程總結

      網友投稿 928 2025-04-02

      視頻課?https://edu.csdn.net/course/play/7940

      一.??SQL Server數據庫命名規范

      數據庫命名規范:

      1. 數據庫名:

      1.1)用產品或項目的名字命名;

      1.2)Pascal Case,如AdventureWork;

      1.3)避免使用特殊字符,如數字,下劃線,空格之類;

      1.4)避免使用縮寫

      2. 表名

      2.1)使用復數,Pascal Case,而復數只加在最后一個單詞上如:Products,Users,UserRoles

      2.2)避免使用特殊字符,如數字,下劃線,空格之類;

      2.3)避免使用縮寫

      3. 列名

      3.1) 使用Pascal Case

      3.2) 避免和表名重復,避免數據類型前綴如: Int

      3.3) 避免使用縮寫或者特殊字符

      4. 存儲過程

      4.1)用動詞加表名描述操作類型

      4.2)使用前綴:sp+{“Insert”, “Update”, “Delete”,“Get”, “Validate”,...}

      5. ?視圖

      5.1)參考表名規則

      5.2)用"vw"做前綴

      6. 觸發器

      6.1)使用"trg"前綴

      6.2) 使用操作類型+表名,如:trg_ProductsInsert

      7. 索引

      7.1)使用格式如:idx_{表名}_{索引列名}_{Unique/NonUnique}_{Cluster/NonCluster}

      8. 主鍵

      8.1) 使用格式如:pk_{表名}_{主鍵列名}

      9. 外鍵

      9.1) 使用格式如:fk_{主表名}_{主表的列名}_{引用表名}_{引用表的列名}

      10. default

      10.1) 使用格式如:df_{表名}_{列名}

      11. 約束

      11.1) 使用格式如:ck_{表名}_{列名}

      12. 變量

      12.1) 參照列名規則

      二. 數據庫備份

      備份處理的存儲過程

      set ANSI_NULLS ON

      set QUOTED_IDENTIFIER ON

      go

      /*--備份所有數據庫

      備份的文件名為數據庫名+日期+.bak

      將所有的用戶數據庫(或指定的數據庫列表)

      備分到指定的目錄下.

      /*--調用示例

      --備份所有用戶數據庫

      exec?? p_backupdb??@bkpath='D:\',@dbname=''

      --備份指定數據庫

      exec?? p_backupdb?? @bkpath=D:\',@dbname='數據庫名稱'

      --*/

      create? proc?? [dbo].[p_backupdb]

      @bkpath?? nvarchar(260)='D:\', --備份文件的存放目錄,不指定則使用SQL默認的備份目錄

      @dbname?? nvarchar(4000)='' --要備份的數據庫名稱列表,不指定則備份所有用戶數據庫

      as

      declare?? @sql?? varchar(8000)

      DECLARE @strdate NVARCHAR(200)

      set @strdate = convert(NVARCHAR(10),getdate(),120)

      set @strdate = REPLACE(@strdate, '-' , '')

      --檢查參數

      if?? isnull(@bkpath,'')=''

      begin

      select?? @bkpath=rtrim(reverse(filename))??from?? master..sysfiles?? where??name='master'

      select??@bkpath=substring(@bkpath,charindex('\',@bkpath)+1,4000)

      ,@bkpath=reverse(substring(@bkpath,charindex('\',@bkpath),4000))+'BACKUP\'

      end

      else?? if?? right(@bkpath,1)<>'\'??set?? @bkpath=@bkpath+'\'

      --得到要備份的數據庫列表

      if?? isnull(@dbname,'')=''

      declare?? tb?? cursor?? local??for

      select?? name?? from??master..sysdatabases?? where?? name??not?? in('master','tempdb','model','msdb')

      else

      declare?? tb?? cursor?? local??for

      select?? name?? from??master..sysdatabases

      where?? name?? not??in('master','tempdb','model','msdb')? and(name? like?'%'+@dbname+'%')

      --備份處理

      open?? tb

      fetch?? next?? from?? tb??into?? @dbname

      while?? @@fetch_status=0

      begin

      set?? @sql='backup?? database??'+@dbname

      +'?? to?? disk='''+@bkpath+@dbname+'_'+@strdate

      +'.bak''?? with?? format'

      exec(@sql)

      fetch?? next?? from?? tb??into?? @dbname

      end

      close?? tb

      deallocate?? tb

      go

      二.??????Sql Server 2005的分頁存儲過程

      CREATEPROCEDURE???? [dbo].[TopPageList]

      @strTable??????varchar(200),?? --表名 ("@strTable", "myUser");

      @strColumn?????varchar(50),??? --按該列來進行分頁("@strColumn", "UserId");

      @strOrderColumn? varchar(50),??? --排序字段order by XXX desc

      @intOrder???? int,--排序的順序 0 升序 1降序

      @strColumnlist? varchar(150) , --要查詢出的字段列表,*表示全部字段?cmd.Parameters.Add("@strColumnlist", "*");

      @strWhere??????varchar(800)='',--查詢條件cmd.Parameters.Add("@strWhere", "");

      @intPageSize??? int,?--每頁記錄數? cmd.Parameters.Add("@intPageSize", 15);

      @intPageNum????int,?????????? --指定頁? cmd.Parameters.Add("@intPageNum", 5);

      --? @intPageCount?? int?? OUTPUT? , --總頁數? SqlParameter paramPageCount =cmd.Parameters.Add("@intPageCount", SqlDbType.Int);

      -- paramPageCount.Direction = ParameterDirection.Output;

      @itemCount????? int??OUTPUT

      --?? @doCount bit = 0, -- 返回, 非值則返回記錄總數

      AS

      --設置相應的空格

      --設置DESC ASC

      if @intOrder=0? --0升序

      set @strOrderColumn=' order by '+@strOrderColumn

      else???????????--降序

      set @strOrderColumn=' order by '+@strOrderColumn +' desc '

      DECLARE?? @sql??? nvarchar(2000) --用于構造SQL語句

      DECLARE?? @where1 varchar(800)?? --構造條件語句

      DECLARE?? @where2 varchar(800)?? --構造條件語句

      IF?? @strWhere?? is?? null??or?? rtrim(@strWhere)=''

      -- 為了避免SQL關鍵字與字段、表名等連在一起,首先為傳入的變量添加空格

      BEGIN? --沒有查詢條件

      SET?? @where1=' WHERE '

      SET?? @where2=' '

      END

      ELSE

      BEGIN? --有查詢條件

      SET?? @where1=' WHERE? ('+@strWhere+')? AND?'

      SET?? @where2=' WHERE? ('+@strWhere+')?'

      END

      ------構造SQL語句,計算總頁數。計算公式為總頁數= Ceiling ( 記錄個數/ 頁大小)

      --計算總項數

      SET?? @sql='SELECT?? @itemCount=COUNT('+@strColumn+')?from??'+@strTable +@where2

      print(@sql)

      EXEC sp_executesql? @sql,N'@itemCount? int??OUTPUT',@itemCount?? OUTPUT

      --?? 1:直接計算??? 2:自己寫個分頁控件里面設置一下也可以~!

      -- set @intPageCount? =floor(cast(@itemCount as float)/@intPageSize)

      --?? if @intPageCount

      --?? set @intPageCount =@intPageCount +1

      --

      --執行SQL語句,計算總頁數,并將其放入@intPageCount變量中

      --將總頁數放到查詢返回記錄集的第一個字段前,此語句可省略

      SET? @strColumnlist=' '+ Cast(@itemCount as varchar(30)) + ' asitemCount,' +' '+ @strColumnlist

      --+ Cast(@intPageCount as varchar(30)) + ' as PageCount,'

      SET @sql='SELECT TOP '+ CAST(@intPageSize?? AS??varchar)? +? @strColumnlist +

      ' FROM ' + @strTable + @where1 + '? '+

      @strColumn + ' not in? '+

      '? (SELECT TOP '+ CAST(@intPageSize*(@intPageNum - 1)? AS?varchar) + ' ' +

      @strColumn + ' FROM '+ @strTable+@where2+@strOrderColumn+')? ' +@strOrderColumn

      print(@sql)

      --ELSE

      --???? begin?? --構造降序的SQL---針對2個表的時候會出現聚合函數的異常--適合單個表格的數據庫分頁操作

      --???? SET @sql='SELECT TOP '+CAST(@intPageSize?? AS?? varchar)? +?@strColumnlist +

      --??????????????' FROM ' + @strTable + @where1 + '? '+

      --?????????????@strColumn + '<(SELECT MIN('+@strColumn+')?'+

      --?????????????' FROM (SELECT TOP '+ CAST(@intPageSize*(@intPageNum - 1)? AS?varchar) + ' ' +

      --?????????????@strColumn + ' FROM '+ @strTable+@where2+@strOrderColumn+')? as tblTmp)' +@strOrderColumn

      --??? print(@sql)

      --???? end

      IF?? @intPageNum=1--第一頁

      SET?? @sql='SELECT??TOP?? '+CAST(@intPageSize?? AS?? varchar) +@strColumnlist + ' FROM'+@strTable+

      @where2+@strOrderColumn

      --END

      --PRINT?? @sql

      print(@sql)

      exec(@sql)

      public static void BindingContent(string strTable, string strColumn, stringstrOrderColumn, int intOrder, string strColumnlist, string strWhere,IChangePageStored changePage)

      {

      SqlParameter[] paras=new SqlParameter[9];

      paras[0] =new SqlParameter("@strTable" ,SqlDbType.VarChar);

      paras[0].Value = strTable;

      paras[1] =new SqlParameter("@strColumn", SqlDbType.VarChar);

      paras[1].Value = strColumn;

      paras[2] =new SqlParameter("@strOrderColumn", SqlDbType.VarChar);

      paras[2].Value = strOrderColumn;

      paras[3] =new SqlParameter("@strColumnlist", SqlDbType.VarChar);

      paras[3].Value = strColumnlist;

      paras[4] =new SqlParameter("@intOrder", SqlDbType.Int);

      paras[4].Value = intOrder;

      paras[5] =new SqlParameter("@strWhere", SqlDbType.VarChar);

      paras[5].Value = strWhere;

      paras[6] =new SqlParameter("@intPageSize", SqlDbType.Int);

      paras[6].Value = changePage.PageSize;

      paras[7] =new SqlParameter("@intPageNum", SqlDbType.Int);

      paras[7].Value = changePage.CurrentPage? ;

      //?? paras[8] = newSqlParameter("@intPageCount", SqlDbType.Int);

      //??paras[8].Direction = ParameterDirection.Output;

      paras[8] =new SqlParameter("@itemCount", SqlDbType.Int);

      paras[8].Direction = ParameterDirection.Output;

      DataSet ds =DBTool.ExecuteDataset(CommandType.StoredProcedure, "TopPageList",paras);

      /*?@intPageCount?? int?? OUTPUT? , --總頁數? SqlParameterparamPageCount = cmd.Parameters.Add("@intPageCount", SqlDbType.Int);

      -- paramPageCount.Direction = ParameterDirection.Output;

      @strTable = N'zhq_in_content c? INNER JOIN zhp_in_columns? m ONc.columns_id=m.columns_id',

      @strColumn = N'c.content_id',

      @strOrderColumn = N'c.createdate',

      @intOrder = 1,

      @strColumnlist = N'*',

      @strWhere = N'c.status=0 AND c.del=0',

      @intPageSize = 20,

      @intPageNum =100,*/

      changePage.DataSource = ds.Tables[0].DefaultView;// 設置分頁控件的數據

      if (ds !=null && ds.Tables[0].Rows.Count > 0)

      {

      changePage.RecordCount =int.Parse(ds.Tables[0].Rows[0]["itemCount"].ToString());

      // changePage.PageCount =int.Parse(ds.Tables[0].Rows[0]["PageCount"].ToString());

      }

      if(changePage.DataUI.GetType().BaseType.Name == "BaseDataList")

      {

      changePage.DataUI.DataSource = changePage.DataSource;//設置數據源控件的數據

      changePage.DataUI.DataBind();

      }

      }

      四.SQLServer異構數據庫之間數據的導入導出

      本文討論了如何通過Transact-SQL以及系統函數OPENDATASOURCE和OPENROWSET在同構和異構數據庫之間進行數據的導入導出,并給出了詳細的例子以供參考。

      1. 在SQL Server數據庫之間進行數據導入導出

      (1).使用SELECT INTO導出數據

      在SQL Server中使用最廣泛的就是通過SELECTINTO語句導出數據,SELECT INTO語句同時具備兩個功能:根據SELECT后跟的字段以及INTO后面跟的表名建立空表(如果SELECT后是*, 空表的結構和FROM所指的表的結構相同);將SELECT查出的數據插入到這個空表中。在使用SELECT INTO語句時,INTO后跟的表必須在數據庫不存在,否則出錯,下面是一個使用SELECT INTO的例子。

      假設有一個表table1,字段為f1(int)、f2(varchar(50))。

      SELECT * INTO table2 FROM table1

      這條SQL語的在建立table2表后,將table1的數據全部插入到table1中的,還可以將*改為f1或f2以便向適當的字段中插入數據。

      SELECT INTO不僅可以在同一個數據中建立表,也可以在不同的SQL Server數據庫中建立表。

      USE db1

      SELECT * INTO db2.dbo.table2 FROM table1

      以上語句在數據庫db2中建立了一個所有者是dbo的表table2,在向db2建表時當前登錄的用戶必須有在db2建表的權限才能建立table2。使用SELECT INTO要注意的一點是SELECT INTO不可以和COMPUTE一起使用,因為COMPUTE返回的是一組記錄集,這將會引起二意性(即不知道根據哪個表建立空表)。

      (2).使用INSERTINTO和 UPDATE插入和更新數據

      SELECT INTO只能將數據復制到一個空表中,而INSERT INTO可以將一個表或視圖中的數據插入到另外一個表中。

      INSERT INTO table1 SELECT * FROM table2

      或 INSERT INTO db2.dbo.table1 SELECT * FROMtable2

      但以上的INSERT INTO語句可能會產生一個主鍵沖突錯誤(如果table1中的某個字段是主鍵,恰巧table2中的這個字段有的值和table1的這個字段的值相同)。因此,上面的語句可以修改為

      INSERT INTO table1?? -- 假設字段f1為主鍵

      SELECT * FROM table2 WHERE NOT EXISTS(SELECTtable1.f1 FROM table1 WHERE table1.f1=table2.f1 )

      以上語句的功能是將table2中f1在table1中不存在的記錄插入到table1中。

      要想更新table1可以使用UPDATE語句

      UPDATE table1 SET table1.f1=table2.f1,table1.f2=table2.f2 FROM table2 WHERE table1.f1=table2.f1

      將以上兩條INSERT INTO和UPDATE語句組合起來在一起運行,就可以實現記錄在table1中不存在時插入,存在時更新的功能,但要注意要將UPDATE放在 INSERT INTO前面,否則UPDATE更新的記錄數將是table1和table2記錄數的總和。

      2. 使用OPENDATASOURCE和OPENROWSET在不同類型的數據庫之間導入導出數據

      在異構的數據庫之間進行數據傳輸,可以使用SQL Server提供的兩個系統函數OPENDATASOURCE和OPENROWSET。

      OPENDATASOURCE可以打開任何支持OLE DB的數據庫,并且可以將OPENDATASOURCE做為SELECT、UPDATE、INSERT和DELETE后所跟的表名。如

      SELECT * FROM OPENDATASOURCE('SQLOLEDB', 'DataSource=192.168.18.252;User ID=sa;Password=test').pubs.dbo.authors

      這條語句的功能是查詢192.168.18.252這臺機器中SQL Server數據庫pubs中的authors表。從這條語句可以看出,OPENDATASOURCE有兩個參數,第一個參數是 provider_name,表示用于訪問數據源的 OLE DB 提供程序的 PROGID 的名稱。provider_name 的數據類型為 char,沒有默認值。第二個參數是連接字符串,根據OLE DB Provider不同而不同(如果不清楚自己所使用的OLE DBProvider的連接字符串,可以使用delphi、visualstudio等開發工具中的ADO控件自動生成相應的連接字符串)。

      OPENROWSET函數和OPENDATASOURCE函數類似,只是它可以在打開數據庫的同時對數據庫中的表進行查詢,如以下語句

      OPENROWSET('MSDASQL.1', 'Driver=Microsoft VisualFoxPro Driver; SourceDB=c:\db; SourceType=DBF', SELECT * FROM [b.dbf])

      最后一個參數查詢foxpro表b.dbf,讀者可以通過where條件對b.dbf進行過濾。如果將INSERT INTO、SELECT INTO和OPENDATASOURCE或OPENROWSET一起使用,就可以使SQL Server數據庫和其它類型的數據庫之間進行數據導入導出。下面介紹如何使用這兩個函數在SQL Server數據庫和其它類型的數據庫之間進行數據導入導出。

      (1).SQLServer數據庫和SQL Server數據庫之間的數據導入導出。

      導入數據

      SELECT?? * INTOauthors1 FROMOPENDATASOURCE( 'SQLOLEDB', 'Data Source=192.168.18.252;UserID=sa;Password=abc').pubs.dbo.authors

      導出數據

      INSERT INTO OPENDATASOURCE('SQLOLEDB','DataSource=192.168.18.252;User ID=sa;Password=abc').test.dbo.authors select * frompubs.dbo.authors

      在這條語句中OPENDATASOURCE(...)可以理解為SQL Server的一個服務,.pubs.dbo.authors是這個服務管理的一個數據庫的一個表authors。使用INSERT INTO時OPENDATASOURCE(...)后跟的表必須存在。

      也可以將以上的OPENDATASOURCE換成OPENROWSET

      INSERT INTO OPENROWSET('SQLOLEDB','192.168.18.252;sa;abc',select * from test.dbo.kk) SELECT * FROM pubs.dbo.authors

      使用OPENROWSET要注意一點,192.168.18.252;sa;abc中間是";",而不是","。OPENDATASOURCE和OPENROWSET都不接受參數變量。

      (2).SQL Server數據庫和Access數據庫之間的數據導入導出。

      導入數據

      SELECT * INTO access FROM OPENDATASOURCE( 'Microsoft.Jet.OLEDB.4.0','Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\data.mdb;Persist SecurityInfo=False')...table1

      或者使用OPENROWSET

      SELECT * FROM??OPENROWSET('Microsoft.Jet.OLEDB.4.0', 'c:\data.mdb;admin;',SELECT * FROMtable1)

      導出數據

      INSERT INTOOPENDATASOURCE('Microsoft.Jet.OLEDB.4.0','Provider=Microsoft.Jet.OLEDB.4.0;DataSource=c:\data.mdb;Persist Security Info=False')...table1 SELECT * FROM access

      MSSQL之十一 數據庫高級編程總結

      打開access數據庫的OLE DBProvider叫Microsoft.Jet.OLEDB.4.0,需要注意的是操作非SQL Server數據庫在OPENDATASOURCE(...)后面引用數據庫中的表時使用"...”,而不是“.”。

      (3).SQL Server數據庫和文本文件之間的數據導入導出。

      導入數據

      SELECT * INTO text1 FROMOPENDATASOURCE('MICROSOFT.JET.OLEDB.4.0','Text;DATABASE=c:\')...[data#txt]

      導出數據

      INSERT INTOOPENDATASOURCE('MICROSOFT.JET.OLEDB.4.0','Text;DATABASE=c:\')...[data#txt]SELECT * FROM text1

      或者使用OPENROWSET

      INSERT INTOOPENROWSET('MICROSOFT.JET.OLEDB.4.0','Text;DATABASE=c:\, [data#txt]') SELECT *FROM text1

      如果要插入部分字段,可使用

      INSERT INTOOPENROWSET('MICROSOFT.JET.OLEDB.4.0','Text;DATABASE=c:\, SELECT aa FROM[data#txt]') SELECT aa FROM text1

      這條SQL語句的功能是將c盤根目錄的data.txt文件導入到text1表中,在這里文件名中的“.”要使用“#”代替。在向文本導出時,不僅文本文件要存在,而且第一行必須和要導出表的字段一至。

      (4).SQL Server數據庫和dbase數據庫之間的數據導入導出。

      導入數據

      SELECT * INTO dbase FROMOPENROWSET('MICROSOFT.JET.OLEDB.4.0 ', 'dBase III;HDR=NO;IMEX=2;DATABASE=C:\',SELECT* FROM [b.dbf])

      導出數據

      INSERT INTO OPENROWSET('MICROSOFT.JET.OLEDB.4.0', dBase III;HDR=NO;IMEX=2;DATABASE=C:\,SELECT * FROM [b.dbf]) SELECT * FROMdbase

      OPENROWSET(...)中的b.dbf使用[...]括起來,是為了當dbf文件名有空格等字符時不會出錯,如果沒有這些特殊字符,可以將[...]去掉

      (5).SQL Server數據庫和foxpro數據庫之間的數據導入導出。

      導入數據

      SELECT * INTO foxpro FROMOPENROWSET('MSDASQL.1',?? 'Driver=Microsoft Visual FoxProDriver;SourceDB=c:\; SourceType=DBF, 'SELECT * FROM [a.dbf])

      導出數據

      INSERT INTO OPENROWSET('MSDASQL.1' ,'Driver=Microsoft Visual FoxPro Driver;??SourceDB=c:\db;SourceType=DBF,'SELECT * FROM a.dbf) SELECT * FROM foxpro

      在此處a.dbf不能使用[...]括起來,否則出錯(這是由driver決定的)。

      (6).SQL Server數據庫和excel文件之間的數據導入導出

      導入數據

      SELECT * INTO excel FROMOPENDATASOURCE(MICROSOFT.JET.OLEDB.4.0,Excel 5.0;DATABASE=c:\book1.xls)...[Sheet1$]

      導出數據

      INSERT INTOOPENDATASOURCE(MICROSOFT.JET.OLEDB.4.0,Excel 5.0;DATABASE=c:\book1.xls)...[Sheet1$] SELECT * FROM excel

      在book1.xls的Sheet1中必須有和excel表相對應的字段,否則會出錯。

      以上討論了幾種常用的數據庫和SQL Server數據庫之間如何使用Transact-SQL進行數據導入導出。在SQL Server中還提供了將其它類型的數據庫注冊到SQL Server中的功能,這樣就可以和使用SQL Server數據庫表一樣使用這些被注冊數據庫中的表了。

      EXEC sp_addlinkedserver access,OLE DB Providerfor Jet, Microsoft.Jet.OLEDB.4.0, c:\data.mdb

      以上SQL使用存儲過程sp_addlinkedserver注冊了一個access數據庫,我們可以在SQL Server中使用如下語句查詢在data.mdb中的table1。

      SELECT * FROM access...table1

      這樣就可很方便地查詢access數據庫中的表了,如果要導入table1,可以使用SELECT * INTO table2 FROMaccess...table1。如果想刪除注冊的數據庫連接,使用如下語句。

      EXEC sp_dropserver access

      使用Transact-SQL不僅可以向SQLServer數據庫導入導出數據,而且還可以使任意兩種類型數據庫之間互相導入導出數據。以access和excel為例進行說明。

      INSERT INTOOPENDATASOURCE(MICROSOFT.JET.OLEDB.4.0,Excel 5.0;DATABASE=c:\book1.xls)...[Sheet1$] SELECT * FROM OPENROWSET(Microsoft.Jet.OLEDB.4.0,c:\data.mdb;admin;,SELECT * FROM table1)

      以上SQL語句將access數據庫的table1表的數據插入到excel文件book1.xls中的Sheet1表單中。

      使用Transact-SQL進行數據的導入導出,可以很方便地將這些Transact-SQL語句放到客戶端程序中(如delphi、c#等),從而可以很容易地編寫自已的數據庫導入導出工具。

      五.無限級分類的數據庫設計方案

      第一種方案:

      表為兩張,一張分類表,一張信息表。

      表1:

      `ID` int(10),

      `cID` tinyint(3) ,

      `title` varchar(255),

      表2:

      `cID` tinyint(3) ,

      `parentID` tinyint(3),

      `order` tinyint(3) ,

      `name` varchar(255),

      這樣可以根據cID = parentID來判斷上一級內容,運用遞歸至最頂層 。

      第二種方案:

      設置parentID為varchar類型,將父類id都集中在這個字段里,用符號隔開,比如:1,3,6

      這樣可以比較容易得到各上級分類的ID,而且在查詢分類下的信息的時候,可以使用如:Select * From information Where cID Like "1,3%"。不過在添加分類和轉移分類的時候操作將非常麻煩。

      以上兩種方案地址:http://search.phpres.com/phpres-top2007,98552.html

      第三種方案:

      每級分類遞增兩位數字,這樣,每級分類的數目限定在100個之間,分類方法主要為編碼法;

      示例:

      一級分類:01,02,03

      二級分類:0101,0102,0103,0201,0202........

      三級分類:010101,010102,010103,010104..........

      數據庫查詢時使用 like '01%'就可得到一級分類01下的所有子分類,非常方便!

      如果要列出所有分類的樹型結構,只需用一條語句select * from pro_class order bycode,再稍微處理一下就可。(其中,pro_class為產品分類表,code為類別編碼)。

      設計的數據庫結構如下:

      id:? ?? ?? ?? ?? ?????類別id,主鍵

      classname:? ?? ?? ?類名

      classcode:? ?? ?? ? 類別編碼

      parent:? ?? ?? ?? ? 父id

      left_child:? ?? ?? ? 最左孩子id(或第一個孩子)

      right_sibling:? ?? ?右兄弟id

      layer:? ?? ?? ?? ?? ? 層級(第一級類別為1,第2級類別2,以此類推)

      SQL 數據庫

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:在Excel2010中怎么批量刪除圖片一張一張的刪除太慢(excel怎么快速刪除所有圖片)
      下一篇:Excel表格—設置將數字神奇放大的效果(表格里的數字怎么放大)
      相關文章
      亚洲国产精品免费在线观看| 久久亚洲国产欧洲精品一| 亚洲AV永久纯肉无码精品动漫| 亚洲AV成人无码网站| 亚洲一区在线视频| 亚洲人成激情在线播放| 亚洲国产亚洲综合在线尤物| 亚洲精品免费在线| 亚洲国产视频网站| 亚洲成av人片在线看片| 亚洲国产综合自在线另类| 亚洲专区中文字幕| 亚洲卡一卡二卡乱码新区| 亚洲天然素人无码专区| 亚洲欧美中文日韩视频| 亚洲av无码兔费综合| 亚洲?v无码国产在丝袜线观看| 国产精品亚洲а∨天堂2021 | 亚洲天天做日日做天天欢毛片| 亚洲Av熟妇高潮30p| 亚洲最大福利视频网站| 亚洲网址在线观看| 亚洲午夜一区二区电影院| 亚洲一区二区三区高清不卡| 国产精品高清视亚洲一区二区| 亚洲国产精品无码久久九九大片| 久久亚洲AV成人无码国产电影| 国产大陆亚洲精品国产| 亚洲综合色在线观看亚洲| 好看的电影网站亚洲一区| 亚洲国产精品自在线一区二区| 亚洲第一页在线播放| 亚洲看片无码在线视频 | 亚洲AV永久精品爱情岛论坛| 久久国产亚洲精品无码| 亚洲精品国产精品国自产网站 | 亚洲国产精品无码一线岛国| 亚洲黄色在线观看网站| 亚洲精品免费网站| 日韩精品亚洲专区在线影视| 国内精品99亚洲免费高清|