posts - 17, comments - 12, trackbacks - 0, articles - 23
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

2010年1月18日

1. 在Northwind数据库上建立一个视图 VOrders

代码
SET NOCOUNT ON;
USE Northwind;
GO

IF OBJECT_ID('dbo.VOrders'IS NOT NULL
  
DROP VIEW dbo.VOrders;
GO
CREATE VIEW dbo.VOrders
AS

SELECT O.OrderID, O.OrderDate, O.CustomerID, O.EmployeeID, O.ShipVia,
  
SUM(OD.Quantity) AS Qty,
  
CAST(SUM(OD.Quantity * UnitPrice * (1 - Discount)) AS DECIMAL(122)) AS Value 
FROM dbo.Orders AS O
  
JOIN [Order Details] AS OD
    
ON O.OrderID = OD.OrderID
GROUP BY O.OrderID, O.OrderDate, O.CustomerID, O.EmployeeID, O.ShipVia
GO

 
2. 计算整个表中数据的中位值 (MSSQL 2000的做法)

代码
SELECT
(
 (
SELECT MAX(Value) FROM
   (
SELECT TOP 50 PERCENT Value FROM dbo.VOrders ORDER BY Value) AS H1)
 
+
 (
SELECT MIN(Value) FROM
   (
SELECT TOP 50 PERCENT Value FROM dbo.VOrders ORDER BY Value DESCAS H2)
/ 2 AS Median;

 


3. 用子查询来查询每个员工的中位值(MSSQL 2000的做法)

代码
SELECT EmployeeID,
(
 (
SELECT MAX(Value) FROM
   (
SELECT TOP 50 PERCENT Value FROM dbo.VOrders AS O1
    
WHERE O1.EmployeeID = E.EmployeeID
    
ORDER BY Value) AS H1)
 
+
 (
SELECT MIN(Value) FROM
   (
SELECT TOP 50 PERCENT Value FROM dbo.VOrders AS O2
    
WHERE O2.EmployeeID = E.EmployeeID
    
ORDER BY Value DESCAS H2)
/ 2 AS Median
FROM dbo.Employees AS E;

 


4.1 SQL 2005的做法,首先我们看看用来计算中位值的行的数据,这里用到了通用表(CTE)和Row_Number函数

代码
WITH OrdersRN AS
(
  
SELECT EmployeeID, Value,
    ROW_NUMBER() 
OVER(PARTITION BY EmployeeID ORDER BY Value) AS RowNum,
    
COUNT(*OVER(PARTITION BY EmployeeID) AS Cnt
  
FROM dbo.VOrders
)
SELECT EmployeeID, Value, RowNum, Cnt
FROM OrdersRN
WHERE RowNum IN((Cnt + 1/ 2, (Cnt + 2/ 2);

 


4.2 SQL 2005中,用通用表和Row_Number函数来计算中位值

 

代码
WITH OrdersRN AS
(
  
SELECT EmployeeID, Value,
    ROW_NUMBER() 
OVER(PARTITION BY EmployeeID ORDER BY Value) AS RowNum,
    
COUNT(*OVER(PARTITION BY EmployeeID) AS Cnt
  
FROM dbo.VOrders
)
SELECT EmployeeID, AVG(Value) AS Median
FROM OrdersRN
WHERE RowNum IN((Cnt + 1/ 2, (Cnt + 2/ 2)
GROUP BY EmployeeID;

 

 

关键词:中位值,中位值计算,Median,CTE,Row_Number

posted @ 2010-01-18 17:07 挖土. 阅读(3) | 评论 (0)编辑

2010年1月5日

一个简单的方法就可以调出调整Windows 7系统的全功能控制面板,这一小技巧可以让你从鼠标调整到硬盘分区,启动“上帝模式”非常简单,只要建立一个文件夹,然后将它命名为GodMode.{ED7BA470-8E54-465E-825C-99712043E01C},上帝就出现了,微软并没有解释GodMode的用途,但它应该类似于游戏秘笈show me the money的作用,去试试看吧。

posted @ 2010-01-05 10:21 挖土. 阅读(5) | 评论 (0)编辑

2009年1月22日

     摘要: 这是一个使用序列化和反序列化的详细例子来操作复杂的XML数据,其中还举例数组和List的使用方法和区别。[代码]  阅读全文

posted @ 2009-01-22 00:26 挖土. 阅读(268) | 评论 (0)编辑

2009年1月8日

http://www.sqlservercentral.com/articles/Stored+Procedures/2977/

By Jacob Sebastian, 2007/05/30
Translated by 挖土(Digjim),2009年1月9日, http://digjim.cnblogs.com/

 

介绍

我们大部分人都会遇到特殊的情况去设计可重用、可管理的数据库对象(存储过程,函数,试图等),当一个应用程序很大的时候尤为重要。通用的功能性代码需要可识别,并在定义成函数以后能被程序的不同部分调用。试图、存储过程也是这样。按照这样的方式设计出来的代码提高了可管理性,又极大的提高了可重用性,当然也提高了生产率,减少了错误。

问题

让我们假设,我们在做一个库存管理系统。当一个交易(销售订购,发货,收获,库存调整等)发生,我们需要根据交易来调整相应商品的库存量。我们已经有针对每一个交易的存储过程来保存或更新数据,所有这些存储过程都要去更新相应商品的库存量。

既然库存量需要在不同的地方被更新,那么把这一部分单独拿出来做成一个存储过程就非常有必要了。这样这个存储过程就可以在任何需要更新库存量的地方被调用。这个看上去很简单,但是困难的部分是我们要一次更新多个商品的库存量。

表变量似乎是一个好主意。如果我们可以传输一个包含商品更新信息的表变量,那么可以极大地减少复杂度。但是SQL Server不允许给存储过程传输表变量。那我们怎么办呢?

在这里,我想尝试提供一种通过使用XML来传输一个表到存储过程的解决方法。调用者可以把一个表中的数据转换成XML变量来传输给存储过程。被调用者可以把XML变量转换成表或直接用XQuery来查询数据。

调用者

调用者需要把一个表数据转换成XML变量,数据可能来源于一个表(Table)或查询(Query),下面是一个把查询出来的数据转换成XML变量的例子。

    1 /*

    2     先建一个示例表.

    3 */

    4 

    5 CREATE TABLE [dbo].[OrderDetails](

    6     [OrderDetailID] [int] IDENTITY(1,1) NOT NULL,

    7     [ItemNumber] [varchar](20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,

    8     [Qty] [int] NULL

    9 ) ON [PRIMARY]

   10 

   11 /*

   12     加入一些样例数据

   13 */

   14 INSERT INTO OrderDetails(ItemNumber, Qty)

   15     SELECT 'A001', 10

   16     UNION SELECT 'A002', 20

   17     UNION SELECT 'A003', 30

   18 /*

   19     下面的查询以XML的格式返回查询结果.

   20 */

   21 

   22 SELECT ItemNumber, Qty FROM OrderDetails FOR XML RAW('item'), ROOT('items')

   23 

   24 /*

   25 OUTPUT:

   26 

   27 <items>

   28   <item ItemNumber="A001" Qty="10" />

   29   <item ItemNumber="A002" Qty="20" />

   30   <item ItemNumber="A003" Qty="30" />

   31 </items>

   32 */


 

下面,把查询结果赋给一个XML变量。

    1 -- 定义变量

    2 DECLARE @x XML

    3 

    4 -- 把查询结果保存到XML变量中

    5 SET @x = (SELECT ItemNumber, Qty FROM OrderDetails FOR XML RAW('item'), ROOT('items'), TYPE)

    6 

    7 -- 从XML变量中查询数据(验证一下,我们是不是作对了)

    8 SELECT

    9     x.item.value('@ItemNumber[1]', 'VARCHAR(20)') AS ItemNumber,

   10     x.item.value('@Qty[1]', 'INT') AS Qty

   11 FROM @x.nodes('//items/item') AS x(item)

 

 

这个阶段,我们准备好了一个XML变量,它可以被传到子存储过程或函数中。这个XML变量中包含了我们需要子存储过程或函数来帮我们执行或更新的数据。子存储过程既可以把这个XML变量转换成一个表,也可以直接从XMl变量了都数据。


被调用者

到目前为止,我们看到了怎么样把一个查询结果转换成XML变量。这个XML变量可以传输给根据货物信息来更新货物库存量的存储过程。最简单的方法就是把这个XML里的数据包装成一个试图,然后把他当作一个表来使用。

我们再建另一个表,库存量表,他将被XML传输过来的数据库更新。用下面的脚本来创建这个示例表和数据。 

    1 CREATE TABLE [dbo].[Inventory](

    2     [InventoryID] [int] IDENTITY(1,1) NOT NULL,

    3     [ItemNumber] [varchar](20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,

    4     [Stock] [int] NULL

    5 ) ON [PRIMARY]

    6 

    7 INSERT INTO Inventory (ItemNumber, Stock)

    8     SELECT 'A001', 0

    9     UNION SELECT 'A002', 0

   10     UNION SELECT 'A003', 0

 

下面是被调用者这边需要实现的设计。 

    1 CREATE PROCEDURE [dbo].[UpdateInventory1]

    2 (

    3     @x XML

    4 )

    5 AS

    6 

    7 SET NOCOUNT ON

    8 

    9 /*

   10     下面的代码把XML的数据包装成一个视图

   11     然后更新库存量表"inventory".

   12 */

   13 

   14 UPDATE Inventory SET

   15     stock = stock + v.Qty

   16 FROM Inventory inv

   17 INNER JOIN (

   18     SELECT

   19         x.item.value('@ItemNumber[1]','varchar(20)') AS ItemNumber,

   20         x.item.value('@Qty[1]','INT') AS Qty

   21     FROM @x.nodes('//items/item') AS x(item)

   22 ) v ON (v.ItemNumber = inv.ItemNumber)

   23 

   24 RETURN

 

执行
现在我们来执行这个存储过程,执行下面的代码。 

    1 -- 定义XML变量

    2 DECLARE @x XML

    3 

    4 -- 把结果保存在XML变量中

    5 SET @x = (SELECT ItemNumber, Qty FROM OrderDetails FOR XML RAW('item'), ROOT('items'), TYPE)

    6 

    7 -- 执行存储过程

    8 EXECUTE UpdateInventory1 @x

    9 

   10 -- 查看更新后的数据

   11 SELECT * FROM inventory

 

更新存储过程

上面这些脚本中,把XMl变量包装成视图。这是一个非常简单直接的方法。你也可以直接访问这些数据就像她直接来自一个表或着试图。在内部视图执行XML查询的复杂度就没有了。

下面的例子,给出了另外一种根据XML变量里的数据库来直接更新数据库的方法。

    1 CREATE PROCEDURE [dbo].[UpdateInventory2]

    2 (

    3     @x XML

    4 )

    5 AS

    6 

    7 SET NOCOUNT ON

    8 

    9 /*

   10     这个存储过程用的TSQL代码更少

   11     它根据XML里的数据来直接更新数据库,

   12     而不是把XMl数据转换成试图。

   13 */

   14 

   15 UPDATE Inventory SET

   16     stock = stock + x.item.value('@Qty[1]','INT')

   17 FROM Inventory inv

   18 INNER JOIN @x.nodes('//items/item') x(item) ON

   19     (x.item.value('@ItemNumber[1]','varchar(20)') = inv.ItemNumber)

   20 

   21 RETURN

 

总结
在过去几年里,我好几次碰到这样的情况,需要把一个表传入到存储过程或函数。但是SQL Server不允许把表变量传输给存储过程和函数,我就是用上面的这个方法来完成。当然可能有其他方法也能完成,但是这些方法都会要损失一点性能。我没有做打量的测试来验证是否有性能问题。到目前为止,我没有在我的应用程序中看到任何性能上的问题。

By Jacob Sebastian, 2007/05/30

http://www.cnblogs.com/stu-acer/archive/2008/01/23/1050722.html

 

posted @ 2009-01-08 22:43 挖土. 阅读(215) | 评论 (0)编辑

2008年9月24日

Sometime when you try to install VSIdeTestHost.msi, It will complain "Visual Studio must be installed". So please try this CMD to isntall it.

VSIdeTestHost.msi ADDINXMLDIR="%AllUsersProfile%\Application Data\Microsoft\MSEnvShared\Addins" VSINSTALLDIR="%VSPATH%" ISLAYOUTINSTALL=true

posted @ 2008-09-24 07:09 挖土. 阅读(17) | 评论 (0)编辑

2006年10月24日

posted @ 2006-10-24 23:20 挖土. 阅读(2226) | 评论 (0)编辑

2006年10月23日

     摘要: 你可以叫它DataDube,TeamData,VSTSDBP或者其他任何什么。这个新的Visual Studio工具为你控制的工程的数据库开发阶段指明了正确方向。当然,我知道你的数据库开发已经在控制之中,你的开发者已经创建了所有需要的数据库对象:表,索引,自定义函数,存储过程等等,而且运行得很好,你也确实不需要其它任何的工具了。这些正是我在开始用这个Visual Studio的新工具之前的想法。对...  阅读全文

posted @ 2006-10-23 23:03 挖土. 阅读(1670) | 评论 (7)编辑

2006年9月27日

     摘要: 1、查看当前数据库的状态 SELECT DATABASEPROPERTY ('pubs','IsFulltextEnabled')2、打开FullText功能 sp_fulltext_databse 'enable' 关闭此功能sp_fulltext_databse 'disable'3、建立一个Unique的Index。在Modify Table界面中,鼠标右键,选择Index/Keys...在...  阅读全文

posted @ 2006-09-27 21:24 挖土. 阅读(2204) | 评论 (2)编辑

2006年9月20日

posted @ 2006-09-20 11:24 挖土. 阅读(8866) | 评论 (2)编辑

2006年7月26日

     摘要: declare @t table(表名 varchar(100),字段名 varchar(100),数据类型 varchar(100),长度 varchar(100),描述 sql_variant )declare @table varchar(100),@counter int,@tablecount int,@talben varchar(100),@a varchar(100),@b var...  阅读全文

posted @ 2006-07-26 11:12 挖土. 阅读(428) | 评论 (0)编辑