记录生活
分类 Category : SQL Server

T-SQL象数组一样处理字符串、分割字符串

<Category: SQL Server> 发表评论

    在日常的编程过程中,数组是要经常使用到的。在利用SQL对数据库进行操作时,有时就想在SQL使用数组,比如将1,2,3,4,5拆分成数组。可惜的是在T-SQL中不支持数组。不过还是有变通的办法。我们可以自己编写两函数Get_StrArrayLength(取得字符串的长度-元素的个数)和Get_StrArrayStrOfIndex(按指定符号分割字符串,返回分割后指定索引的第几个元素)。有了这两个函数,我们就可以非常方便的在T-SQL中处理形如1,2,3,4,5这样的字符串了。 

    T-SQL对字符串的处理能力比较弱,比如我要循环遍历象1,2,3,4,5这样的字符串,如果用数组的话,遍历很简单,但是T-SQL不支持数组,所以处理下来比较麻烦。下边的函数,实现了象数组一样去处理字符串。 

一、按指定符号分割字符串,返回分割后的元素个数,方法很简单,就是看字符串中存在多少个分隔符号,然后再加一,就是要求的结果。
CREATE function Get_StrArrayLength
(
 @str varchar(1024),  --要分割的字符串
 @split varchar(10)  --分隔符号
)
returns int
as
 begin
  declare @location int
  declare @start int
  declare @length int
  set @str=ltrim(rtrim(@str))
  set @location=charindex(@split,@str)
  set @length=1
   while @location<>0
     begin
      set @start=@location+1
      set @location=charindex(@split,@str,@start)
      set @length=@length+1
     end
   return @length
 end

调用示例:select dbo.Get_StrArrayLength('78,1,2,3',',')

返回值:4

 

二、按指定符号分割字符串,返回分割后指定索引的第几个元素,象数组一样方便

CREATE function Get_StrArrayStrOfIndex
(
 @str varchar(1024),  --要分割的字符串
 @split varchar(10),  --分隔符号
 @index int --取第几个元素
)
returns varchar(1024)
as
begin
 declare @location int
 declare @start int
 declare @next int
 declare @seed int
 set @str=ltrim(rtrim(@str))
 set @start=1
 set @next=1
 set @seed=len(@split)
 set @location=charindex(@split,@str)
 while @location<>0 and @index>@next
   begin
    set @start=@location+@seed
    set @location=charindex(@split,@str,@start)
    set @next=@next+1
   end
 if @location =0 select @location =len(@str)+1

--这儿存在两种情况:1、字符串不存在分隔符号 2、字符串中存在分隔符号,跳出while循环后,@location为0,那默认为字符串后边有一个分隔符号。
 return substring(@str,@start,@location-@start)
end

调用示例:select dbo.Get_StrArrayStrOfIndex('8,9,4',',',2)

返回值:9

 

三、结合上边两个函数,象数组一样遍历字符串中的元素

 declare @str varchar(50)
 set @str='1,2,3,4,5'
 declare @next int
 set @next=1
 while @next<=dbo.Get_StrArrayLength(@str,',')
   begin
     print dbo.Get_StrArrayStrOfIndex(@str,',',@next)
     set @next=@next+1
   end

 调用结果:
1
2
3
4
5

本文来自: T-SQL象数组一样处理字符串、分割字符串

常用SQL字符串函数问题集锦

<Category: SQL Server> 发表评论

SQL字符串函数
字符串函数对二进制数据、字符串和表达式执行不同的运算。此类函数作用于CHAR、VARCHAR、 BINARY、 和VARBINARY 数据类型以及可以隐式转换为CHAR 或VARCHAR的数据类型。可以在SELECT 语句的SELECT 和WHERE 子句以及表达式中使用字符串函数。常用的字符串函数有:

一、字符转换函数
1、ASCII()
返回字符表达式最左端字符的ASCII 码值。在ASCII()函数中,纯数字的字符串可不用‘’括起来,但含其它字符的字符串必须用‘’括起来使用,否则会出错。 

2、CHAR()
将ASCII 码转换为字符。如果没有输入0 ~ 255 之间的ASCII 码值,CHAR() 返回NULL 。 

3、LOWER()和UPPER()
LOWER()将字符串全部转为小写;UPPER()将字符串全部转为大写。

 4、STR()
