1、SQL Server表设计视图中的数据类型列展示效果
 
在SQL Server 2012的表设计视图中可以看到如下图的效果:
如上图所示红色矩形框圈住的数据类型列中展示的效果,特别针对用户定义数据类型也显示了其基本数据类型。
 
这种针对字段列显示的数据类型效果很直接,很容易看到其数据类类型是什么,甚至看能看到精度或小数位,最重要的是显示了用户定义数据类型的基本数据类型。有时候在数据库设计中往往定义通用的用户定义数据类型,如身份证,手机号码,性别,名称等等通用的用户定义数据类型。
 
有时候将表字段列导出来保存doc、excel以及html,针对字段列的数据类型显示往往需要4个字段列来展示,如下图所示:
上图所示的就不太很直观的看出该字段的数据类型的详细信息,特别该字段列的数据类型为用户定义的数据类型时,更无从看出来它的基本数据类型。
 
注意:在SQL Server中sysname数据定义数据类型默认是系统定义的,在表设计视图中找不到该该数据类型,只能通过DDL命令来定义属于sysname的字段列。
 
2、模拟实现类似的数据类型显示效果
 
为了将字段列显示的数据类型展示的更有清晰简单,本人就模拟SQL Server 表设计视图中的字段列的展示效果的实现功能。
 
实现一个标量函数,支持将基本数据类型大小写的功能,具体的T-SQL代码如下:
  1. IF OBJECT_ID(N'[dbo].[ufn_GetDisplayDataTypeName]', 'FN') IS NOT NULL
  2. BEGIN
  3. DROP FUNCTION [dbo].[ufn_GetDisplayDataTypeName];
  4. END
  5. GO
  6.  
  7. --==================================
  8. -- 功能: 获取字段列显示的数据类型名称
  9. -- 说明: 支持用户定义类型,可以运行于SQL Server 2005+
  10. -- 创建: yyyy-MM-dd hh:mm-hh:mm XXX 创建内容描述
  11. -- 修改: yyyy-MM-dd hh:mm-hh:mm XXX 修改内容描述
  12. --==================================
  13. CREATE FUNCTION [dbo].[ufn_GetDisplayDataTypeName]
  14. (
  15. @intUserTypeID AS INT -- 用户类型ID
  16. ,@sntMaxLength AS SMALLINT -- 最大字节长度
  17. ,@tntPrecision AS TINYINT -- 精度
  18. ,@tntScale AS TINYINT -- 小数位
  19. ,@bitIsUpperDisplay AS BIT = 0 -- 是否大写显示(默认小写显示)
  20. ) RETURNS NVARCHAR(270)
  21. AS
  22. BEGIN
  23. SET @bitIsUpperDisplay = ISNULL(@bitIsUpperDisplay, 0);
  24.  
  25. DECLARE
  26. @nvcDataTypeName AS NVARCHAR(128)
  27. ,@nvcBaseDataTypeName AS NVARCHAR(128)
  28. ,@nvcSuffixDisplayName AS NVARCHAR(14)
  29. SELECT
  30. @nvcDataTypeName = N''
  31. ,@nvcBaseDataTypeName = N''
  32. ,@nvcSuffixDisplayName = N''
  33.  
  34. SELECT
  35. @nvcDataTypeName = [name]
  36. ,@nvcBaseDataTypeName = (CASE WHEN (@nvcDataTypeName = N'sysname' OR [is_user_defined] = 1) THEN TYPE_NAME([system_type_id]) ELSE @nvcDataTypeName END)
  37. FROM
  38. [sys].[types]
  39. WHERE
  40. [user_type_id] = @intUserTypeID;
  41.  
  42. SET @nvcDataTypeName = (CASE WHEN @nvcDataTypeName <> @nvcBaseDataTypeName THEN @nvcDataTypeName + N':' ELSE N'' END);
  43.  
  44. SET @nvcBaseDataTypeName = CASE @bitIsUpperDisplay WHEN 1 THEN UPPER(@nvcBaseDataTypeName) ELSE @nvcBaseDataTypeName END;
  45.  
  46. SET @nvcSuffixDisplayName = (CASE
  47. WHEN @nvcBaseDataTypeName = N'char' THEN QUOTENAME(RTRIM(CAST(@sntMaxLength AS VARCHAR(4))), N')')
  48. WHEN @nvcBaseDataTypeName = N'varchar' THEN (CASE WHEN @sntMaxLength = -1 THEN N'(MAX)' ELSE QUOTENAME(RTRIM(CAST(@sntMaxLength AS VARCHAR(4))), N')') END)
  49. WHEN @nvcBaseDataTypeName = N'nchar' THEN QUOTENAME(RTRIM(CAST(@sntMaxLength / 2 AS VARCHAR(4))), N')')
  50. WHEN @nvcBaseDataTypeName = N'nvarchar' THEN (CASE WHEN @sntMaxLength = -1 THEN N'(MAX)' ELSE QUOTENAME(RTRIM(CAST(@sntMaxLength / 2 AS VARCHAR(4))), N')') END)
  51. WHEN @nvcBaseDataTypeName = N'binary' THEN QUOTENAME(RTRIM(CAST(@sntMaxLength AS VARCHAR(4))), N')')
  52. WHEN @nvcBaseDataTypeName = N'varbinary' THEN (CASE WHEN @sntMaxLength = -1 THEN N'(MAX)' ELSE QUOTENAME(RTRIM(CAST(@sntMaxLength / 2 AS VARCHAR(4))), N')') END)
  53. WHEN @nvcBaseDataTypeName IN (N'numeric', N'decimal') THEN QUOTENAME(RTRIM(CAST(@tntPrecision AS VARCHAR(4))) + N',' + RTRIM(CAST(@tntScale AS VARCHAR(4))), N')')
  54. WHEN @nvcBaseDataTypeName IN (N'time', N'datetime2', N'datetimeoffset') THEN QUOTENAME(RTRIM(CAST(@tntScale AS VARCHAR(4))), N')')
  55. ELSE N'' END);
  56.  
  57. RETURN @nvcDataTypeName + @nvcBaseDataTypeName + @nvcSuffixDisplayName;
  58. END
  59. GO

 

