SQL EXEC 命令用法
EXEC命令有两个用法:执行一个存储过程,或者执行一个动态批次。批次是一个内容为SQL语句的字符串。
    例如:
    declare @schemaName varchar(80),@tableName varchar(80),@objName varchar(512);字符串常量的用法
    set @schemaName='dbo';
    set @tableName='Orders';
    set @objName=@schemaName+'.'+@tableName;
    exec('select count(*) from '+@objName);
注意,在exec的括号里,只允许是字符串变量、字符串常量存在。不允许在这里调用函数或者使用case表达式。
    下面的代码是错误的:
        exec('select count(*) from '+quotename(@objName));
所以,基本的方法是将语句保存到一个变量里,例如:
        set @sql='...';
        exec(@sql);
    这就不存在上述限制了。
1 ,EXEC没有接口
Exec的唯一输入是字符串。一个动态批次无权访问调用它的批次内所定义的局部变量:
            declare @i int
            set @i=1;
            declare @sql varchar(255)
            set @sql='select * ders where rderid=@i';
            exec(@sql);
出错:必须声明标量变量@i
原因还是@i不能放在''之内,它只能通过字符串连接动态的嵌入到SQL语句里:
            set @sql='select * ders where rderid='+cast(@i as varchar(10));
变量与字符串连接会引发所谓的SQL注入安全隐患,如果变量包含了字符串。要防患SQL注入的一个办法是限制字符串的大小。
这种连接会对性能造成映像。SS会为每个字符串单独创建一个执行计划,无论两个字符串是否是一个模式。为此,下面显示了一个例子:
首先清除cache里的执行计划:
            DBCC freeproccache;
然后执行下面的代码三次,分别将@i设置为10248,10249,10250
            DECLARE @i AS INT;
            SET @i = 10248;
            DECLARE @sql AS VARCHAR(52);
            SET @sql = 'SELECT * FROM dbo.Orders WHERE rderID = '
              + CAST(@i AS VARCHAR(10)) + N';';
            EXEC(@sql)
最后查询sys.syscacheobjects:
            SELECT cacheobjtype, objtype, usecounts, sql
            FROM sys.syscacheobjects
            WHERE sql NOT LIKE '%cache%'
              AND sql NOT LIKE '%sys.%';
结果显示为:
它会为每次查询生成一个执行计划。以及一个参数化的执行计划。
    EXEC也没有输出参数。缺省情况下,exec将返回该次查询的输出给调用者。如果希望将该结果保存到变量里,那就必须使用Insert EXEC语法,并从表里从新读取该数据,然后储存到目标变量里。
    DECLARE
      @schemaname AS NVARCHAR(128),
      @tablename AS NVARCHAR(128),
      @colname    AS NVARCHAR(128),
      @sql        AS NVARCHAR(805),
      @cnt      AS INT;
    SET @schemaname = N'dbo';
    SET @tablename = N'Orders';
    SET @colname    = N'CustomerID';
    SET @sql = N'SELECT COUNT(DISTINCT '
      + QUOTENAME(@colname) + N') FROM '
      + QUOTENAME(@schemaname)
      + N'.'
      + QUOTENAME(@tablename)
      + N';';
    CREATE TABLE #T(cnt INT);
    INSERT INTO #T
      EXEC(@sql);
    SET @cnt = (SELECT cnt FROM #T);
    SELECT @cnt;
    DROP TABLE #T;
注意如果忘记输入最后的一条语句“Drop 。。。”,那么就会出现下面的令人讨厌的错误:数据库中已存在名为 '#T' 的对象。
    在上面这段程序里,创建了一个临时表,它对于动态批次是可见的。所以可以修改上面的程序为:
        SET @sql = N'INSERT INTO #T(cnt) SELECT COUNT(DISTINCT '
          + QUOTENAME(@colname) + N') FROM '
          + QUOTENAME(@schemaname)
          + N'.'
          + QUOTENAME(@tablename)
          + N';';
        CREATE TABLE #T(cnt INT);
        EXEC(@sql);
        SET @cnt = (SELECT cnt FROM #T);
        SELECT @cnt;
        DROP TABLE #T;
    因为EXEC的执行是在Create Table之后,所以Insert语句可以移到@sql的定义里。
2,变量的连接
在SS2000里,EXEC优于sp_executesql的一点是,它支持输入的代码长度要长一些。虽然,从技术上说后者的输入代码字符串是NTEXT类型,通常希望用一个局部变量来保存它。但是,局部变量是不能声明成大对象类型的。
所以,实际上sp_executesql的最大支持的字符串长度是Unicode字符串的长度(NVARCHAR,4000个字符)。而EXEC,则支持常规的字符串(VARCHAR),即8000个字符。
而且,EXEC支持多个变量的连接,每个变量最大有8000个字符。
不过在SS2005里,变量类型可以是VARCHAR(max),最大为2G。
 
3 ,EXEC AT 
这是05里的新语法。执行远程主机上的动态SQL语句

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。