我最近看到一条推文,指出您可以SELECT * FROM TableName通过以下方式构建表来阻止其他开发人员使用来从表中读取内容:
CREATE TABLE [TableName]
(
[ID] INT IDENTITY NOT NULL,
[Name] VARCHAR(50) NOT NULL,
[DontUseStar] AS (1 / 0)
);
Run Code Online (Sandbox Code Playgroud)
很容易看到,使用SELECT *此处会尝试将空白列名称读取为1除以0(从而导致除以零的错误),但没有为该列分配数据类型。
为什么SQL允许您创建一个没有分配数据类型的列,并且知道它的名称是非法的?
Dan*_*l N 10
对于计算列,这是一种完全有效的语法。尽管可以持久保存值,但可以使用计算列来选择某些值,而无需实际存储它们。
之所以允许1/0,是因为直到运行时才评估实际的计算列值。例如,可以将计算列定义为columna / columnb,如果columnb中的任何行具有0且为,则将发生相同的错误,但仅当选择了该行/列时才会发生。
if object_id('tempdb..#t') IS NOT NULL
drop table #t;
CREATE TABLE #t
(a int
,b int
,div as (a/b)
);
INSERT INTO #t
values
(1,1)
,(2,0);
SELECT * FROM #t WHERE a = 1;
SELECT a from #t; -- NO ERRORS
SELECT * FROM #t WHERE a=2; --WILL RESULT IN AN ERROR
SELECT * FROM #t; --WILL RESULT IN AN ERROR
Run Code Online (Sandbox Code Playgroud)
您创建的是一个计算列,它非常强大且有用!
表达式可以是任何东西。例如,您可以定义:
CREATE TABLE [TableName] (
[ID] INT IDENTITY NOT NULL,
[Name] VARCHAR(50) NOT NULL,
NameLength as (LEN(Name))
);
Run Code Online (Sandbox Code Playgroud)
这将创建一个称为的列NameLength,并且始终具有Name您引用该列时的长度update-no s,没有触发器,没有视图。它只是工作。
您不需要类型,因为SQL Server可以弄清楚。
您所犯的错误甚至可能是有益的-如果您确实想强制执行用户永远不会使用的错误select *。
| 归档时间: |
|
| 查看次数: |
385 次 |
| 最近记录: |