3、测试效果
 
演示上面标量函数的展示效果,以下定义若干用户定义数据类型来验证标量函数dbo.ufn_GetDisplayDataTypeName的效果。
 
以下准备要验证效果的数据如下:

  1. CREATE TYPE [dbo].[fd_udt_digest] FROM [NVARCHAR](255) NULL
  2. GO
  3.  
  4. CREATE TYPE [dbo].[fd_udt_id] FROM [CHAR](15) NOT NULL
  5. GO
  6.  
  7. CREATE TYPE [dbo].[fd_udt_username] FROM [NVARCHAR](20) NULL
  8. GO
  9.  
  10. CREATE TYPE [dbo].[UFemail] FROM [VARCHAR](100) NULL
  11. GO
  12.  
  13. CREATE TYPE [dbo].[UFFlag] FROM [CHAR](1) NULL
  14. GO
  15.  
  16. CREATE TYPE [dbo].[UFhyperlink] FROM [VARCHAR](100) NULL
  17. GO
  18.  
  19. CREATE TYPE [dbo].[UFMedia] FROM [IMAGE] NULL
  20. GO
  21.  
  22. CREATE TYPE [dbo].[UFreference] FROM [VARCHAR](30) NULL
  23. GO
  24.  
  25. CREATE TYPE [dbo].[UFtext] FROM [NTEXT] NULL
  26. GO
  27.  
  28. CREATE TYPE [dbo].[UFUID] FROM [UNIQUEIDENTIFIER] NULL
  29. GO
  30.  
  31. CREATE TYPE [dbo].[userdecimal] FROM [DECIMAL](28, 6) NOT NULL
  32. GO
  33.  
  34. CREATE TYPE [dbo].[udtProduct] AS TABLE
  35. (
  36. ProductID INT NOT NULL
  37. ,UnitPrice DECIMAL(9, 2) NOT NULL
  38. ,Quantity INT NOT NULL
  39. PRIMARY KEY ([ProductID] ASC)
  40. )
  41. GO
  42.  
  43. CREATE TABLE [dbo].[ScaleDataTypeTable](
  44. [ColDecimal] [NUMERIC](18, 2) NULL,
  45. [ColNumeric] [NUMERIC](9, 2) NULL,
  46. [ColFloat] [FLOAT] NULL,
  47. [ColReal] [REAL] NULL,
  48. [ColTime] [TIME](5) NOT NULL,
  49. [ColDateTime2] [DATETIME2](3) NULL,
  50. [ColDateTimeOffset] [DATETIMEOFFSET](5) NULL,
  51. [ColSqlVariant] [SQL_VARIANT] NULL,
  52. [ColMoney] [MONEY] NULL,
  53. [ColSmallMoney] [SMALLMONEY] NULL,
  54. [Col1] [dbo].[fd_udt_digest] NULL,
  55. [Col2] [dbo].[fd_udt_id] NULL,
  56. [Col3] [dbo].[fd_udt_username] NULL,
  57. [Col4] [dbo].[UFemail] NULL,
  58. [Col5] [dbo].[UFFlag] NULL,
  59. [Col6] [dbo].[UFhyperlink] NULL,
  60. [Col7] [dbo].[UFMedia] NULL,
  61. [Col8] [dbo].[UFreference] NULL,
  62. [Col9] [dbo].[UFtext] NULL,
  63. [Col10] [dbo].[UFUID] NULL,
  64. [Col11] [dbo].[userdecimal] NULL,
  65. [Col12] HIERARCHYID NULL,
  66. [Col13] GEOMETRY NULL,
  67. [Col14] GEOGRAPHY NOT NULL,
  68. [Col15] CHAR(10) NOT NULL,
  69. [Col16] VARCHAR(25) NOT NULL,
  70. [Col16Max] VARCHAR(MAX) NOT NULL,
  71. [Col17] NCHAR(16) NOT NULL,
  72. [Col18] NVARCHAR(32) NOT NULL,
  73. [Col18Max] NVARCHAR(MAX) NOT NULL,
  74. [ColBigint] BIGINT NOT NULL,
  75. [ColInt] INT NOT NULL,
  76. [ColSmallint] INT NOT NULL,
  77. [ColTinyint] TINYINT NOT NULL,
  78. [ColBit] BIT NOT NULL,
  79. [Col19] DECIMAL(9,7) NOT NULL,
  80. [Col20] MONEY NOT NULL,
  81. [Col21] SMALLMONEY NOT NULL,
  82. [Col22] TIMESTAMP NOT NULL,
  83. [Col24] UNIQUEIDENTIFIER NOT NULL,
  84. [Col25] IMAGE NOT NULL,
  85. [Col26] TEXT NOT NULL,
  86. [Col27] NTEXT NOT NULL,
  87. [Col28] BINARY(8) NOT NULL,
  88. [Col29] VARBINARY(8) NOT NULL,
  89. [Col29Max] VARBINARY(MAX) NOT NULL,
  90. [ColMxml] XML NULL,
  91. [Col30] DATE NOT NULL,
  92. [Col31] DATETIME NOT NULL,
  93. [Col32] SMALLDATETIME NOT NULL
  94. ) ON [PRIMARY];
  95.  
  96. GO
  97.  
  98. CREATE TABLE [dbo].[UpdateDataTable]
  99. (
  100. UpdateDataTableId INT NOT NULL,
  101. [Col23] ROWVERSION NOT NULL,
  102. [Colname] sysname NOT NULL
  103. ) ON [PRIMARY];
  104. GO

基本数据类型小写展示的效果的T-SQL代码和效果截图如下:

  1. SELECT
  2. T2.[name] AS [table_name]
  3. ,[T1].[name] AS [column_name]
  4. ,TYPE_NAME([T1].[user_type_id]) AS [column_datatype]
  5. ,[dbo].[ufn_GetDisplayDataTypeName]([T1].[user_type_id], [T1].[max_length], [T1].[precision], [T1].[scale], 0) AS [column_display_datatype]
  6. ,[T1].[max_length]
  7. ,[T1].[precision]
  8. ,[T1].[scale]
  9.  
  10. FROM
  11. [sys].[all_columns] AS T1
  12. INNER JOIN [sys].[all_objects] AS T2
  13. ON [T1].[object_id] = [T2].[object_id]
  14. WHERE
  15. [T2].[name] IN (N'ScaleDataTypeTable', N'UpdateDataTable')
  16. --AND EXISTS (SELECT 1 FROM [sys].[types] WHERE ([name] = N'sysname' OR [is_user_defined] = 1) AND [user_type_id] = [T1].[user_type_id]);
  17. GO

 
基本数据类型大写展示的效果的T-SQL代码和效果截图如下:
  1. SELECT
  2. T2.[name] AS [table_name]
  3. ,[T1].[name] AS [column_name]
  4. ,TYPE_NAME([T1].[user_type_id]) AS [column_datatype]
  5. ,[dbo].[ufn_GetDisplayDataTypeName]([T1].[user_type_id], [T1].[max_length], [T1].[precision], [T1].[scale], 1) AS [column_display_datatype]
  6. ,[T1].[max_length]
  7. ,[T1].[precision]
  8. ,[T1].[scale]
  9.  
  10. FROM
  11. [sys].[all_columns] AS T1
  12. INNER JOIN [sys].[all_objects] AS T2
  13. ON [T1].[object_id] = [T2].[object_id]
  14. WHERE
  15. [T2].[name] IN (N'ScaleDataTypeTable', N'UpdateDataTable')
  16. --AND EXISTS (SELECT 1 FROM [sys].[types] WHERE ([name] = N'sysname' OR [is_user_defined] = 1) AND [user_type_id] = [T1].[user_type_id]);
  17. GO
 
4、总结语
 
这个功能刚开始自己使用了2个标量函数,针对sys.types每次查询最多调用四次;第二版本则集中到一个标量函数中,还是针对sys.types每次查询最多调用4次;第三版则重构和优化为sys.types每次查询最多2次;第4版本继续重构代码将函数返回的结果分为三个部分的联结,这样重构更简单明了;最后一版本增加了针对基本数据类型的大小写功能。
 
都说代码重构,这个功能的实现我确实感受到了重构和优化的效果,以上五个版本下来,有确实感觉到真正做好一件事情确实要好好的思考和动手实践的,不然很容易要么头脑迟钝要么眼高手低等不好的习惯养成的。近来一直在看数据库和商业智能方便的数据集,更印证了知道的越多,不知道和迫切想了解的就更多。如何将理论更好的指导实践以及实践更好的印证理论的可行性,需要更多的身体力行。
 
尽量要求自己每周至少发一篇博文和大家一起讨论学习进步。虽然自己也在转载和记录工作中或是自己动手实践的东西,有时候真的感觉时间有些不够用,需要更多的汲取其他优秀人员的技能和理论,才能谨慎的写下自己的所思所想,如果不周或认知不正确的地方也请各位海涵。近来学习到的东西太多,才发现之前发布的的东西有不正确的地方,慢慢地我根据现有的认知来更正。
 
5、参考清单列表
无。

