20 Undocumented T-SQL

An ounce of technique is worth a pound of technology.
Danny Thorpe

I can’t stress enough how important it is to avoid relying on undocumented routines unless absolutely necessary. They’re undocumented for a reason. As a rule, the functions, DBCC command verbs, stored procedures, and trace flags that have been omitted from the SQL Server documentation have been left out because Microsoft doesn’t want you to use them. They can be dangerous—possibly even catastrophic—if used improperly. Wanton misuse of a DBMS’s undocumented features is a fast ticket to lost data and apathy from the vendor.

So be careful with the commands and syntax that follow. Use them sparingly and, even then, with due caution. A mangled server quickly extinguishes the joy you get from using this or that gadget simply because you’ve just learned that it exists.

If you decide to use undocumented routines in your own code, go into it with the full expectation that those routines may change in a future release of the product. The PWDENCRYPT() function below, for example, changed between releases 6.5 and 7.0 of SQL Server, and people who wrote code that relied on it ran into trouble when they migrated to 7.0.

Don’t expect vendor support for undocumented routines. When you see the word “undocumented,” read “unsupported.” Leaving a feature undocumented frees the vendor to change it at will without having to be concerned about breaking customer code. If you decide to base mission-critical code on undocumented aspects of the product, you do so at your own risk.

Defining Undocumented

Undocumented Transact-SQL, as defined here, refers to commands, functions, trace flags, DBCC command verbs, and stored procedures not listed in the SQL Server Books Online. Some of these routines are found in other publicly available Microsoft documentation; some aren’t. For this chapter, the bottom line is this: If it isn’t in the BOL, it isn’t documented.

Undocumented DBCC Commands

The DBCC (database consistency checker) command originally housed a small collection of database maintenance routines that were outside the realm and syntax of traditional Transact-SQL. The idea was to group these routines under an easy-to-remember, easy-to-use command “toolbox,” out of the way of normal queries. This worked well and was basically a good idea.

Since that time, Sybase and Microsoft have expanded DBCC’s original mission to include loads of functionality not foreseen by the original designers. The verb list for the command has grown to include dozens of things not related to database error checking—to the point of being extremely unwieldy and bordering a bit on the ridiculous. These days, DBCC does everything from checking databases for consistency to wrangling full-text indexes, from managing server caches to interacting with Performance Manager. It’s practically a language unto itself.

Many of these command verbs are not documented—some for very good reasons. Why some of them were not made separate Transact-SQL commands, only the vendors know.

Before we delve into DBCC’s undocumented command verbs, there are a few pointers to be aware of. First, include the WITH NO_INFOMSGS option to limit DBCC output to error messages. This makes the output from some loquacious commands like DBCC CHECKALLOC much more manageable without losing anything of real importance. Second, use DBCC HELP(commandverb) to list built-in help on DBCC command verbs. Most of the undocumented commands aren’t displayed by the command, but it never hurts to check. Last, use DBCC TRACEON(3604) to route DBCC output to your client connection rather than the system error log. Many of the undocumented commands send their output to the error log by default, so keep this in mind. If you execute one of the commands below and receive nothing back from the server, it’s likely that the command’s output went to the error log, and you need to use trace flag 3604 to route it to you instead.

DBCC ADDEXTENDEDPROC(procname,DLL)

This command adds an extended procedure to the list maintained by the server. It has the same basic functionality as the sp_addextendedproc stored procedure and is, in fact, called by the procedure. The procname parameter is the name of the extended procedure, and DLL is the name of the DLL in which it resides.

DBCC ADDEXTENDEDPROC(’xp_computemode’,’xp_stats.dll’)

DBCC ADDINSTANCE(object,instance)

This command adds an object instance to track in Performance Monitor. Stored procedures that initialize Performance Monitor counters use this to set up various areas of SQL Server for performance tracking. Object is the name of the object that contains the instance (e.g., “SQL Replication Agents”), and instance is the name of the instance to add (e.g., “Logreader”).

