热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

sqlcast,convert,QUOTENAME,exec函数学习记录

将某种数据类型的表达式显式转换为另一种数据类型。CAST和CONVERT提供相似的功能。

语法
使用 CAST:

CAST ( expression AS data_type )

使用 CONVERT:

CONVERT (data_type[(length)], expression [, style])

参数
expression

是任何有效的 Microsoft SQL Server" 表达式。有关更多信息,请参见表达式。

data_type

目标系统所提供的数据类型,包括 bigint 和 sql_variant。不能使用用户定义的数据类型。有关可用的数据类型的更多信息,请参见数据类型。

length

nchar、nvarchar、char、varchar、binary 或 varbinary 数据类型的可选参数。

style

日期格式样式,借以将 datetime 或 smalldatetime 数据转换为字符数据(nchar、nvarchar、char、varchar、nchar 或 nvarchar 数据类型);或者字符串格式样式,借以将 float、real、money 或 smallmoney 数据转换为字符数据(nchar、nvarchar、char、varchar、nchar 或 nvarchar 数据类型)。



将某种数据类型的表达式显式转换为另一种数据类型。有关可用的数据类型的更多信息,请参见数据类型。日期格式样式,借以将 datetime 或 smalldatetime 数据转换为字符数据(nchar、nvarchar、char、varchar、nchar 或 nvarchar 数据类型);或者字符串格式样式,借以将 float、real、money 或 smallmoney 数据转换为字符数据(nchar、nvarchar、char、varchar、nchar 或 nvarchar 数据类型)。当转换为字符数据时输出。
 

隐性转换对于用户是不可见的。
SQL Server 自动将数据从一种数据类型转换成另一种数据类型。例如,如果一个 smallint 变量和一个 int 变量相比较,这个 smallint 变量在比较前即被隐性转换成 int 变量。

显式转换使用 CAST 或 CONVERT 函数。
CAST 和 CONVERT 函数将数值从一个数据类型(局部变量、列或其它表达式)转换到另一个数据类型。

例如,下面的 CAST 函数将数值 $157.27 转换成字符串 ''$157.27'':CAST ( $157.27 AS VARCHAR(10) )
CAST 函数基于 SQL-92 标准并且优先于 CONVERT。

当从一个 SQL Server 对象的数据类型向另一个转换时,一些隐性和显式数据类型转换是不支持的。例如,nchar 数值根本就不能被转换成 image 数值。nchar 只能显式地转换成 binary,隐性地转换到 binary 是不支持的。nchar 可以显式地或者隐性地转换成 nvarchar。

