<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    整理了一些t-sql技巧(轉自csdn)

    ?

    一、?只復制一個表結構,不復制數據

    ?

    select ? top ? 0 ? * ? into ? [ t1 ] ? from ? [ t2 ]


    二、?獲取數據庫中某個對象的創建腳本

    1、?先用下面的腳本創建一個函數

    if ? exists ( select ? 1 ? from ?sysobjects? where ?id = object_id ( ' fgetscript ' )? and ? objectproperty (id, ' IsInlineFunction ' ) = 0 )
    ?
    drop ? function
    ?fgetscript
    go


    create ? function ?fgetscript(
    ?
    @servername ? varchar ( 50 )????? -- 服務器名

    ?, @userid ? varchar ( 50 ) = ' sa ' ???? -- 用戶名,如果為nt驗證方式,則為空
    ?, @password ? varchar ( 50 ) = '' ???? -- 密碼
    ?, @databasename ? varchar ( 50 )???? -- 數據庫名稱
    ?, @objectname ? varchar ( 250 )???? -- 對象名

    )?
    returns ? varchar ( 8000 )
    as

    begin
    ?
    declare ? @re ? varchar ( 8000 )???????? -- 返回腳本
    ? declare ? @srvid ? int , @dbsid ? int ??????? -- 定義服務器、數據庫集id
    ? declare ? @dbid ? int , @tbid ? int ???????? -- 數據庫、表id
    ? declare ? @err ? int , @src ? varchar ( 255 ),? @desc ? varchar ( 255 )? -- 錯誤處理變量

    -- 創建sqldmo對象
    ? exec ? @err = sp_oacreate? ' sqldmo.sqlserver ' , @srvid ?output
    ?
    if ? @err <> 0 ? goto
    ?lberr

    -- 連接服務器

    ? if ? isnull ( @userid , '' ) = '' ? -- 如果是?Nt驗證方式
    ? begin
    ??
    exec ? @err = sp_oasetproperty? @srvid , ' loginsecure ' , 1
    ??
    if ? @err <> 0 ? goto ?lberr

    ??
    exec ? @err = sp_oamethod? @srvid , ' connect ' , null , @servername

    ?
    end
    ?
    else
    ??
    exec ? @err = sp_oamethod? @srvid , ' connect ' , null , @servername , @userid , @password

    ?
    if ? @err <> 0 ? goto ?lberr

    -- 獲取數據庫集

    ? exec ? @err = sp_oagetproperty? @srvid , ' databases ' , @dbsid ?output
    ?
    if ? @err <> 0 ? goto
    ?lberr

    -- 獲取要取得腳本的數據庫id

    ? exec ? @err = sp_oamethod? @dbsid , ' item ' , @dbid ?output, @databasename
    ?
    if ? @err <> 0 ? goto ?lberr

    -- 獲取要取得腳本的對象id

    ? exec ? @err = sp_oamethod? @dbid , ' getobjectbyname ' , @tbid ?output, @objectname
    ?
    if ? @err <> 0 ? goto ?lberr

    -- 取得腳本

    ? exec ? @err = sp_oamethod? @tbid , ' script ' , @re ?output
    ?
    if ? @err <> 0 ? goto
    ?lberr

    ?
    -- print?@re

    ? return ( @re )

    lberr:
    ?
    exec ?sp_oageterrorinfo? NULL ,? @src ?out,? @desc
    ?out?
    ?
    declare ? @errb ? varbinary ( 4
    )
    ?
    set ? @errb = cast ( @err ? as ? varbinary ( 4
    ))
    ?
    exec ?master..xp_varbintohexstr? @errb , @re
    ?out
    ?
    set ? @re = ' 錯誤號:? ' + @re

    ???
    + char ( 13 ) + ' 錯誤源:? ' + @src
    ???
    + char ( 13 ) + ' 錯誤描述:? ' + @desc
    ?
    return ( @re )
    end

    go

    2、?用法如下
    用法如下,

    print ?dbo.fgetscript( ' 服務器名 ' , ' 用戶名 ' , ' 密碼 ' , ' 數據庫名 ' , ' 表名或其它對象名 ' )

    3、?如果要獲取庫里所有對象的腳本,如如下方式

    declare ? @name ? varchar ( 250 )
    declare ?#aa? cursor ? for

    ?
    select ?name? from ?sysobjects? where ?xtype? not ? in ( ' S ' , ' PK ' , ' D ' , ' X ' , ' L ' )
    open
    ?#aa
    fetch ? next ? from ?#aa? into ? @name

    while ? @@fetch_status = 0
    begin
    ?
    print ?dbo.fgetscript( ' onlytiancai ' , ' sa ' , ' sa ' , ' database ' , @name )
    ?
    fetch ? next ? from ?#aa? into ? @name

    end
    close ?#aa
    deallocate
    ?#aa

    4、?聲明,此函數是csdn鄒建鄒老大提供的
    三、?分隔字符串
    如果有一個用逗號分割開的字符串,比如說"a,b,c,d,1,2,3,4",如何用t-sql獲取這個字符串有幾個元素,獲取第幾個元素的值是多少呢?因為t-sql里沒有split函數,也沒有數組的概念,所以只能自己寫幾個函數了。
    1、?獲取元素個數的函數

    create ? function ?getstrarrlength?( @str ? varchar ( 8000 ))
    returns ? int

    as
    begin
    ??
    declare ? @int_return ? int
    ??
    declare ? @start ? int
    ??
    declare ? @next ? int
    ??
    declare ? @location ? int
    ??
    select ? @str ? = ' , ' + ? @str ? + ' , '
    ??
    select ? @str = replace ( @str , ' ,, ' , ' , ' )
    ??
    select ? @start ? = 1

    ??
    select ? @next ? = 1 ?
    ??
    select ? @location ? = ? charindex ( ' , ' , @str , @start
    )
    ??
    while ?( @location ? <> 0
    )
    ??
    begin

    ????
    select ? @start ? = ? @location ? + 1
    ????
    select ? @location ? = ? charindex ( ' , ' , @str , @start )
    ????
    select ? @next ? = @next ? + 1

    ??
    end
    ?
    select ? @int_return ? = ? @next - 2
    ?
    return ? @int_return
    end

    2、?獲取指定索引的值的函數

    create ? function ?getstrofindex?( @str ? varchar ( 8000 ), @index ? int ? = 0 )
    returns ? varchar ( 8000
    )
    as

    begin
    ??
    declare ? @str_return ? varchar ( 8000 )
    ??
    declare ? @start ? int

    ??
    declare ? @next ? int
    ??
    declare ? @location ? int
    ??
    select ? @start ? = 1
    ??
    select ? @next ? = 1 ? -- 如果習慣從0開始則select?@next?=0
    ?? select ? @location ? = ? charindex ( ' , ' , @str , @start )
    ??
    while ?( @location ? <> 0 ? and ? @index ? > ? @next
    ?)
    ??
    begin

    ????
    select ? @start ? = ? @location ? + 1
    ????
    select ? @location ? = ? charindex ( ' , ' , @str , @start )
    ????
    select ? @next ? = @next ? + 1

    ??
    end
    ??
    if ? @location ? = 0 ? select ? @location ? = len ( @str ) + 1 ? -- 如果是因為沒有逗號退出,則認為逗號在字符串后
    ?? select ? @str_return ? = ? substring ( @str , @start , @location ? - @start )? -- @start肯定是逗號之后的位置或者就是初始值1
    ?? if ?( @index ? <> ? @next ?)? select ? @str_return ? = ? '' ? -- 如果二者不相等,則是因為逗號太少,或者@index小于@next的初始值1。
    ?? return ? @str_return
    end

    3、?測試

    SELECT ? [ dbo ] . [ getstrarrlength ] ( ' 1,2,3,4,a,b,c,d ' )
    SELECT ? [ dbo ] . [ getstrofindex ] ( ' 1,2,3,4,a,b,c,d ' , 5
    )

    四、?一條語句執行跨越若干個數據庫
    我要在一條語句里操作不同的服務器上的不同的數據庫里的不同的表,怎么辦呢?
    第一種方法:

    select ? * ? from ? OPENDATASOURCE ( ' SQLOLEDB ' , ' Data?Source=遠程ip;User?ID=sa;Password=密碼 ' ).庫名.dbo.表名

    第二種方法:
    先使用聯結服務器:

    EXEC ?sp_addlinkedserver? ' 別名 ' , '' , ' MSDASQL ' , NULL , NULL , ' DRIVER={SQL?Server};SERVER=遠程名;UID=用戶;PWD=密碼; '
    exec ?sp_addlinkedsrvlogin?? @rmtsrvname = ' 別名 ' , @useself = ' false ' , @locallogin = ' sa ' , @rmtuser = ' sa ' , @rmtpassword = ' 密碼 '
    GO

    然后你就可以如下:

    select ? * ? from ?別名.庫名.dbo.表名
    insert ?庫名.dbo.表名? select ? * ? from
    ?別名.庫名.dbo.表名
    select ? * ? into ?庫名.dbo.新表名? from
    ?別名.庫名.dbo.表名
    go

    五、?怎樣獲取一個表中所有的字段信息
    蛙蛙推薦:怎樣獲取一個表中所有字段的信息
    先創建一個視圖

    Create ? view ?fielddesc????
    as

    select ?o.name? as ?table_name,c.name? as ?field_name,t.name? as ?type,c.length? as ?

    length,c.isnullable?
    as ?isnullable, convert ( varchar ( 30 ),p.value)? as
    ?desp?
    from
    ?syscolumns?c??
    join ?systypes?t? on ?c.xtype? =
    ?t.xusertype
    join ?sysobjects?o? on ?o.id =
    c.id?
    left ? join ????sysproperties?p? on ?p.smallid = c.colid? and ?p.id =
    o.id????
    where ?o.xtype = ' U '


    查詢時:

    Select ? * ? from ?fielddesc? where ?table_name? = ? ' 你的表名 '

    ?

    還有個更強的語句,是鄒建寫的,也寫出來吧

    SELECT ?
    ?(
    case ? when ?a.colorder = 1 ? then ?d.name? else ? '' ? end )?N ' 表名 '
    ,
    ?a.colorder?N
    ' 字段序號 '
    ,
    ?a.name?N
    ' 字段名 '
    ,
    ?(
    case ? when ? COLUMNPROPERTY (?a.id,a.name, ' IsIdentity ' ) = 1 ? then ? ' ' else ? '' ? end )?N ' 標識 '
    ,
    ?(
    case ? when ?( SELECT ? count ( *
    )
    ?
    FROM
    ?sysobjects
    ?
    WHERE ?(name? in

    ???????????(
    SELECT ?name
    ??????????
    FROM
    ?sysindexes
    ??????????
    WHERE ?(id? = ?a.id)? AND ?(indid? in

    ????????????????????(
    SELECT ?indid
    ???????????????????
    FROM
    ?sysindexkeys
    ???????????????????
    WHERE ?(id? = ?a.id)? AND ?(colid? in

    ?????????????????????????????(
    SELECT ?colid
    ????????????????????????????
    FROM
    ?syscolumns
    ????????????????????????????
    WHERE ?(id? = ?a.id)? AND ?(name? = ?a.name)))))))? AND

    ????????(xtype?
    = ? ' PK ' )) > 0 ? then ? ' ' ? else ? '' ? end )?N ' 主鍵 ' ,
    ?b.name?N
    ' 類型 '
    ,
    ?a.length?N
    ' 占用字節數 '
    ,
    ?
    COLUMNPROPERTY (a.id,a.name, ' PRECISION ' )? as ?N ' 長度 '
    ,
    ?
    isnull ( COLUMNPROPERTY (a.id,a.name, ' Scale ' ), 0 )? as ?N ' 小數位數 '
    ,
    ?(
    case ? when ?a.isnullable = 1 ? then ? ' ' else ? '' ? end )?N ' 允許空 '
    ,
    ?
    isnull (e. text , '' )?N ' 默認值 '
    ,
    ?
    isnull (g. [ value ] , '' )? AS ?N ' 字段說明 '

    -- into?##tx

    FROM ??syscolumns??a? left ? join ?systypes?b?
    on ??a.xtype =
    b.xusertype
    inner ? join
    ?sysobjects?d?
    on ?a.id = d.id?? and ??d.xtype = ' U ' ? and ??d.name <> ' dtproperties '

    left ? join ?syscomments?e
    on ?a.cdefault =
    e.id
    left ? join
    ?sysproperties?g
    on ?a.id = g.id? AND ?a.colid? =
    ?g.smallid??
    order ? by ? object_name
    (a.id),a.colorder

    六、?時間格式轉換問題
    因為新開發的軟件需要用一些舊軟件生成的一些數據,在時間格式上不統一,只能手工轉換,研究了一下午寫了三條語句,以前沒怎么用過convert函數和case語句,還有"+"操作符在不同上下文環境也會起到不同的作用,把我搞暈了要,不過現在看來是差不多弄好了。

    1、把所有"70.07.06"這樣的值變成"1970-07-06"

    UPDATE ?lvshi
    SET ?shengri? = ? ' 19 ' ? + ? REPLACE (shengri,? ' . ' ,? ' - '
    )
    WHERE ?(zhiyezheng? = ? ' 139770070153 ' )

    ?

    2、在"1970-07-06"里提取"70","07","06"

    SELECT ? SUBSTRING (shengri,? 3 ,? 2 )? AS ? year ,? SUBSTRING (shengri,? 6 ,? 2 )? AS ? month ,?
    ??????
    SUBSTRING (shengri,? 9 ,? 2 )? AS ? day

    FROM ?lvshi
    WHERE ?(zhiyezheng? = ? ' 139770070153 '
    )

    3、把一個時間類型字段轉換成"1970-07-06"

    UPDATE ?lvshi
    SET ?shenling? = ? CONVERT ( varchar ( 4 ),? YEAR
    (shenling))?
    ??????
    + ? ' - ' ? + ? CASE ? WHEN ? LEN ( MONTH (shenling))? = ? 1 ? THEN ? ' 0 ' ? + ? CONVERT ( varchar ( 2
    ),?
    ??????
    month (shenling))? ELSE ? CONVERT ( varchar ( 2 ),? month
    (shenling))?
    ??????
    END ? + ? ' - ' ? + ? CASE ? WHEN ? LEN ( day (shenling))? = ? 1 ? THEN ? ' 0 ' ? + ? CONVERT ( char ( 2
    ),?
    ??????
    day (shenling))? ELSE ? CONVERT ( varchar ( 2 ),? day (shenling))? END

    WHERE ?(zhiyezheng? = ? ' 139770070153 ' )

    七、?分區視圖
    分區視圖是提高查詢性能的一個很好的辦法

    -- 看下面的示例

    -- 示例表
    create ? table ?tempdb.dbo.t_10(
    id?
    int ? primary ? key ? check (id? between ? 1 ? and ? 10 ),name? varchar ( 10
    ))

    create ? table
    ?pubs.dbo.t_20(
    id?
    int ? primary ? key ? check (id? between ? 11 ? and ? 20 ),name? varchar ( 10
    ))

    create ? table
    ?northwind.dbo.t_30(
    id?
    int ? primary ? key ? check (id? between ? 21 ? and ? 30 ),name? varchar ( 10
    ))
    go


    -- 分區視圖
    create ? view ?v_t
    as

    select ? * ? from ?tempdb.dbo.t_10
    union ? all

    select ? * ? from ?pubs.dbo.t_20
    union ? all

    select ? * ? from ?northwind.dbo.t_30
    go


    -- 插入數據
    insert ?v_t? select ? 1 ?, ' aa '
    union ?? all ? select ? 2 ?, ' bb '
    union ?? all ? select ? 11 , ' cc '
    union ?? all ? select ? 12 , ' dd '
    union ?? all ? select ? 21 , ' ee '
    union ?? all ? select ? 22 , ' ff '

    -- 更新數據
    update ?v_t? set ?name = name + ' _更新 ' ? where ? right (id, 1 ) = 1

    -- 刪除測試
    delete ? from ?v_t? where ? right (id, 1 ) = 2

    -- 顯示結果
    select ? * ? from ?v_t
    go


    -- 刪除測試
    drop ? table ?northwind.dbo.t_30,pubs.dbo.t_20,tempdb.dbo.t_10
    drop ? view
    ?v_t

    /* --測試結果

    id??????????name???????
    -----------?----------?
    1???????????aa_更新
    11??????????cc_更新
    21??????????ee_更新

    (所影響的行數為?3?行)
    ==
    */


    八、?樹型的實現

    -- 參考

    -- 樹形數據查詢示例
    --
    作者:?鄒建

    -- 示例數據
    create ? table ? [ tb ] ( [ id ] ? int ? identity ( 1 , 1 ), [ pid ] ? int ,name? varchar ( 20 ))
    insert ? [ tb ] ? select ? 0 , ' 中國 '

    union ?? all ?? select ? 0 , ' 美國 '
    union ?? all ?? select ? 0 , ' 加拿大 '
    union ?? all ?? select ? 1 , ' 北京 '
    union ?? all ?? select ? 1 , ' 上海 '
    union ?? all ?? select ? 1 , ' 江蘇 '
    union ?? all ?? select ? 6 , ' 蘇州 '
    union ?? all ?? select ? 7 , ' 常熟 '
    union ?? all ?? select ? 6 , ' 南京 '
    union ?? all ?? select ? 6 , ' 無錫 '
    union ?? all ?? select ? 2 , ' 紐約 '
    union ?? all ?? select ? 2 , ' 舊金山 '
    go

    -- 查詢指定id的所有子
    create ? function ?f_cid(
    @id ? int

    )
    returns ? @re ? table ( [ id ] ? int , [ level ] ? int )
    as

    begin
    ?
    declare ? @l ? int
    ?
    set ? @l = 0
    ?
    insert ? @re ? select ? @id , @l
    ?
    while ? @@rowcount > 0
    ?
    begin
    ??
    set ? @l = @l + 1
    ??
    insert ? @re ? select ?a. [ id ] , @l
    ??
    from ? [ tb ] ?a, @re ?b
    ??
    where ?a. [ pid ] = b. [ id ] ? and ?b. [ level ] = @l - 1

    ?
    end
    /**/ /* --如果只顯示最明細的子(下面沒有子),則加上這個刪除
    ?delete?a?from?@re?a
    ?where?exists(
    ??select?1?from?[tb]?where?[pid]=a.[id])
    --
    */

    ?
    return
    end
    go

    -- 調用(查詢所有的子)
    select ?a. * ,層次 = b. [ level ] ? from ? [ tb ] ?a,f_cid( 2 )b? where ?a. [ id ] = b. [ id ]
    go

    -- 刪除測試
    drop ? table ? [ tb ]
    drop ? function ?f_cid
    go


    ?

    九、?排序問題

    CREATE ? TABLE ? [ t ] ?(
    ?
    [ id ] ? [ int ] ? IDENTITY ?( 1 ,? 1 )? NOT ? NULL
    ?,
    ?
    [ GUID ] ? [ uniqueidentifier ] ? NULL
    ?
    )?
    ON ? [ PRIMARY ]

    GO


    下面這句執行5次

    insert ?t? values ?( newid ())


    查看執行結果

    select ? * ? from ?t


    1、?第一種

    select ? * ? from ?t
    ?
    order ? by ? case ?id? when ? 4 ? then ? 1

    ??????????????????
    when ? 5 ? then ? 2
    ??????????????????
    when ? 1 ? then ? 3
    ??????????????????
    when ? 2 ? then ? 4
    ??????????????????
    when ? 3 ? then ? 5 ? end


    2、?第二種

    select ? * ? from ?t? order ? by ?(id + 2 ) % 6


    3、?第三種

    select ? * ? from ?t? order ? by ? charindex ( cast (id? as ? varchar ), ' 45123 ' )


    4、?第四種

    select ? * ? from ?t
    WHERE ?id? between ? 0 ? and ? 5

    order ? by ? charindex ( cast (id? as ? varchar ), ' 45123 ' )


    5、?第五種

    select ? * ? from ?t? order ? by ? case ? when ?id? > 3 ? then ?id - 5 ? else ?id? end


    6、?第六種

    select ? * ? from ?t? order ? by ?id? / ? 4 ? desc ,id? asc

    ?

    十、?一條語句刪除一批記錄
    首先id列是int標識類類型,然后刪除ID值為5,6,8,9,10,11的列,這里的cast函數不能用convert函數代替,而且轉換的類型必須是varchar,而不能是char,否則就會執行出你不希望的結果,這里的"5,6,8,9,10,11"可以是你在頁面上獲取的一個chkboxlist構建成的值,然后用下面的一句就全部刪
    除了,比循環用多條語句高效吧應該。

    delete ? from ? [ fujian ] ? where ? charindex ( ' , ' + cast ( [ id ] ? as ? varchar ) + ' , ' , ' , ' + ' 5,6,8,9,10,11, ' + ' , ' ) > 0


    還有一種就是

    delete ? from ?table1? where ?id? in ( 1 , 2 , 3 , 4 ?)


    十一、獲取子表內的一列數據的組合字符串
    下面這個函數獲取05年已經注冊了的某個所的律師,唯一一個參數就是事務所的名稱,然后返回zhuce字段里包含05字樣的所有律師。

    CREATE ??? FUNCTION ?fn_Get05LvshiNameBySuo??( @p_suo ? Nvarchar ( 50 ))
    RETURNS ? Nvarchar ( 2000
    )
    AS

    BEGIN ??
    ?
    DECLARE ? @LvshiNames ? varchar ( 2000 ),? @name ? varchar ( 50
    )
    ?
    select ? @LvshiNames = ''

    ?
    DECLARE ?lvshi_cursor? CURSOR ? FOR


    posted on 2006-08-07 11:51 nbt 閱讀(549) 評論(0)  編輯  收藏 所屬分類: 數據庫技術

    <2006年8月>
    303112345
    6789101112
    13141516171819
    20212223242526
    272829303112
    3456789

    導航

    統計

    常用鏈接

    留言簿(3)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    相冊

    收藏夾

    Java技術網站

    友情鏈接

    國內一些開源網站

    最新隨筆

    搜索

    積分與排名

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 精品视频在线免费观看| 亚洲国产成人久久| 国产亚洲精品成人a v小说| 国产做床爱无遮挡免费视频| 日本免费的一级v一片| 日本一线a视频免费观看| 永久黄网站色视频免费直播| 色吊丝永久在线观看最新免费| 成人性生交视频免费观看| 在线看片无码永久免费视频| 国产成人免费爽爽爽视频| 女人张开腿等男人桶免费视频 | 国产免费高清69式视频在线观看| 思思久久99热免费精品6| 成在线人直播免费视频| 中文在线观看永久免费| 久久精品国产免费一区| 3d成人免费动漫在线观看| aⅴ在线免费观看| 免费毛片在线看片免费丝瓜视频 | 美女视频黄的免费视频网页| 久热免费在线视频| 可以免费看黄视频的网站| 成全视频免费高清| 免费人妻av无码专区| 国产亚洲精品无码专区| 亚洲第一AAAAA片| 亚洲国产成人精品无码区在线秒播| 亚洲剧场午夜在线观看| 99亚洲乱人伦aⅴ精品| 午夜成人无码福利免费视频| 两个人看的www免费视频中文| 一级毛片在线免费观看| 中文字幕无码不卡免费视频 | 18pao国产成视频永久免费| 久久精品免费全国观看国产| 国产精品免费小视频| 亚洲色成人网站WWW永久| 亚洲精品国产情侣av在线| 久久人午夜亚洲精品无码区| 成在人线av无码免费高潮水|