DBCC ADDINSTANCE("SQL Replication Agents", "Snapshot")

DBCC BCPTABLOCK(dbid, tabid, setflag)

This command sets the table lock on bulk load option for a table and can improve performance for bulk inserts since it avoids setting a row lock for every inserted row. Dbid is the database ID, tabid is the table’s object ID, and setflag is a 1 or 0 indicating whether to set the option.

DECLARE @dbid int, @objid int
SELECT @dbid=DB_ID(’pubs’), @objid=OBJECT_ID(’titles’)
DBCC BCPTABLOCK(@dbid,@objid,1)

DBCC BUFFER(dbid[,objid][,numberofbuffers][,printopt {0 | 1 | 2}])

This command is used to dump the contents of SQL Server memory buffers. Buffers can be listed for a specific object or for an entire database.

DECLARE @dbid int, @objid int
SELECT @dbid=DB_ID(’pubs’), @objid=OBJECT_ID(’pubs..titles’)
SELECT COUNT(*) FROM pubs..titles -- Load up the buffers
DBCC BUFFER(@dbid,@objid,1,2)

(Results abridged)

Image

DBCC BYTES(startingaddress,length)

This command lists the contents of the memory area beginning at startingaddress for length bytes. The address specified must be a valid address within the SQL Server process space.

Image

DBCC CALLFULLTEXT(funcid[,catid][,objid])

This command is used to perform a variety of full-text-related functions. Funcid specifies what function to perform and what parameters are valid. Catid is the full-text catalog ID, and objid is the object ID of the affected object. Note that CALLFULLTEXT is valid only within a system stored procedure. This procedure must have its system bit set (see the undocumented procedure sp_MS_marksystemobject below for more info), and its name must begin with “sp_fulltext_.” Table 20.1 lists the supported functions:

Table 20.1 DBCC CALLFULLTEXT() functions.

Image

USE master
GO
IF OBJECT_ID(’sp_fulltext_resource’) IS NOT NULL
   DROP PROC sp_fulltext_resource
GO
CREATE PROC sp_fulltext_resource @value int    -- value for ’resource_usage’
AS
   DBCC CALLFULLTEXT(9,@value)                        -- FTSetResource (@value)
   IF (@@error<>0) RETURN 1
   -- SUCCESS --
RETURN 0   -- sp_fulltext_resource
GO

EXEC sp_MS_marksystemobject ’sp_fulltext_resource’
EXEC sp_fulltext_resource 3

DBCC DBCONTROL(dbname,option)

This command sets database options. It performs many of the functions of sp_dboption and is, in fact, called by the procedure. Dbname is the name of the database, and option is a token specifying the option to set. Table 20.2 lists the valid values for option:

Table 20.2 Valid option values for DBCC DBCONTROL().

Image

DBCC DBCONTROL(’pubs’,multi)

DBCC DBINFO(dbname)

This command lists system-level information about the specified database, including its creation date, ID, status, next timestamp value, etc.

DBCC DBINFO(’pubs’)

DBINFO STRUCTURE:

DBINFO @0x0690F998
------------------
dbi_dbid = 5                    dbi_status = 4194436               dbi_nextid = 1810821513
dbi_dbname = pubs       dbi_maxDbTimestamp = 2000 dbi_version = 515
dbi_createVersion = 515 dbi_nextseqnum = 1900-01-01 00:00:00.000
dbi_crdate = 1998-11-13 03:10:45.610                                dbi_filegeneration = 1

dbi_checkptLSN
--------------
m_fSeqNo = 65 m_blockOffset = 340   m_slotId = 1

dbi_dbbackupLSN
---------------
m_fSeqNo = 43 m_blockOffset = 326   m_slotId = 1

dbi_lastdbbackupLSN
-------------------
m_fSeqNo = 43 m_blockOffset = 332   m_slotId = 1

dbi_createIndexLSN
------------------
m_fSeqNo = 0              m_blockOffset = 0 m_slotId = 0
dbi_sortord = 52          dbi_charset = 1   dbi_LcidCfg = 1033
dbi_CompFlagsCfg = 196609 dbi_maxLogSpaceUsed = 3828736