把数值型数据转换为字符型数据。
STR (<float_expression>[,length[, <decimal>]])
length 指定返回的字符串的长度,decimal 指定返回的小数位数。如果没有指定长度,缺省的length 值为10, decimal 缺省值为0。
当length 或者decimal 为负值时,返回NULL;
当length 小于小数点左边(包括符号位)的位数时,返回length 个*;
先服从length ,再取decimal ;
当返回的字符串位数小于length ,左边补足空格。

 二、去空格函数
1、LTRIM() 把字符串头部的空格去掉。

2、RTRIM() 把字符串尾部的空格去掉。

三、取子串函数
1、left()
LEFT (<character_expression>, <integer_expression>)
返回character_expression 左起 integer_expression 个字符。

2、RIGHT()
RIGHT (<character_expression>, <integer_expression>)
返回character_expression 右起 integer_expression 个字符。

3、SUBSTRING()
SUBSTRING (<expression>, <starting_ position>, length)
返回从字符串左边第starting_ position 个字符起length个字符的部分。

四、字符串比较函数
1、CHARINDEX()
返回字符串中某个指定的子串出现的开始位置。
CHARINDEX ( expression1 ,expression2 [ , start_location ] )
其中substring _expression 是所要查找的字符表达式,expression 可为字符串也可为列名表达式。如果没有发现子串,则返回0 值。
此函数不能用于TEXT 和IMAGE 数据类型。

 2、PATINDEX()
返回字符串中某个指定的子串出现的开始位置。
PATINDEX (<’%substring _expression%’>, <column_ name>)其中子串表达式前后必须有百分号“%”否则返回值为0。
与CHARINDEX 函数不同的是,PATINDEX函数的子串中可以使用通配符,且此函数可用于CHAR、 VARCHAR 和TEXT 数据类型。

五、字符串操作函数
1、QUOTENAME()
返回被特定字符括起来的字符串。
QUOTENAME (<’character_expression’>[, quote_ character]) 其中quote_ character 标明括字符串所用的字符,缺省值为“[]”。

 2、REPLICATE()
返回一个重复character_expression 指定次数的字符串。
REPLICATE (character_expression integer_expression) 如果integer_expression 值为负值,则返回NULL 。

3、REVERSE()
将指定的字符串的字符排列顺序颠倒。
REVERSE (<character_expression>) 其中character_expression 可以是字符串、常数或一个列的值。

4、REPLACE()
返回被替换了指定子串的字符串。
REPLACE (<string_expression1>, <string_expression2>, <string_expression3>) 用string_expression3 替换在string_expression1 中的子串string_expression2。

4、SPACE()
返回一个有指定长度的空白字符串。
SPACE (<integer_expression>) 如果integer_expression 值为负值,则返回NULL 。

5、STUFF()
用另一子串替换字符串指定位置、长度的子串。
STUFF (<character_expression1>, <start_ position>, <length>,<character_expression2>)
如果起始位置为负或长度值为负,或者起始位置大于character_expression1 的长度,则返回NULL 值。
如果length 长度大于character_expression1 中 start_ position 以右的长度,则character_expression1 只保留首字符。

 六、数据类型转换函数
1、CAST()
CAST (<expression> AS <data_ type>[ length ])

2、CONVERT()
CONVERT (<data_ type>[ length ], <expression> [, style])

1)data_type为SQL Server系统定义的数据类型,用户自定义的数据类型不能在此使用。
2)length用于指定数据的长度,缺省值为30。
3)把CHAR或VARCHAR类型转换为诸如INT或SAMLLINT这样的INTEGER类型、结果必须是带正号或负号的数值。
4)TEXT类型到CHAR或VARCHAR类型转换最多为8000个字符,即CHAR或VARCHAR数据类型是最大长度。
5)IMAGE类型存储的数据转换到BINARY或VARBINARY类型,最多为8000个字符。
6)把整数值转换为MONEY或SMALLMONEY类型,按定义的国家的货币单位来处理,如人民币、美元、英镑等。
7)BIT类型的转换把非零值转换为1,并仍以BIT类型存储。
8)试图转换到不同长度的数据类型,会截短转换值并在转换值后显示“+”,以标识发生了这种截断。
9)用CONVERT() 函数的style 选项能以不同的格式显示日期和时间。style 是将DATATIME 和SMALLDATETIME 数据转换为字符串时所选用的由SQL Server 系统提供的转换样式编号,不同的样式编号有不同的输出格式。

  七、日期函数
1、day(date_expression)
返回date_expression中的日期值

2、month(date_expression)
返回date_expression中的月份值

3、year(date_expression)
返回date_expression中的年份值

