DANIEL VAUGHAN

Find Tables with Keyword Names

09 Jun 2024

I was working with an SQL Server schema and discovered that one of my tables was named with a keyword;

SELECT u.*, a.* 
FROM [Bpm].User u
INNER JOIN [Bpm].Account a 
ON u.Id = a.UserId
WHERE u.Username = 'foo@exammple.com'

Msg 156, Level 15, State 1, Line 2 Incorrect syntax near the keyword ‘User’.

Turns out ‘User’ is a keyword and I needed to enclose it in square brackets: FROM [Bpm].[User] .... It’s probably best just to avoid naming things with keywords.

Here’s a query for SQL Server to detect if you have inadvertently named one of your tables with a keyword from one of the following DBMS’s:

  • MySQL
  • PostgreSQL
  • Oracle
  • SQL Server (Transact-SQL)
  • SQLite
  • DB2
-- Step 1: Create a temporary table for reserved keywords
CREATE TABLE #ReservedKeywords (
    Keyword NVARCHAR(128) NOT NULL
);

-- Step 2: Insert the reserved keywords into the temporary table
INSERT INTO #ReservedKeywords (Keyword)
VALUES
('ABORT'), ('ABS'), ('ACCESS'), ('ADD'), ('ADMIN'), ('AFTER'), ('AGGREGATE'),
('ALL'), ('ALLOCATE'), ('ALTER'), ('ANALYZE'), ('AND'), ('ANY'), ('ARE'),
('ARRAY'), ('AS'), ('ASC'), ('ASSERTION'), ('AT'), ('AUTHORIZATION'), ('AVG'),
('BACKUP'), ('BEFORE'), ('BEGIN'), ('BETWEEN'), ('BIGINT'), ('BINARY'), ('BIT'),
('BLOB'), ('BOOLEAN'), ('BOTH'), ('BREAK'), ('BY'), ('BYTE'), ('CALL'),
('CASCADE'), ('CASE'), ('CAST'), ('CATALOG'), ('CHAR'), ('CHARACTER'), ('CHECK'),
('CLOSE'), ('CLUSTER'), ('COALESCE'), ('COLLATE'), ('COLUMN'), ('COMMIT'),
('CONNECT'), ('CONSTRAINT'), ('CONTAINS'), ('CONTINUE'), ('CONVERT'), ('COPY'),
('COUNT'), ('CREATE'), ('CROSS'), ('CUBE'), ('CURRENT'), ('CURRENT_DATE'),
('CURRENT_PATH'), ('CURRENT_ROLE'), ('CURRENT_TIME'), ('CURRENT_TIMESTAMP'),
('CURRENT_USER'), ('CURSOR'), ('CYCLE'), ('DATA'), ('DATABASE'), ('DATE'),
('DAY'), ('DBA'), ('DEALLOCATE'), ('DEC'), ('DECIMAL'), ('DECLARE'), ('DEFAULT'),
('DELETE'), ('DESCRIBE'), ('DESCRIPTOR'), ('DETERMINISTIC'), ('DIAGNOSTICS'),
('DISCONNECT'), ('DISTINCT'), ('DO'), ('DOMAIN'), ('DOUBLE'), ('DROP'),
('DYNAMIC'), ('EACH'), ('ELSE'), ('END'), ('END-EXEC'), ('ESCAPE'), ('EXCEPT'),
('EXCEPTION'), ('EXEC'), ('EXECUTE'), ('EXISTS'), ('EXIT'), ('EXTERNAL'),
('EXTRACT'), ('FALSE'), ('FETCH'), ('FIRST'), ('FLOAT'), ('FOR'), ('FOREIGN'),
('FOUND'), ('FREE'), ('FROM'), ('FULL'), ('FUNCTION'), ('GENERAL'), ('GET'),
('GLOBAL'), ('GO'), ('GOTO'), ('GRANT'), ('GROUP'), ('GROUPING'), ('HAVING'),
('HOST'), ('HOUR'), ('IDENTITY'), ('IF'), ('IGNORE'), ('IMMEDIATE'), ('IN'),
('INCREMENT'), ('INDEX'), ('INDICATOR'), ('INITIAL'), ('INITIALLY'), ('INNER'),
('INOUT'), ('INPUT'), ('INSERT'), ('INT'), ('INTEGER'), ('INTERSECT'),
('INTERVAL'), ('INTO'), ('IS'), ('ISOLATION'), ('JOIN'), ('KEY'), ('LANGUAGE'),
('LAST'), ('LEADING'), ('LEAVE'), ('LEFT'), ('LEVEL'), ('LIKE'), ('LIMIT'),
('LOCAL'), ('LOWER'), ('MATCH'), ('MAX'), ('MIN'), ('MINUTE'), ('MODULE'),
('MONTH'), ('NAMES'), ('NATIONAL'), ('NATURAL'), ('NCHAR'), ('NCLOB'), ('NEW'),
('NEXT'), ('NO'), ('NONE'), ('NOT'), ('NULL'), ('NUMERIC'), ('OBJECT'), ('OF'),
('OFF'), ('OFFSET'), ('OLD'), ('ON'), ('ONLY'), ('OPEN'), ('OPTION'), ('OR'),
('ORDER'), ('OUT'), ('OUTER'), ('OUTPUT'), ('OVER'), ('OVERLAPS'), ('PAD'),
('PARAMETER'), ('PARTIAL'), ('PARTITION'), ('PERCENT'), ('PLACING'), ('POSITION'),
('PRECISION'), ('PREPARE'), ('PRIMARY'), ('PRIOR'), ('PRIVILEGES'), ('PROCEDURE'),
('PUBLIC'), ('RANGE'), ('READ'), ('REAL'), ('REFERENCES'), ('RELATIVE'),
('REPLACE'), ('RESTRICT'), ('RETURN'), ('RETURNS'), ('REVOKE'), ('RIGHT'),
('ROLE'), ('ROLLBACK'), ('ROLLUP'), ('ROUTINE'), ('ROW'), ('ROWS'), ('SAVEPOINT'),
('SCHEMA'), ('SCROLL'), ('SEARCH'), ('SECOND'), ('SECTION'), ('SELECT'), ('SESSION'),
('SET'), ('SETS'), ('SHARE'), ('SHOW'), ('SIMILAR'), ('SIZE'), ('SMALLINT'),
('SOME'), ('SPACE'), ('SPECIFIC'), ('SQL'), ('SQLCODE'), ('SQLERROR'), ('SQLSTATE'),
('START'), ('STATEMENT'), ('STATIC'), ('SUBSTRING'), ('SUM'), ('SYSTEM'),
('TABLE'), ('TEMPORARY'), ('THEN'), ('TIME'), ('TIMESTAMP'), ('TO'), ('TRAILING'),
('TRANSACTION'), ('TRANSLATE'), ('TRANSLATION'), ('TRIGGER'), ('TRUE'), ('UNION'),
('UNIQUE'), ('UNKNOWN'), ('UNNEST'), ('UPDATE'), ('USAGE'), ('USER'), ('USING'),
('VALUE'), ('VALUES'), ('VARCHAR'), ('VARIABLE'), ('VARYING'), ('VIEW'), ('WHEN'),
('WHENEVER'), ('WHERE'), ('WITH'), ('WORK'), ('WRITE'), ('YEAR'), ('ZONE');

