如何在SqlServer与oracel中进行分页的讨论!

使用sql,和oracle数据库进行分页可以有以下三种方法!
下面让我们看一看如果我们要在数据库中取第1000条到第1010条的数据这两种方法是怎么实现的.
1. 使用临时表的方法. (在系统中主要是直接写Sql语句来做)

a) 按所需的排序方式排好序

b) 创建临时表

c) 从数据库里取出第0条 到 第1010条的数据

d) 把这些数据放入临时表中

e) 把临时表再按与 a) 相反的排序方式排好序

f) 然后只需把临时表中的前10条显时出来

g) 销毁临时表


2. 使用 object 的方法

a) 按所需的排序方式排好序

b) 从数据库里取出第0条 到 第1010条的数据

c) 倒着从这1010条数据中取10条 放入一个 object中

d) 把这个 object里的记录 完全倒置一下

e) 把 object里的数据显示出来


显然 第二种 方法优于第一种方法 它减少了系统创建, 销毁临时表所需耗费的资源, 但是它们都有一个共同的弱点. 那就是 它们都要从数据库里取出第0条 到 第1010条的数据 这样就造成了 查询出的记录数很少,但网络传输数据量很大!


因此比较好的分页做法应该是:

每次翻页的时候只从数据库里检索页面大小的块区的数据。这样虽然每次翻页都需要查询数据库,但查询出的记录数很少,网络传输数据量不大,如果使用连接池更可以略过最耗时的建立数据库连接过程。而在数据库端有各种成熟的优化技术用于提高查询速度,比在应用服务器层做缓存有效多了。


对于SqlServer 数据库 如要到得第1000-1010条记录:


Select top 10 * from (

Select top 10 * from (

Select top 1010 * from docdetail order by lastmodidate asc ,Id asc

) temptbl1 order by lastmodidate desc ,Id desc

) temptbl2 order by lastmodidate asc,Id asc

对于oracle 数据库 如要到得第1000-1010条记录 由于oracle中的rownum是在查询之后排序之前赋值的.所以其相应的写法应为:
select * from (

select my_table.*, rownum as temptbl_rownum from (

阅读全文

Sql server中查询的一个比较快的语句

在Access中进行时间的比较sql语句很简单,如Select * From table Where thetime>#”& Now() &”#这样即可
在MSSQL就不能这样,要用DateDiff语句和GetDate()函数进行比较。
如Select Count(*) From table Where DateDiff(s,GetDate(),thetime)>0,我自己特别做了个50万条数据的的表,执行这条语句差不多需要1200毫秒。
后来研究了一下,发现其实不需要用DateDiff函数,可以直接使用>来比较,语句如下:Select Count(*) From table Where thetime>GetDate(),这样差不多只要750毫秒,快了将近500毫秒。

阅读全文

SQL Server端口更改后的数据库连接方式

SQL Server端口,我们可以通过"服务器端网络试用工具"和"客户端实用工具"
来设定,设定方法是:
分别使用"服务器端网络试用工具"和"客户端实用工具"
设置"常规选项"->"启用的协议"->"Tcp/Ip"->"属性"中的默认端口,假设为1455
然后测试你的端口是否起效,可以使用
telnet sql服务器地址 1455
看看能不能telnet通,如果可以,那就可以进行下面的测试
以往的书写中都没有带端口号,所以比较好写,但是现在更改了端口号了,很多朋友就不是很清楚该如何写连接语句了.下面的数据库连接语句就是更改端口后的形式:
------------------------------
Set oConn = Server.CreateObject("ADODB.Connection")
sConn = "Driver={SQL Server};Server=服务器地址,1455;Database=数据库;UID=用户名;PWD=密码;"
oConn.Open sConn
Response.Write oConn
-------------------------------
输出结果为:
-------------------------------
Provider=MSDASQL.1;Extended Properties="DRIVER=SQL Server;SERVER=服务器地址,1455;UID=用户名;PWD=密码;APP=Internet Information Services;WSID=**;DATABASE=数据库"
-------------------------------
这表明我们已经成功连接数据!

阅读全文

SQL Server 2005: 利用新的ranking函数实现高效的数据分页操作

最近MSDN Magazine上的一篇文章10 Tips for Writing High-Performance Web Applications提到了有效的数据分页技术对提高ASP .NET程序性能的重要性;并给出了一个实现数据分页的stored procedure的例子,抄录如下:
CREATE PROCEDURE northwind_OrdersPaged
(
@PageIndex int,
@PageSize int
)
AS
BEGIN
DECLARE @PageLowerBound int
DECLARE @PageUpperBound int
DECLARE @RowsToReturn int
-- First set the rowcount
SET @RowsToReturn = @PageSize * (@PageIndex 1)
SET ROWCOUNT @RowsToReturn
-- Set the page bounds
SET @PageLowerBound = @PageSize * @PageIndex
SET @PageUpperBound = @PageLowerBound @PageSize 1
-- Create a temp table to store the select results
CREATE TABLE #PageIndex
(
IndexId int IDENTITY (1, 1) NOT NULL,
OrderID int
)
-- Insert into the temp table
INSERT INTO #PageIndex (OrderID)
SELECT
OrderID
FROM
Orders
ORDER BY
OrderID DESC
-- Return total count
SELECT COUNT(OrderID) FROM Orders
-- Return paged results
SELECT
O.*
FROM
Orders O,
#PageIndex PageIndex
WHERE
O.OrderID = PageIndex.OrderID AND
PageIndex.IndexID > @PageLowerBound AND
PageIndex.IndexID < @PageUpperBound
ORDER BY
PageIndex.IndexID
END
在SQL Server 2000里面,由于没有一个有效的进行ranking操作的方法,所以该例子先创建了一个有Identity字段的临时表,利用Identity字段的自增长特性,间接的为Orders表的每一行按orderID逆序赋予了一个行号, 然后基于这个行号实现分页。
在SQL Server 2000里面,由于系统提供了内建的ranking函数,为了给Orders表生成行号,我们不再需要利用Identity字段。
例如,利用SQL Server 2000的ROW_NUMBER()函数,按orderID字段逆序排列,给Orders表生成行号的语句如下:

SELECT ROW_NUMBER() OVER(ORDER BY ordered DESC) AS rownum, ordered
FROM Orders
ORDER BY rownum DESC
基于这些新的ranking函数,您可以跟方便的实现数据的分页操作。
关于SQL Server 2005的T-SQL新特性,见文档:

阅读全文

将表数据生成SQL脚本的存储过程

作者:zlt982001
  将表数据生成SQL脚本的存储过程:
CREATE PROCEDURE dbo.UspOutputData
@tablename sysname
AS
declare @column varchar(1000)
declare @columndata varchar(1000)
declare @sql varchar(4000)
declare @xtype tinyint
declare @name sysname
declare @objectId int
declare @objectname sysname
declare @ident int
set nocount on
set @objectId=object_id(@tablename)
if @objectId is null -- 判

阅读全文

从MySQL导出XLS数据库工具(跨平台)

这个脚本是使用Perl生成excel xls文件的工具。依赖一些模块,你可以在linux下使用,产生xls文件。使用方式是命令行 参数。非常方便这个脚本是使用Perl生成excel xls文件的工具。依赖一些模块,你可以在linux下使用,产生xls文件。使用方式是命令行 参数。非常方便。#!/usr/bin/perl#===============================# mysql to excel# lastmodify at 2005-1-5# copyright by hoowa#=============================use...
阅读全文

怎么清除sql server日志

方法1:
第一步:
backup log database_name with no_log
或者 backup log database_name with truncate_only --no_log和truncate_only是在这里是同义的,随便执行哪一句都可以
第二步:
1.收缩特定数据库的所有数据和日志文件,执行 dbcc shrinkdatabase (database_name,[,target_percent])--database_name是要收缩的数据库名称;target_percent是数据库收缩后的数据库文件中所要的剩余可用空间百分比
2.收缩一次一个特定数据库中的数据或日志文件,执行 dbcc shrinkfile(file_id,[,target_size]) --file_id是要收缩的文件的标识 (ID) 号,若要获得文件 ID,请使用 FILE_ID 函数或在当前数据库中搜索 sysfiles;target_size是用兆字节表示的所要的文件大小(用整数表示)。如果没有指定,dbcc shrinkfile 将文件大小减少到默认文件大小
两个dbcc都可以带上参数notruncate或truncateonly,具体意思看帮助。
方法2(这个方法在sqlserver2000的环境下做一般能成功,在sqlserver7及以下版本就不一定了):
第一步:
先备份整个数据库以备不测
第二步:
备份结束后,在Query Analyzer中执行如下的语句:
exec sp_detach_db yourDBName,true --卸除这个DB在MSSQL中的注册信息
第三步:
到日志的物理文件所在的目录中去删除该日志文件或者将该日志文件移出该目录
第四步:
在Query Analyzer中执行如下的语句:
exec sp_attach_single_file_db yourDBName,'d:mssql7datayourDBName_data.mdf'
--以单文件的方式注册该DB,如果成功则MSSQL将自动为这个DB生成一个500K的日志文件。
以上方法在清除log日志中均有效。
但,能否让sql server 不产生log日志呢?以上方法好像均无效。
 
我这儿正好有个case:
我客户的sql server每天都会产生4,500M的log日志,每天都清除一下,非常不便。有没有办法实现不产生log日志呢?
我分析了一下客户产生log日志的原因,并且做了相应测试。
客户是每天将数据库清空,从总系统中将数据导入到sql server里。我感决sqlserver在插入时产生log不大,在delete整个库时产生log极大。
比如:
SELECT * into test_2 from b_bgxx
共45000条记录,产生十几M log,如果
delete from test_2
产生80多M log ,这明显存在问题。
虽然可以换成:
truncate table test_2
但我还是希望能找到不产生log的方法。就如oracle不产生归档一样。

阅读全文

sql server平台用存储过程进行分页的两种方法

killergo的专栏
最近因为稍微有点空闲时间,所以想了下在sql server平台用存储过程的分页方式,现在列示在下面。
实际测试时,在15000条数据情况下两者性能大体相当,在20000-30000条数据的情况下前者明显比后者性能更佳。更大数据量没有进行测试了。
注意,数据表里面是否有 键和索引 对性能的影响相当大
-----------------------------------------------------
第一种:
/*第一个参数是每页条数,第二个参数是目标页码*/
CREATE proc sp_fixpage @pagesize int,@destpage int as
set nocount on
declare @id int
declare @startid int
select @startid = (@destpage - 1)*@pagesize
set rowcount @startid
select @id = id from t_member
set rowcount @pagesize
set nocount off
select * from t_member where id > @id order by id
GO
第二种:
CREATE PROCEDURE sp_fixpage1 @pagesize int ,@destpage int
as
set nocount on

CREATE TABLE #myTable(
[ID] [int] NOT NULL ,
[UserName] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[Name] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[Origin] [int] NULL ,
[LatencyBuyDegree] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[UserType] [varchar] (2) COLLATE Chinese_PRC_CI_AS NULL ,
[Email] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[UserLev] [int] NULL ,
[RegTime] [datetime] NULL ,
[RegMode] [bit] NULL ,
[PaperNum] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[UserClass] [bit] NULL ,
[password] [binary] (64) NULL ,
[Tel] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[drass] [varchar] (150) COLLATE Chinese_PRC_CI_AS NULL ,
[Zip] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[PaperNumlb] [int] NULL ,
[OpUser] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[Province] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[BirthDate] [datetime] NULL
) ON [PRIMARY]
declare @tempPos int
declare @absPos int
declare @nowID int

阅读全文

SQL Server补丁版本的检查和安装过程中常见问题


一、SQL Server补丁版本的检查
SQL Server的补丁版本检查不如Windows 补丁版本检查直接,一个系统管理员,如果不了解SQL Server版本对应的补丁号,可能也会遇到一点麻烦,因此在这说明一下,通过这样的办法判别机器是安全的办法,不会对系统产生任何影响。
1、用Isql或者SQL查询分析器登录到SQL Server,如果是用Isql,请在cmd窗口输入isql -U sa,然后输入密码,进入;如果是用SQL查询分析器,请从程序中启动,输入sa和密码(也可以用windows验证)。
2、在ISQL中输入:
Select @@Version;
go
或者SQL查询分析器中输入(其实如果不想输入,只要打开帮助的关于就可以了:))
Select @@Version;
然后按执行;
这时会返回SQL的版本信息,如下:
Microsoft SQL Server 2000 - 8.00.760 (Intel X86) Dec 17 2002 14:22:05 Copyright (c) 1988-2003 Microsoft Corporation Enterprise Edition on Windows NT 5.0 (Build 2195: Service Pack 3)
其中的8.00.760就是SQL Server的版本和补丁号。对应关系如下:
8.00.194 -——————SQL Server 2000 RTM
8.00.384 -——————(SP1)
8.00.534 -——————(SP2)
8.00.760 -——————(SP3)
这样我们就能看到SQL Server的正确版本和补丁号了。
我们也可以用xp_msver看到更详细的信息。
二、补丁安装过程中常见问题
如果在安装补丁的时候遇到如下类似错误:
1、安装过程中出现“以前进行的程序创建了挂起的文件操作,运行安装程序前,必须重新启动”,请按照下面步骤解决:
a、重启机器,再进行安装,如果发现还有该错误,请按下面步骤
b、在开始->运行中输入regedit
c、到HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession Manager 位置
d、选择文件->倒出,保存
e、在右边窗口右击PendingFileRenameOperations,选择删除,然后确认
f、重启安装,问题解决
如果还有同样问题,请检查其它注册表中是否有该值存在,如有请删掉。

2、在安装SQL Server SP3,有时候会出现:无论用windows认证还是混和认证,都出现密码错误的情况,这时查看临时目录下的sqlsp.out,会发现以下描述:
[TCP/IP Sockets]Specified SQL server not found.
[TCP/IP Sockets]ConnectionOpen (Connect()).

阅读全文

SQL高手篇:精妙SQL语句介绍

说明:复制表(只复制结构,源表名:a 新表名:b)
  SQL: select * into b from a where 1<>1   
  说明:拷贝表(拷贝数据,源表名:a 目标表名:b)
  SQL: insert into b(a, b, c) select d,e,f from b;   
  说明:显示文章、提交人和最后回复时间
  SQL: select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b  
  说明:外连接查询(表名1:a 表名2:b)
  SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c   
  说明:日程安排提前五分钟提醒
  SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())>5   
  说明:两张关联表,删除主表中已经在副表中没有的信息
  SQL:
  delete from info where not exists ( select * from infobz where info.infid=infobz.infid )   
  说明:--
  SQL:
  SELECT A.NUM, A.NAME, B.UPD_DATE, B.PREV_UPD_DATE FROM TABLE1,(SELECT X.NUM, X.UPD_DATE, Y.UPD_DATE PREV_UPD_DATE FROM (SELECT NUM, UPD_DATE, INBOUND_QTY, STOCK_ONHAND FROM TABLE2 WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = TO_CHAR(SYSDATE, 'YYYY/MM')) X, (SELECT NUM, UPD_DATE, STOCK_ONHAND FROM TABLE2 WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = TO_CHAR(TO_DATE(TO_CHAR(SYSDATE, 'YYYY/MM') &brvbar;&brvbar; '/01','YYYY/MM/DD') - 1, 'YYYY/MM') ) Y, WHERE X.NUM = Y.NUM ( )AND X.INBOUND_QTY NVL(Y.STOCK_ONHAND,0) <> X.STOCK_ONHAND ) B WHERE A.NUM = B.NUM   
  说明:--
  SQL:
  select * from studentinfo where not exists(select * from student where studentinfo.id=student.id) and 系名称='"&strdepartmentname&"' and 专业名称='"&strprofessionname&"' order by 性别,生源地,高考总成绩