4、DATEADD()
DATEADD (<datepart>, <number>, <date>)
返回指定日期date 加上指定的额外日期间隔number 产生的新日期。参数“datepart” 取值如下:

 5、DATEDIFF()
DATEDIFF (<datepart>, <date1>, <date2>)
返回两个指定日期在datepart 方面的不同之处,即date2 超过date1的差距值,其结果值是一个带有正负号的整数值。

6、DATENAME()
DATENAME (<datepart>, <date>)
以字符串的形式返回日期的指定部分此部分。由datepart 来指定。

7、DATEPART()
DATEPART (<datepart>, <date>)
以整数值的形式返回日期的指定部分。此部分由datepart 来指定。
DATEPART (dd, date) 等同于DAY (date)
DATEPART (mm, date) 等同于MONTH (date)
DATEPART (yy, date) 等同于YEAR (date)

8、GETDATE()
以DATETIME 的缺省格式返回系统当前的日期和时间

本文来自: 常用SQL字符串函数问题集锦

SQL:获取不同版本中差异参数值

<Category: SQL Server> 发表评论

帮朋友写的一个sql,比较数据里面不同版本的参数数值

阅读这篇文章的其余部分 »

本文来自: SQL:获取不同版本中差异参数值

SQL函数大全及用法

<Category: SQL Server, 数据库> 5 条评论

--聚合函数
use pubs
go
select avg(distinct price) --算平均数
from titles
where type='business'
go
use pubs
go
select max(ytd_sales) --最大数
from titles
go

use pubs
go
select min(ytd_sales) --最小数
from titles
go

use pubs
go
select type,sum(price),sum(advance) --求和
from titles
group by type
order by type
go

use pubs
go
select count(distinct city) --求个数
from authors
go

use pubs
go
select stdev(royalty) --返回给定表达式中所有值的统计标准偏差
from titles
go

阅读这篇文章的其余部分 »

本文来自: SQL函数大全及用法

SQL Server查询中处理特殊字符

<Category: SQL Server> 3 条评论

我们都知道SQL Server查询过程中,单引号“'”是特殊字符,所以在查询的时候要转换成双单引号“''”。
但这只是特殊字符的一个,在实际项目中,发现对于like操作还有以下特殊字符:下划线“_”,百分号“%”,方括号“[]”以及尖号“^”。
其用途如下:
下划线:用于代替一个任意字符(相当于正则表达式中的 ? )
百分号:用于代替任意数目的任意字符(相当于正则表达式中的 * )
方括号:用于转义(事实上只有左方括号用于转义,右方括号使用最近优先原则匹配最近的左方括号)
尖号:用于排除一些字符进行匹配(这个与正则表达式中的一样)以下是一些匹配的举例,需要说明的是,只有like操作才有这些特殊字符,=操作是没有的。
a_b... a[_]b%
a%b... a[%]b%
a[b... a[[]b%
a]b... a]b%
a[]b... a[[]]b%
a[^]b... a[[][^]]b%
a[^^]b... a[[][^][^]]b%

在实际进行处理的时候,对于=操作,我们一般只需要如此替换:
' -> ''
对于like操作,需要进行以下替换(注意顺序也很重要)
[ -> [[] (这个必须是第一个替换的!!)
% -> [%] (这里%是指希望匹配的字符本身包括的%而不是专门用于匹配的通配符)
_ -> [_]
^ -> [^]

在sql语句中,有些特殊字符,是sql保留的。比如 ' [ ] 等。我们可以先看看它们的用法。
2 U* S# k6 B4 Y5 ^# c3 {, E3 i& Z( k
. O2 G, T" R- n# E4 D+ s& w+ a4 q 当需要查询某数据时,加入条件语句,或着当你需要insert记录时,我们用 ' 来将字符类型的数据引起来。比如:) c( H* }# u+ L# v6 c* q! o$ N
Select * from Customers where City = 'London'
; y5 B. U/ K* {" W ] 当表的名字或列的名字中,含有空格等一些特殊字符时,我们需要用[] 将表名引起来,告诉语法分析器,[]号内的才是一个完整的名称。比如
, E& R8 w! T# c4 u* f! ESelect * from [Order Details]% X3 g1 s' A# v4 q; R
如果,字符数据中,含有 ' 改怎么办呢?其实,好多人在这里并没有处理字符川中 ' 符号,才造成sql 注射危险。就那上面的那个例子。在Sql语句拼接的时代,比如
$ Q' a0 ^0 V# a' U1 P$ Z% ^ ~9 Z! v
string = "select * from Customers where CustomerID = '" + temp + "'";* a: n# ~- ]3 s+ l' z# a8 ^
如果,我给temp赋值为 Tom' or 1=1 --- - t8 f2 n( T; H9 i+ P9 [
那么你拼接起来的语句为 select * from Customers where CustomerID = 'Tom' or 1=1 --- ' " @8 H+ V0 p5 C
哈哈,1=1 衡为真,---会把后面的sql语句注释掉。而前面因为有输入的 ' 而使的语句是合法的。那or的条件,会把所有的记录都选出来。这就是sql注入。在做用户登陆时,如果没有处理该问题,那你的系统受危害的可能性会很高的。
2 d! C( @+ y. l& Y7 g9 @$ p7 ?3 X 如何处理字符数据中的 ' 符号呢? 方法很简单,用两个 ' 符号代替一个。 比如,其实际传入的值为Lon'don,处理后为
' c+ t$ `$ Y# J) `! a2 U8 ISelect * from Customers where City = 'Lon''don'# n" M3 w3 c$ d, s8 f' T
如果表或列的名称中含有 [ 或 ] 字符呢?比如Select * from [Order] Details],那中间 ] 符号岂不是先和第一个[ 配了。后面的就是非法的了。怎么办呢? 简单,使用 ]] 代替 ] 。对于[,则无须处理。那就该为! Z& I0 j- g7 G% @
Select * from [Order]] Details]

