曾使用至少两种顶级 DB 产品(例如 Oracle、SQL Server、Informix、Sybase、DB2、Teradata)在 SQL 方面进行可扩展性工作的人是否知道 DB 供应商的 SQL 方言彼此之间有何不同。由于我来自 Oracle 背景,因此我对
start with .. connect by想到)select x, y from a, b where...)问题可能归结为这些功能是否以及在多大程度上受 ansi 标准的监管。
实际上,我想知道是否有“经验法则”可以指示我是否(以及如何)采用在一个数据库上运行的 SQL DML 语句并让它在另一个数据库上运行。
我只知道一点 sql 基础知识,需要编写一个简单的 sql 语法荧光笔/检查器所以我正在努力通过标准......我偶然发现了一些我不确定我是否理解正确的东西,因为我从未见过有人使用一个SET以这种方式。
它的定义如下所示:
<multiple column assignment> ::=
<set target list> <equals operator> <assigned row>
Run Code Online (Sandbox Code Playgroud)
以这种方式定义设置目标列表的地方:
<set target list> ::=
<left paren> <set target> [ { <comma> <set target> }... ] <right paren>
Run Code Online (Sandbox Code Playgroud)
这对我来说听起来是可以做到的:
UPDATE ...
SET (A, B, C) = (1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
将 A 的值更新为 1,B 的值更新为 2,C 的值更新为 3。
我让反刍的是=因为我从来没有见过这样的 SET 并且在网上找不到任何使用这种方式的例子。
所以我也不确定是否正确理解整个定义。
有人能告诉我这是正确的吗?如果不是这样,你能解释一下这个定义的其他定义吗?
我发现相同的查询在不同的 DBMS 中不起作用令人沮丧。
例如,某些 DBMS(例如 Microsoft SQL Server 和 MySQL)似乎支持该information_schema表,而其他DBMS(例如SQLite)则不支持。
一些数据库如 MySQL 允许你做SHOW TABLES,等等。
有些限制使用结果,SELECT TOP 10 ...而其他限制使用... LIMIT 10.
为什么不同的 DBMS 如此不兼容和异常?
他们为什么不遵循 SQL 标准?
哪些擅长坚持SQL标准?
哪些在遵守 SQL 标准方面是出了名的差?
我惊讶地发现is_nullable此查询的列被键入character varying (3)而不是boolean:
select
column_name,
data_type,
is_nullable
from
information_schema.columns
where
table_schema = 'public';
Run Code Online (Sandbox Code Playgroud)
我注意到其他一些列也使用“是”/“否”。这样做的理由是什么?我最初的想法是,也许除了 "YES" 和 "NO" 之外的其他值也是可能的,证明 a 以外的其他值是合理的boolean,但我在当前的数据库中没有看到任何这样的例子。
我试图找到 MS SQL 2016 的合规性确认 - 如果它完全符合 ANSI SQL-92 标准。
我在Microsoft Docs上发现这篇文章指出它不是,但它指的是 ODBC 驱动程序和 Microsoft Jet 引擎 - 不确定这是否完全相同,它不应该也与 T-SQL 相关吗?
在设计数据库表时(使用诸如 Enterprise Architect 之类的工具),当我将来需要切换到不同的数据库时,如何仅使用适用于所有数据库的“通用”数据类型?在切换时,我想避免将新数据库中不可用的列的数据类型更改为新数据库中可用的适当数据类型。
换句话说,是否有任何 ANSI 数据类型可以在具有相同大小的所有数据库中工作?也就是说,类似于“ANSI SQL”,有没有类似“ANSI SQL 数据类型”的东西?
我目前正在使用 SQL Server 2008 R2 服务器和一个数据库,该数据库使用了大量表,这些表是 ANSI_PADDED 设置的混合包。90% 的表都有带有 Ansi Padding 的列,AND 列带有 Ansi Padding 关闭。
我现在的任务是“转换”这些表,以便每一列都使用 Ansi_Padding ON。
我想知道最简单的方法是什么?
我应该编写一个“转换”一个表的脚本,但最后我将需要一个更改所有表的脚本。
sql-server-2008-r2 configuration sql-server-2012 sql-standard
我为我的 sql server 2008 R2 生成了仅模式脚本,这是其中的一部分:-
USE [master]
GO
/****** Object: Database [****] Script Date: 03/25/2015 12:17:09 ******/
CREATE DATABASE [****] ON PRIMARY
( NAME = N'TMS', FILENAME = N'D:\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\****.mdf' , SIZE = 11264KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = N'TMS_log', FILENAME = N'L:\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Data\****.ldf' , SIZE = 4672KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
ALTER DATABASE [****] SET COMPATIBILITY_LEVEL = 100
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled')) …Run Code Online (Sandbox Code Playgroud) 我只是想知道如果您插入的列数少于表提供的列数,规范是否允许在INSERT语句中排除 column-list 子句。我看到 PostgreSQL 有,而 MySQL 和 SQL Server 没有。
使用 PostgreSQL,(有效)
# CREATE TABLE t (a int, b int);
CREATE TABLE
# INSERT INTO t VALUES (42); -- (b is set to DEFAULT)
INSERT 0 1
Run Code Online (Sandbox Code Playgroud)
使用 SQL Server,我得到
Msg 213 Level 16 State 1 Line 1
Column name or number of supplied values does not match table definition.
Run Code Online (Sandbox Code Playgroud)
使用 MariaDB,我得到
Column count doesn't match value count at row …Run Code Online (Sandbox Code Playgroud) SQL-92 标准的第 5.6 节包含规则 10...13,其中未加引号的标识符应大写,因此foo变为FOO但"foo"仍然是foo。
例如,Oracle、IBM DB2、Snowflake和ksqlDB遵守这些规则,但Postgres 、MySQL 或 SQLite 则不遵守这些规则。
问题是,为什么?根据我的理解,在具有大量关键字的语言中可选地引用标识符是有意义的。标识符一致的区分大小写或不区分大小写也是有意义的。但让它依赖于被引用的标识符看起来并不合理。
我缺少什么?
sql-standard ×10
sql-server ×3
postgresql ×2
datatypes ×1
dml ×1
insert ×1
mariadb ×1
syntax ×1
t-sql ×1