首页 > php与数据库

在编写存储过程时使用 Set NoCount On

使用 SET NOCOUNT ON
默认情况下,存储过程将返回过程中每个语句影响的行数。如果不需要在应用程序中使用该信息(大多数应用程序并不需要),请在存储过程中使用 SET NOCOUNT ON 语句以终止该行为。根据存储过程中包含的影响行的语句的数量,这将删除客户端和服务器之间的一个或多个往返过程。尽管这不是大问题,但它可以为高流量应用程序的性能产生负面影响。
create procedure test_MyStoredProc @param1 int
as
set nocount on

阅读全文

PEAR MDB 数据库抽象层 ?? 一次编写?随处运行

Write once - run anywhere
一次编写——随处运行
这是Java的一句行销口号,但是它同时也是PHP的关键特性之一。许多商业模型依赖于操作系统无关性来保证产品能够销售给广泛的客户群体。因而,为什么要把你自己绑在某种数据库厂商的身上呢?数据库抽象层使得你能够与数据库独立的开发你的应用程序。但是,通常情况下它们对性能的影响超过了你所希望的,要么他们并不足够抽象以消除所有和特定数据库相关的代码。
这篇文章将教给我什么?
这篇文章将对数据库抽象包 PEAR MDB 有一个很好的介绍。文章的焦点将是对 MDB 超越类似包所提供的更先进的特性,例如数据类型抽象和基于 XML 的 schema 管理。对 PHP 和 SQL 的基本理解是推荐的。
为什么另外再要一个数据库类?
通常, web 工程在客户已经确定了要使用那种 RDBMS (关系型数据库管理系统)之后被添加给已经存在的 IT 基础结构。即使那并不是因为不同的预算可能影响的你选择何种数据用于部署的情况。最终,你作为开发者可能简单的偏好于不把自己绑在某个厂商身上。自此,意味着给每个支持的数据保持版本或者牺牲更多性能但是获得多于必须的易用性:走入 PEAR MDB 吧。
MDB 是着眼于使得编写 RDBMS 无关的 PHP 程序成为简单的过程的数据库抽象层。大部分其他的 PHP 的所谓数据库抽象层紧紧给所有支持的数据库提供了一个公用 API 以及非常有限的抽象(大部分只是针对序列的)。MDB 另一方面能够用来抽象所有数据库发送和接收的数据。甚至数据库 schema 都能被定义为 RDBMS 无关的格式。但是它提供这些功能的同时仍然保持了很高的性能以及简单易用。这是通过深入观察两个流行的数据库抽象层,PEAR DB 和 Metabase, 之后并且对它们进行了融合后获得的。而且在融合过程中,趁着这个机会清理了它们融合后的 API 以及任何影响性能的设计。
MDB 是怎样出现的?
早在 2001 年的秋天,我就在寻找一种可能能够让我公司的程序框架与 RDBMS 独立的数据库抽象包。这个目标是把特定数据库相关的代码数量减少到零。我发现提供这样的功能的唯一的一个包是 Metabase。但是 Metabase有一些部分是因为为了和 PHP3 兼容的让人不舒服的 API。尽管如此,我们决定 Metabase 是我们唯一的选择。但是即使是在给 Metabase 增加了一个性能改进的补丁之后,我们仍然感到我们放弃了太多的性能。我们在 2001 年的 PHP 国际会议上碰到了 Metabase 的作者,并且我们谈论了让像 Metabase 这样的东西成为 PEAR 工程一部分的好处。后来不久,在 PEAR 邮件列表上就 PEAR DB 和 Metabase 融合的可能的好处又开始了一场讨论。在我们公司进行了许多讨论之后,我们决定承担这个任务。数个月的艰辛工作之后,我们现在有了 MDB 的第一个稳定的 release。

阅读全文

同时安装sql2000和sql2005,经验点滴

