您的位置:首页 > 数据库

20100811 学习记录:数据库相关的自动编号& update

2010-08-12 08:05 656 查看
1.

set nocount on作用

MSDN解释:

阻止在结果集中返回可显示受 Transact-SQL 语句或存储过程影响的行计数的消息。

Stops the message that shows the count of the number of rows affected by a Transact-SQL statement or stored procedure from being returned as part of the result set.


语法

SET NOCOUNT { ON | OFF }


注释

当 SET NOCOUNT 为 ON 时,不返回计数。当 SET NOCOUNT 为 OFF 时,返回计数。

即使当 SET NOCOUNT 为 ON 时,也更新 @@ROWCOUNT 函数。

当 SET NOCOUNT 为 ON 时,将不向客户端发送存储过程中每个语句的 DONE_IN_PROC 消息。如果存储过程中包含一些并不返回许多实际数据的语句,或者如果过程包含 Transact-SQL 循环,网络通信流量便会大量减少,因此,将 SET NOCOUNT 设置为 ON 可显著提高性能。

SET NOCOUNT 指定的设置是在执行或运行时生效,而不是在分析时生效。

触发器使得表和跨数据库之间数据的自动同步行为变得简单。但是,那些一眼看上去不是很明显的东西却会对它们的性能造成显著的影响。这里我将描述一个命令,它可用来减少一些不可预料的问题产生的影响 。

  以反复被触发的INSERT触发器为例,尤其是当使用INSERT INTO语句用来进行大量插入操作时。在语句执行的过程中,当触发器一遍又一遍的被激发的情况下,触发器将会对每个INSERT动作发布DONE_IN_PROC消息,这会使速度明显下降。

  尤其是当触发器作为一个预定了时间的SQL Server Agent工作的结果而被触发时,这个速度的减慢是特别明显的 。SQL Server Agent自动在每个DONE_IN_PROC 信号后强加一个延迟,以避免服务器拥塞 。如果你想通过查询分析器来运行同样的一组命令,由于没有强加这样的延迟,它的执行将会快得多。如果你通过查询分析器运行这样的查询并且查看多个语句产生 的多个"n rows affected",那么很有可能查询会被反复执行,并且触发器也被重新触发多次,这比它实际需要的次数要多很多。

  要关掉DONE_IN_PROC消息,可以在触发器语句的开始用SET NOCOUNT ON命令。大多数时候,以任何方式对行进行计数都是不需要的。如果确实需要,你可以考虑重新构造命令来触发触发器(或者是触发器本身),这样就使所有的改 变作为一个命令完成。如果这个进程仍然花了很长时间,为了简单起见,你应该重新想一个方法来激发触发器。

2.sql查询时增加自动编号

a)在查出结果后存储的结果集里面自己定义一列,循环做出序号。

<ItemTemplate> <%# Container.DataSetIndex + 1 %> </ItemTemplate>

b)建立临时表

use northwind

select identity(int,1,1) as [序号],employees.FirstName as [员工名称] into #a from employees

select * from #a

drop table #a

不能直接select identity(int,1,1) 要 into 所以借用临时表
http://topic.csdn.net/t/20050205/10/3776790.html
c)查询时加序号

没有主键的情形:

Select identity(int,1,1) as iid,* into #tmp from TableName

Select * from #tmp

Drop table #tmp

有主键的情形:

Select (Select sum(1) from TableName where KeyField <= a.KeyField) as iid,* from TableName a

eg:

select (select sum(1) from user_Admin where id<=a.id) as ID,id,displayName from user_Admin a order by a.ID asc

结果:



------------------------------------------------------------

USE 北风贸易;

GO

/* 方法一*/

SELECT 序号= (SELECT COUNT(客户编号) FROM 客户 AS LiMing

WHERE LiMing.客户编号<= Chang.客户编号),

客户编号, 公司名称

FROM 客户 AS Chang ORDER BY 1;

GO

/* 方法二: 使用SQL Server 2005 独有的RANK() OVER () 语法*/

SELECT RANK() OVER (ORDER BY 客户编号 DESC) AS 序号,

客户编号, 公司名称

FROM 客户;

GO

/* 方法三*/

SELECT 序号= COUNT(*), LiMing.客户编号, LiMing.公司名称

FROM 客户 AS LiMing, 客户AS Chang

WHERE LiMing.客户编号>= Chang.客户编号

GROUP BY LiMing.客户编号, LiMing.公司名称

ORDER BY 序号;

GO

/* 方法四

建立一个「自动编号」的字段,然后将数据新增至一个区域性暂存数据表,

然后由该区域性暂存数据表中,将数据选取出来,最后删除该区域性暂存数据表

*/