DBCC DBRECOVER(dbname)

This command manually recovers a database. Normally, databases are recovered at system startup. If this did not occur—due to an error or the disabling of recovery (see trace flags 3607 and 3608 below)—DBCC DBRECOVER can be used to attempt a manual recovery. Dbname is the name of the database to recover.

DBCC DBRECOVER(’pubs’)

DBCC DBTABLE(dbid)

This command lists DBT (DB Table) and FCB (File Control Block) information for the specified database.

Image

DBCC DELETEINSTANCE(object,instance)

This command deletes a Performance Monitor object instance previously set up with DBCC ADDINSTANCE. Object is the name of the Performance Monitor object, and instance is the name of the instance to delete. Specify a wildcard for instance to delete multiple instances.

DBCC DELETEINSTANCE("SQL Replication Merge", "%")

DBCC DES(dbid,objid)

This command lists system-level descriptive information for the specified object.

Image

DBCC DETACHDB(dbname)

This command detaches a database from the server. The database can then be moved to another server and reattached with sp_attach_db. This function is called by the sp_detach_db stored procedure.

DBCC DETACHDB(’northwind2’)

DBCC DROPCLEANBUFFERS

This command flushes all data from memory. This is useful if you’re running benchmarks and don’t want caching to skew test results.

DBCC DROPCLEANBUFFERS

DBCC DROPEXTENDEDPROC(procname)

This command drops an extended procedure. It’s called by sp_dropextendedprocedure.

USE master
DBCC DROPEXTENDEDPROC(’xp_computemode’)

DBCC ERRORLOG

This command closes the current error log and starts another one, cycling the file extensions similarly to a server restart. It’s called by the sp_cycle_errorlog stored procedure.

DBCC ERRORLOG

DBCC EXTENTINFO(dbname, tablename, indid)

This command lists extent information for all the extents belonging to an object. Dbname is the name of the database, tablename is the name of the table, and indid is the index ID of the index to list.

DBCC EXTENTINFO(’pubs’,’titles’,1)

file_id    page_id    pg_alloc   ext_size   obj_id     index_id   pfs_bytes                  avg_used
---------- ----------     ----------     ----------     ----------   ----------   ------------------             --------
1             120            1              1                261575970  1             0x6000000000000000 25
1             132            1              1                261575970  1             0x6000000000000000 25

DBCC FLUSHPROCINDB(dbid)

This command forces a recompile of all the stored procedures in a database. Dbid is the database ID of the target database. This is handy when you’ve changed an option in the database that would materially affect the queries generated for its stored procedures. Sp_dboption, for example, uses DBCC FLUSHPROCINDB to ensure that changes to compile-time options are accommodated by a database’s stored procs.

DECLARE @dbid int
SET @dbid=DB_ID(’pubs’)
DBCC FLUSHPROCINDB(@dbid)

DBCC FREEPROCCACHE

This command flushes the procedure cache. This is handy when you need to eliminate the effects of procedure caching on benchmark tests or when you want procedure execution plans to take new configuration values into account.

DBCC FREEPROCCACHE

DBCC IND(dbid, objid[,printopt {0 | 1 | 2}])

This command lists system-level index information for the specified object.

DECLARE @dbid int, @objid int
SELECT @dbid=DB_ID(’pubs’), @objid=OBJECT_ID(’pubs..authors’)
DBCC IND(@dbid,@objid, 1)

Image

DBCC LOCKOBJECTSCHEMA (objname)

This command blocks schema changes by other connections until the caller commits the current transaction. It also increments the schema_ver column in sysobjects. This command has no effect if executed outside a transaction.

USE pubs
BEGIN TRAN

DBCC LOCKOBJECTSCHEMA(’titleauthor’)

-- Comment out the COMMIT below and try a DDL modification to titleauthor
-- from another connection. Your new connection will wait until this one
-- commits.