当处理 sql_variant 数据类型时,SQL Server 支持将具有其它数据类型的对象隐性转换成 sql_variant 类型。然而,SQL Server 并不支持从 sql_variant 数据隐性地转换到其它数据类型的对象。

 SELECT CONVERT(CHAR(10), CURRENT_TIMESTAMP, 102)

  (102表明使用了ANSI日期模式,即yy.mm.dd型)

  然而,如果你希望将这个变量明确生成为datetime或smalldatetime变量,以此在特定的数据库栏中兼容,那么你可以使用以下语句:

  SELECT CAST(CONVERT(CHAR(10),CURRENT_TIMESTAMP,102) AS DATETIME

  返回值将是 yy.mm.dd 00:00:00(如12:00AM作为时间戳;

函数QUOTENAME
--
功能:返回带有分隔符的Unicode 字符串,分隔符的加入可使输入的字符串成为有效的Microsoft SQL Server 2005 分隔标识符。
--
语法
QUOTENAME ( 'character_string' [ , 'quote_character' ] ) 

--举例说明:

--比如你有一个表,名字叫index
--
你有一个动态查询,参数是表名
declare @tbname varchar(256)
set @tbname='index'
---查这个表里的数据:
print('select * from '+@tbname)
exec('select * from '+@tbname)

--这样print出来的数据是
select * from index

--因为index是字键字,肯定出错,加上括号就可以了:
select * from [index]

--这便有了QUOTENAME,即:
print('select * from '+QUOTENAME(@tbname))
--结果:select * from [index]
exec('select * from '+QUOTENAME(@tbname))

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 * from dbo.orders where rderid=@i';
            exec(@sql);
        出错:必须声明标量变量@i
        原因还是@i不能放在''之内,它只能通过字符串连接动态的嵌入到SQL语句里:
            set @sql='select * from dbo.orders 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语句

加上 N 代表存入数据库时以 Unicode 格式存储。
N'string' 表示string是个Unicode字符串

Unicode 字符串的格式与普通字符串相似,但它前面有一个 N 标识符(N 代表 SQL-92 标准中的国际语言 (National Language))。N 前缀必须是大写字母。例如,'Michél' 是字符串常量而 N'Michél' 则是 Unicode 常量。Unicode 常量被解释为 Unicode 数据,并且不使用代码页进行计算。Unicode 常量确实有排序规则,主要用于控制比较和区分大小写。为 Unicode 常量指派当前数据库的默认排序规则,除非使用 COLLATE 子句为其指定了排序规则。Unicode 数据中的每个字符都使用两个字节进行存储,而字符数据中的每个字符则都使用一个字节进行存储。有关更多信息,请参见使用 Unicode 数据。

Unicode 字符串常量支持增强的排序规则

数据库名是一个标识符,表名也是一个标识符,在SQL SERVER中标识符分为两类:

标识符有两类:

常规标识符

符合标识符的格式规则。在 Transact-SQL 语句中使用常规标识符时不用将其分隔。

SELECT *FROM TableXWHERE KeyCol = 124

分隔标识符

包含在双引号 (") 或者方括号 ([ ]) 内。符合标识符格式规则的标识符可以分隔,也可以不分隔。

SELECT *FROM [TableX]     --Delimiter is optional.WHERE [KeyCol] = 124 --Delimiter is optional.

在 Transact-SQL 语句中,对不符合所有标识符规则的标识符必须进行分隔。

SELECT *FROM [My Table]   --Identifier contains a space and uses a reserved keyword.WHERE [order] = 10  --Identifier is a reserved keyword.

常规标识符和分隔标识符包含的字符数必须在 1 到 128 之间。对于本地临时表,标识符最多可以有 116 个字符。

两者重要的区别:常规标识符必须严格遵守命名的规定,而分隔标识符则可以不遵守命名规定,只要用[],""分隔出来就可以。

标识符格式:
  
  1、标识符必须是统一码(Unicode)2.0标准中规定的字符,以及其他一些语言字符。如汉字.
  
  2、标识符后的字符可以是(除条件一)“_”、“@”、“#”、“$”及数字。
  
  3、标识符不允许是Transact-SQL的保留字。
  
  4、标识符内不允许有空格和特殊字符。
  
  另外,某些以特殊符号开头的标识符在SQL SERVER 中具有特定的含义。

以“@”开头的标识符表示这是一个局部变量或是一个函数的参数;以#开头的标识符表示这是一个临时表或是一存储过程。

以“##”开头的表示这是一个全局的临时数据库对象。T

ransact-SQL的全局变量以“@@”开头。

标识符最多可以容纳128个字符。


推荐阅读
  • 掌握PHP框架开发与应用的核心知识点:构建高效PHP框架所需的技术与能力综述
    掌握PHP框架开发与应用的核心知识点对于构建高效PHP框架至关重要。本文综述了开发PHP框架所需的关键技术和能力,包括但不限于对PHP语言的深入理解、设计模式的应用、数据库操作、安全性措施以及性能优化等方面。对于初学者而言,熟悉主流框架如Laravel、Symfony等的实际应用场景,有助于更好地理解和掌握自定义框架开发的精髓。 ... [详细]
  • PHP连接MySQL的三种方法及预处理语句防止SQL注入的技术详解
    PHP连接MySQL的三种方法及预处理语句防止SQL注入的技术详解 ... [详细]
  • MySQL日志分析在应急响应中的应用与优化策略
    在应急响应中,MySQL日志分析对于检测和应对数据库攻击具有重要意义。常见的攻击手段包括弱口令、SQL注入、权限提升和备份数据窃取。通过对MySQL日志的深入分析,不仅可以及时发现潜在的攻击行为,还能详细还原攻击过程并追踪攻击源头。此外,优化日志记录和分析策略,能够提高安全响应效率,增强系统的整体安全性。 ... [详细]
  • 在《OWASP TOP 10 注入漏洞》中,详细探讨了注入攻击的发生机制:当应用程序未能有效识别和拦截恶意输入时,攻击者可以通过 SQL 注入等手段利用这一漏洞。本文将重点介绍 SQL 注入的基本原理及其防范措施,帮助读者全面了解并有效应对这一常见安全威胁。 ... [详细]
  • 智能制造数据综合分析与应用解决方案
    在智能制造领域,生产数据通过先进的采集设备收集,并利用时序数据库或关系型数据库进行高效存储。这些数据经过处理后,通过可视化数据大屏呈现,为生产车间、生产控制中心以及管理层提供实时、精准的信息支持,助力不同应用场景下的决策优化和效率提升。 ... [详细]
  • 本题库精选了Java核心知识点的练习题,旨在帮助学习者巩固和检验对Java理论基础的掌握。其中,选择题部分涵盖了访问控制权限等关键概念,例如,Java语言中仅允许子类或同一包内的类访问的访问权限为protected。此外,题库还包括其他重要知识点,如异常处理、多线程、集合框架等,全面覆盖Java编程的核心内容。 ... [详细]
  • 探索 PHP 8.0 的重大更新:轻松获取年度月份数据
    PHP 8.0 引入了多项重要更新,包括增强的类型系统、全新的 JIT 编译器以及联合类型等特性。这些改进不仅提升了性能,还简化了开发流程。本文将重点介绍如何利用 PHP 8.0 的新功能轻松获取年度和月份数据,为开发者提供更高效、更简洁的解决方案。 ... [详细]
  • SQLmap自动化注入工具命令详解(第28-29天 实战演练)
    SQL注入工具如SQLMap等在网络安全测试中广泛应用。SQLMap是一款开源的自动化SQL注入工具,支持12种不同的数据库,具体支持的数据库类型可在其插件目录中查看。作为当前最强大的注入工具之一,SQLMap在实际应用中具有极高的效率和准确性。 ... [详细]
  • MarsJava 最新发布了 2.1.7 版本,此次更新带来了多项性能优化和功能增强。新版本在系统稳定性、响应速度和资源管理方面进行了显著改进,进一步提升了用户体验。同时,新增了多个实用功能,满足开发者在复杂应用场景中的需求。 ... [详细]
  • 中国安全防护服务运营分析:视频监控维护服务的未来走向与发展潜力
    本文探讨了视频监控运维服务在中国的发展趋势与潜力。近年来,随着对安全防护需求的不断增加,视频监控系统作为高效、直观且准确的防范工具,逐渐受到政府和企业的高度重视。该系统能够实时呈现设防区域的现场情况,为安全管理和应急响应提供了重要支持。未来,随着技术的不断进步和应用场景的拓展,视频监控运维服务有望迎来更加广阔的发展空间。 ... [详细]
  • 深入解析MyBatis的高级映射技术
    在前一章节中,我们探讨了MyBatis的基本对象映射方法,其中对象属性与数据库表字段之间实现了直接的一对一映射。然而,在实际开发中,这种简单的映射方式往往难以满足复杂业务需求。本文将深入分析MyBatis的高级映射技术,介绍如何通过配置和注解实现更为灵活的对象与数据库表之间的映射关系,包括嵌套结果、联合查询和动态SQL等高级功能,以提高开发效率和代码可维护性。 ... [详细]
  • 在 Spring Boot 项目中,实现多数据源配置以支持 MySQL 和 Oracle 数据库的 JDBC 集成。通过合理配置 `application.properties` 文件,可以轻松管理不同数据源的连接属性,确保应用能够高效地访问多种数据库系统。具体配置包括端口设置、字符编码以及数据库连接参数等,为开发者提供了灵活的数据访问解决方案。 ... [详细]
  • 内网渗透技术详解:PTH、PTT与PTK在域控环境中的应用及猫盘内网穿透配置
    本文深入探讨了内网渗透技术,特别是PTH、PTT与PTK在域控环境中的应用,并详细介绍了猫盘内网穿透的配置方法。通过这些技术,安全研究人员可以更有效地进行内网渗透测试,解决常见的渗透测试难题。此外,文章还提供了实用的配置示例和操作步骤,帮助读者更好地理解和应用这些技术。 ... [详细]
  • Spring 中获取 Request 的多种方式及其线程安全性的深入解析
    本文深入探讨了在Spring MVC框架下获取HTTP请求对象的多种方法,详细分析了每种方法的实现原理及其线程安全性,为开发者提供了全面的技术参考。 ... [详细]
  • 作为140字符的开创者,Twitter看似简单却异常复杂。其简洁之处在于仅用140个字符就能实现信息的高效传播,甚至在多次全球性事件中超越传统媒体的速度。然而,为了支持2亿用户的高效使用,其背后的技术架构和系统设计则极为复杂,涉及高并发处理、数据存储和实时传输等多个技术挑战。 ... [详细]
author-avatar
迷人的哈喽柯柯_458
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有