SELECT 序号= IDENTITY(INT,1,1), 管道, 程序语言, 讲师, 资历

INTO #LiMing

FROM 问券调查一;

GO

SELECT * FROM #LiMing;

GO

DROP TABLE #LiMing;

GO

/*

方法五

使用 SQL Server 2005 独有的ROW_NUMBER() OVER () 语法

搭配 CTE (一般数据表表达式,就是 WITH 那段语法)选取序号2 ~ 4 的数据

*/

WITH 排序后的图书 AS

(SELECT ROW_NUMBER() OVER (ORDER BY 客户编号 DESC) AS 序号,

客户编号, 公司名称

FROM 客户)

SELECT * FROM 排序后的图书

WHERE 序号 BETWEEN 2 AND 4;

GO

------------分页使用---------------------------

SELECT RANK() OVER (ORDER BY id asc) AS no,* into #temp

FROM Bbs_reply select * from #temp where no between 1 and 100 drop table #temp

from: http://hi.baidu.com/wenjunlin/blog/item/fd85c101258881dd277fb5cc.html
d)asp.net中显示DataGrid控件列序号的几种方法

asp.net中显示DataGrid控件列序号的几种方法

作者:郑佐 2004-9-10

在aps.net中多数据绑定的控件很多,论功能来说,应该属DataGrid最为齐全,但它没有提供现成的显示记录序号的功能,不过我们可以通过它所带的一些参数来间接得到序号,下面来看看怎样得到和显示序号值计算方式如下:

(1)在后台

DataGrid.CurrentPageIndex * DataGrid.PageSize + e.Item.ItemIndex + 1

(2)在前台

DataGrid1.CurrentPageIndex * DataGrid1.PageSize + Container.ItemIndex + 1

说明:

e表示System.Web.UI.WebControls.DataGridItemEventArgs参数类的实例;

DataGrid1这里表示前台的一个实例;

DataGrid.CurrentPageIndex:获取或设置当前显示页的索引;

DataGrid.PageSize :获取或设置要在 DataGrid 控件的单页上显示的项数。

下面我使用了4种方法来在前台显示序号,不过都是围绕上面的计算式展开。

(1) 使用DataGrid的ItemCreated设置值,而前台的单元格可以是绑定列或者模板列(包括空模板);

(2) 使用DataGrid的ItemDataBound设置值,而前台的单元格可以是绑定列或者模板列(包括空模板);

(3) 在前台直接绑定计算表达式;

(4) 在后台类中编写方法计算表达式由前台页面类继承调用。

备注:在数据库中获取数据时设置额外的序号列这里不做讨论,我认为这是最糟糕的实现方法。

下面以获取Northwind数据库的Customers表的数据为列,显示如下:



下面是WebFormPaging.aspx文件代码,

<%@ Page language="c#" Codebehind="WebFormPaging.aspx.cs" AutoEventWireup="false" Inherits="AspnetPaging.WebForm1" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

<HTML>

<HEAD>

<title>WebForm1</title>

<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">

<meta content="C#" name="CODE_LANGUAGE">

<meta content="JavaScript" name="vs_defaultClientScript">

<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">

</HEAD>

<body>

<form id="Form1" method="post" runat="server">

<TABLE id="Table1" cellSpacing="1" cellPadding="1" width="400" align="center" border="1">

<TR>

<TD><asp:datagrid id="DataGrid1" runat="server" AutoGenerateColumns="False" Width="100%" AllowPaging="True">

<Columns>

<asp:BoundColumn HeaderText="序号1"></asp:BoundColumn>

<asp:TemplateColumn HeaderText="序号2"></asp:TemplateColumn>

<asp:TemplateColumn HeaderText="序号3">

<ItemTemplate>

<asp:Label ID="itemIndex" runat="server"></asp:Label>

</ItemTemplate>

</asp:TemplateColumn>

<asp:TemplateColumn HeaderText="序号4">

<ItemTemplate>

<%# (DataGrid1.CurrentPageIndex * DataGrid1.PageSize + Container.ItemIndex + 1) %>

</ItemTemplate>

</asp:TemplateColumn>

<asp:TemplateColumn HeaderText="序号5">

<ItemTemplate>

<%# GetRecordIndex( Container.ItemIndex ) %>

</ItemTemplate>

</asp:TemplateColumn>

<asp:BoundColumn DataField="CustomerID" HeaderText="CustomerID"></asp:BoundColumn>

</Columns>

<PagerStyle Mode="NumericPages"></PagerStyle>

</asp:datagrid></TD>

</TR>