COMMIT TRAN

DBCC LOG(dbid)

This command displays log record information from the current database’s transaction log. You can use INSERT..EXEC() to trap this output in a table for further processing.

CREATE TABLE #logrecs
(CurrentLSN varchar(30),
 Operation varchar(20),
 Context varchar(20),
 TransactionID varchar(20))

INSERT #logrecs
EXEC(’DBCC LOG(’’ubs’’’)

SELECT * FROM #logrecs
GO
DROP TABLE #logrecs

(Results abridged)

Image

DBCC PAGE (dbid|dbname, filenum, pagenum [,printopt][,cacheopt])

This command dumps the contents of a specific database page. Dbid|dbname is the ID or name of the database, filenum is the database file number containing the page, pagenum is the number of the page, printopt specifies what to print, and cacheopt specifies whether to dump the disk or memory version of the page (values 0 and 1, respectively).

Table 20.3 lists the valid values for printopt:

Table 20.3 Valid printopt values.

Image

Note that this command requires DBCC TRACEON(3604) in order to direct its output to your client connection.

DBCC TRACEON(3604)
GO
DBCC PAGE(’pubs’,1,70,2,0)
GO
DBCC TRACEOFF(3604)
GO

(Results abridged)

Image

DBCC PRTIPAGE(dbid, objid, indexid[, printopt {0 | 1 | 2}])

This command lists page information for the specified index.

DECLARE @dbid int, @pagebin varchar(12), @pageid int, @fileid int, @objid int
SELECT TOP 1 @dbid=DB_ID(’pubs’), @objid=id, @pagebin=first
FROM pubs..sysindexes WHERE id=OBJECT_ID(’pubs..authors’)

EXEC sp_decodepagebin @pagebin, @fileid OUT, @pageid OUT

DBCC PRTIPAGE(@dbid, @objid, 2, @pageid)

(Results abridged)

Image

DBCC RESOURCE

This command lists resource utilization information for the server.

Image

Image

DBCC SETINSTANCE(object,counter,instance,val)

This command sets the value of a Performance Monitor instance counter. You can use this when benchmarking query and stored procedure performance to set a user-definable counter inside Performance Monitor. In fact, this is how the sp_user_counternn procedures work—they call DBCC SETINSTANCE. Object is the name of the Performance Monitor object, instance is the name of the object’s instance to adjust, counter is the name of the performance counter to change, and val is the new value of the counter.

DBCC SETINSTANCE(’SQLServer:User Settable’, ’Query’, ’User counter 1’, 3)

DBCC TAB(dbid,objid[,printopt {0 | 1 | 2}}])

This command lists system-level information for the specified table.

Image

DBCC UPGRADEDB(dbname)

This command upgrades the system objects in the specified database to the current version of the database engine.

DBCC UPGRADEDB(’oldpubs’)

Undocumented Functions and Variables

As I said earlier, undocumented Transact-SQL elements, including functions, are usually not documented for a reason. They can be dangerous or even catastrophic if improperly used. They may also change between releases. So, use good judgment when you decide whether to use these functions in your own code.

ENCRYPT(string)

This command encrypts a string. It’s used internally by the server to encrypt Transact-SQL code stored in syscomments (when WITH ENCRYPTION is specified).

SELECT ENCRYPT(’VALET’)
----------------------------------------------------
0x594F55415245415348414D454C4553535359434F5048414E54

GET_SID(username)

This command returns the current NT system ID for a specified user or group name as a varbinary(85). Prefix username with U to search for an NT user ID; prefix it with G to search for an NT group ID. Note that this function works only within system-stored procedures that have their system bit set—see the undocumented procedure sp_MS_marksystemobject below for more information.

USE master
GO
IF (OBJECT_ID(’sp_get_sid’) IS NOT NULL)
   DROP PROC sp_get_sid
GO
CREATE PROCEDURE sp_get_sid
   @loginame sysname
AS
DECLARE @sid varbinary(85)

IF (charindex(’’, @loginame) = 0)
   SELECT SUSER_SID(@loginame) AS ’SQL User ID’
ELSE BEGIN
   SELECT @sid=get_sid(’U’+@loginame, NULL)
   IF @sid IS NULL
      SELECT @sid=get_sid(’G’+@loginame, NULL) -- Maybe it’s a group
   IF @sid IS NULL BEGIN
      RAISERROR(’Couldn’t find an ID for the specified loginame’,16,10)
         RETURN -1
      END ELSE SELECT @sid AS ’NT User ID’
   RETURN 0
END
GO
EXEC sp_MS_marksystemobject ’sp_get_sid’
EXEC sp_get_sid ’LEX_TALIONISKHEN’

NT User ID
--------------------------------------------------------------------------------
0x0105000000000005150000000A423635BE3136688847202CE8030000

OBJECT_ID(..,’local’)

While the OBJECT_ID() function itself is, of course, documented, its optional second parameter isn’t. Since you can pass a fully qualified object name as the first argument, OBJECT_ID() can return ID numbers for objects that reside in databases other than the current one. There may be times when you want to prevent this. For example, if you’re performing a task on an object that requires access to catalog information in the current database, you may need to ensure not only that the object name translates to a valid object ID but also that it’s a local object. Pass ’local’ as OBJECT_ID()’s second parameter in order to ensure that it sees objects in the current database only, like so:

USE pubs
SELECT OBJECT_ID(’Northwind..Orders’), OBJECT_ID(’Northwind..Orders’,’local’)
--------- ---------------------------------------------------
357576312 NULL

PWDCOMPARE(str,pwd,oldenc)

This command compares a string with an encrypted password. Str is the string to compare, pwd is the encrypted password to use, and oldenc is a 1 or 0 indicating whether old-style encryption was used to encrypt pwd. You can retrieve an encrypted password directly from the sysxlogins password column, or you can use the undocumented PWDENCRYPT() function to create one from a string (see below).

SELECT PWDCOMPARE(’enmity’, password, (CASE WHEN xstatus&2048=2048 THEN 1 ELSE 0 END))
FROM sysxlogins
WHERE name=’k_reapr’

-----------
1

PWDENCRYPT(str)

This command encrypts a string using SQL Server’s password encryption algorithm. Stored procedures that manage SQL Server passwords use this function to encrypt user passwords. You can use the undocumented PWDCOMPARE() function to compare an unencrypted string with the return value of PWDENCRYPT().

SELECT PWDENCRYPT(’vengeance’) AS EncryptedString,PWDCOMPARE(’vengeance’,
PWDENCRYPT(’vengeance’), 0) AS EncryptedCompare
EncryptedString EncryptedCompare

EncryptedString  EncryptedCompare
---------------- ----------------
________         1

TSEQUAL(ts1,ts2)

This command compares two timestamp values—returns 1 if they’re identical, raises an error if they’re not. The TSEQUAL() function has been around for years—it dates back to the days when Microsoft SQL Server was merely an OS/2 port of Sybase SQL Server. It’s not used as often any more, mainly because it’s no longer necessary. You can compare two timestamp columns directly and decide for yourself whether to raise an error. There’s also no performance advantage to using TSEQUAL rather than a simple equality comparison. Still, it’s not documented in the Books Online, so I’m compelled to include it here.

USE tempdb
CREATE TABLE #testts
(k1 int identity,
timestamp timestamp)

DECLARE @ts1 timestamp, @ts2 timestamp

SELECT @ts1=@@DBTS, @ts2=@ts1

SELECT CASE WHEN TSEQUAL(@ts1, @ts2) THEN ’Equal’ ELSE ’Not Equal’ END

INSERT #testts DEFAULT VALUES

SET @ts2=@@DBTS

SELECT CASE WHEN TSEQUAL(@ts1, @ts2) THEN ’Equal’ ELSE ’Not Equal’ END
GO
DROP TABLE #testts

---------
Equal