sql2000的服务器版本是8.0,sql2005是9.0
首先要读安装必须配置(见后记)
1.我是先装2000的,安装好后打上sp4补丁,(sa密码不要太简单)
1.然后安装sql2005,安装的时候只要找到tools目录下的setup.exe 安装就可以了,安装完毕会有个SQL Server Management Studio,这个就是sql2000的企业管理器,
2,好多人都连接不上SQL Server Management Studio2005的数据库,开始的时候我也试了好多,
其实只要选择数据库引擎,然后服务器名称里面要填写"机器名SQLEXPRESS",如果你的机器名是haha,那么"hahaSQLEXPRESS",验证方式根据你的需求选择,点连接就能连上sql数据库引擎了,你要是自定义服务名了就用你的自定义服务名替换SQLEXPRESS
我在附加数据库的时候2005附加过后的数据库,不能被2000附加了
Q:ms sql 2005 的数据库可以导到(还原or恢复)ms sql 2000 里面么?
A:可以在sql 2005中生成数据库的脚本, 注意生成的时候, 要选择生成sql 2000这个版本的脚本然后在2000中用这个脚本建立目标库, 再用数据导入/导出把数据从2005导到2000即可.
Q:SQL Sever2005的用户名和口令应如何设置?
A:--把chinawn替换成你要建的用户
sp_addlogin 'chinawn','a','pubs'
go
EXEC sp_adduser 'chinawn', 'chinawn', 'db_owner'
后记:
安装 SQL Server 2005 的硬件和软件要求

阅读全文

SQL Server 7.0 入门(六)

建立存储过程体
存储过程逻辑驻留在存储过程体中。一个存储过程体中可以包含任意条Transact SQL语句。下面的Transact SQL语句不能在任何存储过程体中出现:
· CREATE DEFAULT
· CREATE TRIGGER
· CREATE PROCEDURE
· CREATE VIEW
· CREATE RULE
1、 局部变量
局部变量保持存储过程中间值。当一个值在存储过程中需要多次,或者某个查询的结果需要在随后的查询中使用时,需要使用局部变量。在这些情形下,值被存储在局部变量中,并可用于将来的使用。本地变量的名称以“@”符号开头。变量的名称可以包含字符和数值。局部变量在使用前需要进行类型声明。对局部变量进行赋值需要使用SELECT语句。SELECT可以从一个表中检索出值并将其赋给某个变量,也可以给变量赋一个常量值。一个简单的SELECT语句可以给多个局部变量赋值。
例如:
DECLARE @var1 integer, @var2 varchar(20)
SELECT @var1 = 32,
@var2 = 'MyAge’
如果从SELECT查询中没有返回任何数据,而SELECT又要将数据的值赋予局部变量,则该局部变量的值将不会发生改变。
2、 条件词句
存储过程中提供的条件语句包括:
· IF……ELSE语句。
· WHILE语句。
1) IF……ELSE语句。在该语句中包含三个部分:布尔运算表达式,IF语句块和ELSE语句块。语法如下:
IF (boolen_expr)
{statements}
ELSE
{statements}
在IF或ELSE语句块中可以有多条语句,这种情形下,需要语句BEGIN和END来标志语句块。
2) WHILE语句。WHILE语句用于处理直到某个条件为TRUE前重复执行的语句。语法如下:
WHILE (boolen_expr)
BEGIN
statement(s)
BREAK
Statement(s)
CONTINUE
END
BEGIN和END语句标志循环体。BREAK语句结束循环的执行(即走到END语句之后)。CONTINUE语句将控制处理过程回到循环的开始处(即BEGIN语句的右边)。
注意:如果有两个或多个WHILE循环被嵌套,则内部的BREAK退出的是次外层的循环。内部循环结束之后的所有语句在内部循环执行之后才能继续执行。
3、 GOTO语句
在存储过程的执行中,语句是顺序执行的。GOTO语句则是用来打破这种语句执行的顺序,它立即跳到某条语句上执行,而这条语句往往不紧跟在前一语句之后。GOTO语句与一个标志(Label)一起使用,该标志用来标识一条语句。

阅读全文

关于在SQL-SERVER里调用COM组件

