EXEC()执行Transact-SQL批处理问题

williamxiao 2009-11-26 03:14:26
SQL批处理如下:

DECLARE @OAID varchar(5)--声明流程ID变量
--1.获得OAID
DECLARE @tbid varchar(5)--声明数据流表名中的ID
SET @tbid=20
DECLARE @condition nvarchar(100)--声明流程查询条件
SET @condition='%abc%'
DECLARE @sql nvarchar(1000)--声明sql查询语句
SET @sql='SELECT @OAID=OAID FROM OA_FLOW_'+@tbid+'_Main WHERE FileTile LIKE '''+@condition+''''
print '执行的SQL语句:'+@sql
EXEC(@sql)--执行查询
print '获得的OAID:'+@OAID

错误如下:

执行的SQL语句:SELECT @OAID=OAID FROM OA_FLOW_20_Main WHERE FileTile LIKE '%abc%'
服务器: 消息 137,级别 15,状态 1,行 1
必须声明变量 '@OAID'。

问,批处理中已经声明了@OAID局部变量,为啥会有有错呢?
...全文
126 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
bancxc 2009-11-26
  • 打赏
  • 举报
回复
恩 应该用sp_executesql
williamxiao 2009-11-26
  • 打赏
  • 举报
回复
也可以写成如下方式(容易理解点):

DECLARE @OAID varchar(5)--声明流程ID变量
--1.获得OAID
DECLARE @tbid varchar(5)--声明数据流表名中的ID
SET @tbid=20
DECLARE @condition nvarchar(100)--声明流程查询条件
SET @condition='%标准文本合同审批单(王珏, 2009-11-18 14:11)%'
DECLARE @sql nvarchar(1000)--声明sql查询语句
SET @sql='SELECT @OAID=OAID FROM OA_FLOW_'+@tbid+'_Main WHERE FileTile LIKE @condition'
--执行查询
EXEC sp_executesql
@stmt=@sql,
@params=N'@OAID varchar(5) OUTPUT,@condition nvarchar(100)',
@OAID=@OAID OUTPUT,@condition=@condition;
print '获得的OAID:'+@OAID
williamxiao 2009-11-26
  • 打赏
  • 举报
回复
解决了,谢谢icelovey.
解决后的SQL批处理如下:

DECLARE @OAID varchar(5)--声明流程ID变量
--1.获得OAID
DECLARE @tbid varchar(5)--声明数据流表名中的ID
SET @tbid=20
DECLARE @condition nvarchar(100)--声明流程查询条件
SET @condition='%abc%'
DECLARE @sql nvarchar(1000)--声明sql查询语句
SET @sql='SELECT @OAID=OAID FROM OA_FLOW_'+@tbid+'_Main WHERE FileTile LIKE @condition'
--执行查询
EXEC sp_executesql
@sql,
N'@OAID varchar(5) OUTPUT,@condition nvarchar(100)',
@OAID OUTPUT,@condition;
print '获得的OAID:'+@OAID

结果如下:

获得的OAID:1518

参考的资料如下:
1.Exec和sp_executesql的用法区别:http://lqingtao.blog.163.com/blog/static/34192802008111711476947/
2.Transact-SQL 参考 sp_executesql:http://www.yesky.com/imagesnew/software/tsql/ts_sp_ea-ez_2h7w.htm
icelovey 2009-11-26
  • 打赏
  • 举报
回复
2.sq_executesql
a.提供了很强大的借口--避免了串联变量的问题还可以输出LOOK
DECLARE @i AS INT;
SET @i = 10248;

DECLARE @sql AS NVARCHAR(46);
SET @sql = 'SELECT * FROM dbo.Orders WHERE OrderID = @oid;';
-----请注意,上面的@oid就不要在转化成字符串联进去了直接上直接上直接上
EXEC sp_executesql
@stmt = @sql,--这个相当存储过程一个查询主体,就是AS后面的东西
@params = N'@oid AS INT',--这个相当于存储过程的传入参数声明,就是AS前面的东西
@oid = @i;--这里相当于你调用存储过程的时候后面那个参数列表
------这里如果你给@id赋值三个不同的值10348 10349 10897 它为此产生的执行计划只有一个哦~只有一个不是三个!!!节约成本

b.它可以通过传入的参数检查,用来防止SQL注入.
我的理解就是通过传入的参数的长度类型之类的进行判断吧.
icelovey 2009-11-26
  • 打赏
  • 举报
回复
要返回参数的话用这个sp_executesql好点吧
williamxiao 2009-11-26
  • 打赏
  • 举报
回复

SET @sql='SELECT '+@OAID+'=OAID FROM OA_FLOW_'+@tbid+'_Main WHERE FileTile LIKE '''+@condition+''''

这种方法不对,print '获得的OAID:'+@OAID没有结果,空白.
午夜还在张 2009-11-26
  • 打赏
  • 举报
回复
经典
liguoqiang4888 2009-11-26
  • 打赏
  • 举报
回复
DECLARE @OAID varchar(5)--声明流程ID变量
--1.获得OAID
DECLARE @tbid varchar(5)--声明数据流表名中的ID
SET @tbid=20
DECLARE @condition nvarchar(100)--声明流程查询条件
SET @condition='%abc%'
DECLARE @sql nvarchar(1000)--声明sql查询语句
SET @sql='SELECT '+@OAID+'=OAID FROM OA_FLOW_'+@tbid+'_Main WHERE FileTile LIKE '''+@condition+''''
print '执行的SQL语句:'+@sql
EXEC(@sql)--执行查询
print '获得的OAID:'+@OAID
--小F-- 2009-11-26
  • 打赏
  • 举报
回复
SET @sql='SELECT '+@OAID+'=OAID FROM OA_FLOW_'+@tbid+'_Main WHERE FileTile LIKE '''+@condition+'''' 
print '执行的SQL语句:'+@sql
EXEC(@sql)--执行查询
print '获得的OAID:'+@OAID
you_tube 2009-11-26
  • 打赏
  • 举报
回复
sp_executesql
华夏小卒 2009-11-26
  • 打赏
  • 举报
回复

SET @sql='SELECT '+@OAID+'=OAID FROM OA_FLOW_'+@tbid+'_Main WHERE FileTile LIKE '''+@condition+''''
print '执行的SQL语句:'+@sql
EXEC(@sql)--执行查询
print '获得的OAID:'+@OAID


SQL Server 中 EXEC 与 SP_EXECUTESQL 的区别 MSSQL为我们提供了两种动态执行SQL语句的命令,分别是 EXEC 和 SP_EXECUTESQL ,我们先来看一下两种方式的用法。 先建立一个表,并添加一些数据来进行演示: 复制代码 CREATE TABLE t_student( Id INT NOT NULL, Name NVARCHAR (10) NULL, Age TINYINT NULL, School NVARCHAR(20) NULL, Class NVARCHAR(10) NULL, Score FLOAT NULL, CONSTRAINT [PK_Student_Id] PRIMARY KEY CLUSTERED(Id) ) GO INSERT INTO t_student VALUES(1,'张小红',8,'育才小学','一班',92) INSERT INTO t_student VALUES(2,'王丽丽',8,'育才小学','一班',90) INSERT INTO t_student VALUES(3,'张燕',7,'云华小学','二班',86) INSERT INTO t_student VALUES(4,'刘华',6,'云华小学','二班',85) 复制代码 一、EXEC EXEC命令可以执行一个存储过程也可以执行一个动态SQL语句。先来看看怎么执行存储过程: 新建一个存储过程 SP_GetStudent ,返回 成绩大于90 分的学生: 复制代码 CREATE PROCEDURE [dbo].[Sp_GetStudent] @Score FLOAT, @Nums INT OUTPUT AS BEGIN SET NOCOUNT ON; SELECT * FROM t_student WHERE Score >=@Score SELECT @Nums=COUNT(1) FROM t_student WHERE Score >=@Score IF(@Nums>0) RETURN 1 ELSE RETURN 0 END GO 复制代码 该存储过程涉及了 查询操作、返回值和输出参数,我们来看用EXEC 命令如何调用: 复制代码 DECLARE @return_value int, @OutNums int EXEC @return_value = [dbo].[Sp_GetStudent] @Score = 90, @Nums = @OutNums OUTPUT SELECT @OutNums as N'大于90分的人数' SELECT '返回值' = @return_value GO 复制代码 执行结果: 我们发现EXEC 执行存储过程和我们平时程序执行一个方法是几乎一样的,返回值参数 直接就可以等于存储过程的执行后的返回值,输出参数 在后面需要增加 OUTPUT 关键字。 执行存储过程不是重点,重点是执行动态sql语句,同样看一下例子: DECLARE @TableName NVARCHAR(50),@Sql NVARCHAR(MAX),@Score INT; SET @TableName = 't_Student'; SET @Score = 90; SET @sql = 'SELECT * FROM '+QUOTENAME(@TableName) +'WHERE Score >= '+CAST(@Score AS NVARCHAR(10)) EXEC (@sql); 执行结果: 注意:在执行拼接SQL 语句的时候,的EXEC括号中只允许包含一个字符串变量,但是可以串联多个变量,如果我们直接执行这个SQL语句: --这是错误的调用 EXEC ('SELECT * FROM '+QUOTENAME(@TableName) +'WHERE Score >= '+CAST(@Score AS NVARCHAR(10))); 执行就会提示错误。但是这样就没有问题: 复制代码 DECLARE @TableName NVARCHAR(50),@Sql NVARCHAR(MAX),@Score INT DECLARE @Sql2 NVARCHAR(MAX) SET @TableName = 't_Student'; SET @Score = 90; SET @sql = 'SELECT * FROM '+QUOTENAME(@TableName) SET @Sql2=' WHERE Score >= '+CAST(@Score AS NVARCHAR(10)) EXEC (@sql+@sql2) 复制代码 EXEC 执行拼接sql语句的时候不支持 嵌入式参数,如下: DECLARE @OUT_Nums INT,@IN_Score INT,@Sql NVARCHAR(MAX) SET @IN_Score = 90 SET @sql = 'SELECT @Nums=COUNT(1) FROM t_student WHERE Score >= @Score' EXEC (@sql) 通过上面的代码发现,EXEC 执行拼接的SQL语句的时候,不支持内嵌参数,包括输入参数和输出参数。有的时候我们想把得到的count(*)传出来,用EXEC是不好办到的。接下来,再来看看SP_EXECUTESQL的使用: 二、SP_EXECUTESQL: SP_EXECUTESQL 是在 SQL 2005中引入的新的系统存储过程,也是用来处理动态SQL 语句的。它比EXEC 更加灵活,首先也执行一下第一次的拼接SQL语句: DECLARE @TableName NVARCHAR(50),@Sql NVARCHAR(MAX),@Score INT; SET @TableName = 't_Student'; SET @Score = 90; SET @sql = 'SELECT * FROM '+QUOTENAME(@TableName) +'WHERE Score >= '+CAST(@Score AS NVARCHAR(10)) EXEC SP_EXECUTESQL @sql --注意这里没有了() 执行结果: SP_EXECUTESQL 支持内嵌参数: 先来看一下SP_EXECUTESQL的语法: sp_executesql [ @stmt = ] stmt [ {, [@params=] N'@parameter_name data_type [ OUT | OUTPUT ][,...n]' } {, [ @param1 = ] 'value1' [ ,...n ] } ] 说明: [ @stmt = ] stmt 包含 Transact-SQL 语句或批处理的 Unicode 字符串。stmt 必须是 Unicode 常量或 Unicode 变量。不允许使用更复杂的 Unicode 表达式(例如使用 + 运算符连接两个字符串)。不允许使用字符常量。如果指定了 Unicode 常量,则必须使用 N 作为前缀。例如,Unicode 常量 N'sp_who' 是有效的,但是字符常量 'sp_who' 则无效。字符串的大小仅受可用数据库服务器内存限制。在 64 位服务器中,字符串大小限制为 2 GB,即 nvarchar(max) 的最大大小。stmt 中包含的每个参数在 @params 参数定义列表和参数值列表中均必须有对应项 [ @params = ] N'@parameter_namedata_type[ ,... n ] ' 包含 stmt 中嵌入的所有参数定义的字符串。字符串必须是 Unicode 常量或 Unicode 变量。每个参数定义由参数名称和数据类型组成。n 是表示附加参数定义的占位符。在 stmt 中指定的每个参数必须在 @params 中定义。如果 stmt 中的 Transact-SQL 语句或批处理不包含参数,则不需要 @params。该参数的默认值为 NULL。 [ @param1 = ] 'value1' 参数字符串中定义的第一个参数的值。该值可以是 Unicode 常量,也可以是 Unicode 变量。必须为 stmt 中包含的每个参数提供参数值。如果 stmt 中的 Transact-SQL 语句或批处理没有参数,则不需要这些值。 [ OUT | OUTPUT ] 指示参数是输出参数。除非是公共语言运行 (CLR) 过程,否则 text、ntext 和 image 参数均可用作 OUTPUT 参数。使用 OUTPUT 关键字的输出参数可以为游标占位符,CLR 过程除外。 n 附加参数值的占位符。这些值只能为常量或变量,不能是很复杂的表达式(例如函数)或使用运算符生成的表达式。 返回代码值 : 0(成功)或非零(失败) 结果集:从生成 SQL 字符串的所有 SQL 语句返回结果集 看不懂没有关系,通过例子就会非常明白的,依旧还执行上面的 SQL 语句: DECLARE @OUT_Nums INT,@IN_Score INT,@Sql NVARCHAR(MAX) SET @IN_Score = 90 SET @sql = 'SELECT @Nums=COUNT(1) FROM t_student WHERE Score >= @Score' EXEC SP_EXECUTESQL @sql,N'@Nums INT OUT,@Score INT',@OUT_Nums OUTPUT,@IN_Score SELECT @OUT_Nums AS '人数' 执行结果: 需要注意的是: 1、要求动态Sql和动态Sql参数列表必须是NVARCHAR 2、动态Sql的参数列表与外部提供值的参数列表顺序必需一致 3、一旦使用了 '@name = value' 形式之后,所有后续的参数就必须以 '@name = value' 的形式传递,比如: DECLARE @OUT_Nums INT,@IN_Score INT,@Sql NVARCHAR(MAX) SET @IN_Score = 90 SET @sql = 'SELECT @Nums=COUNT(1) FROM t_student WHERE Score >= @Score' EXEC SP_EXECUTESQL @stmt=@sql,@params=N'@Nums INT OUT,@Score INT',@Nums=@OUT_Nums OUTPUT,@Score=@IN_Score SELECT @OUT_Nums AS '人数' 通过上面的例子已经很清晰的表明了,在执行动态SQL 语句的时候,EXEC 和 SP_EXECUTESQL 的区别了,来总结一下: 1、 性能: 官方描述:sp_executesql stmt 参数中的 Transact-SQL 语句或批处理执行 sp_executesql 语句时才编译。随后,将编译 stmt 中的内容,并将其作为执行计划运行。该执行计划独立于名为 sp_executesql批处理执行计划。sp_executesql 批处理不能引用调用 sp_executesql批处理中声明的变量。sp_executesql 批处理中的本地游标或变量对调用 sp_executesql批处理是不可见的。对数据库上下文所做的更改只在 sp_executesql 语句结束前有效。如果只更改了语句中的参数值,则 sp_executesql 可用来代替存储过程多次执行 Transact-SQL 语句。因为 Transact-SQL 语句本身保持不变,仅参数值发生变化,所以 SQL Server 查询优化器可能重复使用首次执行时所生成的执行计划。 说通俗一点就是:如果用 EXEC 执行一条动态 SQL 语句,由于每次传入的参数不一样,所以每次生成的 @sql 就不一样,这样每执行一次SQL SERVER 就必须重新将要执行的动态 Sql 重新编译一次 。但是SP_EXECUTESQL 则不一样,由于将数值参数化,要执行的动态 Sql 永远不会变化,只是传入的参数的值在变化,那每次执行的时候就不用重新编译,速度和效率自然有所提升。 2、从上面的例子我们已经能够看出 SP_EXECUTESQL 命令比 EXEC 命令更灵活,因为它提供一个接口,该接口及支持输入参数也支持输出参数。 3、EXEC 执行纯动态SQL执行时可能无法使用预编译的执行计划,关键是不安全,可以导致 SQL 注入 ,而 SP_EXECUTESQL 执行参数化动态 SQL ,执行时能使用预编译的执行计划,而且保存存储过程时就可以确定可以使用的预编译的执行计划,而且最重要的是“安全”,天然免疫SQL 注入 作者:Rising Sun 出处:http://www.cnblogs.com/lxblog/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
精心收集整理的各种SQL语句示例,帮助您更加容易的熟悉和使SQL。 1 DECLARE @local_variable 1.1 使用 DECLARE 以下示例将使用名为 @find 的局部变量检索所有姓氏以“Man”开头的联系人信息。 USE AdventureWorks; GO DECLARE @find varchar(30); SET @find = 'Man%'; SELECT LastName, FirstName, Phone FROM Person.Contact WHERE LastName LIKE @find; 2 EXECUTE 2.1 使用 EXECUTE 传递单个参数 uspGetEmployeeManagers 存储过程需要一个参数 (@EmployeeID)。 以下示例执行 uspGetEmployeeManagers 存储过程,以 Employee ID 6 作为参数值。 USE AdventureWorks; GO EXEC dbo.uspGetEmployeeManagers 6; GO 2.2 在执行过程中变量可以显式命名: EXEC dbo.uspGetEmployeeManagers @EmployeeID = 6; GO 2.3 使用多个参数 以下示例执行 spGetWhereUsedProductID 存储过程。 该存储过程将传递两个参数:第一个参数为产品 ID (819),第二个参数 @CheckDate, 是 datetime 值。 USE AdventureWorks; GO DECLARE @CheckDate datetime; SET @CheckDate = GETDATE(); EXEC dbo.uspGetWhereUsedProductID 819, @CheckDate; GO 3 sp_executesql 执行可以多次重复使用或动态生成的 Transact-SQL 语句或批处理Transact-SQL 语句或批处理可以包含嵌入参数。 sp_executesql 支持与 Transact-SQL 字符串分开的参数值的设置,如以下示例所示。 DECLARE @IntVariable int; DECLARE @SQLString nvarchar(500); DECLARE @ParmDefinition nvarchar(500); /* Build the SQL string one time.*/ SET @SQLString = N'SELECT EmployeeID, NationalIDNumber, Title, ManagerID FROM AdventureWorks.HumanResources.Employee WHERE ManagerID = @ManagerID'; SET @ParmDefinition = N'@ManagerID tinyint'; /* Execute the string with the first parameter value. */ SET @IntVariable = 197; EXECUTE sp_executesql @SQLString, @ParmDefinition, @ManagerID = @IntVariable; /* Execute the same string with the second parameter value. */ SET @IntVariable = 109; EXECUTE sp_executesql @SQLString, @ParmDefinition, @ManagerID = @IntVariable; 输出参数也可用于 sp_executesql。以下示例从 AdventureWorks.HumanResources.Employee 表中检索职务,并在输出参数 @max_title 中返回它。 DECLARE @IntVariable int; DECLARE @SQLString nvarchar(500); DECLARE @ParmDefinition nvarchar(500); DECLARE @max_title varchar(30); SET @IntVariable = 197; SET @SQLString = N'SELECT @max_titleOUT = max(Title) FROM AdventureWorks.HumanResources.Employee WHERE ManagerID = @level'; SET @ParmDefinition = N'@level tinyint, @max_titleOUT varchar(30) OUTPUT'; EXECUTE sp_executesql @SQLString, @ParmDefinition, @level = @IntVariable, @max_titleOUT=@max_title OUTPUT; SELECT @max_title; 3.1 执行简单的 SELECT 语句 以下示例将创建并执行一个简单的 SELECT 语句,其中包含名为 @level 的嵌入参数。 EXECUTE sp_executesql N'SELECT * FROM AdventureWorks.HumanResources.Employee WHERE ManagerID = @level', N'@level tinyint', @level = 109; 3.2 执行动态生成的字符串 以下示例显示使用 sp_executesql 执行动态生成的字符串。该示例中的存储过程用于向一组表中插入数据,这些表用于划分一年的销售数据。一年中的每个月均有一个表,格式如下: CREATE TABLE May1998Sales (OrderID int PRIMARY KEY, CustomerID int NOT NULL, OrderDate datetime NULL CHECK (DATEPART(yy, OrderDate) = 1998), OrderMonth int CHECK (OrderMonth = 5), DeliveryDate datetime NULL, CHECK (DATEPART(mm, OrderDate) = OrderMonth) ) 3.3 使用 OUTPUT 参数 以下示例使用 OUTPUT 参数将由 SELECT 语句生成的结果集存储于 @SQLString 参数中。然后将执行两个使用 OUTPUT 参数值的 SELECT 语句。 USE AdventureWorks; GO DECLARE @SQLString nvarchar(500); DECLARE @ParmDefinition nvarchar(500); DECLARE @SalesOrderNumber nvarchar(25); DECLARE @IntVariable int; SET @SQLString = N'SELECT @SalesOrderOUT = MAX(SalesOrderNumber) FROM Sales.SalesOrderHeader WHERE CustomerID = @CustomerID'; SET @ParmDefinition = N'@CustomerID int, @SalesOrderOUT nvarchar(25) OUTPUT'; SET @IntVariable = 22276; EXECUTE sp_executesql @SQLString, @ParmDefinition, @CustomerID = @IntVariable, @SalesOrderOUT = @SalesOrderNumber OUTPUT; -- This SELECT statement returns the value of the OUTPUT parameter. SELECT @SalesOrderNumber; -- This SELECT statement uses the value of the OUTPUT parameter in -- the WHERE clause. SELECT OrderDate, TotalDue FROM Sales.SalesOrderHeader WHERE SalesOrderNumber = @SalesOrderNumber; 4 CAST 和 CONVERT 将一种数据类型的表达式显式转换为另一种数据类型的表达式。CAST 和 CONVERT 提供相似的功能。 DECLARE @myval decimal (5, 2) SET @myval = 193.57 SELECT CAST(CAST(@myval AS varbinary(20)) AS decimal(10,5)) -- Or, using CONVERT SELECT CONVERT(decimal(10,5), CONVERT(varbinary(20), @myval)) 4.1 同时使用 CAST 和 CONVERT -- Use CAST USE AdventureWorks; GO SELECT SUBSTRING(Name, 1, 30) AS ProductName, ListPrice FROM Production.Product WHERE CAST(ListPrice AS int) LIKE '3%'; GO -- Use CONVERT. USE AdventureWorks; GO SELECT SUBSTRING(Name, 1, 30) AS ProductName, ListPrice FROM Production.Product WHERE CONVERT(int, ListPrice) LIKE '3%'; GO 4.2 使用包含算术运算符的 CAST USE AdventureWorks; GO SELECT CAST(ROUND(SalesYTD/CommissionPCT, 0) AS int) AS 'Computed' FROM Sales.SalesPerson WHERE CommissionPCT != 0; GO 4.3 使用 CAST 进行连接 USE AdventureWorks; GO SELECT 'The list price is ' + CAST(ListPrice AS varchar(12)) AS ListPrice FROM Production.Product WHERE ListPrice BETWEEN 350.00 AND 400.00; GO 4.4 使用 CAST 生成可读性更高的文本 USE AdventureWorks; GO SELECT DISTINCT CAST(p.Name AS char(10)) AS Name, s.UnitPrice FROM Sales.SalesOrderDetail s JOIN Production.Product p on s.ProductID = p.ProductID WHERE Name LIKE 'Long-Sleeve Logo Jersey, M'; GO 4.5 对日期时间数据使用 CAST 和 CONVERT SELECT GETDATE() AS UnconvertedDateTime, CAST(GETDATE() AS nvarchar(30)) AS UsingCast, CONVERT(nvarchar(30), GETDATE(), 126) AS UsingConvertTo_ISO8601 ; GO 5 SELECT 5.1 将 DISTINCT 与 SELECT 一起使用 以下示例使用 DISTINCT 以避免检索重复标题。 USE AdventureWorks ; GO SELECT DISTINCT Title FROM HumanResources.Employee ORDER BY Title ; GO 5.2 使用 SELECT INTO 创建表 以下第一个示例将在 tempdb 中创建一个名为 #Bicycles 的临时表。若要使用该表,则必须使用与下面显示的名称完全相同的名称进行引用。这包括数字符号 (#)。 USE tempdb ; IF OBJECT_ID (N'#Bicycles',N'U') IS NOT NULL DROP TABLE #Bicycles ; GO USE AdventureWorks; GO SET NOCOUNT ON SELECT * INTO #Bicycles FROM Production.Product WHERE ProductNumber LIKE 'BK%' SET NOCOUNT OFF SELECT name FROM tempdb..sysobjects WHERE name LIKE '#Bicycles%' ; GO 5.3 使用相关子查询 以下示例显示了语义等价的查询并说明了使用 EXISTS 关键字和 IN 关键字的区别。两个都是有效子查询示例,用于检索产品型号为长袖标志运动衫且 ProductModelID 编号在 Product 和 ProductModel 两个表中相匹配的每种产品名称的实例。 USE AdventureWorks ; GO SELECT DISTINCT Name FROM Production.Product p WHERE EXISTS (SELECT * FROM Production.ProductModel pm WHERE p.ProductModelID = pm.ProductModelID AND pm.Name = 'Long-sleeve logo jersey') ; GO -- OR USE AdventureWorks ; GO SELECT DISTINCT Name FROM Production.Product WHERE ProductModelID IN (SELECT ProductModelID FROM Production.ProductModel WHERE Name = 'Long-sleeve logo jersey') ; GO 5.4 使用 GROUP BY 以下示例查找数据库中各销售订单的总额。 USE AdventureWorks ; GO SELECT SalesOrderID, SUM(LineTotal) AS SubTotal FROM Sales.SalesOrderDetail sod GROUP BY SalesOrderID ORDER BY SalesOrderID ; GO 由于使用了 GROUP BY 子句,因此针对每个销售订单只返回一行销售总额。 5.5 对多个组使用 GROUP BY 以下示例查找按产品 ID 和特价产品 ID 分组的平均价格和迄今为止的年销售总额。 Use AdventureWorks SELECT ProductID, SpecialOfferID, AVG(UnitPrice) AS 'Average Price', SUM(LineTotal) AS SubTotal FROM Sales.SalesOrderDetail GROUP BY ProductID, SpecialOfferID ORDER BY ProductID GO 5.6 使用 GROUP BY 和 WHERE 以下示例在只检索标价大于 $1000 的行后,将结果进行分组。 USE AdventureWorks; GO SELECT ProductModelID, AVG(ListPrice) AS 'Average List Price' FROM Production.Product WHERE ListPrice > $1000 GROUP BY ProductModelID ORDER BY ProductModelID ; GO 5.7 将 GROUP BY 与表达式一起使用 以下示例按表达式进行分组。如果表达式不包含聚合函数,则可以按表达式进行分组。 USE AdventureWorks ; GO SELECT AVG(OrderQty) AS 'Average Quantity', NonDiscountSales = (OrderQty * UnitPrice) FROM Sales.SalesOrderDetail sod GROUP BY (OrderQty * UnitPrice) ORDER BY (OrderQty * UnitPrice) DESC ; GO 6 日期和时间 Syntax for CAST: CAST ( expression AS data_type [ (length ) ]) Syntax for CONVERT: CONVERT ( data_type [ ( length ) ] , expression [ , style ] ) 不带世纪数位 (yy) (1) 带世纪数位 (yyyy) 标准 输入/输出 (3) - 0 或 100 (1, 2) 默认设置 mon dd yyyy hh:miAM(或 PM) 1 101 美国 mm/dd/yyyy 2 102 ANSI yy.mm.dd 3 103 英国/法国 dd/mm/yy 4 104 德国 dd.mm.yy 5 105 意大利 dd-mm-yy 6 106 (1) - dd mon yy 7 107 (1) - mon dd, yy 8 108 - hh:mi:ss - 9 或 109 (1, 2) 默认设置 + 毫秒 mon dd yyyy hh:mi:ss:mmmAM(或 PM) 10 110 美国 mm-dd-yy 11 111 日本 yy/mm/dd 12 112 ISO yymmdd - 13 或 113 (1, 2) 欧洲默认设置 + 毫秒 dd mon yyyy hh:mi:ss:mmm(24h) 14 114 - hh:mi:ss:mmm(24h) - 20 或 120 (2) ODBC 规范 yyyy-mm-dd hh:mi:ss(24h) - 21 或 121 (2) ODBC 规范(带毫秒) yyyy-mm-dd hh:mi:ss.mmm(24h) - 126 (4) ISO8601 yyyy-mm-ddThh:mi:ss.mmm(无空格) 127(6, 7) 带时区 Z 的 ISO8601。 yyyy-mm-ddThh:mi:ss.mmmZ (无空格) - 130 (1, 2) 回历 (5) dd mon yyyy hh:mi:ss:mmmAM - 131 (2) 回历 (5) dd/mm/yy hh:mi:ss:mmmAM Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AM Select CONVERT(varchar(100), GETDATE(), 1): 05/16/06 Select CONVERT(varchar(100), GETDATE(), 2): 06.05.16 Select CONVERT(varchar(100), GETDATE(), 3): 16/05/06 Select CONVERT(varchar(100), GETDATE(), 4): 16.05.06 Select CONVERT(varchar(100), GETDATE(), 5): 16-05-06 Select CONVERT(varchar(100), GETDATE(), 6): 16 05 06 Select CONVERT(varchar(100), GETDATE(), 7): 05 16, 06 Select CONVERT(varchar(100), GETDATE(), 8): 10:57:46 Select CONVERT(varchar(100), GETDATE(), 9): 05 16 2006 10:57:46:827AM Select CONVERT(varchar(100), GETDATE(), 10): 05-16-06 Select CONVERT(varchar(100), GETDATE(), 11): 06/05/16 Select CONVERT(varchar(100), GETDATE(), 12): 060516 Select CONVERT(varchar(100), GETDATE(), 13): 16 05 2006 10:57:46:937 Select CONVERT(varchar(100), GETDATE(), 14): 10:57:46:967 Select CONVERT(varchar(100), GETDATE(), 20): 2006-05-16 10:57:47 Select CONVERT(varchar(100), GETDATE(), 21): 2006-05-16 10:57:47.157 Select CONVERT(varchar(100), GETDATE(), 22): 05/16/06 10:57:47 AM Select CONVERT(varchar(100), GETDATE(), 23): 2006-05-16 Select CONVERT(varchar(100), GETDATE(), 24): 10:57:47 Select CONVERT(varchar(100), GETDATE(), 25): 2006-05-16 10:57:47.250 Select CONVERT(varchar(100), GETDATE(), 100): 05 16 2006 10:57AM Select CONVERT(varchar(100), GETDATE(), 101): 05/16/2006 Select CONVERT(varchar(100), GETDATE(), 102): 2006.05.16 Select CONVERT(varchar(100), GETDATE(), 103): 16/05/2006 Select CONVERT(varchar(100), GETDATE(), 104): 16.05.2006 Select CONVERT(varchar(100), GETDATE(), 105): 16-05-2006 Select CONVERT(varchar(100), GETDATE(), 106): 16 05 2006 Select CONVERT(varchar(100), GETDATE(), 107): 05 16, 2006 Select CONVERT(varchar(100), GETDATE(), 108): 10:57:49 Select CONVERT(varchar(100), GETDATE(), 109): 05 16 2006 10:57:49:437AM Select CONVERT(varchar(100), GETDATE(), 110): 05-16-2006 Select CONVERT(varchar(100), GETDATE(), 111): 2006/05/16 Select CONVERT(varchar(100), GETDATE(), 112): 20060516 Select CONVERT(varchar(100), GETDATE(), 113): 16 05 2006 10:57:49:513 Select CONVERT(varchar(100), GETDATE(), 114): 10:57:49:547 Select CONVERT(varchar(100), GETDATE(), 120): 2006-05-16 10:57:49 Select CONVERT(varchar(100), GETDATE(), 121): 2006-05-16 10:57:49.700 Select CONVERT(varchar(100), GETDATE(), 126): 2006-05-16T10:57:49.827 Select CONVERT(varchar(100), GETDATE(), 130): 18 ???? ?????? 1427 10:57:49:907AM Select CONVERT(varchar(100), GETDATE(), 131): 18/04/1427 10:57:49:920AM

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