SQL动态表查询

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介:
在程序设计过程中,经常会遇到需要根据用户的选择进行查询的情况,这时,用户不同的选择可能需要查询不同的表名,而且这个表名可能还不宜事先在程序中定死,需要能动态的随机选择。当然还包括表名和用户的某些信息相关,可能不同的用户需要进入不同的表,甚至表名的一部分就是用户名的一部分,等等。对于这些情况,我是使用EXEC语句进行动态甚至动态跨服务器进行查询。我记得刚开始学习SQL语句的时候花了不少时间来找方法,现在将这个方法记下来和有兴趣的人共同分享。
例程如下:
DECLARE @TABLE VARCHAR(50)
SET @TABLE = 'dbo.Mfg_SHOPCAL'
EXEC ('SELECT TOP 100 * FROM  ' + @TABLE + ' WHERE YEAR(CALDATE)=2008 AND MONTH(CALDATE)=5')
 
这里主要是使用了EXECUTE(可以简写成EXEC)语句。这个语句功能十分强大,利用它可以在其他程序中随意构建SQL语句,增加了程序的灵活性。
 
EXEC的主要作用是执行 Transact-SQL 批中的命令字符串、字符串或执行下列模块之一:系统存储过程、用户定义存储过程、标量值用户定义函数或扩展存储过程。
SQL Server 2005 扩展了 EXECUTE 语句,以使其可用于向链接服务器发送传递命令。此外,还可以显式设置执行字符串或命令的上下文。
 
EXEC的语句规则如下:
Execute a stored procedure or function
[ { EXEC | EXECUTE } ]
    { 
      [ @return_status = ]
      { module_name [ ;number ] | @module_name_var } 
        [ [ @parameter = ] { value 
                           | @variable [ OUTPUT ] 
                           | [ DEFAULT ] 
                           }
        ]
      [ ,...n ]
      [ WITH RECOMPILE ]
    }
[;]
Execute a character string
{ EXEC | EXECUTE } 
        ( { @string_variable | [ N ]'tsql_string' } [ + ...n ] )
    [ AS { LOGIN | USER } = ' name ' ]
[;]
Execute a pass-through command against a linked server
{ EXEC | EXECUTE }
        ( { @string_variable | [ N ] 'command_string' } [ + ...n ]
        [ {, { value | @variable [ OUTPUT ] } } [...n] ]
        ) 
    [ AS { LOGIN | USER } = ' name ' ]
    [ AT linked_server_name ]
[;]
参数
@return_status 
可选的整型变量,存储模块的返回状态。这个变量在用于 EXECUTE 语句前,必须在批处理、存储过程或函数中声明过。
在用于调用标量值用户定义函数时,@return_status变量可以是任何标量数据类型module_name 
是要调用的存储过程或标量值用户定义函数的完全限定或者不完全限定名称。模块名称必须符合标识符规则。无论服务器的排序规则如何,扩展存储过程的名称总是区分大小写。
用户可以执行在另一数据库中创建的模块,只要运行模块的用户拥有此模块或具有在该数据库中执行该模块的适当权限。用户可以在另一台运行 SQL Server 的服务器中执行模块,只要该用户有相应的权限使用该服务器(远程访问),并能在数据库中执行该模块。如果指定了服务器名称但没有指定数据库名称,则SQL Server 2005 Database Engine会在用户的默认数据库中查找该模块。
;number 
是可选整数,用于对同名的过程分组。该参数不能用于扩展存储过程。
注意
后续版本的Microsoft SQL Server将删除该功能。请避免在新的开发工作中使用该功能,并应着手修改当前还在使用该功能的应用程序。
@module_name_var 
是局部定义的变量名,代表模块名称。
@parameter 
module_name的参数,与在模块中定义的相同。参数名称前必须加上符号 。
在使用@parameter_name=value 格式时,参数名称和常量不必按在模块中定义的顺序提供。但是,如果任何参数使用了 @parameter_name=value 格式,则对后续的所有参数均必须使用该格式。
默认情况下,参数可为空。如果传递NULL参数值,且该参数用于CREATE 或ALTER TABLE 语句,由于在这些语句中引用的列不允许为 NULL值(例如,插入到不允许为NULL 的列),数据库引擎就会引发错误。为避免将NULL参数值传递给不允许为 NULL的列,可以在模块中添加编程逻辑或使用该列的默认值(使用 CREATE或ALTER TABLE语句中的DEFAULT 关键字
value 
传递给模块或传递命令的参数值。如果参数名称没有指定,参数值必须以在模块中定义的顺序提供。
对链接服务器执行传递命令时,参数值的顺序取决于链接服务器的OLE DB 访问接口。大多数OLE DB访问接口按从左到右的顺序将值绑定到参数。
如果参数值是一个对象名称、字符串或由数据库名称或架构名称限定,则整个名称必须用单引号括起来。如果参数值是一个关键字,则该关键字必须用双引号括起来。
如果在模块中定义了默认值,用户执行该模块时可以不必指定参数。
默认值也可以为NULL。通常,模块定义会指定当参数值为 NULL 时应该执行的操作。
@variable 
是用来存储参数或返回参数的变量
OUTPUT 
指定模块或命令字符串返回一个参数。该模块或命令字符串中的匹配参数也必须已使用关键字 OUTPUT创建。使用游标变量作为参数时使用该关键字。
如果value 定义为对链接服务器执行的模块的OUTPUT,则OLE DB 访问接口对相应@parameter 所执行的任何更改都将在模块执行结束时复制回该变量。
如果使用OUTPUT 参数,目的是在调用批处理或模块的其他语句中使用其返回值,则参数值必须作为变量传递,如 @parameter = @variable。如果一个参数在模块中没有定义为OUTPUT 参数,则不能通过对该参数指定 OUTPUT 执行模块。不能使用OUTPUT 将常量传递给模块;返回参数需要变量名称。在执行过程之前,必须声明变量的数据类型并赋值。
当对远程存储过程使用EXECUTE或对链接服务器执行传递命令时,OUTPUT 参数不能是任何大型对象(LOB) 数据类型。
返回参数可以是 LOB 数据类型之外的任意数据类型。
DEFAULT 
根据模块的定义,提供参数的默认值。当模块需要的参数值没有定义默认值并且缺少参数或指定了DEFAULT 关键字,会出现错误。
WITH RECOMPILE 
执行模块后,强制编译、使用和放弃新计划。如果该模块存在现有查询计划,则该计划将保留在缓存中。
如果所提供的参数为非典型参数或者数据有很大的改变,使用该选项。该选项不能用于扩展存储过程。建议尽量少使用该选项,因为它消耗较多系统资源。
@string_variable 
是局部变量的名称。
@string_variable 可以是任意char、varchar、nchar 或 nvarchar数据类型。其中包括(max) 数据类型。
[N] 'tsql_string' 
常量字符串。tsql_string 可以是任意 nvarchar 或varchar 数据类型。如果包含N,则字符串将解释为nvarchar数据类型。
AS <context_specification> 

指定执行语句的上下文。有关详细信息,请参阅了解执行上下文。

LOGIN 指定要模拟的上下文是登录名。模拟范围为服务器。 USER 指定要模拟的上下文是当前数据库中的用户。模拟范围只限于当前数据库。对数据库用户的上下文切换不会继承该用户的服务器级别权限. 重要事项: 当到数据库用户的上下文切换处于活动状态时,任何对数据库外部资源的访问尝试都会导致语句失败。这包括 USE database 语句、分布式查询和使用三部分或四部分标识符引用其他数据库的查询。若要将上下文切换的范围扩展到当前数据库之外,请参阅使用EXECUTE AS 扩展数据库模拟。 'name' 有效用户或登录名。name 必须是 sysadmin 固定服务器角色成员或分别为sys.database_principals或sys.server_principals的主体。 name 不能为内置帐户,如 NT AUTHORITY\LocalService、NT AUTHORITY\NetworkService 或NT AUTHORITY\LocalSystem。 [N] 'command_string' 常量字符串,包含要传递给链接服务器的命令。如果包含N,则字符串将解释为nvarchar 数据类型。 AT linked_server_name 指定对linked_server_name 执行command_string,并将结果(如果有)返回客户端。linked_server_name 必须引用本地服务器中的现有链接服务器定义。链接服务器使用sp_addlinkedserver定义。


     本文转自fengyp 51CTO博客,原文链接:http://blog.51cto.com/fengyp/77220,如需转载请自行联系原作者




相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
相关文章
|
10天前
|
SQL
sql语句加正则 简化查询
sql语句加正则 简化查询
14 0
sql语句加正则 简化查询
|
28天前
|
SQL
sql server链接查询
sql server链接查询
17 1
|
28天前
|
SQL
sql server简单查询
sql server简单查询
14 1
|
1月前
|
SQL 数据库 C#
C# .NET面试系列十一:数据库SQL查询(附建表语句)
#### 第1题 用一条 SQL 语句 查询出每门课都大于80 分的学生姓名 建表语句: ```sql create table tableA ( name varchar(10), kecheng varchar(10), fenshu int(11) ) DEFAULT CHARSET = 'utf8'; ``` 插入数据 ```sql insert into tableA values ('张三', '语文', 81); insert into tableA values ('张三', '数学', 75); insert into tableA values ('李四',
62 2
C# .NET面试系列十一:数据库SQL查询(附建表语句)
|
18天前
|
SQL 关系型数据库 MySQL
mysql一条sql查询出多个统计结果
mysql一条sql查询出多个统计结果
13 0
|
28天前
|
SQL
sql高级查询
sql高级查询
12 0
|
1月前
|
SQL 存储 数据可视化
10个高级的 SQL 查询技巧
10个高级的 SQL 查询技巧
|
29天前
|
SQL 数据库
sql server高级查询,看这篇文章就够了
sql server高级查询,看这篇文章就够了
21 0
|
1月前
|
SQL Java 关系型数据库
MyBatis的动态SQL之OGNL(Object-Graph Navigation Language)表达式以及各种标签的用法
MyBatis的动态SQL之OGNL(Object-Graph Navigation Language)表达式以及各种标签的用法
16 0
|
1月前
|
SQL Java 关系型数据库
MyBatis中的9种常用动态sql标签精妙用法
MyBatis中的9种常用动态sql标签精妙用法
48 0