Sql-server里可以调用基于IDispatch的COM组件
有兴趣的可以自己去查SQL帮助里的sp_OACreate、sp_OAMethod、sp_OADestroy等存储过程的用法。
下面是我在一个短信报警的小项目里的一些sql代码,报警信息通过各类软件插入到sql-server里,然后通过触发器调用组件,并发送短信到指定手机上去,实现自动报警功能。
//测试数据库的触发器
ALTER TRIGGER message_Trigger1
ON dbo.message
FOR INSERT /*, UPDATE, DELETE */
AS
/* IF UPDATE (column_name) ...*/
begin
declare @PhoneNum nvarchar(50)
declare @Content nvarchar(140)
declare @MessageId nvarchar(70)
declare @index int
declare @hr int
declare @object int
select @PhoneNum = phone_num, @Content = Content, @MessageId = message_id from inserted
select @index = 1
/*调用COM发送短信*/
begin
EXEC @hr = sp_OACreate '{26850DDA-862C-44FF-9232-282937F2CA4B}',@object OUT
if @hr = 0
begin
exec @hr=sp_OAMethod @object,'SendMsg',NULL,@Content,@PhoneNum,@index,@MessageId
exec sp_OADestroy @object
end
end
end
这里的代码可以说是没有问题,但是也可以说是有很大的问题。
关键就在于组件的SendMsg方法,为什么呢?我可以举出几个我实际碰到的问题来做具体说明。
最主要有2点
第1:此COM组件是否为进程内组件,组件内部代码是否足够强壮
第2:创建组件和销毁组件及组件方法要尽最大可能的快速
我对上述两点做一个说明
如果COM组件为进程内组件的话,意味着此组件被sql-server加载,如果此代码不够健壮,那么,由于组件本身导致的挂起,崩溃,会直接影响到整个sql-server,那么情况是非常严重的,这种错误,发生一次就足以要了你的小命,如果恰好在客户的脸上爆炸的话……
解决的方法只有这样:首先保证你的组件代码足够强壮,强壮到不能再强壮为止。还有就是尽量让组件不要是进程内的,如果已经是DLL了,那么就交给COM Catalog来管理。这样就解决了因为组件崩溃挂起导致sql-server产生问题。

阅读全文

SQL Server 7.0 入门(五)

使用SQL Server开发应用程序
编写存储过程与触发器
存储过程和触发器是由用户创建的、驻留在服务器的一组Transact SQL查询语句。触发器是系统在特定条件下执行的。存储过程能够改善应用程序的性能。当客户程序需要访问数据时,一般要经过5个步骤才能访问到数据:
1) 查询语句被发送到服务器。
2) 服务器编译SQL代码。
3) 优化产生查询的执行计划。
4) 数据引擎执行查询。
5) 结果发回客户程序。
存储过程是在创建时编译的,当存储过程第一次执行时,SQL Server产生查询执行计划并将其存储进来,以利于将来使用。当通过存储过程发出一个请求时,上述的第2和第3步就没有了,这能大大改善系统的性能。即使在第1步上也能提高性能。因为此时发送到服务器的语句只是一条存储过程的EXECUTE语句,而不是庞大的、复杂的查询。这种特性能降低网络的流量。
除了性能方面的改善外,存储过程还提供了方便地集中维护应用程序的功能。如果将查询嵌入到应用程序中。而又需要对查询进行改变,则应用程序需要重新编译,并重新发布到所有的客户端。而在存储过程中,修改对用户而言是透明的,它只需要在服务器上重新编译存储过程。
存储过程还能提供安全机制,尽管用户可能无权执行存储过程中的命令,但它却可能有权执行存储过程本身。有时候,系统管理员不会给用户以数据修改(UPDATE、INSERT和DELETE)的权力。创建的存储过程却能进行这些操作。当然用户需要拥有执行该存储过程的权力。
建立存储过程
存储过程可以达到以下目的:
· 带参数。
· 返回状态值。
· 调用其它存储过程。
· 在远程服务器上执行。
存储过程在“sysobjects”系统表中有一个表项,其类型为“P”。存储过程的文本存储在“syscomments”系统表中。创建存储过程需要使用Transact SQL命令CREATE PROCEDURE。
例如:
USE pubs
GO

CREATE PROCEDURE ap_GetAuthorsForPublisher
AS
SELECT a.au_lname,a.au_fname
FROM authors a, titleauthor ta, titles t, publishers p
WHERE a.au_id = ta.Au_id
AND ta.Title_id = t.title_id
AND t.pub_id = p.pub_id
AND p.pub_name = ’New Moon Books’
GO

阅读全文

SQL Server 7.0 入门(二)