Server: Msg 532, Level 16, State 2, Line 16
The timestamp (changed to 0x0000000000000093) shows that the row has been updated by
another user.

@@MICROSOFTVERSION

This automatic variable returns an internal tracking number used by Microsoft.

SELECT @@MICROSOFTVERSION
-----------

117441211

Undocumented Trace Flags

Trace flags are special server settings that you can configure primarily by calling DBCC TRACEON() or via the –T server command-line option. Some options make sense only on a server-wide basis, so they’re best specified on the server command line. Most, however, are specified via DBCC TRACEON( flagnum), where flagnum is the flag you want to set. To set more than one flag at a time, separate them with commas.

Use DBCC TRACESTATUS( flagnum) to list whether a flag is enabled. Pass a –1 to return a list of all flags currently set. Here’s a simple DBCC TRACEON() / TRACESTATUS() example:

EXEC master..xp_logevent 99999,’CHECKPOINT before setting flag
3502’,informational
CHECKPOINT
DBCC TRACEON(3604,3502)
DBCC TRACESTATUS(-1)
EXEC master..xp_logevent 99999,’CHECKPOINT after setting flag
3502’,informational
CHECKPOINT
DBCC TRACEOFF(3604,3502)
DBCC TRACESTATUS(-1)

Here’s what the error log looks like as a result of these commands (trace flag 3502 enables extra CHECKPOINT log information):

1999-07-27 19:57:20.06 spid11 Error: 99999, Severity: 10, State: 1
1999-07-27 19:57:20.06 spid11 CHECKPOINT before setting flag 3502.
1999-07-27 19:57:20.06 spid11 DBCC TRACEON 3604, server process ID (SPID) 11.
1999-07-27 19:57:20.06 spid11 DBCC TRACEON 3502, server process ID (SPID) 11.
1999-07-27 19:57:20.07 spid11 Error: 99999, Severity: 10, State: 1
1999-07-27 19:57:20.07 spid11 CHECKPOINT after setting flag 3502.
1999-07-27 19:57:20.07 spid11 Ckpt dbid 4 started (100000)
1999-07-27 19:57:20.07 spid11 Ckpt dbid 4 phase 1 ended (100000)

Table 20.4 A few of SQL Server’s undocumented trace flags.

Image

1999-07-27 19:57:20.07 spid11 Ckpt dbid 4 complete
1999-07-27 19:57:20.07 spid11 DBCC TRACEOFF 3604, server process ID (SPID) 11.
1999-07-27 19:57:20.07 spid11 DBCC TRACEOFF 3502, server process ID (SPID) 11.

Table 16.7 lists some of the many undocumented SQL Server trace flags. (See the Books Online for a list of documented flags.) This list is not comprehensive—there are many undocumented flags not included here.

Undocumented Procedures

There are scads of undocumented procedures. By my count, there are nearly a hundred of them, not counting replication routines. I’ve listed most of them in Table 20.5. I haven’t included all of them here for a number of reasons. First, there are simply too many to cover with any sort of adequacy. That’s why I’ve intentionally omitted the undocumented routines related to replication. Also, some undocumented routines are so dangerous and add so little value to the Transact-SQL command set that they are best left undocumented. As they say, some things are better left unsaid. Last, some of the undocumented routines behave so erratically or are so reliant on code external to the server (e.g., in Enterprise Manager or SQL-DMO) that they are either unusable or of dubious value to the Transact-SQL developer. The idea here is to provide thorough coverage without being excessive

Table 20.5 Undocumented system and extended stored procedures.

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Summary

This chapter explored a number of SQL Server trace flags, DBCC commands, functions, variables, and stored procedures that are not documented in the Books Online. If you decide to use them in your own work, you should do so with care and with the expectation that they may change in a future release of the product. And don’t expect any support from Microsoft—that’s the whole idea of not documenting something—you don’t have to support it, and you can change it at will. Using the undocumented features of any product—SQL Server included—is generally inadvisable. You shouldn’t do it unless absolutely necessary.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.78.30