<TR>

<TD></TD>

</TR>

<TR>

<TD></TD>

</TR>

</TABLE>

</form>

</body>

</HTML>

后台WebFormPaging.aspx.cs代码如下:

using System;

using System.Collections;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Web;

using System.Web.SessionState;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.HtmlControls;

namespace AspnetPaging

{

public class WebForm1 : System.Web.UI.Page

{

private int recordCount = 0;

protected System.Web.UI.WebControls.DataGrid DataGrid1;

private void Page_Load(object sender, System.EventArgs e)

{

if(!Page.IsPostBack)

{

DataGridDataBind();

}

}

//绑定数据

private void DataGridDataBind()

{

DataSet ds = DataAccess.GetCustomersData();

this.DataGrid1.DataSource = ds;

this.DataGrid1.DataBind();

}

#region Web 窗体设计器生成的代码

override protected void OnInit(EventArgs e)

{

InitializeComponent();

base.OnInit(e);

}

/// <summary>

/// 设计器支持所需的方法 - 不要使用代码编辑器修改

/// 此方法的内容。

/// </summary>

private void InitializeComponent()

{

this.DataGrid1.ItemCreated += new System.Web.UI.WebControls.DataGridItemEventHandler(this.DataGrid1_ItemCreated);

this.DataGrid1.PageIndexChanged += new System.Web.UI.WebControls.DataGridPageChangedEventHandler(this.DataGrid1_PageIndexChanged);

this.DataGrid1.ItemDataBound += new System.Web.UI.WebControls.DataGridItemEventHandler(this.DataGrid1_ItemDataBound);

this.Load += new System.EventHandler(this.Page_Load);

}

#endregion

//翻页

private void DataGrid1_PageIndexChanged(object source, System.Web.UI.WebControls.DataGridPageChangedEventArgs e)

{

DataGrid1.CurrentPageIndex = e.NewPageIndex;

DataGridDataBind();

}

//获取当前项

protected int GetRecordIndex(int itemIndex)

{

return (DataGrid1.CurrentPageIndex * DataGrid1.PageSize + itemIndex + 1);

}

private void DataGrid1_ItemCreated(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)

{

DataGrid dg = (DataGrid)sender;

if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)

{

e.Item.Cells[0].Text = (dg.CurrentPageIndex * dg.PageSize + e.Item.ItemIndex + 1).ToString();

e.Item.Cells[1].Text = (dg.CurrentPageIndex * dg.PageSize + e.Item.ItemIndex + 1).ToString();

}

}

private void DataGrid1_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)

{

DataGrid dg = (DataGrid)sender;

if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)

{

((Label)e.Item.FindControl("itemIndex")).Text = (dg.CurrentPageIndex * dg.PageSize + e.Item.ItemIndex + 1).ToString();

}

}

}

}

数据层代码如下:

using System;

using System.Data;

using System.Data.SqlClient;

using System.Configuration;

namespace AspnetPaging

{

public class DataAccess

{

private static string connString = ConfigurationSettings.AppSettings["ConnString"];

private DataAccess()

{

}

public static DataSet GetCustomersData()

{

SqlConnection conn = new SqlConnection(connString);

SqlCommand comm = new SqlCommand("GetCustomers",conn);

comm.CommandType = CommandType.StoredProcedure;

SqlDataAdapter dataAdapter = new SqlDataAdapter(comm);

DataSet ds = new DataSet();

dataAdapter.Fill(ds);

return ds;

}

}

}

总结,上面的四种方法前两种其实处理起来是一样的,只是处理的时间不同而已;对于第三种我认为最简单,直接在前台页面绑定,不需要额外的辅助;对于第四种的方法绑定到前台我认为最为灵活,需要注意的是GetRecordIndex方法需要protected或public,使它的继承类能访问的到。

http://blog.csdn.net/zhzuo/archive/2004/09/10/100882.aspx

3. 使用一条UPDATE语句更新多个字段,语法如下所示:

update table_name
set column1 = 'value',
[colunmn2 = 'value',]
[colunmn3 = 'value',]
[where condition]

注意其中使用的SET 这里只有一个SET,但是有多个列,每个列之间以逗号分隔

可以看出SQL里的一种趋势:通常使用逗号来分隔不同类型的参数。下面的代码使用逗号分隔要更新的两列。同样,WHERE子句是可选的,但通常是必要的。

update orders_tbl
set qty = 1,
cust_id = '221'
where ord_num = '23A16';

1 row updated.

注意:在每个UPDATE语句里,关键字SET只使用一次。如果需要一次更新多个字段,就使用逗号来分隔他们。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: