SQL EXEC用法总结

一、使用EXEC执行存储过程

例如存储过名为:myprocedure

  1. use AdventureWorks
  2.  
  3. create procedure myprocedure @city varchar(20) 
  4.  
  5. as 
  6.  
  7. begin 
  8.  
  9.     select * from Person.Address 
  10.  
  11. end 
  1. exec myprocedure @city = 'Bothell' 
  2.  
  3. --或 
  4.  
  5. exec myprocedure 'Bothell' 

二、使用EXEC执行动态的SQL语句

注意:动态的sql必须包含于圆括号内如:

  1. exec ('select * from mytable'

使用EXEC执行动态sql语句注意下面问题

1.不能有输入参数,输出参数

下面的脚本是错误的:

  1. DECLARE @i AS INT
  2. SET @i = 10248; 
  3.  
  4. DECLARE @sql AS VARCHAR(52); 
  5. SET @sql = 'SELECT * FROM dbo.Orders WHERE OrderID = @i;'
  6. EXEC(@sql); 
  7. GO 

2.园括号内部能使用函数或case表达式

下面的脚本是错误的:

  1. DECLARE @schemaname AS NVARCHAR(128), @tablename AS NVARCHAR(128); 
  2. SET @schemaname = N'dbo'
  3. SET @tablename = N'Order Details'
  4. EXEC(N'SELECT COUNT(*) FROM ' 
  5.      + QUOTENAME(@schemaname) + N'.' + QUOTENAME(@tablename) + N';'); 
  6. GO 

不过把函数放在变量中是可以的:

  1. DECLARE 
  2.   @schemaname AS NVARCHAR(128), 
  3.   @tablename AS NVARCHAR(128), 
  4.   @sql AS NVARCHAR(539); 
  5. SET @schemaname = N'dbo'
  6. SET @tablename = N'Order Details'
  7. SET @sql = N'SELECT COUNT(*) FROM ' 
  8.   + QUOTENAME(@schemaname) + N'.' + QUOTENAME(@tablename) + N';' 
  9. EXEC(@sql); 

3.不能利用重用执行计划,存所以存在性能问题

  1. DECLARE @i AS INT
  2. SET @i = 10248; 
  3.  
  4. DECLARE @sql AS VARCHAR(52); 
  5. SET @sql = 'SELECT * FROM dbo.Orders WHERE OrderID = ' 
  6.   + CAST(@i AS VARCHAR(10)) + N';'
  7. EXEC(@sql); 
  8. GO 

当@i = 10248, 10249, 10250要生成3个执行计划。

4。容易被sql注入,存在安全问题。

  1. DECLARE @lastname AS NVARCHAR(40), @sql AS NVARCHAR(200); 
  2. SET @lastname = N''' DROP TABLE dbo.Employees --'
  3. SET @sql = N'SELECT * FROM dbo.Employees WHERE LastName = ''' 
  4.   + @lastname + ''';'
  5. EXEC @sql; 
  6. GO 

实际执行的sql为:

  1. SELECT * FROM dbo.Employees WHERE LastName = '' DROP TABLE dbo.Employees --'; 
### 关于 SQL EXEC 查询及其返回结果的处理 `EXEC` 是一种用于执行动态 SQL 的方法,在某些数据库管理系统(DBMS)中广泛使用。然而,需要注意的是 `EXEC` 存在一定的局限性,特别是在涉及参数化查询或复杂数据操作时。 #### 使用 SQL EXEC 执行查询 当通过 `EXEC` 来运行动态 SQL 语句时,通常会将完整的 SQL 字符串传递给该命令。例如: ```sql DECLARE @SQL NVARCHAR(MAX); SET @SQL = 'SELECT * FROM Employees WHERE DepartmentID = ''HR'''; EXEC(@SQL); -- 这里直接执行字符串形式的 SQL 命令 ``` 上述代码片段展示了如何构建并执行一条简单的 SELECT 语句[^1]。但是要注意,这种方式并不支持直接获取输出参数或者更复杂的交互逻辑。 #### 处理 EXEC 返回的结果集 对于只读型的操作来说,像上面的例子那样调用即可满足需求;但如果希望捕获某个特定值(比如记录总数),则需要借助其他机制来完成这一目标。由于标准版的 `EXEC` 不具备内置功能去接收来自内部计算得出的数据项(如 COUNT() 函数产生的计数值),所以这里推荐改用更为灵活强大的替代方案——`sp_executesql`。 以下是利用 `sp_executesql` 实现带输出参数的功能演示: ```sql -- 定义存储过程使用的局部变量 DECLARE @RowCount INT; DECLARE @DynamicTSQLStatement NVARCHAR(500); -- 构造动态 T-SQL 表达式 SET @DynamicTSQLStatement = N'SELECT @TotalRowsOUT=COUNT(*) FROM HumanResources.Employee'; -- 调用 sp_executesql 并指定输入/输出参数映射关系 EXECUTE sp_executesql @DynamicTSQLStatement, N'@TotalRowsOUT INT OUTPUT', @TotalRowsOUT=@RowCount OUTPUT; -- 输出最终统计数目 PRINT 'The number of rows is ' + CONVERT(VARCHAR, @RowCount); ``` 此脚本不仅能够成功取得员工表内的总条目数,还体现了良好的可维护性和安全性特点。 #### SQLite 中的结果处理 (sqlite3_get_table 方法) 如果是在轻量级的关系型数据库引擎 SQLite 上工作,则可以考虑采用 C API 提供的方法之一 —— sqlite3_get_table ,它可以方便快捷地一次性提取整个表格结构的内容至内存当中以便进一步分析加工[^3] 。下面给出一段伪代码样例展示基本流程: ```c #include <stdio.h> #include "sqlite3.h" int main(void){ int i,j,nrow,ncolumn; char **azResult; const char* data="Callback function called"; /* Open database */ sqlite3 *db; char *zErrMsg = 0; int rc = sqlite3_open("test.db", &db); if( rc ){ fprintf(stderr,"Can't open database: %s\n", sqlite3_errmsg(db)); return(0); }else{ printf("Opened database successfully\n"); } /* Execute SQL statement */ rc = sqlite3_get_table( db, /* An open database connection */ "select * from table_name limit 1;",/* The SQL to be evaluated */ &azResult,&nrow,&ncolumn,zErrMsg ); if( rc!=SQLITE_OK ){ fprintf(stderr,"%s\n", zErrMsg ); sqlite3_free(zErrMsg); } // Display the results. for(i=0; i<nrow; ++i){ for(j=0; j<ncolumn; ++j){ printf("%s ", azResult[i*ncolumn+j]); } puts(""); } /* Release memory allocated by sqlite3_get_table(). */ sqlite3_free_table(azResult); /* Close Database Connection */ sqlite3_close(db); } ``` 这段程序首先打开名为 test.db 数据库文件连接,接着尝试从中检索前几行样本数据并通过循环打印出来最后记得释放资源关闭链接结束任务。 ### 注意事项 - 当涉及到敏感信息传输时务必采取适当措施防止注入攻击风险。 - 对大型数据集合谨慎运用此类技术以免消耗过多系统资源影响性能表现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值