-------------------------以上来自网络,未一一验证
1.有这样一个库:$(DatabaseNa[]me)
我们可以这样使用:
use "$(DatabaseNa[]me)";
select * from dbo.app_dataconnection;
或者use [$(DatabaseNa[]me)];
这样也是可以的。
2.库改名,加个单引号:$(DatabaseNa[]me')
就只能这样了:
use "$(DatabaseNa[]me')";
select * from dbo.app_dataconnection;
3.如果再加个双引号呢

本文来自: SQL Server查询中处理特殊字符

奇怪的大小写问题

<Category: SQL Server> 发表评论

use master; select  C.TABLE_CATALOG,C.TABLE_NAME,K.COLUMN_NAME,C.CONSTRAINT_NAME,c.CONSTRAINT_SCHEMA  as SCHEMA_NAME   from  INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS K, INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS C  where   K.CONSTRAINT_NAME=C.CONSTRAINT_NAME  and  C.CONSTRAINT_TYPE='PRIMARY KEY'

Msg 4104, Level 16, State 1, Line 1
无法绑定由多个部分组成的标识符 "c.CONSTRAINT_SCHEMA"。
这个SQL在有些库执行没有问题,在有些库执行就报错,奇怪了,仔细看,主要是大小写不一样,sqlserver默认安装是不区分大小写的啊,看来以后写SQL得注意,不管sqlserver大小写区不区分,我自己也还是得区分的。

本文来自: 奇怪的大小写问题

SQLServer2005批量创建N个空表

<Category: SQL Server> 发表评论

刚刚需要创建500个表来采元数据,写了个存储过程,批量生成测试表,表的字段默认为100个。
阅读这篇文章的其余部分 »

本文来自: SQLServer2005批量创建N个空表

SQL Server 中 DELETE 与 TRUNCATE TABLE

<Category: SQL Server> 1 条评论

清空表数据的两种方法:

 

在SQL Server中,每一个操作SQL Server都会做一定的Log记录,比较说Insert,Update 或者Delete事件,每一个操作都会锁定行,然后对行操作做一些记录。

当一个表中的数据行很多的时候,几十万条或更多,那么删除的时候TRUNCATE TABLE则更快,它是一种快速、无日志记录的方法。TRUNCATE TABLE 与不含有 WHERE 子句的 DELETE 语句在功能上相同。但是,TRUNCATE TABLE 速度更快,并且使用更少的系统资源和事务日志资源。

与 DELETE 语句相比,TRUNCATE TABLE 具有以下优点:

所用的事务日志空间较少。

DELETE 语句每次删除一行,并在事务日志中为所删除的每行记录一项。TRUNCATE TABLE 通过释放用于存储表数据的数据页来删除数据,并且在事务日志中只记录页释放。

使用的锁通常较少。

当使用行锁执行 DELETE 语句时,将锁定表中各行以便删除。TRUNCATE TABLE 始终锁定表和页,而不是锁定各行。

如无例外,在表中不会留有任何页。

执行 DELETE 语句后,表仍会包含空页。例如,必须至少使用一个排他 (LCK_M_X) 表锁,才能释放堆中的空表。如果执行删除操作时没有使用表锁,表(堆)中将包含许多空页。对于索引,删除操作会留下一些空页,尽管这些页会通过后台清除进程迅速释放。

与 DELETE 语句相同,使用 TRUNCATE TABLE 清空的表的定义与其索引和其他关联对象一起保留在数据库中。

如果这个表与其他表存在外键关联,则是删除不了的。

Msg 4712, Level 16, State 1, Line 1

Cannot truncate table xxx_primarykey' because it is being referenced by a FOREIGN KEY constraint.

本文来自: SQL Server 中 DELETE 与 TRUNCATE TABLE

【转】获取SQL Server数据库元数据的方法

<Category: SQL Server, 数据库> 发表评论

元数据简介

元数据 () 最常见的定义为“有关数据的结构数据”,或者再简单一点就是“关于数据的信息”,日常生活中的图例、图书馆目录卡和名片等都可以看作是元数据。在关系型数据库管理系统 (DBMS) 中,元数据描述了数据的结构和意义。比如在管理、维护 Server 或者是开发数据库应用程序的时候,我们经常要获取一些涉及到数据库架构的信息:

◆某个数据库中的表和视图的个数以及名称;

◆某个表或者视图中列的个数以及每一列的名称、数据类型、长度、精度、描述等;

◆某个表上定义的约束;

◆某个表上定义的索引以及主键/外键的信息。

下面我们将介绍几种获取元数据的方法。

获取元数据

使用系统存储过程与系统函数访问元数据

获取元数据最常用的方法是使用 提供的系统存储过程与系统函数。

系统存储过程与系统函数在系统表和元数据之间提供了一个抽象层,使得我们不用直接查询系统表就能获得当前数据库对象的元数据。

常用的与元数据有关的系统存储过程有以下一些:

系统存储过程

◆sp_columns 返回指定表或视图的列的详细信息。

◆sp_databases 返回当前服务器上的所有数据库的基本信息。

◆sp_fkeys 若参数为带有主键的表,则返回包含指向该表的外键的所有表;若参数为带有外键的表名,则返回所有同过主键/外键关系与该外键相关联的所有表。

◆sp_pkeys 返回指定表的主键信息。

◆sp_server_info 返回当前服务器的各种特性及其对应取值。

◆sp_sproc_columns 返回指定存储过程的的输入、输出参数的信息。

◆sp_statistics 返回指定的表或索引视图上的所有索引以及统计的信息。

◆sp_stored_procedures 返回当前数据库的存储过程列表,包含系统存储过程。

◆sp_tables 返回当前数据库的所有表和视图,包含系统表。

常用的与元数据有关的系统函数有以下一些:

系统函数

◆COLUMNPROPERTY 返回有关列或过程参数的信息,如是否允许空值,是否为计算列等。

◆COL_LENGTH 返回指定数据库的指定属性值,如是否处于只读模式等。

◆DATABASEPROPERTYEX 返回指定数据库的指定选项或属性的当前设置,如数据库的状态、恢复模型等。

◆OBJECT_ID 返回指定数据库对象名的标识号

◆OBJECT_NAME 返回指定数据库对象标识号的对象名。

◆OBJECTPROPERTY 返回指定数据库对象标识号的有关信息,如是否为表,是否为约束等。

◆fn_listextendedproperty 返回数据库对象的扩展属性值,如对象描述、格式规则、输入掩码等。

由于我们无法直接利用到存储过程与函数的返回结果,因此只有在我们关心的只是查询的结果,而不需要进一步利用这些结果的时候,我们会使用系统存储过程与系统函数来查询元数据。

例如,如果要获得当前服务器上所有数据库的基本信息,我们可以在查询分析器里面运行:

EXEC sp_databases
GO

在返回结果中我们可以看到数据库的名称、大小及备注等信息。

但是如果要引用这部分信息,或者存储这部分信息以供后面使用,那么我们必须借助中间表来完成这个操作:
阅读这篇文章的其余部分 »

本文来自: 【转】获取SQL Server数据库元数据的方法

存储过程加解密,SQLServer2000和SQLserver2005

<Category: SQL Server> 发表评论

加密篇

create procedure Test_o with encryption
as select '' as y;

阅读这篇文章的其余部分 »

本文来自: 存储过程加解密,SQLServer2000和SQLserver2005