模拟实现SQL Server字段列显示的数据类型的更多相关文章

  1. SQL Server 关于列的权限控制

    在SQL SERVER中列权限(Column Permissions)其实真没有什么好说的,但是好多人对这个都不甚了解,已经被人问了几次了,所以还是在这里介绍一下,很多人都会问,我能否单独对表的某列授 ...

  2. SQL Server 字段类型 decimal(18,6)小数点前是几位?记一次数据库SP的BUG处理

    原文:SQL Server 字段类型 decimal(18,6)小数点前是几位?记一次数据库SP的BUG处理 SQL Server 字段类型 decimal(18,6)小数点前是几位? 不可否认,这是 ...

  3. SQL Server 索引列的顺序——真的没关系吗

    原文:SQL Server 索引列的顺序--真的没关系吗 翻译自:http://www.mssqltips.com/sqlservertip/2718/sql-server-index-column- ...

  4. mysql/sql server和java之间的数据类型对应关系

    Mysql************************************当前列 ClassName ColumnType DisplaySize TypeName0: java.lang.I ...

  5. sql server 数据库优化--显示执行计划

      刚开始用SQL Server的时候,我没有用显示执行计划来对查询进行分析.我曾经一直认为我递交的SQL查询都是最优的,而忽略了查询性能究竟如何,从而对“执行计划”重视不够.在我职业初期,我只要能获 ...

  6. 使用sql语句创建修改SQL Server标识列(即自动增长列)

    一.标识列的定义以及特点SQL Server中的标识列又称标识符列,习惯上又叫自增列.该种列具有以下三种特点:1.列的数据类型为不带小数的数值类型2.在进行插入(Insert)操作时,该列的值是由系统 ...

  7. SQL Server 一列或多列重复数据的查询,删除(转载)

    转载来源:https://www.cnblogs.com/sunxi/p/4572332.html 业务需求 最近给公司做一个小工具,把某个数据库(数据源)的数据导进另一个数据(目标数据库).要求导入 ...

  8. SQL Server计算列

    计算列由可以使用同一表中的其他列的表达式计算得来.表达式可以是非计算列的列名.常量.函数,也可以是用一个或多个运算符连接的上述元素的任意组合.表达式不能为子查询. 例如,在 AdventureWork ...

  9. SQL Server 字段提取拼音首字母

    目前工作中遇到一个情况,需要将SQL Server中的一个字段提取拼音的首字母,字段由汉字.英文.数字以及“-”构成,百度了一堆,找到如下方法,记录一下,以备后用! 首先建立一个函数 --生成拼音首码 ...

随机推荐

  1. 移动端click时间延迟300

    解决移动端click延迟事件方法,,引入fastclick.js  然后在script标签里面写上FastClick.attach(document.body); <!DOCTYPE html& ...

  2. java基本数据类型

    基本数据类型概念 java是一种强类型语言,意味着必须为每一个变量声明一种数据类型. java拥有8中基本数据类型,主要包含如下:4中整形类型(long.int.short.byte)表示整形数值:两 ...

  3. 多种坐标系之间的转换 Proj.NET和DotSpatial

    Proj.NET ( http://projnet.codeplex.com/)是一个.NET下开源的空间参照和投影引擎,遵循OGC相关标准.负责人(Coordinators )是D_Guidi 和S ...

  4. ABP理论学习之开篇介绍

    返回总目录 为了和2016年春节赛跑,完成该系列博客,我牺牲了今天中午的时间来完成该系列的第一篇----开篇介绍.开篇介绍嘛,读过大学教材的同学都知道,这玩意总是那么无聊,跟考试没关系,干脆直接跳过, ...

  5. 【腾讯Bugly干货分享】WebP原理和Android支持现状介绍

    本文来自于腾讯bugly开发者社区,未经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/582939577ef9c5b708556b0d 1.背景 目前网络中图片仍然是占 ...

  6. 自己动手写文件查找,字符串查找,查询jar包等工具

    文件查找——搜索当前目录下的文件 知道大概的文件名称,使用 findf FileName findf.py import argparse, re, os from os.path import jo ...

  7. 垃圾回收机制GC知识再总结兼谈如何用好GC

    一.为什么需要GC 应用程序对资源操作,通常简单分为以下几个步骤: 1.为对应的资源分配内存 2.初始化内存 3.使用资源 4.清理资源 5.释放内存 应用程序对资源(内存使用)管理的方式,常见的一般 ...

  8. UpdateData(TRUE)与UpdateData(FALSE)的使用

    二者是更新对话框的控件与变量. 1.先要建立对应关系 如 编辑框IDC_Edit  和 变量 m_name DDX_Text(pDX, IDC_EDIT, m_name); 2.若是在编辑框输入名字 ...

  9. Ucos系统任务间的通信详解

    物联网开发中,ucos系统任务间的通信是指,两个任务之间有数据的交互,具体的一起来看看吧. 1)消息邮箱 我们还是提供两个任务Task1和Task2,假设我们还是解决刚刚的问题,Task1进行按键扫描 ...

  10. 浅谈ThinkPHP3.2的子域名部署和路由优化(一)

    前言:建立一个网站系统,往往包含多个子网站,例如PC官网,移动端官网,后台管理,数据源自一个相同的数据库,整个架构上,从ThinkPHP来看,可以大体理解为Model(M)是一样的,Controlle ...