65.9K
CodeProject 正在变化。 阅读更多。
Home

SQL Champ - 证明您的 SQL 知识的测验

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.42/5 (9投票s)

2008 年 3 月 31 日

CPOL

7分钟阅读

viewsIcon

46139

软件架构师邀请您通过参加月度测验来证明您在微软 .NET 技术某些主题方面的知识。本月测验的主题是 SQL Server。

SQLChampLogo.png

引言

软件架构师 邀请您通过参加月度测验来证明您在微软 .NET 技术某些主题方面的知识。本月,测验的主题是 SQL Server。在本文中,您可以重读这些问题。此外,您还将获得关于正确答案的背景信息。

您现在还没有做测试吗? 先尝试一下,然后再回来阅读答案!

以下是测验中包含的所有问题列表。使用超链接跳转到您感兴趣的主题

问题 1 - 一个简单的开始

您想访问不在您域中的 SQL Server 实例。您唯一能使用的网络协议是 TCP/IP。您需要在您的计算机和运行 SQL Server 的服务器之间的防火墙上打开哪些端口?

  1. SQL Server 使用随机端口
  2. 1433
  3. 1433 和 1434
  4. 这取决于;端口可以由管理员选择

正确答案是这取决于;端口可以由管理员选择。1433 是 SQL Server 默认实例的默认端口(由 IANA - Internet Assigned Numbers Authority 分配;请参见 http://www.iana.org/assignments/port-numbers)。在 2000 版本之前,一个端口就足够了,因为在单台服务器上,您只能运行一个 SQL Server 实例。然而,自 2000 版本以来,可以有多个实例,因此管理员可以选择哪个端口被哪个实例使用。

端口 1434 (UDP) 用于 SQL Server Browser 服务。客户端可以使用此服务查询有关所有运行中的 SQL Server 实例的连接信息(TCP/IP 端口或命名管道)。如果您知道要连接的实例正在使用哪个端口,则根本不需要 SQL Server Browser。因此,在这种情况下,您不需要连接到端口 1434。

sqlQuizQuestion1.png

SQL Server 配置管理器中的端口设置

问题 2 - 数据类型

您想跟踪每行最后一次写入访问(INSERT, UPDATE)的日期和时间。如何实现?

  1. 向表中添加 TIMESTAMP 列;SQL Server 将自动跟踪每次更改的日期和时间。
  2. 向表中添加 DATETIME 列,并将 getdate() 指定为默认值。
  3. 向表中添加 DATETIME 列,并编写一个触发器来设置其值。
  4. 向表中添加 UNIQUEIDENTIFIER 列,并将其与 SQL Server 的内置函数一起使用。

正确答案是向表中添加 DATETIME 列,并编写一个触发器来设置其值TIMESTAMP 在这种情况下没有帮助,因为它不记录任何日期或时间值。它只是提供了一种生成唯一二进制数字的方法,当行内容发生更改时,该数字会发生变化。以下脚本展示了如何使用 TIMESTAMP

use tempdb;

create table ChangeTrackingTest ( 
  MyId int primary key, 
  MyDesc varchar(50), 
  MyTimestamp timestamp 
); 

insert into ChangeTrackingTest ( MyId, MyDesc ) 
values ( 1, 'Test' ); 

select * from ChangeTrackingTest; 

update ChangeTrackingTest 
set MyDesc = 'Test 2' 
where MyId = 1; 

select * from ChangeTrackingTest;

这是此批处理的结果。请注意 TIMESTAMP 列的值是如何变化的

(1 row(s) affected) 

MyId MyDesc MyTimestamp 
---------------------------
1 Test 0x00000000000007D4 


(1 row(s) affected) 
(1 row(s) affected) 


MyId MyDesc MyTimestamp 
---------------------------
1 Test 2 0x00000000000007D5 

(1 row(s) affected)

第二个答案是错误的,因为此解决方案只会记录每行创建时的日期和时间。在 UPDATE 语句的情况下,列的内容不会改变。第四个答案也是错误的,仅仅因为没有这样的内置函数。

如果您只想记录最后更改的日期和时间,以识别自某个时间点以来发生更改的行(例如,用于 DWH 的增量加载),并且您可以使用 SQL Server 2008,请查看 更改跟踪和数据捕获。它们提供了一种无需更改表结构即可实现此目的的机制。

问题 3 - 日期和时间处理

以下语句的结果是什么:select cast(floor(cast(@MyDateTime as float)) as datetime)

  1. 相对于 @MyDateTime 的下一个星期日。
  2. @MyDateTime 的日期部分。
  3. @MyDateTime 的时间部分。
  4. 无法工作,因为无法将 float 转换为 datetime

第二个答案@MyDateTime 的日期部分是正确的。如果将 datetime 值转换为 float,则会得到一个浮点值,表示自 1900 年 1 月 1 日以来的天数

select cast(cast('1900-01-01 00:00:00' as datetime) as float)

---------------------- 
0 

(1 row(s) affected)

小数部分代表时间

select cast(cast('1900-01-01 12:00:00' as datetime) as float)

---------------------- 
0,5 

(1 row(s) affected)

上面显示的语句将 datetime 变量转换为 float,使用 floor 删除小数部分,然后将结果转换回 datetime。因此,它删除了 datetime 变量的时间部分。与 SQL Server 2005 相比,2008 版本提供了独立的日期和时间数据类型。在 MSDN 中阅读有关这些新数据类型的更多信息。

问题 4 - 聚合

以下语句在 SQL Server 2005 中是否有效?

select CustomerKey, 
       ProductKey, 
       sum(SalesAmount) as SumSalesAmount, 
       sum(SalesAmount) / 
         sum(sum(SalesAmount)) over ( partition by CustomerKey ) 
         * 100 as SumSumSalesAmount 
from   dbo.FactInternetSales 
group by CustomerKey, 
       ProductKey 
order by CustomerKey, 
       ProductKey
  1. 否,语法错误
  2. 否,但 SQL Server 2008 支持此语法

此语句在 SQL Server 2005 中有效!您可能知道 over 关键字来自 排名函数。但是,人们普遍不知道 over 也可以与传统的聚合函数一起使用。

我们上面的示例生成了销售统计信息,包括客户、产品以及每个客户通过每个产品产生的收入。第四列计算每个产品收入占客户总收入的比例。

注意:您可以使用 Microsoft 的示例数据库 AdventureWorksDW 来尝试此语句。

问题 5 - SQLCLR

在权限集设置为 SAFE 的情况下,.NET Framework 的哪些类可以在 SQLCLR 程序集中使用?

  1. 所有类。权限集设置为 SAFE 仅限制对非托管代码的使用。
  2. 无。要在 SQL Server 中使用 .NET Framework 中的类,至少需要将权限集设置为 EXTERNAL。
  3. 其中一些经过了专门测试,可在 SQL Server 中使用,它们可以使用。
  4. 权限集与 SQLCLR 无关。

正确答案是其中一些经过了专门测试,可在 SQL Server 中使用,它们可以使用。有一个硬编码的类程序集列表,SQL Server 从文件系统中加载这些类程序集。这些类程序集已经过广泛的代码审查,以确保它们不会破坏 SQL Server 的稳定性。可以在 MSDN 上找到 SQL Server 从 GAC 加载的类程序集列表。

但是,一些类程序集包含受支持和不受支持的功能(例如,mscorlib)。对于这些情况,Microsoft 引入了 HostProtectionAttribute 属性。不允许在 SQL Server 中使用的类型和成员都带有此属性。您可以在 MSDN 中找到不允许的类型和成员列表。

问题 6 - 数据库快照

使用最新的四核服务器和 RAID 5 创建一个 100GB 数据库的快照大约需要多长时间?

  1. 几秒钟。
  2. 大约 5 分钟。
  3. 通常大约一个小时;取决于服务器上的负载。
  4. 超过一个小时,但它在后台运行。

正确答案是几秒钟。数据库快照使用稀疏文件(有关稀疏文件的更多信息,请参阅 Wikipedia)。这意味着在创建快照时不会复制数据库。数据页在源数据库中被修改之前会被立即复制。此机制称为写时复制。因此,创建数据库快照非常快。当您在源数据库上写入时,需要付出性能代价。

CopyOnWrite.gif

写时复制(来源:MSDN

问题 7 - TOP 子句

在 SQL Server 2005 中,可以在哪些语句中使用 TOP 子句?

  1. SELECT
  2. SELECT, INSERT(如果与 INSERT...SELECT 语法一起使用)
  3. SELECT, INSERT, UPDATE, DELETE
  4. 无。 TOP 是 SQL Server 2008 新增的功能

正确答案是SELECT, INSERT, UPDATE, DELETE。在 SQL Server 2000 中,TOP 只在 SELECT 语句中受支持。自 SQL Server 2005 起,您也可以在 INSERT, UPDATEDELETE 语句中使用 TOP。以下是 TOPDELETE 语句中使用的示例

use tempdb;

create table Orders ( OrderId int, CustId int, Revenue money ); 

insert into Orders ( OrderId, CustId, Revenue ) 
select 1, 1, 5000 union all 
select 2, 1, 1000 union all 
select 3, 2, 500 union all 
select 4, 2, 100 union all 
select 5, 3, 50 union all 
select 6, 3, 10; 

while exists ( select 1 from Orders where CustId = 1 ) 
  delete top(1) from Orders where CustId = 1; 

select * from Orders;

您可能会问,为什么有人会写这样奇怪的脚本来删除某个客户的所有订单。想象一下 Orders 表包含大量行。如果您在单个 Delete 语句中删除客户 1 的所有订单,这将导致一个非常大的事务。处理起来可能很困难(例如,事务日志的磁盘空间可能非常关键,停止事务可能需要很长时间等)。使用 delete top(n),您可以将大事务分解为多个小事务。

注意:在 INSERT, UPDATEDELETE 语句中,分隔 TOP 中表达式的括号是必需的。为了向后兼容,支持不带括号的 TOP 表达式,但 Microsoft 不推荐这样做。

© . All rights reserved.