存取数据
select语句
1. 选择表中的所有列
“*”对Select语句有特殊意义。它指定表中的所有列,而不用列出列的名字。列的顺序和表中的顺序相同。
2. 选择不同的值
如果被选择列表中的列有重复值,这时“distinct”关键字可以用来忽略重复值。
注意: 如果Select list中多于一列,则distinct关键字对它们总体有效。如果一列有重复值,而其他列的值是唯一的,则有重复值的一列包含在结果中。
3. 在结果数据集合中对列重命名
结果中列的默认名字是源数据库中的列名,用户可以用自己指定的列名来代替默认的列名。
Select AuthorFirstName = au_fname from authors
--将列名由“au_fname”改成“AuthorFirstName”
4. 选择计算值
在Select list中可以包含计算值或常量。计算值是在算术表达式的基础上计算而来的,它可包含在表中的一列或多列。
Select totalSale = price * ytd_sales from titles
条件选择(Where子句)
使用一个比较或逻辑操作在Where子句中指定过滤条件,来生成表中想得到的行。
1. 比较操作
比较操作能比较数值、字符和日期数据,返回TRUE或FALSE。
比较操作符
<(小于)
>(大于)
=(等于)
<>(不等于)
>=(大于等于)
<=(小于等于)
!=(不等于)
!<(不小于)
!>(不大于)
2. 逻辑操作
逻辑操作测试某些条件是否正确,并根据测试结果返回TRUE或FALSE。
· LIKE 如果操作和指定的字符串相同,则返回TRUE,指定的字符串也可包含通配符。
有通配符的like操作更有用。
· “%”规定所有字符串可代替字符“%”的位置。任何在“%”之前或之后的指定字符串视为常量。如:“New%”表示所有以“New”开头的字符串,“%New”表示以“New”结尾的字符串。
· “_”规定任何单个字符可代入“_”的位置。这在只有一个字符不同的相近字符的情况下非常有用。
· “[]”规定使用方括号中定义的字符代替一个字符。方括号中可能是独立的字符(如[ahg]),也可是字符范围(如[c-i])。
· “[^]”规定方括号中“^”之后的字符为不能用来代入的字符,它可以是独立字符(如[ahg]),也可是字符范围(如[c-i])。
注意:可以在一个表达式中组合运用这些通配符。
· BETWEEN 如果操作数在提供的范围之内,则返回TRUE。

阅读全文

一种通过sql server的作业调度 存储过程来建立自动备份的方法

1.在要备份的数据上建立以下存储过程:
CREATE PROCEDURE [dbo].[过程名] AS
declare
@filename nvarchar(100),--文件名
@NowDay int --设置时间
set @filename='F:JXXdata' cast(Day(GetDate()) as varchar(2)) '.dat' --文件路径及文件名
Set @NowDay=Day(GetDate())
if (@NowDay>=20) or (@NowDay<=10) --这个月的20到下个月的10要备份
begin
print @filename BACKUP DATABASE [数据库名()你也可以设参数] TO DISK = @filename WITH INIT , NOUNLOAD , NAME = N'XX数据备份', NOSKIP , STATS = 10, NOFORMAT
end
存储过程要调试好无误
2、进入企业管理器中->管理->sql server代理->作业,新建作业,作业名称随便取,例如:data备份,所有者选择sa,当然你也可以选择其他用户,前提是该用户有执行作业的权限;
3.在步骤中取名-选中要备份的数据库 --在命令中输入 exec('过程名')
4.在调度中选反复出现--更改--选每天--时间自己输入
5.测试完后-最后导入脚本 进入服务器
6.把SQlServer服务管理器 启用SqlServer Agent服务

阅读全文

MS SQL SERVER 图像或大文本的输入输出

在MS SQL SERVER 安装目录下有个可执行文件叫 TEXTCOPY.EXE
可对 MS SQL SERVER 中的文本或图像数据进行输入输出.
不过你可以在MS-DOS方式下执行textcopy /? 得到它的描述。
 
下面是这个工具的描述:
Copies a single text or image value into or out of SQL Server. The val
ue
is a specified text or image 'column' of a single row (specified by th
e
"where clause") of the specified 'table'.
If the direction is IN (/I) then the data from the specified 'file' is
copied into SQL Server, replacing the existing text or image value. If
the
direction is OUT (/O) then the text or image value is copied from
SQL Server into the specified 'file', replacing any existing file.
TEXTCOPY [/S ][sqlserver]] [/U [login]] [/P ][password]]
[/D ][database]] [/T table] [/C column] [/W"where clause"]
[/F file] [{/I | /O}] [/K chunksize] [/Z] [/?]
/S sqlserver The SQL Server to connect to. If 'sqlserver' is n
ot
specified, the local SQL Server is used.
/U login The login to connect with. If 'login' is not spec
ified,
a trusted connection will be used.
/P password The password for 'login'. If 'password' is not
specified, a NULL password will be used.
/D database The database that contains the table with the tex
t or
image data. If 'database' is not specified, the d
efault
database of 'login' is used.
/T table The table that contains the text or image value.
/C column The text or image column of 'table'.
/W "where clause" A complete where clause (including the WHERE keyw
ord)
that specifies a single row of 'table'.
/F file The file name.
/I Copy text or image value into SQL Server from 'fi