-- Step 3: Query to find tables with reserved keyword names
SELECT 
    TABLE_NAME
FROM 
    INFORMATION_SCHEMA.TABLES
WHERE 
    TABLE_TYPE = 'BASE TABLE'
    AND TABLE_NAME COLLATE Latin1_General_CI_AS IN (SELECT Keyword FROM #ReservedKeywords);

-- Cleanup: Drop the temporary table after use
DROP TABLE #ReservedKeywords;

The list of keyword according to ChatGPT:

ABORT
ABS
ACCESS
ADD
ADMIN
AFTER
AGGREGATE
ALL
ALLOCATE
ALTER
ANALYZE
AND
ANY
ARE
ARRAY
AS
ASC
ASSERTION
AT
AUTHORIZATION
AVG
BACKUP
BEFORE
BEGIN
BETWEEN
BIGINT
BINARY
BIT
BLOB
BOOLEAN
BOTH
BREAK
BY
BYTE
CALL
CASCADE
CASE
CAST
CATALOG
CHAR
CHARACTER
CHECK
CLOSE
CLUSTER
COALESCE
COLLATE
COLUMN
COMMIT
CONNECT
CONSTRAINT
CONTAINS
CONTINUE
CONVERT
COPY
COUNT
CREATE
CROSS
CUBE
CURRENT
CURRENT_DATE
CURRENT_PATH
CURRENT_ROLE
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_USER
CURSOR
CYCLE
DATA
DATABASE
DATE
DAY
DBA
DEALLOCATE
DEC
DECIMAL
DECLARE
DEFAULT
DELETE
DESCRIBE
DESCRIPTOR
DETERMINISTIC
DIAGNOSTICS
DISCONNECT
DISTINCT
DO
DOMAIN
DOUBLE
DROP
DYNAMIC
EACH
ELSE
END
END-EXEC
ESCAPE
EXCEPT
EXCEPTION
EXEC
EXECUTE
EXISTS
EXIT
EXTERNAL
EXTRACT
FALSE
FETCH
FIRST
FLOAT
FOR
FOREIGN
FOUND
FREE
FROM
FULL
FUNCTION
GENERAL
GET
GLOBAL
GO
GOTO
GRANT
GROUP
GROUPING
HAVING
HOST
HOUR
IDENTITY
IF
IGNORE
IMMEDIATE
IN
INCREMENT
INDEX
INDICATOR
INITIAL
INITIALLY
INNER
INOUT
INPUT
INSERT
INT
INTEGER
INTERSECT
INTERVAL
INTO
IS
ISOLATION
JOIN
KEY
LANGUAGE
LAST
LEADING
LEAVE
LEFT
LEVEL
LIKE
LIMIT
LOCAL
LOWER
MATCH
MAX
MIN
MINUTE
MODULE
MONTH
NAMES
NATIONAL
NATURAL
NCHAR
NCLOB
NEW
NEXT
NO
NONE
NOT
NULL
NUMERIC
OBJECT
OF
OFF
OFFSET
OLD
ON
ONLY
OPEN
OPTION
OR
ORDER
OUT
OUTER
OUTPUT
OVER
OVERLAPS
PAD
PARAMETER
PARTIAL
PARTITION
PERCENT
PLACING
POSITION
PRECISION
PREPARE
PRIMARY
PRIOR
PRIVILEGES
PROCEDURE
PUBLIC
RANGE
READ
REAL
REFERENCES
RELATIVE
REPLACE
RESTRICT
RETURN
RETURNS
REVOKE
RIGHT
ROLE
ROLLBACK
ROLLUP
ROUTINE
ROW
ROWS
SAVEPOINT
SCHEMA
SCROLL
SEARCH
SECOND
SECTION
SELECT
SESSION
SET
SETS
SHARE
SHOW
SIMILAR
SIZE
SMALLINT
SOME
SPACE
SPECIFIC
SQL
SQLCODE
SQLERROR
SQLSTATE
START
STATEMENT
STATIC
SUBSTRING
SUM
SYSTEM
TABLE
TEMPORARY
THEN
TIME
TIMESTAMP
TO
TRAILING
TRANSACTION
TRANSLATE
TRANSLATION
TRIGGER
TRUE
UNION
UNIQUE
UNKNOWN
UNNEST
UPDATE
USAGE
USER
USING
VALUE
VALUES
VARCHAR
VARIABLE
VARYING
VIEW
WHEN
WHENEVER
WHERE
WITH
WORK
WRITE
YEAR
ZONE