T-SQL常见基础疑点问答总结
--建立测试环境
IF object_id('tb') IS NOT NULL
DROP TABLE tb
GO
CREATE TABLE tb(id INT IDENTITY(1,1),v VARCHAR(10))
GO
INSERT tb SELECT 'a'
UNION ALL SELECT 'b'
INSERT tb SELECT 'x'
UNION ALL SELECT 'z'
GO
--=**********************************************
--为什么我执行下面的语句选不到正确数据
CREATE PROC p
(
@field VARCHAR(10),--字段名
@value VARCHAR(10) --值
)
AS
SELECT * FROM tb WHERE @field=@value
GO EXEC p 'v','a'
GO
DROP PROC p
GO
上面的proc执行正确
为什么我执行下面语句报错
CREATE PROC p
(
@table VARCHAR(10),--表名
@value VARCHAR(10) --值
)
AS
SELECT * FROM @table WHERE v=@value
说明:
在这二个存储过程中,@table,@field,@value都被定义为varchar
第一个实际上执行的是两个变量的比较,它的作用相当于
IF @field=@value
SELECT * FROM tb
语法未错,意思上却大错特错
第二个实际上执行的是
SELECT * FROM 一个字串 WHERE v=@value
如何能从一个字串中查询结果集呢?错误的把字串当成表对象来理解.
请记住@table是个表名,它是个字段,而非表对象,不是object
(2)为什么我在执行一个批语句(可能是存储过程,
也可能是个FUNCTION,也可能只是几条语句的组合)时,
提示错误,我照着提示的错误,检查,但是那里没有报错啊
--=**********************************************
比如,上面的第二个存储过程,@table明明是存储过程的输入参数,它为什么提示我@table未定义
在上面,我已经讲了这句为什么出错的原因,
当然@table如果是表变量的话,那么那句select是不会有问题的,
但表变量不能用做输入参数。但它为什么这样提示呢?
这与sql内部机制有关,sql查询语句执行前先由命令解析器进行语法检查,如果语法检查未通过,
会扔出错误信息(通常这里的提示是精确的),
当语法检查通过,则将其编译为可执行的内部格式(查询树),
而非语法错误时,因为是执行时报错,执行期间是内部格式代码,只能扔出个大致错误信息.
了解了这一点,当您的sql语句报错后,先检查是否语法错误,
如果不是,那么需要仔细检查了,因为按着错误提示去找,很有可能兜圈子。
说明
SELECT 变量=字段 FROM tb
这种赋值与SET赋值的主要区别:
a, SET赋值,一次只能给一个变量赋值,而SELECT 则可多个
b, SET赋值语义更明确,是赋值。而SELECT 可能是赋值也可能是数据查询
c, 最重要的一个,SELECT 可以从表中取值,而SET不能。
说到这有人会说 SET @v=(SELECT TOP 1 v FROM tb) 也可以,
这样确实可以,但实际上它还是调用SELECT来完成.
d, SELECT赋值时是滚动赋值(或许用词不科学),我来说明一下我的'滚动赋值'指的什么
即,当SELECT v FROM tb有多个结果时,
SELECT @v=v FROM tb 在产生结果集的过程中,每得到一条记录,
@v都被赋一次值,也就是说,语句会滚动结果集,每次都对@v赋值。
这样,也就产生了递规查询变量:"
T-SQL常见基础疑点问答总结的更多相关文章
- SQL Tuning 基础概述10 - 体会索引的常见执行计划
在<SQL Tuning 基础概述05 - Oracle 索引类型及介绍>的1.5小节,提到了几种"索引的常见执行计划": INDEX FULL SCAN:索引的全扫描 ...
- SQL常见笔试面试题
sql理论题 1.触发器的作用? 答:触发器是一中特殊的存储过程,主要是通过事件来触发而被执行的.它可以强化约束,来维护数据的完整性和一致性,可以跟踪数据库内的操作从而不允许未经许可的更新和变化.可以 ...
- Sql注入基础原理介绍
说明:文章所有内容均截选自实验楼教程[Sql注入基础原理介绍]~ 实验原理 Sql 注入攻击是通过将恶意的 Sql 查询或添加语句插入到应用的输入参数中,再在后台 Sql 服务器上解析执行进行的攻击, ...
- SQL夯实基础(九)MySQL联接查询算法
书接上文<SQL夯实基础(八):联接运算符算法归类>. 这里先解释下EXPLAIN 结果中,第一行出现的表就是驱动表(Important!). 对驱动表可以直接排序,对非驱动表(的字段排序 ...
- SQL Tuning 基础概述10
在<SQL Tuning 基础概述05 - Oracle 索引类型及介绍>的1.5小节,提到了几种"索引的常见执行计划": INDEX FULL SCAN:索引的全扫描 ...
- SQL——语法基础篇(上)
用数据库的方式思考SQL是如何执行的 虽然 SQL 是声明式语言,我们可以像使用英语一样使用它,不过在 RDBMS(关系型数据库管理系统)中,SQL 的实现方式还是有差别的.今天我们就从数据库的角度来 ...
- JAVA多线程和并发基础面试问答(转载)
JAVA多线程和并发基础面试问答 原文链接:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-ans ...
- SQL server基础知识(表操作、数据约束、多表链接查询)
SQL server基础知识 一.基础知识 (1).存储结构:数据库->表->数据 (2).管理数据库 增加:create database 数据库名称 删除:drop database ...
- 数据库开发基础-SQl Server 基础
SQL Server 基础 1.什么是SQL Server SQL:Structured Query Language 结构化查询语言 SQL Server是一个以客户/服务器(c/s)模式访问.使 ...
随机推荐
- 关于python的GIL全局解释器锁的简单理解
GIL是解释器内部的一把锁,确切一点说是CPython解释器内部的一把锁,所以要注意区分 这和我们在Python代码中使用线程锁Lock并不是一个层面的概念. 1. GIL产生的背景: 在CPytho ...
- css3 media
@media screen and (max-width: 320px) { .cloud{position:;top: 70%;width: 150px;} .cloud2{;top: 30%;wi ...
- SpringCloud第二弹(高可用Eureka+Ribbon负载均衡)
先建立父工程 .. ..一路next 搭建注册中心(需要建立三个工程,端口不一样) .. .. .. 修改入口类 package com.cloud.eurekaserver1111; import ...
- CentOS Bash 命令补全增强软件包 bash-completion
引言 之前安装的 CentOS 7 是最小化安装,在使用 systemctl 命令进行服务的管理时,经常手动输入相关服务名.如果对一个服务名称不熟悉,这样可以迫使我们记住它,但如果对一个服务名已经很熟 ...
- 微信小程序:import导入公共文件方式
wxss: @import "../common/ali_icon.wxss"; wxml: 公共文件(位置:../common/head.wxml)如下---- <temp ...
- SVN YUM安装
一,安装: yum install subversion 二,创建配置SVN仓库: 目录自定,我这是在/home下: #cd /home # mkdir svn #svnadmin create /h ...
- ajax传值修改数据
主界面代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www. ...
- Java父类与子类方法调用顺序
父类 FatherClass package 父类与子类方法调用顺序; /** * 父类 * @author shundong * */ public class FatherClass { priv ...
- golang 使用os/exec配合context实现的超时机制
在使用golang开发中,调用外部可执行程序通过exec包是我们常用的方式.如何控制超时请见如下样例: var ( Timeout = 3 * time.Second ) func Command(n ...
- kubernetes1.5.2 dashboard配置
镜像:https://hub.daocloud.io/#!/repos/f8919a2c-2540-424e-8758-d23cc76b6d80 启动Kubernetes集群 配置Kubernetes ...