阅读全文

SQL Server SA权限总结经典技术

前提需要工具:SQL Query Analyzer和SqlExec Sunx Version
  
  第一部分:
  
  有关去掉xp_cmdshell来保护系统的分析总结:
  首先知道一下语句:
  1.去掉xp_cmdshell扩展过程的方法是使用如下语句:
  if exists (select * from dbo.sysobjects where id=object_id(N'[dbo].[xpcmdshell]') and OBJECTPROPERTY(id,N'IsExtendedProc')=1)exec sp_dropextendedproc N'[dbo].[xp_cmdshell]'
  2.添加xp_cmdshell扩展过程的方法是使用如下语句:
  sp_addextendedproc xp_cmdshell,@dllname='xplog70.dll'
  现在看看现象:
  我们在取得SA权限后远程用Sqlexec执行cmd命令,出现提示SQL_ERROR,那么很可能是去掉了xp_cmdshell。
  
  现在来看看被去掉xp_cmdshell后恢复的两种方法:
  
  方法一、使用SQL Query Analyzer连接对方后直接写入,挺方便sp_addextendedproc xp_cmdshell,@dllname='xplog70.dll'方法二、使用SqlExec Sunx Version首先在SqlExec Sunx Version的Format选项里填上%s,在CMD选项里输入sp_addextendedproc 'xp_cmdshell','xpsql70.dll'或者对Sql2000情况下使用sp_addextendedproc 'xp_cmdshell','xplog70.dll'另外使用SqlExec Sunx Version来去除xp_cmdshell的方法和加的时候选择条件一样,然后输入sp_dropextendedproc 'xp_cmdshell'就可以了
  
  第二部分:
  
  假如对方已经把xplog70.dll删除或者改了名,我们来用下面的方法继续我们的hack任务:
  
  当出现如下现象暗示代表很有可能是xplog70.dll删除或者改了名。
  
  在查询分析器中写入sp_addextendedproc xp_cmdshell,@dllname='xplog70.dll'提示数据库中已存在名为'xp_cmdshell'的对象。

阅读全文

SQL中DATALENGTH 用法

返回任何表达式所占用的字节数。
语法
DATALENGTH ( expression )
参数
expression
任何类型的表达式。
返回类型
int
注释
DATALENGTH 对 varchar、varbinary、text、image、nvarchar 和 ntext 数据类型特别有用,因为这些数据类型可以存储
可变长度数据。
NULL 的 DATALENGTH 的结果是 NULL。
说明 兼容级别可能影响返回值。有关兼容级别的更多信息,请参见 sp_dbcmptlevel。
示例
此示例查找 publishers 表中 pub_name 列的长度。
USE pubs
GO
SELECT length = DATALENGTH(pub_name), pub_name
FROM publishers
ORDER BY pub_name
GO
下面是结果集:
length pub_name
----------- ----------------------------------------
20 Algodata Infosystems
16 Binnet & Hardley
21 Five Lakes Publishing
5 GGG&G
18 Lucerne Publishing
14 New Moon Books
17 Ramona Publishers
14 Scootney Books
(8 row(s) affected)

阅读全文

SQL中HAVING从句的用法

HAVING
用户在使用SQL语言的过程中可能希望解决的一个问题就是对由sum或其它集合函数运算结果的输出进行限制。例如,我们可能只希望看到Store_Information数据表中销售总额超过1500美圆的商店的信息,这时我们就需要使用HAVING从句。语法格式为:
SELECT "column_name1", SUM("column_name2")
FROM "table_name"
GROUP BY "column_name1"
HAVING (arithematic function condition)
(GROUP BY从句可选)
由此,我们可以使用如下命令实现上述查询目的:
SELECT store_name, SUM(sales)
FROM Store_Information
GROUP BY store_name
HAVING SUM(sales) > 1500
查询结果显示为:
store_name SUM(Sales)
Los Angeles $1800
小注:
SQL语言中设定集合函数的查询条件时使用HAVING从句而不是WHERE从句。通常情况下,HAVING从句被放置在SQL命令的结尾处

阅读全文