阅读全文

Sql server数据库备份还原另一方法

直接拷贝数据文件把数据库的数据文件(*.mdf)和日志文件(*.ldf)都拷贝到目的服务器,在SQL Server Query Analyzer中用语句进行恢复: EXEC sp_attach_db @dbname = 'test', @filename1 = 'd:mssql7data est_data.mdf', @filename2 = 'd:mssql7data est_log.ldf' 这样就把test数据库附加到SQL Server中,可以照常使用。如果不想用原来的日志文件,可以用如下的命令: EXEC sp_detach_db @dbname = 'test' EXEC sp_attach_single_file_db @dbname = 'test', @physname = 'd:mssql7data est_data.mdf' 这个语句的作用是仅仅加载数据文件,日志文件可以由SQL Server数据库自动添加,但是原来的日志文件中记录的数据就丢失了。

阅读全文

ACCESS改为SQL需要注意哪几个地方

看到别人有时问这个方面的问题。。于是在各网站总结前前辈高人的几点想法,拿来共享:
数据库导入以后,自动增加字段需要重写,所有的数字类型需要增加长度,最好用decimal。
所有的默认值都丢失了。主要是数字类型和日期类型。
所有now(),time(),date()要改成getdate()。
所有datediff('d', time1, time2)要改成datediff(day, time1, time2)
有可能一些true/false类型不能使用,要变为1/0。
备注类型要通过cast(column as varchar)来使用。
CursorType要改成1,也就是打开数据库时要给出第一个数字参数为1,否则记录可能显示不完整。
isnull(rowname)要改成rowname = null
ACCESS的数据库中的自动编号类型在转化时,sql server并没有将它设为自动编号型,我们需在SQL创建语句中加上identity,表示自动编号!
转化时,跟日期有关的字段,SQL SERVER默认为smalldatetime型,我们最好将它变为datetime型,因为datetime型的范围比smalldatetime型大。有时用smalldatetime型时,转化失败,而用datetime型时,转化成功。
对此两种数据库进行操作的sql语句不全相同,例如:在对ACCESS数据库进行删除纪录时用:"delete * from user where id=10",而对SQL SERVER数据库进行删除是用:"delete user where id=10".
日期函数不相同,在对ACCESS数据库处理中,可用date()、time()等函数,但对SQL SERVER数据库处理中,只能用datediff,dateadd等函数,而不能用date()、time()等函数。
在对ACCESS数据库处理中,sql语句中直接可以用一些VB的函数,像cstr()函数,而对SQL SERVER数据库处理中,却不能用。

阅读全文