Part 1 Introduction

Introduction

Microsoft® SQL Server™ 6.5 enhances the performance, reliability, and scalability provided by earlier releases of SQL Server by making the processes of developing applications, managing systems, and replicating data easier than ever. The new and enhanced features in SQL Server 6.5 meet government and industry standards for openness and interoperability. SQL Server 6.5 features comply with American National Standards Institute (ANSI) SQL-92 standards and with the Federal Information Processing Standards (FIPS 127-2) as established by the National Institute of Standards and Technology (NIST).

The server includes these new components: MS Query, SQL Trace, Microsoft Distributed Transaction Coordinator (MS DTC), OLE Automation Stored Procedures, SQL Server Web Assistant, and Simple Network Management Protocol Management Information Base (SNMP MIB) and SNMP agent. New client components include MS Query, SQL Trace, MS DTC (client), SQL Server Web Assistant, and other ODBC drivers for heterogeneous replication use. (These components are detailed later in this document.)


Setup Highlights

SQL Server platform support has been expanded to now run on the PowerPC™. SQL Server 6.5 requires the Microsoft® Windows NT™ 3.51 or later operating system. (Earlier versions of Windows NT are not supported.)

SQL Server setup provides additional character sets: Japanese, Chinese (simplified), Chinese (traditional), and Korean.


Administration Highlights

SQL Server 6.5 administration has been enhanced, and it includes many new features, including:

Backup and Recovery

SQL Server 6.5 maintains a history of database backups. It also supports point-in-time recovery, which enables transaction logs to be recovered through a specific date and time. And now individual tables can be backed up and restored (using table dump and load).

Database Maintenance Plan Wizard

In just a few simple steps in the Database Maintenance Plan Wizard, you can automatically schedule daily or weekly routine database maintenance tasks, including database and transaction log backups, database consistency checks, and statistics updates.

The Database Maintenance Plan Wizard can be run from SQL Enterprise Manager, or you can run the sqlmaint command-line utility. You can even generate a report about database maintenance that can be e-mailed to a designated mail account.

SQL Server Web Assistant

With the new SQL Server Web Assistant, you can format data in hypertext markup language (HTML) and automatically deliver SQL Server data to a web server. The SQL Server Web Assistant provides a graphical user interface that simplifies the task of converting data to HTML and of creating interactive, database-driven web sites with automated information retrieval. This functionality is also available through the sp_makewebtask, sp_runwebtask, and sp_dropwebtask stored procedures.

SQL Trace

SQL Trace provides a new way to track server activity. With SQL Trace, you can now view statements or remote procedure calls that are sent to any Microsoft SQL Server, and you can create filters to monitor specific user activity, applications, or clients. SQL Trace information can be saved in a Transact-SQL® script or as an activity log.

Fallback Support

Fallback support is now available, and enables a separate computer running SQL Server to automatically assume control of the crucial databases and devices of a primary server that is experiencing hardware or software failure. A server designated as the fallback server can simultaneously hold databases from many primary servers and can provide active fallback support for three of those primary servers at the same time. Fallback support ensures that databases will be accessible even if an equipment failure occurs.

Communications Enhancements

SQL Mail is enhanced in SQL Server 6.5, and SQL Mail is now compatible with Microsoft® Exchange Server. Other enhancements include the ability to stop and start SQL Mail from the Server Manager window of SQL Enterprise Manager, the ability to assign a mail login name and password from SQL Enterprise Manager, and the ability to set SQL Mail to impersonate a client for security purposes.

In addition, SQL Server supports custom server configuration using the multi-protocol net-library, which will listen for incoming network conections on named pipes, a TCP/IP port, and an SPX socket. The named pipe name, TCP/IP port, and SPX socket number are normally chosen dynamically. Administrators can configure SQL Server to listen for incoming connections on a particular port by manually editing the appropriate Registry keys.

SQL Performance Monitor Enhancements

SQL Performance Monitor integrates the Windows NT Performance Monitor with SQL Server, providing up-to-the-minute activity and performance statistics. SQL Server 6.5 provides new objects and counters that you can use to monitor data returned from SQL Performance Monitor, including new user-defined counters that you can use to monitor values specific to an application.

SNMP Enhancements

Communication between Simple Network Management Protocol (SNMP) clients and SQL Server is enabled in SQL Server 6.5. You can use SNMP applications to monitor the status of SQL Server installations, monitor performance information, access databases, view server and database configuration parameters, and set conditions that initiate an alert message to be sent to workstations that are running SNMP monitoring applications.

Remote Server Management

The Remote Servers and Logins Manager interface in SQL Enterprise Manager centralizes administrative tasks and makes it easy for one person to manage many servers. You can also set distribution options for replication and configure ODBC subscribers from this interface.

In addition, Transact-SQL statements and stored procedures give you the ability to retrieve information from remote databases that is useful in managing remote servers effectively.


MS DTC Highlights

SQL Server 6.5 includes the Microsoft® Distributed Transaction Coordinator (MS DTC), which provides a robust, high-performance, scalable, easy-to-use distributed transaction facility for the Microsoft Windows NT and Microsoft® Windows® 95 operating systems. MS DTC addresses the challenges of processing transactions over a distributed set of software components that exist on a single computer or on a system of networked computers. MS DTC is fully integrated with Microsoft SQL Server. Via MS DTC, remote stored procedure calls can now participate in distributed transactions, so that changes on multiple servers can be committed as a single unit of work.

SQL Enterprise Manager provides an interface to control and monitor MS DTC. You can view running transactions and their status, manually resolve transactions, and force transaction changes when necessary. For details about MS DTC, see the Guide to Microsoft Distributed Transaction Coordinator.


Replication Highlights

SQL Server 6.5 enables replication to ODBC subscribers other than SQL Server. You can exchange data with Microsoft® Access and ORACLE® databases, and with other ODBC subscribers.

Replication also now supports text and image datatypes.


Transact-SQL Highlights

SQL Server 6.5 adds new Transact-SQL capabilities and provides some significant enhancements. SQL Server 6.5 features comply with ANSI SQL-92 standards and with the Federal Information Processing Standards (FIPS 127-2) as established by NIST. The new CUBE and ROLLUP operators are useful in writing data warehousing and decision support system applications. Transact-SQL changes for SQL Server 6.5 extend the ability to temporarily disable constraints during replication, thereby eliminating the effort required to drop and then add constraints as with earlier versions of SQL Server; provide the ability to dump and load a single table; provide the ability to use Data Definition Language (DDL) statements within transactions; and enable row-level locking during INSERT operations. Other Transact-SQL enhancements include:

Bound Connections

Bound connections are enabled for SQL Server 6.5. With bound connections, two or more discrete connections can share the same transaction lock space and the same transaction, allowing them to work on the same data without lock conflicts. This allows extended stored procedures to call back into the database within the lock context of the parent transaction.

INSERT...EXECUTE

The INSERT INTO statement now supports the EXECute stored_procedure clause in place of insert variables or constants, simplifying the way that the return values from stored procedures are handled. The results set from executing the stored procedure is inserted into a table or variable as specified in the INSERT statement.

CUBE and ROLLUP Operators

The CUBE and ROLLUP operators of the SELECT statement deliver aggregates and super-aggregates for elements within a GROUP BY statement.

The CUBE operator delivers a multi-dimensional data results set instead of the typical zero- or one-dimensional data results set and is useful for cross-referencing information without having to write additional procedures. The CUBE operator creates all combinations of groupings from the list of columns in the GROUP BY statement. You can use the CUBE operator to produce results sets that you can use to enhance charts, graphs, and summary tables.

The ROLLUP operator produces cumulative aggregates, such as running sums or running averages, that can be incorporated into reports, charts, and graphs. The ROLLUP operator differs from the CUBE operator in that it creates groupings by moving in only one direction, from right to left, along the list of columns in the GROUP BY statement. It then applies the aggregate function to all but the rightmost column of these groupings. The ROLLUP operator is useful for extracting statistics and summary information from results sets.

Insert Row-level Locking (IRL)

The lock manager has been enhanced to provide row-level locking (IRL) for most INSERT operations. IRL improves performance in situations where access contention and hotspots (areas of unusually high access) occur.


Server Configuration Enhancements

SQL Server 6.5 allows you to tune performance for SMP systems, and it allows you to configure remote connection timeouts.

Thread Affinity

Thread affinity has been introduced into SQL Server to increase and tune performance on SMP systems with four or more processors. The affinity mask configuration option is a bit vector, where each bit maps to a CPU. This allows you to specify which CPUs are used by SQL Server. Because moving the thread structures and thread data between CPUs is minimized, the threads that handle the network interrupts are masked off. Testing shows an increase in throughput of heavy loads when using the affinity mask configuration option to specify on which CPUs SQL Server threads run.

Remote Connection Timeout

SQL Server now maintains connections to remote servers for a configurable period of time, rather than closing these connections at the end of every remote stored procedure call.


OLE Automation Stored Procedures

SQL Server 6.5 includes OLE Automation stored procedures that allow you to use standard OLE Automation objects within a Transact-SQL statement batch. Because these OLE objects reside and run on the SQL Server computer, they behave as OLE extended stored procedures. You can use existing OLE Automation objects, such as the SQL Distributed Management Objects (SQL-DMO), or you can use the 32-bit Microsoft® Visual Basic® programming system version 4.0 to create your own OLE Automation objects.


SQL-DMO Enhancements

SQL Distributed Management Objects (SQL-DMO) objects have been added and enhanced to support SQL Server 6.5 features, including ConnectionPoint events, which you can use to write COM objects that are notified by SQL-DMO when certain events occur.


ODBC Enhancements

The ODBC SQL Server driver includes support for enlisting in MS DTC transactions using a new driver-specific connection option, the ability to log performance data and long-running queries, and support for connecting to fallback servers. Many other enhancements have also been included. For details about ODBC enhancements, see Programming ODBC for Microsoft SQL Server.

Note that the ODBC Help file contains version 6.0 information. For version 6.5 information, see Programming ODBC for Microsoft SQL Server.


DB-Library for C Enhancements

DB-Library™ for C now includes two new functions, dbenlisttrans and dbenlistxatrans, that support MS DTC. Fallback support is handled by the DBSETLFALLBACK function. Quoted identifiers are now supported by DB-Library with the DBQUOTEDIDENT option. You can now pass program variables as stored procedure parameters when you open a cursor by calling the dbrpcinit function and the dbrpcparam function.

New programming examples are provided in the SQL Server Workstation System in the \PTK\SAMPLES directory. Additional information about the samples is included in the Workstation's README.TXT file.


DB-Library for Visual Basic Enhancements

SQL Server 6.5 includes a new DB-Library for Visual Basic OLE custom control, a 32-bit OLE custom control for creating DB-Library for Visual Basic projects using 32-bit Visual Basic 4.0.

DB-Library for Visual Basic includes the same enhancements as DB-Library for C, except for MS DTC support. It also includes the new SqlCursorRowStatus function for returning the row fetch status value for a row in the cursor fetch buffer.

New programming examples are provided in the SQL Server Workstation System in the \PTK\SAMPLES directory. Additional information about the samples is included in the Workstation's README.TXT file.


Open Data Services Enhancements

Open Data Services includes a new function, srv_getbindtoken, which provides bound connection support for extended stored procedures.

New programming examples are provided in the SQL Server Workstation System, in the \PTK\SAMPLES directory. Additional information about the samples is included in the Workstation's README.TXT file.


Future Feature Support

SQL Server 6.5 includes new features that supersede the functionality of some existing features. Although all features from SQL Server 6.0 continue to be supported in 6.5, future versions of SQL Server might not support some statements where the same functionality can be achieved using other means. For example, the following features are supported in 6.5 but might be discontinued in future versions:

Device Mirroring

If your installation of SQL Server is currently using SQL Server mirroring, it is recommended that you use the mirroring functionality of Windows NT or hardware-based mirroring instead. For more information on Windows NT mirroring, see the Windows NT documentation.

Outer Join Syntax

With SQL Server 6.5, the "*=" and "=*" syntax for outer joins can be replaced with the ANSI-standard join syntax: LEFT OUTER JOIN, RIGHT OUTER JOIN, and FULL OUTER JOIN.

SELECT FOR BROWSE

Although SELECT FOR BROWSE is supported in 6.5, the functionality of the FOR BROWSE clause in SELECT statements can now be achieved more efficiently by using cursors. For more information about cursors, see the DECLARE CURSOR statement, later in this document. Also see the Microsoft SQL Server Transact-SQL Reference, Programming DB-Library for C, and Programming DB-Library for Visual Basic.


About This Document

What's New in SQL Server 6.5 provides information supplementary to the Microsoft SQL Server 6.0 documentation set. In many cases, especially when a feature has been enhanced, it is important that you read the version 6.0 information about that feature in addition to reading about the enhancements in What's New in SQL Server 6.5.

Important SQL Server Books Online contains the most up-to-date information for Microsoft SQL Server 6.5. See Books Online for information that changed or was unavailable at the time the documentation was printed.

The new SQL Server 6.5 features and more are detailed in the following parts:

  • Part 2, What's New for Setup
  • Part 3, What's New for Administrators
  • Part 4, What's New for Transact-SQL
  • Part 5, What's New for OLE Automation Stored Procedures
  • Part 6, What's New for SQL-DMO
  • Part 7, What's New for DB-Library for C
  • Part 8, What's New for DB-Library for Visual Basic
  • Part 9, What's New for Open Data Services


Document Conventions

What's New in SQL Server 6.5 uses the following conventions to distinguish elements of text:

Convention | Purpose
UPPERCASE | Represents Transact-SQL syntax, paths, and filenames.
small capitals | Represent key names, such as ctrl.
bold | Represents system procedures, utility programs, commands, and user-entered text.
italic | Represents database names, table names, book titles, and variables.
monospace | Represents examples, display text, and error messages.
[brackets] | Identify optional items in syntax. Type only the information within the brackets; do not type the brackets.
{braces} | Identify required items in syntax. Type only the information within the braces; do not type the braces.
| (vertical bar) | Means "or" and signifies that you can choose only one of the items within the brackets or braces.


Obtaining Technical Support

Microsoft offers a variety of support options to help you get the most from Microsoft SQL Server 6.5. For information about these options, see the service and support information included with your SQL Server 6.5 CD.


Part 2 What's New for Setup

What's New for Setup

The information in this part supplements Microsoft SQL Server Setup and other Microsoft SQL Server 6.0 documents.

The following features are new or enhanced for the SQL Server 6.5 setup program. Features are in alphabetical order.

Feature | New | Enhanced
Character sets | · |
Installation components |  | ·
Keywords | · |
MSSQLServer service |  | ·
Platform support |  | ·
Unattended setup |  | ·


Installing or Upgrading SQL Server

Installing Microsoft SQL Server version 6.5 requires approximately 96 MB of disk space, plus 1 to 15 MB for SQL Server Books Online. Upgrade requirements are as follows.

Upgrading from | Disk space required for SQL Server 6.5 | Free space required in the master database | Disk space required for SQL Server Books Online
New installation | 56 MB | 25 MB | 1 MB if run from CD 15 MB installed
SQL Server 6.0 | 20 MB | 2 MB | 1 MB if run from CD 15 MB installed
SQL Server 4.2x | 65 MB | 9 MB | 1 MB if run from CD 15 MB installed

In all cases, the required disk space must be available on the drive where SQL Server is located. The setup program checks for required disk space by using somewhat smaller values, so you must manually confirm that enough disk space is available.

The setup program will automatically expand the master database and the MASTER device as required.

Before you begin an upgrade, run the CHKUPG65.EXE utility, which checks that database status is acceptable, that all necessary comments exist in syscomments, and that there are no keyword conflicts. CHKUPG65.EXE writes this information to an output file. Review the report and take any action the report indicates is necessary to prepare the existing installation for an upgrade. For more information about running the CHKUPG65.EXE utility, see Running the CHKUPG.EXE Utility. Note that CHKUPG.EXE is now called CHKUP65.EXE, but the functionality has not changed.

When upgrading to SQL Server 6.5 from version 6.0 or 4.2x, the Open Databases configuration option must be equal to or greater than the total number of databases on your system, including the master, model, tempdb, and pubs databases. If the Open Databases configuration option is less than the total number of databases on your system, the upgrade will fail. You can change the Open Databases configuration option by using SQL Enterprise Manager or the sp_configure system stored procedure.

Note Earlier versions of Microsoft SQL Server must be shut down before installing or upgrading to version 6.5. Also, before an upgrade, stop replication and make sure that the log is empty. It is recommended that the system administrator's default database be set to master.

If you are upgrading from an earlier version of SQL Server and you have databases that contain objects that rely on the setting SET QUOTED_IDENTIFIER ON, you should run SETUP.EXE from the command line using the following syntax:

setup /t SetQuotedId = ON

For more information about running SETUP.EXE from the command line, see "Performing an Unattended Installation" in Microsoft SQL Server Setup.


Compatibility Between SQL Server 6.5 and SQL Server 6.0

SQL Server version 6.5 affects version 6.0 in the following ways:

  • SQL Server 6.0 can be upgraded to 6.5.
  • SQL Server 6.0 backups can be loaded into 6.5.
  • SQL Server 6.5 backups can be loaded into version 6.0 by using Microsoft SQL Server 6.0 Service Pack 3, which is available separately from Microsoft.
  • SQL Server 6.0 and 6.5 cannot be run side by side.
  • If you have not used reserved words in your code, SQL Server applications can remain unchanged. Reserved words are listed in Microsoft SQL Server Setup and in SQL Server Books Online.


Running the Setup Program

Important Earlier versions of Microsoft SQL Server should be shut down before installing or upgrading to version 6.5. Also, before upgrading, stop replication and make sure that the log is empty.

To install or upgrade to SQL Server 6.5
  • From the SQL Server CD, open the appropriate platform directory and run setup.

    For example, to install SQL Server on a Windows NT 3.51 or later, Intel®-based system, run setup from the i386 subdirectory on the SQL Server CD.

The default installation directory for SQL Server 6.5 is MSSQL. You can change the installation directory during setup.


Platform Support

The following platform changes are included with SQL Server 6.5:

  • SQL Server 6.5 can be installed on a Power PC by running the setup program from the PPC subdirectory.
  • SQL Server 6.5 requires Microsoft Windows NT operating system version 3.51 or later. Earlier versions of Windows NT are not supported.


Running on Windows NT 3.51 or Later

On Windows NT 3.51 or later - based systems, to take advantage of SQL Server features that require the SQL Server service to access the network (such as replicating data to an ODBC subscriber or generating web pages), you must set up the MSSQLServer service to log on under a user account.

During SQL Server installation, the setup program asks you to provide the domain, username, and password of a Windows NT user account, which it then assigns to SQL Executive. SQL Server setup installs the MSSQLServer service to run under the LocalSystem account, not under a user acocunt.

After installation, you can modify SQL Server to run under a different user account. For example, to explicitly control SQL Server permissions to access resources on other computers, run SQL Server under a domain user account. You can change account assignments by using the Control Panel Services application.

To set up the MSSQLServer service to log on under a different user account
  1. From Windows NT, open Control Panel.
  2. Open the Services application.
  3. Select the MSSQLServer service.
  4. Choose the Startup button.
  5. Under the Log On As option, select This Account, and then type in the account information.

Note The account under which MSSQLServer service logs on must meet the same requirements as the account under which SQL Executive logs on. For convenience, run the MSSQLServer service and the SQL Executive service under the same user account.


MSSQLServer Service and SQL Executive Requirements

The requirements for MSSQLServer service and SQL Executive accounts can be set by using the Windows NT User Manager application:

  • The account must be a member of the Administrators local group.
  • The account must have the Password Never Expires attribute.
  • The account must be granted the following advanced User Rights:
    • Log on as a service
    • Act as part of the operating system
    • Replace a process level token
    • Increase quotas


Installation Components

Both server and client installations have been enhanced for SQL Server 6.5.


Server Installation

During SQL Server 6.5 installation, the following new components are installed in addition to those provided by SQL Server 6.0. Each component is described in detail later in this document:

  • Microsoft Distributed Transaction Coordinator (MS DTC), running as a Windows NT service
  • Microsoft Query
  • Simple Network Management Protocol Management Information Base (SNMP MIB) and SNMP agent
  • SQL Server Web Assistant
  • SQL Trace


Client Installation

The following components are new for SQL Server 6.5 and are optional for client installations:

  • MS DTC (client utility support installed)
  • Microsoft Query
  • Other ODBC client drivers for heterogeneous replication use
  • SQL Server Web Assistant
  • SQL Trace

Note To install on a Windows 95 - based client, you must have an AUTOEXEC.BAT file before installing. This is the only place that setup sets the path, and it will not create the file for you.


Keywords and Character Sets

The following words, reserved in SQL Server 6.0, are keywords in SQL Server 6.5:

AUTHORIZATION | LEFT
CASCADE | OUTER
CROSS | PRIVILEGES
DISTRIBUTED | RESTRICT
ESCAPE | RIGHT
FULL | SCHEMA
INNER | WORK
JOIN |

The following character sets were added in SQL Server 6.0 and were listed in the README.TXT file:

  • CP1250Central European
  • CP1251Cyrillic
  • CP1253Greek
  • CP1254Turkish
  • CP1255Hebrew
  • CP1256Arabic
  • CP1257Baltic

For these character sets, three generic sort orders are defined:

  • Binary: binary sort order
  • Diction: dictionary, case-sensitive sort order
  • Nocase: dictionary, case-insensitive sort order

In a given character set, these sort orders should be used for all languages that do not have a specific sort order. Specific sort orders are provided in two variants: case-sensitive and case-insensitive.

The following character sets are new with SQL Server 6.5:

  • CP932Japanese
  • CP936Chinese (simplified)
  • CP949Korean
  • CP950Chinese (traditional)

Two new sort orders are supported for all character sets:

  • Binary
  • Windows NT Provided

All character set files are located in \MSSQL\CHARSETS.


Unattended Setup

SQL Server 6.5 can be installed non-interactively by using a setup initialization file. Additionally, because a complete setup requires rebooting, a ForceReboot entry has been added and is defined later in this section.


A Sample Unattended Setup Initialization File

[License]
FullName=SMS Automated Install
OrgName=Unknown
ProductID=0000000000
Mode=0
PerServerUsers=50

[SQLPath]
SQLPath=\MSSQL
LogicalSQLDrive=c:

[MasterPath]
MasterSize=35
LogicalDBDrive=c:
MasterDBPath=\MSSQL\DATA
MasterDBFileName=MASTER.DAT

[NewOptions]
AutoServerService=CHECKED
AutoExecutiveService=CHECKED
BooksOnline=1

[CharSet]
CharSet=cpISO

[SortOrder]
SortFileName=nocase.iso
SortConfigValue=52

[Network]
NetLibList={"SSNMPN60"}
ServerNMPipe=\\.\pipe\sql\query
MultiProtEncrypt=NOTCHECKED
SPXServiceName=SPXName
TCPIPSocketNumber=1433
VinesStreetName=VinesName
ADSPObjectName=ADSPName
DecNetObjectID=DecID

[LogonAccount]
LocalSystem=CHECKED
Username=None
UserPassword=None

[Scripts]
CustScPath=c:\
CustomScriptList={}
ForceReboot=TRUE


ForceReboot

SQL Server 6.5 includes a ForceReboot entry to complete the system reboot required at the conclusion of the setup program. ForceReboot must be the final entry of the [SCRIPTS] section and accepts an argument of either TRUE or FALSE. TRUE indicates that the server will be automatically rebooted at the conclusion of SQL Server setup.

For example, to run an unattended setup and reboot the server, your initialization file would contain the following entry at the end of the [SCRIPTS] section:

ForceReboot=TRUE

For more information, see Microsoft SQL Server Setup and SQL Server Books Online.


Setup Errata

The following changes should be made to Microsoft SQL Server Setup for Microsoft SQL Server 6.0.

  • On page 99, the Orgname entry should be OrgName.
  • On page 101, the [Charset] section title should be [CharSet].
  • On page 101, the value for the 850 Multilingual character set should be cp850.
  • On page 107, the unattended setup initialization file is incorrect. The correct file is in A Sample Unattended Setup Initialization File.


Part 3 What's New for Administrators

What's New for Administrators

Part 3 highlights administrative additions and improvements that are provided with Microsoft SQL Server 6.5, and supplements the information that is presented in the Microsoft SQL Server Administrator's Companion for Microsoft SQL Server 6.0. The following table identifies administrative features as new or enhanced for SQL Server 6.5. Features are in alphabetical order.

Features | New | Enhanced
Alerts management interface |  | ·
ANSI to OEM replication | · |
Backup and recovery |  | ·
Configurable packet size |  | ·
Connecting to SQL Server over the Internet | · |
Custom server configuration using the multiprotocol networking library | · |
Database Backup/Restore dialog box |  | ·
Database Maintenance Plan Wizard | · |
Extended stored procedures manager | · |
External tools support | · |
Fallback support | · |
Graph controls | · |
Installing SQL Server 6.5 on multiple servers |  | ·
ISQL/w |  | ·
Menus and commands |  | ·
Message management |  | ·
Microsoft Distributed Transaction Coordinator | · |
Microsoft Query | · |
Object definitions | · |
Point-in-time recovery | · |
Print support |  | ·
Remote server registration | · |
Remote servers and logins manager | · |
Replication |  | ·
Replication and invalid SQL Server names | · |
Replication between SQL Server 6.0 and 6.5 | · |
Replication for owner-qualified tables | · |
Replication log reader |  | ·
Replication to Microsoft Access subscribers | · |
Replication to ODBC subscribers | · |
Replication to ORACLE subscribers | · |
Replication of text and image data | · |
Screen refresh | · |
SERVERS.BIN file |  | ·
Server registration information maintenance |  | ·
SHOWPLAN output |  | ·
AND EXISTS |  | ·
CONSTRAINT | · |
EXISTS TABLE |  | ·
FULL OUTER JOIN | · |
GROUP BY WITH CUBE | · |
LEFT OUTER JOIN | · |
NOT EXISTS |  | ·
OR EXISTS |  | ·
SUBQUERY |  | ·
UNION ALL | · |
WITH CHECK OPTION |  | ·
SNMP support |  | ·
Specifying columns during replication | · |
SQL Enterprise Manager |  | ·
SQL Executive configuration parameters |  | ·
SQL Mail |  | ·
SQL Performance Monitor counters | · |
SQL Performance Monitor objects | · |
SQL Performance Monitor with integrated security | · |
SQL Server Web Assistant | · |
SQL Trace | · |
SQLExecutiveCmdExec account | · |
SQLServer object |  | ·
SQLServer User-defined Counters object | · |
SQLServer-Licensing object | · |
SQLServer-Lock object |  | ·
SQLServer-Log object |  | ·
SQLServer-Procedure Cache object | · |
Stored procedures that support replication to ODBC subscribers | · |
sp_dsninfo | · |
sp_enumdsn | · |
Table backup and restore | · |
Task scheduling interface |  | ·
text and image replication | · |
Transaction log point-in-time recovery | · |
Transfer management interface | · |
Uninstalling replication | · |
Wizard and assistant | · |


Wizards and Assistants

SQL Server 6.5 provides additional user-assistance and easy-to-use tools. These tools help you complete a task by answering questions, which allows you to progress in an organized manner toward completing a goal.

The Database Maintenance Plan Wizard assists users in maintaining robust databases and provides a sound recovery strategy in case of system failure. The SQL Server Web Assistant is a flexible publishing tool that you can use to generate a standard Hypertext Markup Language (HTML) page from SQL Server data one time or as a recurring task.

Here are a few things to remember about wizards and assistants:

  • You move systematically through the tool by answering questions that appear on the screen.
  • You can return to the previous screen at any time by choosing the Previous button.
  • You can advance to the next screen at any time by choosing the Next button.
  • You can advance to the final screen by choosing the Finish button. By choosing the Finish button, you permit the wizard or assistant to make all remaining decisions for you.


Database Maintenance Plan Wizard

The Database Maintenance Plan Wizard sets up and schedules core maintenance actions for a selected database. These maintenance actions include checking data allocation, data and index linkages, and system data; updating optimizer information and reorganizing data and index pages; and performing database and transaction log backups. Maintenance actions can be scheduled for automatic execution at preset daily or weekly intervals.

To run the Database Maintenance Plan Wizard

  • From SQL Enterprise Manager, choose the Wizard icon from the toolbar or, from the Help menu, choose Database Maintenance Wizard and then follow the on-screen instructions.


Using the Database Maintenance Plan Wizard

The screens in the Database Maintenance Plan Wizard are described below. On most of the screens, the best options will already be selected for you. Unless you have a clear reason not to, accept the defaults.

  1. Introduction screen

    Provides a brief explanation of the wizard. Select the database to set up a maintenance plan for.

  2. About the Data in Your Database screen

    Tailoring the maintenance plan to the selected database requires that you know how often the data is updated and created.

    Updated data is existing data in the database that is modified. Calculate the amount of data that is updated daily and match that amount to the closest value in the following list:

    • Data is never changed
    • Less than 5%
    • More than 5% but less than 20%
    • More than 20%

    For example, if you have a 22MB database and 5MB of data in that database is updated each day, choose the 20% option.

    Created data, referred to as Data Growth on the screen, is data that is new to the database and causes new records to be stored. Calculate the amount of data that is added daily and match that amount to the closest value in the following list:

    • No new data is ever added
    • Less than 2%
    • More than 2% but less than 10%
    • More than 10%

    For example, if you have a 32MB database that is growing slowly, you will choose the Less Than 2% option.

  3. Data Verification screen

    Verifying data is the process of checking that correct relationships among data, metadata, and allocations are maintained. The following are tests you can run:

    Check data linkage
    Examines each data page of each table in the database to verify that they are joined in the correct order. Pages that are not joined correctly will cause errors when queries access broken pages.

    For more information about data linkage, see DBCC CHECKDB in the Microsoft SQL Server Transact-SQL Reference.

    Check index linkage
    Examines each index page of each table in the database to verify that they are joined in the correct order. Pages that are not joined correctly will cause errors when queries access the broken pages.

    For more information about index linkage, see DBCC CHECKDB in the Microsoft SQL Server Transact-SQL Reference.

    Check data allocation
    Examines each data page of each table in the database to verify that the server's internal information about which pages are in use and which pages are not in use is correct. Mismatches will cause errors when queries access these pages. In the worst case, data can be lost.

    For more information about data allocation, see DBCC NEWALLOC in the Microsoft SQL Server Transact-SQL Reference.

    Check index allocation
    Examines each index page of each table in the database to verify that the server's internal information about which pages are in use and which pages are not in use is correct. In the worst case, data can be lost.

    For more information about index allocation, see DBCC NEWALLOC in the Microsoft SQL Server Transact-SQL Reference.

    Check text/image data allocation
    Runs allocation and linkage checks for each text/image page in the database.

    For more information, see DBCC TEXTALL with the FAST option in the Microsoft SQL Server Transact-SQL Reference.

    Check system data
    Examines the system tables (for example, sysindexes and sysobjects) to verify that the information in and between them is consistent.

    For more information, see DBCC CHECKCATALOG in the Microsoft SQL Server Transact-SQL Reference.

    Add the data verification tests to
    Determines the schedule for verification tests. For daily data verification, choose the daily maintenance plan. For weekly data verification, choose the weekly maintenance plan.
  4. Data Optimization screen

    When you delete, update, and create data records, the fullness of SQL Server's pages can become nonuniform over time. Data optimization is the process of refilling pages to a uniform fullness and of updating SQL Server metadata concerning table data distribution. Effective data optimization will help to maximize SQL Server performance.

    Choose from the following options to optimize your data:

    Update optimizer information
    Specifies that each data page of each table in the selected database will be examined to gather and store an accurate sampling (per table) of that data. This distribution information will subsequently be used by the server when optimizing queries.

    For more information, see the UPDATE STATISTICS statement in the Microsoft SQL Server Transact-SQL Reference.

    Reorganize data and index pages
    Specifies that all indexes on all tables in the database should be rebuilt. This option is useful for pages that become full and then split. The splitting process increases the size of a table and, because it happens dynamically, can increase the execution time of queries that modify data. Rebuilding the indexes refills each page to its optimal fullness based on the value that is specified in the Change Free Space To box.

    For more information, see DBCC DBREINDEX in the Microsoft SQL Server Transact-SQL Reference.

    Maintain original free space
    Indicates that the percentage of free space specified when the index was created (or last rebuilt using DBCC DBREINDEX) will be used again to rebuild the index. Free space is the inverse of fill factor (for example, free space of 30 percent is the same as a fill factor of 70 percent).

    For more information, see DBCC DBREINDEX in the Microsoft SQL Server Transact-SQL Reference.

    Change free space to
    Specifies the percentage of free space to leave in each index leaf page when the index is rebuilt. It is important to have enough free space to accommodate future growth and to reduce page splitting. Free space is the inverse of fill factor (for example, free space of 30 percent is the same as a fill factor of 70 percent).

    For more information, see the FILLFACTOR clause of the CREATE INDEX statement in the Microsoft SQL Server Transact-SQL Reference.

    Add the Data Optimizations to
    Specifies that data optimization options be added to the daily or weekly maintenance plan.
  5. Data Protection screen

    Protecting your data is crucial to protecting the integrity of a database. With the Data Protection option, you can schedule database backups. Maintaining backups provides you a way to recover data in case of equipment or other problems.

    Good candidates for daily backups are:

    • Databases with data that is frequently modified and/or added
    • Databases that are critical to operations
    • Databases that are under heavy loads and/or experience frequent equipment failures

    Good candidates for weekly backups are:

    • Databases with data that is changed or added infrequently
    • Databases with data that is easily recovered from other sources

    Select the Only Do The Backup If check box if you want to do a backup only if data verification tests succeed. This assures you that backups will always contain verified data.

  6. Backup Destination screen

    Specifies a destination for the database backup. A backup can be saved to disk or tape.

    Use the Delete Files Older Than check box to delete backup files older than 1 week.

  7. When to Run, Who to Notify screen

    Specifies a schedule for a backup, and whether to generate a report and send a notice through e-mail that the backup is completed.

  8. Wizard Complete screen

    Confirms the selections you made for the maintenance plan.

  9. Print dialog

    Displays a message that prompts you to print your maintenance plan, if you have not already selected to do so.

    Important After you create your maintenance plan and exit the wizard, you cannot easily access the maintenance plan. It is strongly recommended that you print your database maintenance plan.

  10. Confirmation dialog

    Displays a message that states that the wizard is complete. Presents the option to run the plan immediately. If you run the plan immediately, it will not affect the schedule you have specified.


SQL Server Web Assistant

Microsoft SQL Server 6.5 includes the SQL Server Web Assistant, a tool that you can use to generate standard Hypertext Markup Language (HTML) files from SQL Server data. The SQL Server Web Assistant generates HTML files by using Transact-SQL queries, stored procedures, and extended stored procedures. HTML files, also known as web pages, can be viewed by using any HTML browser. HTML files are resources for displaying information on the World Wide Web (WWW) and on internal networks.

The architecture of the SQL Server Web Assistant provides improved performance and scalability for non-interactive queries compared to database access solutions provided by Common Gateway Interface (CGI) applications.

With the SQL Server Web Assistant, you can generate an HTML file on a one-time basis or as a regularly scheduled SQL Server task. An HTML file can be updated by using a trigger whenever relevant data changes. With this task-scheduling flexibility and the power of Transact-SQL, you can create web pages to serve a variety of purposes. For example, you can use the SQL Server Web Assistant to:

  • Schedule a task to automatically update a web page price list whenever a new item is added or a price is changed, thus publishing a dynamic inventory and price list for customers and sales staff.
  • Publish and distribute management reports including the latest sales statistics, resource allocations, or other SQL Server data.
  • Publish server reports with information about who is currently accessing the server, which locks are being held, and by which users.
  • Use extended stored procedures to publish information outside of SQL Server.
  • Use a table of favorite web sites to publish server jump lists.

You can create a web page with the SQL Server Web Assistant in a few simple steps:

  • Start the SQL Server Web Assistant.
  • Create a query using the Query screen.
  • Schedule the query using the Scheduling screen.
  • Name and add options to the HTML file using the File Options screen.
  • Include some basic formatting for the HTML file using the Formatting screen.

Each of these screens is described in the following sections. Additionally, each screen contains a More Info button that provides detailed Help information.

Note The SQL Server Web Assistant provides an interface for the stored procedure sp_makewebtask. The SQL Server Web Assistant interface is available only on Intel-based computers; however, you can run the stored procedure that creates the HTML file from any supported platform. For more information, see Calling the SQL Server Web Assistant from a Program and What's New for Transact-SQL, later in this document.


Running the SQL Server Web Assistant

The SQL Server Web Assistant is automatically installed with Microsoft SQL Server 6.5, and can be optionally installed on 32-bit clients.

The SQL Server Web Assistant works with databases created with SQL Server version 6.5.

To function properly, the SQL Server Web Assistant requires the following privileges:

  • CREATE PROCEDURE privileges in the database you are using
  • SELECT privileges on columns
  • The account in which SQL Server is running must have adequate privilege to create files
To run the SQL Server Web Assistant

  • From the SQL Server program group, double-click the SQL Server Web Assistant icon.

    The SQL Server Web Assistant Login screen appears.

The login settings are identical to those for SQL Server logins.

To log in to SQL Server
  1. Enter a SQL Server name.
  2. Enter a login ID.
  3. Enter a password.
  4. To continue, choose the Next button.

Or

  1. Enter a SQL Server name.
  2. Select the Use Windows NT Security To Log In Instead Of Entering A Login ID And/Or A Password option.
  3. To continue, choose the Next button.


Creating Queries with the SQL Server Web Assistant

The SQL Server Web Assistant offers several ways to build queries. You can:

  • Build a query from a database/table hierarchy.
  • Enter a query as free-form text.
  • Use an existing stored procedure.

Building a Query from a Database/Table Hierarchy

Select this option for interactive assistance in building a query.

The SQL Server Web Assistant Query screen appears.

To interactively build a query from a database/table hierarchy
  1. From the Query screen, select the Build A Query From A Database Hierarchy option.
  2. From the database list, select and expand a database. To expand a database object, click the plus sign (+) next to it.
  3. From the expanded database list, select the table(s) to use in your query. This option is equivalent to a SELECT * FROM table_name statement.
  4. To select individual columns, expand the table selection. All columns are selected by default. To cancel a selection, clear the column(s).
  5. In the Do You Want Any Additional Criteria . . . box, type additional clauses for the query, such as WHERE or ORDER BY.
  6. To continue, choose the Next button. To exit, choose the Cancel button.

For example, to create a web page that contains author information from the sample pubs database, select and expand the pubs database, and then select the authors table. To include only au_id and au_lname columns, expand the authors table and select only these columns. To further refine the query and include only authors from the state of California, add the following clause to the Additional Criteria list box:

WHERE state = "CA"

Note You must enclose string values in double quotation marks ("). Using a single quotation mark (') will generate a syntax error.

Entering a Query as Free-form Text

Select this option to directly enter Transact-SQL queries or to execute external stored procedures. When you select this option from the Query screen, the following screen appears.

To enter a Transact-SQL query
  1. From the Query screen, select the Enter A Query As Free-Form Text option and select a database.
  2. In the Type Your Query text box, type your query.
  3. To continue, choose the Next button. To exit, choose the Cancel button.

You can use the free-form text option with the EXECUTE command to execute existing stored procedures or extended stored procedures.

To execute an extended stored procedure
  1. From the Query screen, select the Enter A Query As Free-Form Text option and select a database.
  2. Use the EXECUTE command with the extended stored procedure call and applicable arguments.
  3. To continue, choose the Next button. To exit, choose the Cancel button.

For example, to execute a directory command in the command shell, use the xp_cmdshell stored procedure within the following syntax:

EXEC xp_cmdshell dir

Using a Query in a Stored Procedure

Select this option to execute Transact-SQL stored procedures. When you select this option from the Query screen, the following screen appears.

To use a query in a stored procedure
  1. From the Query screen, select the Use A Query In A Stored Procedure option and select a database.
  2. Select a stored procedure.

    The procedure text is displayed and cannot be edited.

  3. In the Does Your Stored Procedure Require Any Arguments text box, type applicable arguments for the stored procedure.
  4. To continue, choose the Next button. To exit, choose the Cancel button.


Scheduling SQL Server Web Assistant Queries

You can use the SQL Server Web Assistant to execute queries on a one-time basis or as a regularly scheduled SQL Server task.

The Scheduling screen offers these options.

Scheduling option | Description | Arguments
Now | An immediate, one-time execution | None
Later | A scheduled, one-time execution | Date, time
When Data Changes | An automatic, triggered execution, displays Alter Trigger dialog box | Table(s), column(s) from expandable list
On Certain Days of the Week | A scheduled execution | Days, time
On a Regular Basis | A scheduled execution | Every n hours, days, or weeks

To use the SQL Server Web Assistant scheduling option
  1. From the Scheduling screen, select a scheduling option. Depending on your selection, you might be asked for more information, as shown in the previous table. Define arguments as necessary to complete your scheduling selection.
  2. To continue, choose the Next button. To exit, choose the Cancel button.


Using SQL Server Web Assistant File Options

Use the SQL Server Web Assistant File Options screen to specify file locations, titles, reference text, and reference links.

The SQL Server Web Assistant File Options screen offers these options.

Option | Description
Type the filename of the web page | Is the full path specification to reference the generated HTML file. This filename is relative to where SQL Server is running. The default file specification is C:\WEB.HTML. You must have adequate privilege to create files in the specified directory.
A template file called | Is the full path specification used to reference an HTML template file. This filename is relative to where SQL Server is running. The default is <no template file will be used>. If you use a template file, The Following Information option does not apply. For more information on using template files, see Using HTML Template Files later in this section.
The following information | Specifies whether to use web page formatting options.
What is the title of the Web page? | Specifies the title used by your browser when displaying the web page. The default title is "SQL Server Web Assistant."
What is the title for the query results? | Specifies the title for the results data. The default results title is "Query Results."
Do you want to include URL links and reference text in your web page? | Specifies whether to include one or more URL links to a home page or other location.

Using URL and Reference Text Options

Use these options to include URL links and reference text in your web page.

To include one URL link And reference text
  1. Select the Yes, Add One URL And Reference Text option.

    Two text box options appear.

  2. Type the internet address of the link.
  3. Type the label for the link.
To include multiple URL links and reference text
  1. Select the Yes, Add A List Of Urls And Reference Text From A Table option.

    A text box appears.

  2. Type a query that will return a two-column table containing URLs and reference text. The first column must contain the URL. The second column must contain the reference text.


Using HTML Template Files

To receive query results, you can use your own HTML template file. A template file is any HTML file with the marker <%insert_data_here%> to indicate where the query results should be inserted.

To use a template file with the SQL Server Web Assistant
  1. Add an <%insert_data_here%> marker to your HTML template file and save the changes. HTML tables are supported.
  2. Start the SQL Server Web Assistant.
  3. In the File Options screen, type the full path and name of the HTML file to be generated.
  4. Select the A Template File Called option.
  5. Type the full path and name of your HTML template file.

    If a template file is used, the options listed in the next section titled "Using SQL Server Web Assistant Formatting Options" do not apply.

  6. To continue, choose the Next button. To exit, choose the Cancel button.

For more information on template files, see the sp_makewebtask @templatefile parameter description, later in this document.


Using SQL Server Web Assistant Formatting Options

If you do not choose to use a template file, you can use the Formatting screen of the SQL Server Web Assistant to add some basic font characteristics to the results title and the results data.

To apply formatting options
  1. Select a formatting option for the query results title.
  2. Select a formatting option for the query results data.
  3. Select or clear the date/time stamp option.
  4. Select or clear the column name option.
  5. Select or clear the row limit option.
  6. Choose Finish.


Calling the SQL Server Web Assistant from a Program

You can use the SQL Server Web Assistant to build a query, schedule a task, and generate an HTML file. You can put this functionality into your own code by using the sp_makewebtask stored procedure that generates the HTML file. This system stored procedure can be called by a Transact-SQL program. You can also call system stored procedures to run the task or drop the task.

To call the SQL Server Web Assistant HTML generator from a program
  • Execute sp_makewebtask.
To run a SQL Server Web Assistant task from a program
  • Execute sp_runwebtask.
To drop a SQL Server Web Assistant task from a program
  • Execute sp_dropwebtask.

For more information about these stored procedures, see What's New for Transact-SQL, later in this document.


SQL Trace

Microsoft SQL Trace is a graphical utility that monitors and records SQL Server 6.5 database activity. SQL Trace can display all server activity in real time or create filters that focus on the actions of particular users, applications, or host servers. SQL Trace can display any SQL statements or remote procedure calls (RPCs) that are sent to any Microsoft SQL Server 6.5 server. SQL Trace also records connections and disconnections made to and from the server. SQL Trace activity can be saved to disk in an ISQL/w-compatible script or as an activity log.

All events can be annotated with SQL Server login name, Windows NT domain\username, application name, and host name (where available). The statistics start time, end time, duration, CPU usage, reads, and synchronous writes are avaliable for all events. For language and RPC events, the statistics refer to the individual events. For events such as disconnection, the statistics refer to the complete session. Complete session statistics can be used for auditing.

SQL Trace provides a graphical user interface to the extended stored procedure xp_sqltrace. Many of the features provided by SQL Trace can also be achieved programmatically by using xp_sqltrace directly. For example, by creating an auto-start stored procedure that calls xp_sqltrace, it is possible to automatically start SQL Server auditing.

SQL Trace is installed with SQL Server 6.5 server software and, optionally, with the 32-bit client software.

To start SQL Trace from the command line
  • From the command line, type:

sqltrace /Uusername /Ppassword /E /Hhostname /Ffilter

where

/Uusername
Specifies the username to log on under.
/Ppassword
Specifies the password for the username.
/E
Specifies that a secure connection will be used.
/Hhostname
Specifies the computer's hostname.
/Ffilter
Specifies a SQL Trace filter.
To start SQL Trace from the user interface

  1. From the Microsoft SQL Server 6.5 program group, choose the SQL Trace icon.

    The Connect Server dialog box appears.

  2. In the Server box, specify a server to connect to and choose the Connect button.

    If filters have been defined for the selected server, the Start Selected Filters dialog box appears. If filters have not been defined for the selected server, a dialog box appears in which you can choose to create a filter. When you choose Yes, the New Filter dialog box appears.

To create a filter
  • When you connect to a server without defined filters, a dialog box appears in which you can choose to create a filter. Choose the Yes button and complete the New Filter dialog box that appears.

Or

  • In the SQL Trace window, from the toolbar choose the New Filter button to open the New Filter dialog box.

Or

  • From the File menu, choose New Filter to open the dialog box.

For more information about New Filter dialog box options, from the New Filter dialog box choose Help.

You can modify or delete an existing filter by using the Filter Properties dialog box.

To modify a filter
  1. In the SQL Trace window, from the toolbar choose the Edit Filter Properties button.
  2. Complete the Filter Properties dialog box that appears.

Or

  • From the File menu, choose Edit Filter Properties to open the Filter Properties dialog box.

Or

  • In the Filter Status pane, double-click the filter name to open the Filter Properties dialog box.

For more information about Filter Properties dialog box options, from the Filter Properties dialog box, choose Help.

You can delete an inactive filter.

To delete a filter
  1. In the Filter Status pane, verify that the filter you want to delete is not running.
  2. In the SQL Trace window, from the toolbar choose the Delete Filters button.

    Complete the Delete Selected Filters dialog box that appears.

Or

  • From the File menu, choose Delete Filters to open the Delete Selected Filters dialog box and select the filter to delete.

Or

  • In the Filter Status pane, double-click the filter name to open the Filter Properties dialog box and choose the Delete button.

For more information about Delete Selected Filters dialog box options, from the Delete Selected Filters dialog box, choose Help.

The SQL Trace window contains the following elements.

Element | Description
SQL Trace title bar | Displays the name of the connected server.
Active Filter pane | Displays the activity of the named filter and the requests that are coming to the server named in the SQL Trace title bar. The Active Filter pane title bar displays the filter name.
Filter Status pane | Lists the filters that are currently defined on the server, displays information about these filters, and provides Start, Pause, and Stop buttons.
Screen check box | Specifies whether to display filter activity in the Active Filter pane.
Script check box | Specifies whether to save filter activity as an SQL script.
Log check box | Specifies whether to save filter activity to a log.
Active Filters box | Displays in the lower, right-hand corner of the status bar the number of active filters. To display the Active Filters box, from the View menu, select Statusbar. To hide the Active Filters box, from the View menu, clear Statusbar.

To control filter activity from the Filter Status pane

To start a filter, choose the right-pointing arrow Start button.

To pause a filter, choose, the parallel vertical bars Pause button.

To stop a filter, choose the solid box Stop button.

To modify a filter from the Filter Status pane
  1. Double-click the filter name to modify.
  2. Complete the Filter Properties dialog box that appears.

For more information about configuring and using SQL Trace, see the SQL Trace online Help.


Microsoft Distributed Transaction Coordinator

Microsoft Distributed Transaction Coordinator (MS DTC) coordinates transactions across a network of Microsoft® Windows NT™- and Microsoft® Windows® 95-based systems. With MS DTC, SQL Server can:

  • Update data that resides on two or more SQL Server systems.
  • Participate in transactions that are controlled by X/Open™ DTP XA-compliant transaction-processing monitors such as Transarc's Encina®, AT&T Global Information Solutions Company's Top End®, and tuxedo®.
  • Provide an easy-to-use graphical user interface for distributed transactions.

With MS DTC in SQL Enterprise Manager, you can:

  • Start and stop MS DTC (as a Windows NT service).
  • Open the DTC Transactions window, where you can view all transactions that are running and the status of each transaction. You can force prepared transactions to resolve as being committed or to stop. You can force active transactions to stop. You can also force a coordinating MS DTC server to remove a transaction from its log.
  • Open the DTC Trace window, where you can view event log information as well as MS DTC trace information. You can filter the displayed information by severity level.
  • Open the DTC Statistics window, where you can view statistics about MS DTC counters, including:
    • Current number of active transactions
    • Peak number of concurrent transactions
    • Number of committed transactions
    • Number of aborted transactions
    • Number of in-doubt transactions
    • Number of administratively resolved transactions
    • Total number of transactions processed
    • Transaction response times
    • The date and time the MS DTC session started
  • Open the DTC Configuration window, where you can set MS DTC update frequency, transaction display retention, log file location, and checkpoint and flush timers.

MS DTC is installed when SQL Server 6.5 is installed. The MS DTC service is added to the Services application in Control Panel.

To use MS DTC from SQL Enterprise Manager

  1. In the Server Manager window, select a server and expand the tree for that server.

    A Distributed Transaction Coordinator icon appears under the name of the server if that server has MS DTC installed.

  2. To start, stop, or administer MS DTC, click the right mouse button on the Distributed Transaction Coordinator icon.
  3. From the shortcut menu, select the appropriate command.

You can also use MS DTC by using the Distributed Transaction Coordinator command from the Server menu.

For more information about configuring and using MS DTC, see the Guide to Microsoft Distributed Transaction Coordinator.


Replication

In SQL Server 6.5, the capabilities of data replication have been extended to include text and image datatypes. Also in SQL Server 6.5, replication has been enhanced to support replication to heterogeneous databases that are using ODBC.

text and image Datatype Replication

Replication to ODBC Subscribers

Additional Replication Information


text and image Replication

The process of replicating text and image datatypes is subject to the following considerations:

  • INSERT, UPDATE, and DELETE statements are supported.
  • Logged text operations can be replicated by using WRITETEXT and UPDATETEXT with the WITH LOG option on tables that are published for replication. A text or image column that is published for replication using WRITETEXT and UPDATETEXT operations with the WITH NO_LOG option are not supported, because the replication process monitors the transaction log.
  • UPDATETEXT operations can be performed for Microsoft SQL Server 6.0 and later subscribers (not for other SQL Server subscribers). Also, the UPDATETEXT option will fail at the publisher if an ODBC subscriber has a subscription on the text or image column.
  • WRITETEXT operations are replicated as UPDATE statements, enabling replication of WRITETEXT to ODBC subscribers as well as to SQL Server. (UPDATETEXT operations are replicated as UPDATETEXT.)
  • Custom procedures are not used if multiple text columns are being modified, because the other text column values are not logged. A standard UPDATE statement is generated instead.
  • A configurable parameter, max text repl size, controls the maximum size (in bytes) of text and image data that can be replicated. This permits support of ODBC drivers and other SQL Server databases that cannot handle large text and image values, and distributors that have system resource (virtual memory) constraints. When a text or image column is published and an INSERT, UPDATE, WRITETEXT, or UPDATETEXT operation is run that exceeds the configured limit, the operation fails.

    The max text repl size parameter is set by using the sp_configure system stored procedure or the SQL Enterprise Manager Server Configuration dialog box.

    For more information on setting max text repl size, see sp_configure.

  • Because SQL Server is log-based, for text and image columns to be replicated, the text pointer must be retrieved within the same transaction as the UPDATETEXT or WRITETEXT operation.

    Also, once the text pointer has been obtained, you should not perform any operations that can alter the location of the text pointed to by the text pointer (such as updating the primary key), before exectuing the UPDATETEXT or WRITETEXT statement.

    This is the recommended way of using UPDATETEXT and WRITETEXT operations with data to be replicated:

    1. Begin the transaction.
    2. Obtain the text pointer.
    3. Use the text pointer in the UPDATETEXT or WRITETEXT operation.
    4. Commit the transaction.
  • To replicate a text or image column, publish the table using SQL Enterprise Manager and include the text or image column in the published article. For more information about publishing tables and columns, see the Microsoft SQL Server Administrator's Companion.


text and image Replication Limitations

An important consideration when sizing subscribing databases is that the text pointer for replicated text and image columns will be initialized on subscriber tables, even when uninitialized on the publisher. Consequently, each text and image column added to the subscriber table by the distribution task will consume a minimum of 2K database storage.


Replication to ODBC Subscribers

SQL Server 6.5 supports replication to heterogenous databases that are using ODBC. ODBC subscribers to SQL Server include:

  • Microsoft Access databases
  • ORACLE databases
  • Other databases on ODBC subscribers that comply with SQL Server ODBC subscriber requirements

For more information about ODBC subscriber requirements, see About Other ODBC Subscribers.


Publishing to ODBC Subscribers

You must set up ODBC subscriptions by administering the publisher (that is, by using the push subscription model). You cannot set up ODBC subscriptions by administering a subscriber (the pull subscription model). For ODBC subscribers, the subscribing database has no administrative capabilities regarding the replication being performed.

To publish to an ODBC subscriber
  1. From Control Panel, run the ODBC administration application and add the subscriber's data source name (DSN) as a system DSN.

    For more information about adding system DSNs, see the online Help for the ODBC administration application.

  2. Using SQL Enterprise Manager, configure the newly added system DSN as a subscribing server to the publishing server by choosing the New Subscriber button from the Replication - Publishing dialog box.

    The New Subscriber dialog box appears.

  3. From the New Subscriber dialog box, choose the ODBC Subscriber button.

    Complete the New ODBC Subscriber dialog box that appears.

    Note Only system DSNs are listed in the New ODBC Subscriber dialog box.

    For more information about completing the New ODBC Subscriber dialog box, see the online Help for SQL Enterprise Manager.

  4. While using SQL Enterprise Manager to create or edit a publication, perform a push subscription to the subscriber by choosing the Subscribers button from the Edit Publications or Edit Article dialog box. Complete the dialog box that appears.

    For more information about push subscribing, see the Microsoft SQL Server Administrator's Companion.

Note Replication creates tables on the ODBC subscribers by using quoted identifiers (for example, "authors" rather than authors). Some database query tools do not support objects created using quoted identifiers. Verify that your query tool supports quoted identifiers if you cannot view replicated tables.


Support for ODBC Subscribers

SQL Enterprise Manager supports replication to ODBC subscribers with the following additions for SQL Server 6.5:

  • In the Replication - Publishing dialog box, the New Subscriber button opens the New Subscriber dialog box, which contains an ODBC Subscriber button. This button opens the New ODBC Subscriber dialog box, which presents a list of system DSNs that are registered with the publisher.

    You can also enter a username and a password if they are required by the ODBC subscriber. The username and the password are used by the distributor to connect to the ODBC subscriber. In many cases, entering the username or password in this dialog box is not necessary, because they are often entered and stored (depending on the ODBC driver) during the process of registering a system DSN with the ODBC administration application in Control Panel.

    Note A username or password that is entered in the Replication - Publishing dialog box will override any username or password that is entered in the ODBC administration application for a registered DSN.

  • The login name and password for ODBC subscribers can be edited in the Distribution Options dialog box. These options are not available if a SQL Server subscriber is being administered.
  • A Subscriptions button has been added to the New Publications and Edit Publications dialog boxes. This button provides the ability to do a push subscription of an entire publication. (In SQL Server 6.0, push subscriptions can be performed only for individual articles.)


Stored Procedures that Support Replication to ODBC Subscribers

SQL Server 6.5 provides the following stored procedures and extended stored procedures to support replication to ODBC subscribers.

Procedure | Description
sp_enumdsn | Reports all defined ODBC DSNs in the same user context as the server. If the server is running in its default system account, only system DSNs will be reported. A server can be run in a Windows NT account; if the sp_enumdsn stored procedure is called, all DSNs for the system account are returned. When running as a service under a private user's Windows NT account, only those DSNs that are defined under the user's account are returned.
sp_dsninfo | Retrieves ODBC DSN information from the replication distributor that is associated with the current server if replication is installed.

Note SQL Enterprise Manager (the recommended tool) automatically uses these stored procedures to set up replication to ODBC subscribers. You will use these stored procedures directly only if you are not using SQL Enterprise Manager.

For more information about these replication stored procedures, see What's New for Transact-SQL.


Replication Restrictions for ODBC Subscribers

The following restrictions apply to replication to all ODBC subscriber types:

  • Batched statements to ODBC subscribers are not supported (because the distribution task -c option is ignored).
  • The ODBC DSN must conform to the SQL Server naming conventions (because the DSN is stored in the sysservers table).
  • The publication option to truncate before synchronization is not supported if the ODBC DSN is not a SQL Server DSN. ODBC subscribers will not be allowed to subscribe to publications that have this option selected.
  • The target server's quoted identifier character (as reported by the ODBC driver) is used.
  • The Character Format bulk copy method must be selected for synchronization (in the Edit Publications dialog box). ODBC subscribers cannot subscribe to publications that have selected the Native Format bulk copy method for synchronization.


Datatype Mappings for ODBC Subscribers

When replicating to ODBC subscribers, the distribution task maps SQL Server datatypes to the closest datatype on the target database. The following table shows the datatype mappings for replication to Microsoft Access subscribers.

SQL Server datatype | Maps to Microsoft Jet datatype
bit | BIT
tinyint | BYTE
image | LONGBINARY
varbinary | VARBINARY
binary | BINARY
timestamp | BINARY
text | LONGTEXT
char | CHAR
numeric | CHAR
decimal | CHAR
money | CHAR
smallmoney | DOUBLE
int | LONG
smallint | SHORT
float | DOUBLE
real | SINGLE
datetime | CHAR
smalldatetime | DATETIME
varchar | VARCHAR2

The following table shows the datatype mappings for replication to ORACLE subscribers.

SQL Server datatype | Maps to ORACLE datatype
bit | NUMBER
tinyint | NUMBER
image | LONG RAW
varbinary | RAW
binary | RAW
timestamp | RAW
text | LONG
char | CHAR
numeric | NUMBER
decimal | NUMBER
money | NUMBER
smallmoney | NUMBER
int | NUMBER
smallint | NUMBER
float | FLOAT
real | FLOAT
datetime | CHAR
smalldatetime | DATE
varchar | VARCHAR2


About Microsoft Access Subscribers

SQL Server 6.5 includes an ODBC driver that supports Microsoft Access subscriptions to SQL Server replication. The ODBC driver exists only for Intel-based computers. To install the driver, run SETUP.EXE from the \I386\ODBCREPL directory on the SQL Server CD-ROM.

To replicate to Microsoft Access subscribers, you must assign to the MSSQLServer service the same domain user account as is assigned by SQL Executive to have necessary permissions to connect to an .MDB file over the network. Use the services application in Control Panel to do this.

Note When you register a Microsoft Access DSN on a remote server, supply a UNC path (not a redirected drive letter).


Replication Restrictions for Microsoft Access

  • SQL Server datetime, numeric, decimal, and many other datatypes are mapped to char. Numeric and decimal datatypes that are converted to char cause some precision loss.
  • Some character datatypes in SQL Server are not supported in Microsoft Access.


About ORACLE Subscribers

SQL Server 6.5 includes an ODBC driver that supports ORACLE subscriptions to SQL Server. The driver is redistributed by Microsoft from Visigenic™. The driver exists only for Intel-based computers. To install the driver, run the setup program from the \I386\ODBCREPL directory on the SQL Server CD-ROM.

Note To replicate to ORACLE ODBC subscribers, you must also obtain the appropriate ORACLE SQL*Net driver from ORACLE or from your software vendor.

When you use the ODBC administration application in Control Panel to register an ORACLE DSN, you must enter a username. The username is stored by the system and is used by the distributor to connect to the ORACLE ODBC subscriber.

The ODBC driver for ORACLE also creates a password key in the Registry. You can edit the Registry to provide a value for the password. The Registry key for the ORACLE ODBC driver password is:

HKEY_CURRENT_USER\SOFTWARE\ODBC\ODBC.INI\ORACLE\PWD:REG_SZ:password

If a password is provided in the Registry, then the ORACLE ODBC driver will connect to ORACLE without requesting a password.

If a password is not provided in the Registry, then when setting up subscriptions for ORACLE, you must enter a username and a password for the ODBC data source when specifying the DSN in the New ODBC Subscriber dialog box of SQL Enterprise Manager.

Note The ODBC driver for ORACLE that is provided with SQL Server 6.5 is not double-byte character set (DBCS)-enabled.


About Other ODBC Subscribers

Drivers for other ODBC subscriber types must conform to the Microsoft SQL Server replication requirements for generic ODBC subscribers. The ODBC driver:

  • Must be ODBC Level 1 compliant.
  • Must be 32-bit, thread-safe, and for the processor architecture (Intel, PPC, MIPS®, Alpha AXP™) that the distribution process runs on.
  • Must be transaction capable.
  • Must support the Data Definition Language (DDL).
  • Cannot be read-only.


ODBC Driver Support

ODBC drivers for Microsoft Access and ORACLE are included on the SQL Server 6.5 CD. Microsoft technical support will support problems encountered when using these drivers for replication. For information about Microsoft technical support options, see the service and support card included in your SQL Server 6.5 package.

If you encounter problems trying to replicate to ODBC data sources using other ODBC drivers, please contact the ODBC driver vendor for support.


Additional Replication Information

SQL Server 6.5 provides the following additional changes to replication:

  • The DBREPL.SQL script has been removed.
  • The explicit (NOLOCK) optimizer hint is no longer needed in a replication filter; the lock manager has been updated to ignore table locks on the replicated base table during a replication filter.
  • NOT FOR REPLICATION can be added to foreign key constraint declarations. For more information, see What's New for Transact-SQL.
  • The Replication Topology window includes New Subscriber and Remove Subscriber buttons that you can use to add or remove subscribers. The Replication Topology window also includes graphical images that represent the type of subscriber (SQL Server, Microsoft Access ODBC, generic ODBC, and so on).
  • Several of the replication dialog boxes in SQL Enterprise Manager have been enhanced. For more information, run SQL Enterprise Manager and review its replication interface or see the SQL Enterprise Manager online Help.


ANSI to OEM Replication

In SQL Server 6.5, replication between two SQL Servers with different code pages is supported. In version 6.0, replication can occur only between servers that have the same code page.

All data that is sent to ODBC subscribers from SQL Server will be in the ANSI code page (ISO 8859-1). An ODBC subscriber must translate the data to its native code page.

To define a translation
  1. From Control Panel, choose the ODBC administration application.

    The System Data Sources dialog box appears.

  2. Select the data source.
  3. Choose Setup.

    The ODBC SQL Server Setup dialog box appears.

  4. Choose Options, and in the lower half of the dialog box that appears, choose Select.

    The Select Translator dialog box appears.

  5. Specify the translation and choose OK.


Replication for Owner-qualified Tables

Users other than database owners (DBOs) can replicate tables between databases and maintain their ownership of the tables. A table that is replicated from a publisher to a subscriber can be owned by the owner of the published table; it is then referred to as an owner-qualified table.

This feature is useful for users who want to maintain ownership of their replicated tables in the subscriber database.

To set up owner-qualified tables
  1. Create articles and a publication.
  2. From the Edit Publication dialog box, choose Edit.

    The Manage Article dialog box appears.

  3. Select the Owner-Qualify Table Name check box.
  4. Choose OK.

    Note When using the owner-qualified option, automatic synchronization is not supported.


Specifying Columns During Replication

In SQL Server 6.5, the replication INSERT statements can include a column list. This column list guarantees that inserted data will populate the correct columns in the subscriber's table.

In SQL Server 6.0, INSERT statements that were generated by replication did not include a column list. This could result in replication errors if the subscribing table had columns in a different order than the source table, or if the subscribing table included columns that were not present in the source table.

Important This functionality should be enabled only if you suspect problems will occur with replication. Enabling the column list increases the length of the generated INSERT statements, resulting in higher storage requirements for the distribution database and increased network traffic.

To create column lists for an article
  1. Create a publication and articles.
  2. From the Edit Publication dialog box, choose edit.

    The Manage Article dialog box appears.

  3. Select the Use Column Names in SQL Statements check box.
  4. Choose OK.


Replication Synchronization Task

When using character-mode synchronization, SQL Server uses tab characters to delimit fields and newline characters to delimit rows (or lines) in a character mode data file. If text or character fields within a table contain tab or newline characters, character-mode synchronization can fail because the data file that is used for synchronization cannot be processed correctly.

To perform character-mode synchronization of tables with tab or newline characters in data, SQL Server 6.5 allows alternate field and row delimiters to be specified for the synchronization task.

Syntax

-r row_delimiter -f field_delimiter

where

-r row_delimiter
Specifies a sequence of one or more characters to use as a row delimiter. The -r parameter is case-sensitive. The delimiter must appear immediately after the parameter.
-f field_delimiter
Specifies that a field delimiter is necessary to replace tab characters. The -f parameter is case-sensitive. The delimiter must appear immediately after the parameter.

Remarks

Field and row delimiters must be sequences of characters that do not appear in any text or character fields in the table that is being processed. It is important to verify that the delimiters you use are character sequences that will not appear in the table that is being replicated. Otherwise, the synchronization task will be unable to associate data source files with columns in the target table when performing a character-mode synchronization.

When the task scheduler issues the synchronization event, it will use the field and row delimiters you have specified in the Command text box of the Edit Task dialog box.

To use the row and field delimiter parameters
  1. Stop SQL Executive if it is running.
  2. From the Manage menu, choose Replication/Publications and in the Manage Publications dialog box that appears, choose New.

    The Edit Publications dialog box appears.

  3. Create your publication and in the Synchronization tab, set the initial synchronization method to Bulk Data Copy - Character Format (Compatibility).
  4. From the Server Menu, choose Scheduled Tasks.

    The Manage Scheduled Tasks dialog box appears.

  5. Refresh the Manage Scheduled Tasks window. In the Task List tab, in the Type column, there should now be a task named Sync for your new publication.
  6. Double-click the task.

    The Edit Task dialog box appears.

  7. In the Command text box, add the desired parameters.
  8. Choose Modify to close the dialog box and save changes.
  9. Restart SQL Executive.

Note If you know that tabs and newline characters will not appear in character data, then there is no need to make use of the row and field delimiter parameters.

Examples

A. Using Words as Delimiters

This example uses <<FIELD>> and <<ROW>> as field and row delimiters:

-f<<FIELD>> -r<<ROW>>
B. Abbreviating Delimiters

This example uses _D1_ and _D2_ as field and row delimiters:

-f_D1_ -r_D2_


Replication Log Reader

The log reader provides switches to help improve log reader performance during replication.

The log reader moves replication data from the publisher to the distributor, so that data can later be replicated to subscribers. The data is inserted into the distribution database in transactions. The amount of data that is transferred within each transaction is controlled by log reader -b, -c, and -t parameters.

Large batch sizes(-b, -c) move data out of the transaction log more quickly than small batch sizes. However, large batch inserts into the distributed database can cause subscriber tasks to block, waiting for access to the data. You must tailor the log reader parameters for optimal performance.

The following switches control the behavior of the log reader task. Although the transaction batch size -b and commit batch size -c parameters are included in the following table, only the command threshold parameter -t is new for SQL Server 6.5.

Switch parameter | Description
-b | Specifies the transaction batch size. This parameter determines the maximum number of transactions that are read out of the log before the log reader begins the COMMIT TRANSACTION process. The default is 100.
-c | Specifies the commit batch size. This parameter determines how many transactions are placed in the distribution database before a COMMIT TRANSACTION can be issued in the distribution database. The default is 100.
-t Specifies the command threshold. This parameter determines the number of commands within a transaction to accept before a COMMIT TRANSACTION can be issued in the distribution database.

When this threshold number is exceeded, the log reader moves to commit the transaction even though the number of transactions may not have exceeded the commit batch size. In this way, you can improve distribution database access for subscribers.

When the parameter value is missing or 0, the command threshold logic is not applied to the log reader process.

In SQL Server 6.5, the log reader will commit the current batch of jobs to the distribution database if:

  • The number of jobs exceeds the commit batch size -c parameter
  • The number of commands in the last job exceeds the command threshold -t parameter

The command threshold parameter can lessen the impact of large transactions by allowing the log reader to commit the transactions as soon as they are completely processed instead of waiting for all pending transactions to be processed.

Important If you are not experiencing subscriber access delays, you should not set these parameters.

To set the log reader parameters
  1. Stop SQL Executive if it is running.
  2. From the Server Manager window, select a server and then from the toolbar, choose the Manage Scheduled Tasks button. Or, from the Server menu, choose Scheduled Tasks.

    The Manage Scheduled Tasks window appears.

  3. Choose the New Task button to display the New Task dialog box. Or from the task list, select the log reader task and then choose the Edit Task button.

    The Edit Task dialog box appears.

  4. Modify text in the Command box as necessary.
  5. Choose Add or Modify.


Snapshot Replication

A subscriber table that is populated using snapshot replication does not require a primary key. Incremental updates are not used to propagate changes to data in the table, so it is not necessary to uniquely identify each row.

To enable snapshot replication to tables without primary keys, run the sp_addarticle stored procedure to create the articles; the table names will not appear in the Article Table list if they do not have a declared primary key.


Replicating between SQL Server 6.0 and SQL Server 6.5

SQL Server 6.5 supports replicating between 6.0 and 6.5 SQL Servers. Before setting up replication between servers of different versions, consider the following constraints:

  • The Publisher and Distributor must be the same version. Choose either 6.0 or 6.5 for both Publisher and Distributor.
  • Replication administration must be done from SQL Enterprise Manager on a SQL Server 6.5.
  • You must install the SQLOLE65.SQL script on the 6.0 server involved in replication. To install SQLOLE65.SQL, run the script for your platform found on the SQL Server CD-ROM. From the SQL Server CD-ROM, choose the subdirectory for your platform, and then choose the subdirectory for ODBC. The correct script resides in the ODBC subdirectory.
  • When replicating from a SQL Server 6.0 server to a SQL Server 6.5 server, the replication process works as a SQL Server 6.0 replication process. The enhanced replication features of SQL Server 6.5 will not be available. For more information about SQL Server 6.0 replication, see the Microsoft SQL Server Administrator's Companion for 6.0.
  • When replicating from a SQL Server 6.5 server to a SQL Server 6.0 server, the SQL Server 6.0 server is treated as an ODBC server. You must set up a data source name (DSN) for the SQL Server 6.0 server.
To set up the SQL Server 6.0 server as a DSN:
  1. On the machine where SQL Server 6.5 resides, from the Main program group, click Control Panel.
  2. From Control Panel, run the ODBC Administration application, and add the subscriber's DSN as a system DSN.
  3. Using SQL Enterprise Manager, configure the newly added system DSN as a subscribing server to the publishing server by choosing the New Subscriber button from the Replication - Publishing dialog box.

    The New Subscriber dialog box appears.

  4. From the New Subscriber dialog box, choose the ODBC Subscriber button.
    Complete the New ODBC Subscriber dialog box that appears.

    Note Only system DSNs are listed in the New ODBC Subscriber dialog box.

  5. While using SQL Enterprise Manager to create or edit a publication, perform a push subscription to the subscriber by choosing the Subscribers button from the Edit Publications or Edit Article dialog box.

    Complete the dialog box that appears.


Replication and Invalid SQL Server Names

In SQL Server 6.0, replication to and from servers with Windows NT-based computers that are invalid SQL Server names is not supported. (For example, names with hyphens are invalid SQL Server names). The reason for this is that in SQL Server 6.0, replication uses the srvname column in the sysservers system table, and entries in this column need to be valid SQL Server names.

SQL Server 6.5 relaxes this restriction by using the srvnetname column in sysservers instead.

To set up an invalid SQL Server name as a publisher, distributor, or publisher/distributor
  1. In the SQL Client Configuration utility, in the Advanced dialog box, create a DB-Library alias from a valid server name to the Windows NT-based machine name. For example, if the machine name is new-server-name (with invalid hyphens), the client configuration information will be:
Server: | new_server_name
DLL: | Named pipes
Connection string: | new-server-name

For more information, see the Microsoft SQL Server Administrator's Companion.

  2. In SQL Enterprise Manager, from the Server menu, register the server using the alias defined in step 1.

    For example, register the server as new_server_name.

    Note that you will not be able to start and stop SQL Server or SQL Executive from SQL Enterprise Manager. You can use SQL Service Manager. Also, you will be unable to view the SQL Executive icon. View SQL Executive tasks via the Server menu/Scheduled Tasks selection in SQL Enterprise Manager.

  3. Using stored procedure sp_addserver, create a local server name for SQL Server that matches the server alias created in step 1, as follows:
    sp_addserver new_server_name, LOCAL

    where

    new_server_name
    Specifies a logical server name to replace the invalid server name.
    LOCAL
    Specifies the server is on the local machine.
  4. Start SQL Server.
  5. In SQL Enterprise Manager, from the Server menu, choose Replication Configuration/Install Publishing.

    Complete the Install Replication Publishing dialog box that appears.

  6. In SQL Enterprise Manager, from the Server menu, choose Replication Configuration/Publishing.

    The Replication - Publishing dialog box appears.

  7. In the Working Directory box, type the network machine name; it will be using the registered server name.
  8. In SQL Enterprise manager, create publications and articles on the publisher. You can also use stored procedures to create publications and articles.
  9. With SQL Enterprise Manager focus set on a subscribing server, set the publisher's srvnetname on the subscriber as follows:
    sp_setnetname new_server_name, 'new-server-name'

    where

    new_server_name
    Is the server alias for the publisher that was defined on the subscriber by SQL Enterprise Manager.
    new-server-name
    Is the invalid machine name.
  10. Enable subscribing from the publishing server.

    You can now create either push or pull subscriptions.

To set up an invalid SQL Server name as a subscriber
  1. Change the SQL Server name by using the stored procedure sp_addserver, as follows:
    sp_addserver new_server_name, LOCAL

    where

    new_server_name
    Specifies a logical server name to replace the invalid server name.
    LOCAL
    Specifies the local machine.
  2. Restart SQL Server.
  3. From SQL Enterprise Manager, add a subscriber using the logical name (for example, new-server-name) on the Publisher/Distributor.
  4. Set the subscriber's srvnetname on the Publisher/Distributor by using:
    sp_setnetname new_server_name, 'new-server-name'

    where

    new_server_name
    Specifies a logical server name to replace the invalid server name.
    new-server-name
    Specifies the real machine name, which contains hyphens in this example.
  5. Create publications and articles on the publisher.
  6. Create push or pull subscriptions.

For more information on replication, see the Microsoft SQL Server Administrator's Companion.


Replication Troubleshooting

This section contains troubleshooting techniques for SQL Server.

Revising a Database Name

Dropping a publishing database does not remove references to it in the distribution database. This can cause a problem if you re-create a database with the same name and attempt to use it as a publishing database. The distribution database will already have references to the named database, but they will not correctly reflect the newly created publishing database.

To reuse a database name that has been involved in publishing
  • In the distribution database, reset the distribution database by running the following query:
    delete from MSjob_subscriptions WHERE
publisher = 'publisher' AND
publisher_db = 'published db'

For more information about the DELETE statement, see the Microsoft SQL Server Transact-SQL Reference.

Replicating text and image Columns

When loading tables that contain text and image columns, the synchronization process will automatically initialize NULL text pointers for the text and image columns.

If the tables are large and have many uninitialized text or image columns, many records will be written to the transaction log. To minimize the impact of the initialization, you can:

  • Use automatic transaction log backups through Windows NT Performance Monitor, as described in the Microsoft SQL Server Administrator's Companion.
  • Minimize the number of NULL text and image columns in the published table.
  • Disable this functionality (which is on by default) by adding the -N switch on the distribution process(s). Ensure that applications modifying text and image columns in the published table initialize text pointers using a value other than NULL in the UPDATE statement.


Uninstalling Replication

SQL Server 6.5 automates uninstalling replication from SQL Enterprise Manager. Once replication is installed on a server, the Install Publishing menu option becomes Uninstall Publishing. Uninstalling replication causes all publications for the current server to be deleted and the distribution database to be dropped.

To uninstall replication
  1. From the Server menu, choose Replication Configuration/Uninstall Publishing.

    The Uninstall Replication dialog box appears.

  2. Choose Yes.


Fallback Support

Some customers require that their application databases be available all the time. However, in these situations there is the concern that hardware or system failure could render the databases unavailable. To address this potential problem, SQL Server provides fallback support, which enables another computer that is running SQL Server to adopt the crucial databases and device files of a failed primary server. SQL Server's fallback functionality is based on underlying hardware or operating system support for transferring the control of the hard drive array from a primary server to a fallback server.


Fallback Hardware Configurations

The SQL Server fallback feature is flexible enough to support a fallback strategy relating many primary servers to many fallback servers.

Plausible means of implementing fallback are becoming available through specialized hardware and operating system features. Major vendors now offer specialized hardware that is capable of automatically shifting the control of a "switchable" hard drive array from a failed primary server to a fallback server. For example, hardware can be configured with one separately housed hard drive array connected to two computers. Only one of the connections to the hard drive array is active at any one time. The other hard drive connection becomes active only if the system detects that the computer currently in control of the hard drive has shut down because of a hardware or operating system failure. Detection of such failures is made possible by a direct connection between a COM port on both computers, over which "heartbeat" signals are continuously transmitted. The automatic process can also invoke a user-written program on the fallback server when the hard drive array is switched to the fallback server.

This type of automated fallback hardware configuration allows one fallback server to support one primary server. Contact your hardware vendor to verify that your hardware can support this fallback option.


General Design of Fallback Process

The SQL Server fallback feature is invoked by executing system stored procedures. In most cases, these procedures begin with the common prefix sp_fallback_. To shift the control of databases and devices from a broken primary server to a fallback server, one or two procedures are executed on the primary server, but most others are executed on the fallback server. The procedures that are executed on the fallback server can contain remote procedure calls (RPCs) to the primary server.

The sp_fallback_ procedures interact with the sysdatabases, sysdevices, and sysusages system tables of the primary and fallback servers. The system tables on the primary server are only read from; on the fallback server, SELECT, INSERT, UPDATE, and DELETE statements are executed against the system tables. The sp_fallback_ procedures also interact with some corresponding user tables on the fallback server, which are all named with the prefix spt_fallback_.

In general, the sp_fallback_ procedures copy information from the system tables of the primary server into the spt_fallback_ tables on the fallback server to enroll specific databases for future fallback support. If the primary server fails, a procedure is run to recalculate and copy information from those spt_fallback_ tables into the system tables of the fallback server to activate the databases that are enrolled for fallback support. Recalculated information includes the columns sysdatabases.dbid, sysdevices.low, and sysusages.vstart.

After the primary server is repaired, you have the option of running procedures to deactivate the fallback support and return control of the switchable hard drive array to the primary server.


Accomplishing Fallback Support

To invoke fallback support for two databases in a one-primary to one-fallback configuration, follow the steps that are listed below. Only the system administrator (SA) can invoke the fallback feature. Each sp_fallback_ procedure takes only seconds to complete.

To invoke the fallback feature
  • On the primary server, execute the following steps:
    1. Record the designated server svrfallback as the fallback server on the primary server svrprimary and execute the following:
      exec sp_addserver 'svrfallback' ,'fallback'
    2. Give the SA on the fallback server the ability to log on as SA on the primary server by executing the following:
      exec sp_addremotelogin 'svrfallback' ,'sa' ,'sa'
  • On the fallback server, execute the following steps:
    1. Record the primary servers to provide fallback support to:
      exec sp_addserver 'svrprimary'
    2. Run a simple test to verify that RPC connections are working and execute the following:
      exec svrfallback...sp_helplogins
    3. Enroll databases owned by the fallback server for potential fallback support. RPCs are issued to the fallback server. The first parameter value must match a value in sysservers.srvname (not necessarily srvnetname).
      exec sp_fallback_enroll_svr_db 'svrprimary' ,'DabSales'
exec sp_fallback_enroll_svr_db 'svrprimary' ,'DabProduct'

    Note The databases DabSales and DabProduct that are being configured for fallback must be on a switchable disk for fallback to work.

To take over a switchable disk

The following steps should be performed each time the fallback server takes over a switchable disk from the primary server and assigns a new drive letter to the disk:

  1. Record that the switchable hard drive seen as "D:" by the primary server will be seen as "H:" by the fallback server:
    exec sp_fallback_upd_dev_drive 'svrprimary' ,'D:' ,'H:'
  2. Activate live fallback support for all databases enrolled from that server and execute the following:.
    exec sp_fallback_activate_svr_db 'svrprimary', '%'

If the underlying fallback architecture supports registering applications that are launched automatically when the fallback server takes over, then an application (using DB-Library or ODBC) could be written that connects to the fallback server and executes the stored procedures after each disk switchover.

Note If your model database is 1 MB, then a database device of only 1 MB can hold an entire database. To experiment and familiarize yourself with setting up fallback, use a standard 1.44 MB floppy diskette. To activate the fallback server, you can transfer the floppy diskette from the primary server to the fallback server after stopping the primary server.


Follow-up Steps

Additional fallback-related system stored procedures are listed below.

On primary server svrprimary:

  1. To list the name of the fallback servers for this primary server, execute:
    exec sp_helpserver
  2. If svrfallback has already been added as an RPC or replication server, then execute:
    exec sp_serveroption 'svrfallback', 'fallback', true
  3. Invoke the following stored procedure when the primary server is fixed and is ready to take over the disk from the fallback server. This leaves the enrollment of the databases of the primary server intact on the fallback server.
    exec sp_fallback_deactivate_svr_db 'svrprimary', '%'
  4. Invoke the following stored procedure on the fallback server to make the fallback SQL Server server the permanent owner of databases enrolled from another SQL server:
    exec sp_fallback_permanent_svr 'svrprimary' ,1
  5. On the fallback server svrfallback, produce a report of enrollment and activation statuses, and perform integrity checks:
    exec sp_fallback_help

On the fallback server SVRFALLBACK:

  • Invoke the following stored procedure on the fallback server to remove the enrollment of a specific database from the fallback database server:
    exec sp_fallback_withdraw_svr_db 'svrprimary' ,'DabProduct'


Fallback Considerations

Consider the following factors when you are setting up SQL Server fallback support:

  • The sp_fallback_ procedures should not be executed within a user transaction. Avoid initiating CREATE/ALTER DATABASE or DISK INIT statement activity while running sp_fallback_ procedures.
  • The sp_fallback_ procedures always return the value 0 to indicate success and a value greater than 0 to indicate failure. In almost all cases, a value greater than 0 will have been taken from @@ERROR.
  • Only enroll databases that do not share a device file with any other databases.
  • Issuing database commands against an enrolled database is not recommended. These commands include dropping, altering, creating, and renaming a database. Before executing a CREATE DATABASE statement in a self-enrolled server, make sure the fallback tables have no entries for the server.
  • Execute permission on sp_fallback_help is granted to the public group at installation. All other sp_fallback_ procedures can be executed only by the SA.
  • If you want to provide fallback support for replicating servers, the publisher and the distributor should reside on the same server.
  • ODBC and DB-Library clients can be set up to automatically switch to the fallback server under certain conditions. This works reliably when the primary server has exactly one fallback server defined.
  • A database switched to a fallback server includes the database user information in sysusers. However, the mapping between database users and SQL Server login IDs is not maintained when the database is enrolled and/or activated on the fallback server. This problem can be handled by maintaining identical login IDs (identical name and suid columns in the syslogins table) in both SQL Servers. Add the same login IDs in the same order in both SQL Servers.

    Alternately, the system stored procedure sp_change_users_login could be used to fix the mapping between sysusers and syslogins. This, however, requires another fix after the database has been switched back to the primary server.


Troubleshooting the Fallback Process

To detect integrity problems, sp_fallback_help can be executed on the fallback server (either directly or via an RPC) at any time. Integrity problems that are detected are:

  • Internal to the sysdatabases, sysdevices, and sysusages tables.
  • Internal to spt_fallback_db, spt_fallback_dev, and spt_fallback_usg tables.
  • Between the two sets of tables. Simple referential integrity is checked, as is "activation integrity." Activation integrity means system and fallback tables agree on the status of a database's fallback status.
  • Whenever NULL, the following columns indicate a database, a device, or usage is enrolled but not active:
    spt_fallback_db.xfallback_dbid
spt_fallback_dev.xfallback_low
spt_fallback_usg.xfallback_vstart

Some integrity problems can be solved by setting these columns to NULL. Some integrity problems could be fixed by updating a NULL spt_fallback_db.xfallback_dbid to the corresponding sysdatabases.dbid.

  •
During active fallback support, no commands should be issued that could affect the physical devices or space allocations on them. Commands like ALTER DATABASE or DISK RESIZE could permanently eliminate the option of the original primary server resuming control of its enrolled databases and devices. If ALTER DATABASE is mistakenly issued, use sp_fallback_permanent_svr and sp_dbremove (the latter on the primary server only).
    •

  •
The SA is responsible for passing the proper parameter values when executing sp_fallback_upd_dev_drive. If a bad value is used but realized before activation, then another execution can solve the problem. If activation with a bad value is attempted before the problem is recognized, then sp_fallback_deactivate_svr_db should be enough to allow another execution of sp_fallback_upd_dev_drive.
    •

  •
On the primary server, the DBO for a given database can be logged on to a login other than SA. But when fallback is activated, each database is installed with the DBO recorded as the SA. You can, however, execute the necessary procedures to change the DBO of a database that is being actively supported on the fallback server.
    •

  •
Like all spt_ tables, the spt_fallback_ tables should not be updated directly unless you are instructed to do so by technical support personnel.
    •


SQL Mail

SQL Server 6.5 provides the following enhancements to SQL Mail:

  • You can start and stop SQL Mail, and you can assign a mail login name and a password to SQL Mail from SQL Enterprise Manager.
To start and stop SQL Mail from SQL Enterprise Manager

  1. In the Server Manager window, expand the tree for the server, and click the right mouse button on that server's SQL Mail icon.
  2. From the shortcut menu, choose Start or Stop.
To assign a mail login name and a password to SQL Mail from SQL Enterprise Manager
  1. In the Server Manager window, click the right mouse button on the SQL Mail icon.
  2. From the shortcut menu, choose Configure.

    The SQL Mail Configuration dialog box appears.

  3. Complete the dialog box.

    On servers where Microsoft Exchange has been installed, this dialog box will ask for a profile name.

    For more information about setting up a SQL Mail Client, see the Microsoft SQL Server Administrator's Companion.

  • Enhancement to xp_sendmail makes it easier to use within triggers. For more information, see What's New for Transact-SQL, later in this document.
  • Enhancement to xp_readmail now supports an additional output parameter that returns the mail message originator's mail address.
  • SQL Mail is compatible with Microsoft® Exchange.
To set up SQL Mail to work with Microsoft Exchange
  1. At the Microsoft Exchange server, set up a mailbox for the user account that will be used by the MSSQLServer service. This account must be a domain account that adheres to the requirements listed under Platform Support in "What's New for Setup," earlier in this document. For example,
Account: | DOMAIN1\SQLServerAccount
Mailbox: | SQL1

  2. At the SQL Server machine, log on to Windows NT using the same user account that will be used by the MSSQLServer service ("DOMAIN1\SQLServerAccount" in the example above).
  3. Install the Microsoft Exchange Client on the SQL Server machine.
  4. Start the Microsoft Exchange Client and use the Exchange Setup Wizard to configure the client to connect to Microsoft Exchange Server. After setup is complete, verify that you can send and receive mail interactively.

    Note You cannot use the Microsoft Exchange Client to connect SQL Server to Microsoft Mail post offices.

  5. Start the Microsoft Exchange Services application (also called the Mail and Fax application in Control Panel). Choose the Show Profiles button to find the name of the profile that the Exchange Setup Wizard has created (for example, SQL Server).

    Note Before you configure Microsoft Exchange Server, read the SQL Mail and Microsoft Exchange Server Configuration Requirements section.

  6. From Control Panel, open the Services application and configure the MSSQLServer service to run under the same Windows NT user account that Microsoft Exchange is set to use. Start or restart the MSSQLServer service.
  7. In SQL Enterprise Manager, select a server and from the Server menu, choose SQL Mail/Configure or right-click the SQL Mail icon below the selected server and choose Configure. Type the profile name you found in step 5. You do not need to provide a password for Microsoft Exchange; it uses the account and password configured for the MSSQLServer service.
  8. In SQL Enterprise Manager, from the Server menu, choose SQL Mail/Start or right-click the SQL Mail icon and choose Start. The SQL Mail icon will become green if SQL Mail has started successfully.

    For more information on setting up Microsoft Exchange, see the Microsoft Exchange Server Installation Guide.


SQL Mail and Microsoft Exchange Server Configuration Requirements

Some Microsoft® Exchange Server configurations might cause SQL Mail to process messages incorrectly. If Microsoft Exchange Server is configured to deliver mail to a local folder, SQL Mail messages and subsequent Microsoft Exchange Server messages are queued in the outbox of the local folder and never sent. These messages can be removed only by stopping SQL Mail and Microsoft Exchange Server and re-starting Microsoft Exchange Server. This may require rebooting your system. To prevent this problem, specify that Microsoft Exchange Server deliver mail to the mail server.

To deliver mail to the mail server
  1. Open Microsoft Exchange.
  2. From the Tools Menu, select Options.

    The Options dialog appears.

  3. Click the Delivery tab.
  4. From the Deliver new mail to the following location option, choose the Mailbox - Username option.
  5. Click OK.


Microsoft Query

Microsoft Query (MS Query) provides a query interface to relational databases. With SQL Server 6.5, Microsoft Query is installed by the SQL Server setup program. It is always installed with the server and can be optionally installed on 32-bit clients.

To run Microsoft Query, choose the MS Query icon from the Microsoft SQL Server 6.5 program group. For information about using Microsoft Query, see the Microsoft Query online Help.


SQL Enterprise Manager

SQL Enterprise Manager provides many new and enhanced features. You can restore data in a database to a specified point in time. You can easily transfer objects from one server to another. External tools can be added to the SQL Enterprise Manager toolbar. These and many more enhancements and new features in SQL Enterprise Manager are detailed in the following sections.

Note SQL Enterprise Manager for SQL Server 6.5 administers SQL Server 6.0 and 6.5 servers. SQL Enterprise Manager for SQL Server 6.0 cannot administer SQL Server 6.5 servers. To connect to a SQL Server 6.5 server, you must upgrade to a SQL Server 6.5 client installation.


Alerts Management Interface

The SQL Enterprise Manager alerts management interface includes these changes:

  • A Send Mail button has been added to the New Operator and Edit Operator dialog boxes. (Both dialog boxes are opened from the Manage Alerts window, which appears after choosing Alerts from the Server menu). The Send Mail button is enabled when the local mail client is already running.

    Choosing the Send Mail button opens the Send Note window from the underlying mail system.

    The Send Mail button is useful for notifying operators about changes in their alert-handling responsibilities.

  • The SQLALRTR.EXE command includes parameter -M, with which you can supply parameters to errors. The SQLALRTR.EXE command requires a comma (,), but no spaces, between each error message parameter. Strings must be delimited with single quotation marks ('). Note that any messages containing the format string %.*s will require two parameters to be supplied: the length and the string. Separate these parameters with a comma (,).

    The following example specifies that message 50001 will receive three parameters:

    'add'
5
5,'alpha'

    This is the message string associated with message 50001:

    Testing the %s procedure for the %ldth time. Using test %.*s.

    This is the example command and the message returned:

    sqlalrtr -E 50001 -M 'add',5,5,'alpha'

Testing the add procedure for the 5th time. Using test alpha.
  • SNMP traps can be raised as part of an alert response. For more information, see SNMP Support, later in this document.
  • New task parameters support alert response tasks. For more information, see Task Scheduling Interface.


Alert System Troubleshooting

Under unusual circumstances, the SQL Executive alert engine can inadvertently become caught in the endless recursive firing of the same alert. Such circumstances generally arise when the SQL Server runs out of some essential global resource, such as locks, and an alert has been defined on this event, either explicitly by error number or implicitly by severity level.

In such circumstances, the following sequence starts and can be stopped only when the SQL Server's global resource problem is manually fixed:

  1. SQL Server reports a global resource error.
  2. SQL Executive invokes the alert for this event.
  3. The alert, as part of its response, attempts to perform some action on the SQL Server.
  4. This action causes the server to hit the global resource error again.
  5. The steps repeat.

These are symptoms of a repeating alert:

  • The event log rapidly fills up with the same error.
  • An unusually high CPU usage occurs.
  • Numerous alert responses are received for the alert involved.

Should you encounter a problem, it is possible to configure the SQL Executive alert engine to treat specific error numbers as non-alert-generating errors. That is, if the error occurs and an alert has been defined on it, explicitly by error number or implicitly by severity level, then SQL Executive will not fire the alert. Instead it will write a message (event 323) to the Windows NT event log stating that the alert was ignored according to the non-alert-generating status that was assigned to it.

To configure an error to be non-alert-generating
  1. At the command prompt, invoke the Registry editor by typing:
    regedt32
  2. Access the directory tree, as follows:
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\SQLExecutive
  3. In the NonAlertableErrors list, enter the error number. The list can be up to 255 characters long, should not contain spaces, and each item must be separated with a comma (,) from the previous item. Any error number that appears after the number 0 in the list will be ignored and will generate an alert. Thus, the whole list can be temporarily suspended by adding 0 as the first item in the list.

SQL Enterprise Manager and the stored procedures sp_addalert and sp_updatealert use the NonAlertableErrors list to restrict which errors can be monitored by an alert.

Important There should seldom be the need to modify the default list of entries.

Examples

A. Default Alert Entries

This example shows the default list of non-alert-generating errors. These errors should never be removed.

1204,4002
B. Add Error 100 to Entries

This example adds error 100 to the list of non-alert-generating errors:

1204,4002,100
C. Interrupt Error List

This example shows that having 0 within the list suspends the processing of the rest of the list. Only errors 1204 and 4002 are non-alert-generating; error 100 will generate an alert.

1204,4002,0,100


Backup and Recovery

SQL Server 6.5 provides improved backup and recovery capabilities. Specifically, the SQL Enterprise Manager Database Backup/Restore dialog box supports the following improvements:

  • Histories of database backups are maintained.
  • Individual tables can be backed up and restored.
  • Transaction logs can be recovered through a specified date and time.

SQL Enterprise Manager maintains a record of database backups, including backups that are made through other applications. You can use SQL Enterprise Manager to restore a database or table without knowing where the backup is stored. This makes it easier to restore a database backup and all of its associated transaction logs in the correct order. For backups from SQL Server 6.5 servers, SQL Enterprise Manager automatically presents a list of database backups, table backups, and transaction log backups for you to choose from.

Backup history is maintained in tables in the msdb database, even for the backups that were created by custom applications or third-party tools. The following tables hold the backup information: sysbackupdetail, sysbackuphistory, sysrestoredetail, and sysrestorehistory.

Table Backup and Restore

Point-in-Time Recovery


Table Backup and Restore

With SQL Server 6.5, you can back up and restore individual tables. In SQL Enterprise Manager, a table restore can only be performed from a table backup or from a full database backup.

Restoring a table is useful in a disaster recovery situation where restoring the entire database may be a poor solution.

For example, suppose one table is corrupt and has no foreign keys and no columns that are based on other tables. Restoring only this table would correct your database with the least amount of work.

Full database and transaction log backups remain the basis of a proper backup strategy.

Important Only a full database or transaction log backup ensures that all PRIMARY KEY to FOREIGN KEY constraints are correct.

Table backup and restore operations have the following characteristics:

  • Table restores can be performed from full database backups or from individual table backups.
  • Table restores cannot be performed for tables that have text or image columns or that are published for replication.
  • Triggers, rules, defaults, and declarative referential integrity (DRI) are not enforced for table restores.
  • Source and target table schema must be identical in their nullability, length, and base-system type. User-defined types can be different, but the base types must be the same.
  • Table restores can be performed only when the Select Into/Bulk Copy database option is set.
  • A table restore disables the DUMP TRANSACTION statement until a full database backup is performed.
To back up a table
  1. From SQL Enterprise Manager, in the Server Manager window choose a server.
  2. From the Tools menu, choose Database Backup/Restore.

    The Database Backup/Restore dialog box appears.

  3. In the Backup tab, select the database to back up.
  4. Select Table, expand the list, and select a table to back up.
  5. Under Options, select backup media options.
Backup media option | Description
Initialize Device | Writes over the existing data and initializes the device.
No expiration date | Specifies that the backup has no expiration date and can be overwritten at any time.
Expires after | Specifies that the backup will expire after a set elapsed number of days. If you select this option, then you must also enter the number of days in the adjacent box.
Expires on | Specifies that the backup will expire on a specific date. If you select this option, then you must also enter the number of days in the adjacent box.
Eject Tape at End of Backup | Specifies that the tape is automatically rewound and unloaded when the backup completes. If you will be performing multiple backups to a single tape, clear this option. If you will be performing a single backup or the last backup of several to a tape, select this option.
Skip Tape Header | Specifies that the server should not read the ANSI header on a tape.

  6. Under Backup Devices, select a backup device. You can back up to one or more devices. By choosing the buttons at the bottom of the Backup Devices list box, you can add a device, drop a device, or view header information about a device.
Backup device option | Description
New | Adds a backup device or specifies a file.
Delete | Removes a backup device.
Info | Displays information for a selected backup device.

  7. Schedule the backup.
Schedule option | Description
Backup Now | Performs the backup immediately.
Schedule | Schedules the backup for immediate, one time, or recurring execution.

For more information about backup options, see the online Help for Backup Tab for Databases in SQL Enterprise Manager.

To restore a table
  1. From SQL Enterprise Manager, in the Server Manager window choose a server.
  2. From the Manage menu, choose Databases.

    The Manage Databases dialog box appears.

  3. Choose Edit Database and in the Edit Databases dialog box, choose the Options tab.
  4. Verify that the Select Into/Bulk Copy database option is selected. For details, in the Options tab click Help.
  5. From the Tools menu, choose Database Backup/Restore.

    The Database Backup/Restore dialog box appears.

  6. In the Restore tab, select a database to restore. The Backup History list will be populated with backups for the selected database. Also, the Single Table list will be populated with tables for the selected database.
  7. Under Restore, select the Single Table option. A single table will be restored. A table restore can be performed from a table backup or from a full database backup. Selecting this option populates the list of tables and the Backup History list with available database and table backups. Select a table to restore.
  8. Under Backup History from the Restore column, which displays backups that are available depending upon the Restore option and the database selected, select a backup.
  9. Choose Restore Now.

For more information about backup options, see the online Help for Backup Tab for Databases in SQL Enterprise Manager.

Table backups and restores can also be accomplished using the Transact-SQL DUMP and LOAD statements. For more information, see What's New for Transact-SQL.


Point-in-Time Recovery

Transaction logs can be restored through a date and a time that you specify. Transactions committed after that date and time will be rolled back.

Point-in-time recovery applies to transaction log restores only (not to full database or table restores.)

To perform a point-in-time recovery
  1. From SQL Enterprise Manager, in the Server Manager window select a server.
  2. From the Tools menu, choose Database Backup/Restore.

    The Database Backup/Restore dialog box appears.

  3. Select the Restore tab.
  4. From the Database list, select the database to restore.
  5. Under Backup History, select a backup from the Restore column, which displays backups that are available for the selected source database.
  6. Select the Until Time option to restore a database through a specific time. Adjust the displayed time appropriately. Transactions committed after the specified time will be rolled back.
  7. Choose Restore Now.

For more information about load options, see the online Help for Restoring a Database or a Transaction Log in SQL Enterprise Manager.

Point-in-time recovery can also be accomplished by using the Transact-SQL LOAD TRANSACTION statement with the STOPAT option. For more information, see What's New for Transact-SQL.


Improvements to the Database Backup/Restore Dialog Box

  • You can perform a backup to a striped set using SQL Enterprise Manager. In the Database Backup/Restore dialog box, in the Backup tab, select multiple backup devices from the Backup Devices list.

    Note that striped refers to data that is stored among several devices. Improvements in performance, particularly load balancing, can be achieved by backing up to a striped set.

  • You can select the From Device button on the Restore tab to display the Restore From Device On Server dialog box, from which you can select backup devices to restore from. This is useful when attempting to restore backups that have no histories, such as backups from a previous version of SQL Server, or tape backups made on another machine and moved to the current machine.

  • You can choose the Database and Transaction Logs button in the Restore tab to populate the Backup History list with database backups and their associated transaction logs grouped together.

Note that the Database Backup and Restore dialog box is available for SQL Server 6.0 and later.


Transfer Management Interface

SQL Enterprise Manager includes a transfer management interface that you can use to transfer some or all objects from one database to another. The SQL Transfer Manager application shipped with earlier releases is no longer provided.

The transfer management interface eases migration of databases between servers. With the transfer management interface, you can:

  • Copy all types of objects, or only some types.
  • Copy all objects of a specific type, or only some objects of a specific type.
  • Transfer schema and data, only schema, or only data.
  • Append or replace existing data.
  • Drop destination objects before copying schema.
  • Include the objects that depend on a transferred object.
  • Use default scripting options, or customize the scripts that are used to copy objects and security information.
  • Execute a transfer immediately, or schedule the transfer to execute one time or on a recurring basis.

The destination server must be a Microsoft SQL Server version 6.5 server. The source server can be a Microsoft SQL Server version 4.x or 6.x server, or a SYBASE® server.

To transfer objects between databases
  1. From SQL Enterprise Manager, in the Server Manager window select a server, expand its tree, open its Databases folder, and select a database.
  2. From the Tools menu, choose Database/Object Transfer.
  3. Complete the Database/Object Transfer dialog box that appears.
Dialog box option | Description
Source Server | Specifies the server you are currently administering by default. To select another server, expand the box.
New Source | Opens the Register Server dialog box, which is used to register a server that is not listed in the Source Server box.
Foreign Source | Opens the Foreign Source dialog box, which is used for non-registered servers. For example, a SYBASE server is not registered.
Destination Server | Specifies a server to transfer data to. Note that the source server and the destination server can be the same server. If the required server name is not included in the list, add it to the list. Choose the New Server button and complete the Register Server dialog box that appears.
New Destination | Adds a server name to the Destination Server list. Choose this button and complete the Register Server dialog box that appears.
Destination Database | Specifies the database to transfer data to. Note that the database must already exist and have enough space for the objects and data that you are transferring. The destination database must be different from the source database.
Copy Schema | Copies the table schema from the source database to the destination database.
Drop Destination Objects First | Drops objects from the destination database before objects are transferred from the source database.
Include Dependency Objects | Includes all objects that depend on the object(s) or object type(s) selected for transfer.
Copy Data | Copies table data from the source database to the destination database.
Replace Existing Data | Replaces existing data in the destination tables with transferred data. To retain existing data and append transferred data, clear this option.
Transfer All Objects | Transfers all objects in the database, including tables, views, stored procedures, defaults, rules, and user-defined datatypes.
Choose Objects | Transfers only selected objects, including tables, views, stored procedures, defaults, rules, and user-defined datatypes. You can transfer all, some, or no objects of a particular type. Choose this button and complete the Choose Objects to be Transferred dialog box that appears.
Use Default Scripting Options | Specifies that default object and security scripting options will be used. The options for the default object automatically create scripts that re-create in the destination database table triggers, table DRI, table bindings, nonclustered and clustered indexes, and owner-qualified objects from the source database. The options for default security re-create users and groups, logins, and object and statement permissions.
Scripting Options | Specifies which scripting options to use. This is an advanced option. Choose this option and complete the Transfer Scripting Options dialog box that appears. The options for the default object can automatically create scripts that re-create in the destination database table triggers, table DRI, table bindings, nonclustered and clustered indexes, and owner-qualified objects from the source database. The options for default security can re-create users and groups, logins, and object and statement permissions.
Save Transfer Files in Directory | Specifies where transfer scripts are stored. The default is C:\MSSQL\BINN. To change the location, type a new path in this box. If the directory does not already exist, SQL Enterprise Manager will create it.
Start Transfer | Executes the transfer immediately, as defined by the selections made in this dialog box.
Schedule | Schedules the transfer to occur immediately, one time, or on a recurring basis. Scheduling an immediate transfer (instead of choosing Start Transfer) provides the advantage of executing the transfer as a scheduled (background) task instead of interactively.
View Logs | Displays the transfer log after the transfer has completed.

  1. To execute the transfer immediately, choose Start Transfer. To schedule the transfer, choose Schedule.

For more information about transferring objects, see the online Help for SQL Enterprise Manager.


Extended Stored Procedures Manager

SQL Enterprise Manager includes an extended stored procedures manager. With the extended stored procedures manager, you can add extended stored procedures to or drop existing extended stored procedures from SQL Server. The extended stored procedures manager can be used only when the master database is the current database.

Execute permission defaults to the system administrator.

To use the extended stored procedures manager
  1. From SQL Enterprise Manager, in the Server Manager window select a server, open its Databases folder, and select the master database.
  2. From the Manage menu, choose Extended Stored Procedures.

    The Manage Extended Stored Procedures dialog box appears.

  3. Complete the dialog box to add or drop a procedure.

For more information about using the Extended Stored Procedures Manager, see the online Help for SQL Enterprise Manager.


External Tools Support

You can launch any Windows NT-based application from SQL Enterprise Manager. External applications can be added and run from the Tools menu and from the floating, dockable Tools Bar.

To add an application, from the Tools menu, choose External Tools and complete the dialog box that appears. Note that [SVR] and [DBN] can be used in the Parameters box to represent the current server and database. When the tool is run, SQL Enterprise Manager will substitute the current server and database names, passing them as parameters to the application.

The floating, dockable Tools Bar can be displayed or hidden. To change the current setting, from the View menu choose Tools Bar. When the Tools Bar command is selected, the floating, dockable Tools Bar is displayed.

For more information about adding and running external tools, see the SQL Enterprise Manager online Help.


Remote Servers and Logins Manager

SQL Enterprise Manager includes a way to manage remote servers and remote logins. With the Remote Servers and Logins Manager interface, one person can manage many servers and centralize administrative tasks. With this interface, you can also set distribution options for replication and configure ODBC subscribers.

To manage remote servers and logins
  1. From SQL Enterprise Manager, in the Server Manager window select a server.
  2. From the Server menu, choose Remote Servers.
  3. Complete the Manage Remote Servers dialog box that appears.
Dialog box option | Description
Server Name | Specifies the name of the server to be configured as a remote server (to the server that is being administered by SQL Enterprise Manager).
RPC | Specifies that the server listed in the Server Name box is a remote server.
Subscriber | Specifies that the remote server will have subscriber status for replication.
Publisher | Specifies that the remote server will have publisher status for replication.
Distributor | Specifies that the remote server will have distributor status for replication.
Distribution Publisher | Specifies the remote server as a publisher and as a distributor for replication.
Distribution Options | Sets distribution options for replication. This button opens the Distribution Options dialog box and is enabled only when the Subscriber option is selected.
Translate All Remote Login Names to | Maps login IDs from the remote server to the local login name that is selected from the list box: either to a specific login ID or to the same name.
Trusted | Specifies whether the remote login ID will be validated by Windows NT security or by a password. If this check box is selected, the security will be handled by Windows NT and a password is not required. If this check box is not selected, standard security will be used, and a login ID and a password will be required.
Remote Server Login Name | Specifies a login ID from the remote server.
Mapped Login Name | Specifies a local login ID that the remote login ID is mapped to.
Trusted | Specifies whether the remote login ID is validated by Windows NT security or by a password. If this column is checked, the security is handled by Windows NT and a password is not required. If this column is not checked, standard security is used and a login ID and a password are required.
Add/Modify | Adds the server selected in the Server Name box as a remote server (to the server being administered by SQL Enterprise Manager). When editing an existing remote server, the Add button changes to Modify. Choosing Modify accepts changes that are made to the configuration options for the remote server.
Drop | Removes the remote server status of the server that is selected in the Server Name box.
Drop Login | Drops the login(s) selected from the Remote Server Login Name list.

For more information about managing remote servers and logins, see the online Help for SQL Enterprise Manager. For general information about remote servers and remote logins, Remote Servers and Users, see the Microsoft SQL Server Administrator's Companion.


Remote Server Registration Storage Configuration

SQL Enterprise Manager now stores the server registration information in the Windows NT Registry, providing more alternatives to the location and security for the information.

Server registration information can be accessed in several ways:

  • Access server registration information on a remote central computer.
  • Access private server registration information locally.
  • Access shared server registration information locally.

Accessing the server registration information stored on a remote central computer allows a group of individuals to access the same view of information from different client computers. This configuration makes client access to the central store read-only. Changes to the central store can only be made locally on the central computer running SQL Enterprise Manager configured to save registration information locally without the Store User Independent option enabled.

To set up a central store for server registration information
  • On the remote server:
    1. On the remote machine, in SQL Enterprise Manager, from the Tools menu choose Preferences/Configure.

      The Configure SQL Enterprise Manager dialog box appears.

    2. Choose the Application tab.
    3. Clear the Store User Independent check box.
    4. Use SQL Enterprise Manager to create server groups and register servers.
  • On the local server:
    1. In SQL Enterprise Manager, from the Tools menu choose Preferences/Configure.

      The Configure SQL Enterprise Manager dialog box appears.

    2. Choose the Application tab.
    3. Select the Read From Remote option and type the name of the remote server to use information from.
    4. Choose OK.

When server registration information is stored locally on the client machine, there are times when you want to tailor the display of servers and groups on your machine and prevent others from having access to your configuration. Alternately, the information can be stored so that different users who log on to the workstation have the same registration information.

To prevent others access to your SQL Enterprise Manager display of servers and groups
  1. In SQL Enterprise Manager, from the Tools menu choose Preferences/Configure.

    The Configure SQL Enterprise Manager dialog box appears.

  2. Choose the Application tab.
  3. Choose the Store Locally option and select the Store User Independent check box.
  4. Choose OK.
To store server registration information so that multiple users on a workstation share the same information
  1. In SQL Enterprise Manager, from the Tools menu choose Preferences/Configure.

    The Configure SQL Enterprise Manager dialog box appears.

  2. Choose the Application tab.
  3. Choose the Store Locally option and clear the Store User

    Independent check box if selected.

  4. Choose OK.


Configurable Packet Size

With SQL Enterprise Manager, you can configure packet size. Small packet sizes are best if responsiveness is an important consideration. Larger packet sizes require less overhead and provide better end-to-end throughput of data. When large data sets are sent, increase the packet size so that the task will complete more quickly.

To configure packet size
  1. In SQL Enterprise Manager, from the Tools menu choose Preferences/Configure

    The Configure SQL Enterprise Manager dialog box appears.

  2. Choose the Connection tab.
  3. In the Packet Size box, enter a value.
  4. To accept the new packet size, choose OK. The new packet size will take effect the next time you reconnect.


Graph Controls

Several SQL Enterprise Manager windows provide enhanced charting capabilities. The charts have been refined and buttons have been added that you can use to control graph characteristics and to print the graphs. The following dialog boxes have new option buttons and enhanced charting capabilities.

Dialog box | Has a chart of
Manage Databases | Databases
New Database | Available database devices
Manage Database Devices | Devices
New Database Device | Available storage space
Edit Database Device | Device space usage

The option buttons are:

Graph Properties
Opens the Graph Properties dialog box, in which you can set graph label, solid color, legend display, and graph type properties.

Bar Graph Options
Opens the Bar Graph Options dialog box, in which you can set the graph mode to stretched or selectable, and the orientation to vertical or horizontal.

Print Options
Opens the Print Options dialog box, in which you can set color, formatting, and font options, and can print the graph.
To print a graph
  • In SQL Enterprise Manager, from the File menu choose the Print Setup command and then choose the Print button.


Menus and Commands

For SQL Server 6.5, SQL Enterprise Manager menus and commands have been added, moved, or renamed. The following table describes menu and command changes.

Old menu / Command | New menu / Command | Description
Tools / Task Scheduling | Server / Scheduled Tasks | Opens the Task Scheduling window. For more information on scheduling tasks, see Task Scheduling Interface, later in this document.
Tools / Query Analyzer | Tools / SQL Query Tool | Opens the Query window. For more information, see Query Interface Renamed, earlier in this document.

The following table describes the commands that are new for SQL Server 6.5.

New menu / Command | Description
File / (all) | Contains commands from the toolbar for the active window.
File / Print Setup | Opens the Print Setup dialog box, which is used to configure the default printer.
View / Tools Bar | Displays or hides the floating, dockable Tools Bar for external tools.
View / Refresh | Updates information in the currently selected folder if applicable for a server in the Server Manager window.
Server / Remote Servers | Opens the Manage Remote Servers dialog box, which is used to manage remote servers and logins, and subscribers (including ODBC subscribers).
Server / Distributed Transaction Coordinator | Opens the MS DTC Transactions, Trace, Statistics, or Configuration windows for servers with MS DTC installed. These windows are used to administer MS DTC.
Server / SQL Mail | Opens a shortcut menu, which is used to stop, start, and configure SQL Mail. To open the menu, select the SQL Mail icon for a server and right-click the selection.
Server / SQL Executive | Opens a shortcut menu, which is used to stop, start, and configure SQL Executive. To open the menu, select the SQL Executive icon for a server and right-click the selection.
Server / SQL Server | Opens a shortcut menu, which is used to stop, start, pause, continue, and administer SQL Server. To open the menu, select a server and right-click the selection.
Tools / External Tools | Opens the External Tools dialog box, which is used to add or remove external tools that can be run in SQL Enterprise Manager.
Manage / Extended Stored Procedures | Opens the Manage Extended Stored Procedures dialog box, which is used to add or remove extended stored procedures from the master database only.
Object / Transfer | Opens the Transfer Objects dialog box, which is used to transfer objects from one database to another.
Help / Database Maintenance Wizard | Starts the Database Maintenance Plan Wizard.


Print Support

For SQL Server 6.5, SQL Enterprise Manager provides additional print support from the following windows:

  • Manage Stored Procedures
  • Manage Triggers
  • Manage Views

To print the information from these windows, from the window's toolbar choose the Print button.

To support printing, the default printer can be configured by choosing the Print Setup command from the File menu in SQL Enterprise Manager.


SERVERS.BIN File Replaced by Registry Entries

For SQL Server 6.5, registration information for servers is maintained in the operating system Registry for both Windows NT- and Windows 95-based computers. Server registration information includes the server groups that are used in the Server Manager window of SQL Enterprise Manager, the servers that are registered with SQL Enterprise Manager, and associated data. Putting server registration information in the operating system Registry is a more standard location for this type of information.

For more information about the new server Registry-based storage, see Remote Server Registration Storage Configuration, earlier in this document.

For SQL Server 6.0, registration information for servers is maintained in a SERVERS.BIN file.

The first time SQL Enterprise Manager is run after upgrading a SQL Server 6.0 installation to SQL Server 6.5, the information from the existing SERVERS.BIN file is automatically moved to the Registry.


Task Scheduling Interface

SQL Enterprise Manager contains the following changes to the task scheduling interface:

  • The Task Scheduling command on the Tools menu for SQL Server 6.0 is the Scheduled Tasks command on the Server menu for SQL Server 6.5.
  • CmdExec tasks that are owned by users other than system administrators execute in the security context of a Windows NT user account that is called SQLExecutiveCmdExec. For more information, see SQLExecutiveCmdExec Account.
  • The Command value for Transact-SQL tasks supports multiple Transact-SQL statements and procedures. For example:
    sp_who
go
sp_help
go
  • A user can view tasks and task histories for only those tasks the user created and owns. However, the system administrator can view all tasks.
  • Tasks now return actual error messages (if encountered). Also, the last 230 bytes (approximately) of any CmdExec task output is displayed as part of the message that is shown in the Task History dialog box.
  • Scheduling support has been added for the following long-running operations: create database, expand database, create device, and expand device.
  • The Task History log can be cleared from the Task Engine Options dialog box by using the Clear Task History Log button.
  • The sp_runtask stored procedure has been added. With this stored procedure, a user can invoke a task from Transact-SQL. For more information about sp_runtask, see What's New for Transact-SQL.
  • The number of history rows per task can now be limited by setting the Maximum Task History Rows per Task value in the Task Engine Options dialog box. Setting this value prevents a frequently occurring task from monopolizing the msdb database syshistories table.
  • Task history can also be accessed by choosing the History button in the Edit Task dialog box.
  • Tasks that are created to respond to alerts are supported by the following parameters, which can be set while creating a task.
Parameter | Represents
[SVR] | Server name
[DBN] | Database name
[ERR] | Error number
[SEV] | Severity level
[MSG] | Message text

For example, five servers forward their events to a master "alert management" server. Each event causes an alert to fire and the user has associated a task with each alert. In response to the five alerts, the master server will run a user-defined task for each alert. The task could be defined to log back into the forwarding server, to use the database that caused the initial alert, and to address the problem. To do this, define the task command as:

isql /Usa /p /sairedale /daccounts /Q "sp_fixit"

For more information, see the Microsoft SQL Server Administrator's Companion.

When using the task scheduling interface, note the following:

  • Shell commands such as COPY and RENAME do not work as CmdExec tasks unless you carefully phrase the task. For example:
    cmd /C copy d:\out.txt d:\outmore.txt

    This is necessary because SQL Executive assumes the first space-delimited token of the command specifies an EXE or CMD module name.

  • Do not run programs that require user input as CmdExec tasks, because they run on a virtual desktop and cannot be seen.


Message Management Interface

In the Manage SQL Server Messages dialog box, a User Messages Only check box replaces the System Messages check box of SQL Server 6.0. If the User Messages Only check box is selected, the search is restricted to user-defined messages. If this check box is cleared, the search returns both user-defined and system messages.


Server State Polling of Aliased Servers

Server state polling is not supported for servers that are aliased (using the SQL Client Configuration Utility) and registered with SQL Enterprise Manager. Server status information, such as started, stopped, or paused, is not displayed in the Server Manager window for aliased servers.


Query Interface Renamed

For SQL Server 6.5, the query interface in SQL Enterprise Manager is named SQL Query Tool. For SQL Server 6.0, the command on the Tools menu and the icon on the toolbar are called Query Analyzer.

To use the query tool, from the Tools menu, select SQL Query Tool or from the SQL Enterprise Manager toolbar, choose the SQL Query Tool icon.

For more information, see the online Help for ISQL/w.


Screen Refresh

You can update the information that is displayed in the Server Manager window in two ways. Expand the tree for a server and then:

  • Select a folder, select the View menu, and choose the Refresh command.
  • Click the right mouse button on a folder, and then choose Refresh from the menu that appears.


ISQL/w

SQL Server 6.5 provides the following enhancements to ISQL/w:

  • Configurable packet size
  • Trusted connections


Configurable Packet Size

Packet size can be configured in ISQL/w. Configuring the packet size gives you a choice between responsiveness and overall throughput. Larger packets provide less packet overhead and provide better end-to-end throughput: an entire task completes more quickly with larger packets. Smaller packets are more responsive for those interested in intermediate results. Overall, a smaller packet size provides quicker response time, but usually an entire task takes longer to complete with smaller packets than with larger packets.

To configure packet size
  1. From the File menu, choose Configure.

    The Configure ISQL/w dialog box appears.

  2. Choose the Connection tab and in the Packet Size box, type a value.
  3. To accept the new packet size, choose OK. The new packet size will take effect the next time you reconnect.


Trusted Connections

The ISQL/w login dialog box supports trusted connections. You can choose to connect using a trusted connection or standard SQL Server security (in which case you must supply a login ID and a password).

The /E switch can now be specified from within ISQL/w to indicate that a trusted connection will be used and no password will be requested.


SNMP Support

SQL Server 6.5 provides support for Simple Network Management Protocol (SNMP) monitoring of Microsoft SQL Server.

The Microsoft SQL Server Management Information Base (MSSQL-MIB) is based on the proposed Internet Engineering Task Force (IETF) SNMP Relational Database MS-MIB (RFC 1697), and it has been enhanced specifically for use with Microsoft SQL Server. IETF is the organization that oversees standards for the internet.

With SQL Server 6.5 and the MSSQL-MIB, you can use SNMP applications to monitor the status of SQL Server installations, monitor performance information, explore defined databases, and view server and database configuration parameters.

In addition, SQL Server 6.5 supports the ability to raise SNMP traps. An SNMP trap notifies the SNMP agent that some type of status or condition has occurred on the client or the server. The SNMP agent can then forward that notification to selected workstations that are running an SNMP monitoring application(s).

A copy of the MSSQL-MIB (MSSQL.MIB) and a copy of the SQL Server SNMP extension agent (SQLSNMP.DLL) are installed by the SQL Server setup program and are enabled if the machine is running SNMP at the time of installation. MSSQL.MIB and SQLSNMP.DLL can later be added or dropped by the setup program's Set Server options and enabled if the machine is running SNMP at setup time.


SNMP Terminology

To help you understand the SNMP information provided here, some SNMP terms are defined for use as a quick reference.

Term | Description
SNMP | Is an acronym for Simple Network Management Protocol (SNMP). Use SNMP applications to monitor the status of SQL Server installations and performance information, explore defined databases, and view server and database configuration parameters.
SNMP Agent | Is the SQL SNMP extension agent (SQLSNMP.DLL), which is server software that extends the functionality of the Microsoft SNMP service. The agent processes SNMP requests for data and data objects that reside on the local server. The agent can also send a trap, which alerts an operator and an SNMP console of an extraordinary event, such as a password violation.
SNMP Trap | Are conditions from the client or server that cause an alert message to be sent to the SNMP agent. These conditions can be user-defined and are often related to error-condition handling, but do not necessarily represent an error.
SNMP Alert | Is a message that contains some kind of condition or status message that was raised at the server or client.


Installing the MSSQL-MIB and the SNMP Extension Agents

If the Windows NT-based SNMP service is already installed on the computer when the SQL Server setup program is run, then MSSQL.MIB and SQLSNMP.DLL are installed when SQL Server is installed. SQL Server SNMP support is automatically enabled.

If the Windows NT-based SNMP service is not installed on the computer when the SQL Server setup program is run, then MSSQL.MIB and SQLSNMP.DLL are installed when SQL Server is installed, but SQL Server SNMP support is not enabled. In this situation, to set up SNMP support you must:

  1. Install the Windows NT-based SNMP service.

    To install the Windows NT-based SNMP service, use the Network application in Control Panel. For more information, see your documentation for Windows NT or the online Help for the Network application.

  2. Enable SQL Server support of SNMP.

    To enable SQL Server support of SNMP, run the SQL Server setup program, select Set Server Options and choose Continue, and select the Enable SNMP Support option. For more information, see the online Help for SQL Server Setup.


Copying the MIB to an SNMP Workstation

For SNMP applications to monitor the status of a SQL Server, a copy of the MSSQL-MIB must be placed on the monitoring workstation and loaded into the SNMP application. The MSSQL-MIB enables the SNMP application to access the SQL Server SNMP extension agent on the computer that is running SQL Server and to monitor that SQL Server.

To copy the SQL Server MIB to an SNMP workstation
  1. In the C:\MSSQL\SNMP directory on the computer that is running SQL Server, locate the MSSQL.MIB file.
  2. Copy the MSSQL.MIB file to the appropriate directory on the monitoring workstation.
  3. Repeat for all workstations that will be monitoring SQL Server.

For information about loading the MSSQL-MIB and monitoring SQL Server, see the documentation for your SNMP application.


Defining Trap Destinations

If you will be raising SNMP traps in alert responses (as discussed in Raising SNMP Traps in Alert Responses) you must use the Network application in Control Panel to specify the workstations to receive SNMP trap notifications.

To define trap destinations
  1. From Control Panel, choose the Network application.

    The Network Settings Dialog Box appears.

  2. From the Installed Network Software list, select SNMP Server.
  3. Choose Configure.
  4. In the SNMP Service Configuration dialog box, select a community name (for example, public).

    Each server that runs SNMP must belong to a group of hosts that has a community name. The community name is placed in the SNMP packet when the trap is sent. You can specify one or more communities to which the current computer will send traps.

  5. Add the computer names or IP addresses of the workstations to receive SNMP trap notifications:
    • Type the IP address or the computer name in the Address box, and then choose the Add button to move the entry to the Trap Destination box.
    • Repeat for each workstation to receive SNMP trap notifications.
  6. Choose OK.

For more information, see the online Help for the Network application.


Raising SNMP Traps in Alert Responses

The extension agent, SQLSNMP.DLL, is a process that coordinates SQL Server and the Windows NT-based SNMP service. When the SNMP service is started, SQLSNMP.DLL is loaded and becomes accessible from management workstations via SNMP. The extension agent contains a trap mechanism that can be used to raise alerts from SQL Server. Traps are raised by defining alerts in SQL Enterprise Manager and by specifying that the alert raise an SNMP trap.

To configure an alert to raise an SNMP trap
  1. In SQL Enterprise Manager, from the Server menu choose Alerts.

    The Manage Alerts dialog box appears.

  2. Choose the New Alert icon or the Edit Alert icon.

    The New Alert or Edit Alert dialog box appears.

  3. Complete the dialog box. Select the Raise an SNMP Trap When the Alert Occurs option.

For more information about configuring alerts, see the online Help for SQL Enterprise Manager.

Two extended stored procedures can also be used to raise SNMP traps: xp_snmp_getstate and xp_snmp_raisetrap. For information about these extended stored procedures, see What's New for Transact-SQL.


Object Definitions for the MSSQL.MIB File

The MSSQL.MIB file is a text file that contains the definitions of objects that are available to management workstations. The file consists of read-only variables for monitoring general performance counters, the statuses of SQL Servers and databases, and limited discovery of configuration options and devices. MSSQL.MIB does not define any writeable objects.

The MSSQL.MIB file includes the following tables. Note that these tables are SNMP tables, not SQL Server tables.

SNMP table | Description
mssqlSrvTable | Contains a description of the SQL Server installation. Has a single row for SQL Server (version 6.0 or later) installed on the server computer.
mssqlSrvInfoTable | Contains general information about the active SQL Server process, including performance counters.
mssqlSrvConfigParamTable | Lists the SQL Server configuration parameters.
mssqlSrvDeviceTable | Contains an entry for each SQL Server device that is defined on the system.
mssqlDbTable | Lists SQL Server databases that are defined. Contains a single row for each database.
mssqlDbInfoTable | Contains detailed information about each SQL Server database.
mssqlDbOptionTable | Lists the database options that are set for each database.
mssqlDbDeviceTable | Contains entries for each device fragment on which a particular SQL Server database has been created or altered.


SQL Executive

In SQL Server 6.5, SQL Executive provides flexibility and security in the following features:

  • The ability to set configuration parameters for SQL Executive
  • The ability to execute procedures in the SQLExecutiveCmdExec account


SQL Executive Configuration Parameters

Configuration parameters for SQL Executive can be tailored and set from SQL Enterprise Manager.

To set SQL Executive configuration parameters

  1. From SQL Enterprise Manager, in the Server Manager window select the server to set configuration parameters for.
  2. Click the right mouse button on the server's SQL Executive icon, and in the shortcut menu, choose Configure.

    The Configure SQL Executive dialog box appears.

  3. Set the following parameters.
Parameter | Description
Auto-Start SQL Mail When SQL Executive Starts | Specifies that when SQL Executive is started it will automatically start SQL Mail. SQL Server must be running before SQL Executive is started.
Auto-Restart Server After Unexpected Server-Down | Specifies that if SQL Server stops unexpectedly for reasons other than a shutdown or a net stop mssqlserver command, SQL Executive will automatically restart SQL Server and then write a message to the event log.
Unexpected Server-Down Detection Polling Interval (minutes) | Specifies the interval in minutes that is used by SQL Executive to check for unexpected SQL Server stoppages. The default value is 5 minutes.
Local Host Server | Specifies the name of the local SQL Server. Usually this parameter is set to (default). However, if the server is set to listen on an alternate named pipe, do not use (default). Instead, select the listen-on name from the Local Host Server list. For more information about named pipes, see the Microsoft SQL Server Administrator's Companion.
Error Log File | Specifies the path and the name of a file that error information for SQL Executive will be written to. An error log file adds substantial process overhead. Use the error log file only when directed to do so by Microsoft Technical Support or when you are attempting to troubleshoot a specific SQL Executive problem.
System Account | Specifies that SQL Executive is assigned to run in the server's LocalSystem account. Important: Selecting the System Account option for SQL Executive prevents the use of several features, such as replication and running scheduled tasks that involve other servers. A service running under the LocalSystem account has no user account information associated with it. This prevents certain network server software from allowing the Windows NT service to access resources.
This Account | Specifies that SQL Executive will run in the security context of the Windows NT user account that is entered here. This Account will usually be a domain user account (although it can be a user account on the local server). This Account should be reserved for use by SQL Executive (users should not use it to log on). This account should be a member of the Administrators local group and have a non-expiring password. Important: Generally, the This Account option is assigned through the SQL Server setup program when SQL Server is installed and you do not need to change it. If you must change the user account or update the password, always use the Configure SQL Executive dialog box to do so. Do not use the Services application in Control Panel, because the SQL Executive service account needs additional privileges that are only granted to the account when the Configure SQL Executive dialog box is used.
Password | Specifies the password of the Windows NT user account that is assigned to SQL Executive.
Confirm Password | Verifies the password of the Windows NT user account that is assigned to SQL Executive.
Reset CmdExec Account | Reinstalls the SQLExecutiveCmdExec account, which is a local Windows NT account on the server that is being administered. CmdExec tasks that are owned by users other than system administrators run in the security context of this account. This option resets the account to its default (minimum) level of access rights. Additional rights that may have been granted to this account are removed.
Reset CmdExec Password | Changes the Windows NT password that is used by the SQLExecutiveCmdExec account. The new password is automatically generated by SQL Enterprise Manager. Important: Do not use the Windows NT User Manager to change the SQLExecutiveCmdExec password. If you do, then CmdExec tasks that are owned by users other than system administrators cannot run successfully. If this problem occurs, choose the Reset CmdExec Account button.

  4. To set the specified parameters, choose OK.

For more information about using the Configure SQL Executive dialog box, see the online Help for SQL Enterprise Manager.


SQLExecutiveCmdExec Account

The Windows NT user account, SQLExecutiveCmdExec, permits running CmdExec tasks that are owned by users other than system administrators (SAs). This means that all users can execute CmdExec tasks in the security context that is provided by the SQLExecutiveCmdExec account.

The SQLExecutiveCmdExec account is added by the SQL Server setup program when SQL Server is installed. By controlling the rights, permissions, and group memberships of the SQLExecutiveCmdExec account, Windows NT administrators can control the operating system privileges of tasks that are owned by users other than SAs. To configure the rights, permissions, and group memberships of the SQLExecutiveCmdExec account, use the User Manager application from the Administrative Tools program group under Program Manager.

By default, the SQLExecutiveCmdExec account is a member of the Users local group on the server. CmdExec tasks that are owned by SAs run in the security context of the user account that is assigned to SQL Executive. Generally, the assigned user account belongs to the Administrators local group on the server.


Troubleshooting the SQLExecutiveCmdExec Account

Under certain circumstances, the SQLExecutiveCmdExec account can prevent a task from starting. These circumstances include:

  • An improper installation of the SQLExecutiveCmdExec account.
  • The removal of the SQLExecutiveCmdExec account.
  • An SQLExecutiveCmdExec account password that was changed outside of the Configure SQL Executive dialog box.

A message for a failed task will appear in the Task History dialog box.

The following section explains the messages you can receive, the cause, and the solution.

Message
"A required privilege is not held by the client."
Cause
The SQL Executive service account does not have the privileges that are required to initiate a logon as the SQLExecutiveCmdExec account.
Solution
Open the Configure SQL Executive dialog box and reset the Service Startup Account to a different account, for example, the System Account, and then set it back to the desired user account.

You can manually assign the privileges to the startup account by using the Windows NT User Manager application. The privileges are: Act as Part of the Operating System, Replace a System Level Token, and Increase Quotas. If the SQL Executive service startup account is the current session's account, you must log off and then back on after setting these privileges. You also must stop and restart the SQL Executive server.

Message
"A problem occurred while attempting to log on as the Windows NT user 'SQLExecutiveCmdExec': [specific logon problem description]." An example of [specific logon problem description] is "Logon failure: unknown user name or bad password."
Cause
The SQLExecutiveCmdExec account does not exist, or it exists but is not defined correctly. For example, the password has been changed or the account has been disabled.
Solution
Open the Configure SQL Executive dialog box and choose the Reset CmdExec Account button.
To view the task history log
  1. From the Server Manager window, select a server.
  2. Under the selected server, double-click the SQL Executive icon.

    The Manage Scheduled Tasks window appears.

  3. From the task list, select the task to view history for.
  4. From the Manage Scheduled Tasks toolbar, choose the Task History button.

    The Task History dialog box appears.


SQL Performance Monitor

SQL Performance Monitor integrates Windows NT Performance Monitor with SQL Server, providing up-to-the-minute activity and performance statistics, and graphical information in an understandable format. SQL Server 6.5 provides objects and counters that you can use to monitor data that is returned from SQL Performance Monitor. This section provides information about SQL Performance Monitor objects and counters, and about working with SQL Performance Monitor when the server is using integrated security.


Objects

There are entities on the SQL Server that are referred to as objects. These objects are responsible for providing statistics to Performance Monitor applications that request them. SQL Server provides the following new objects:

  • SQL Server User-Defined Counters object
  • SQLServer-Licensing object
  • SQL Server-Procedure Cache object


SQLServer User-Defined Counters Object

The SQLServer User-Defined Counters object contains SQL User Counter 1 through SQL User Counter 10. Values for these counters can be defined by a user. A counter can monitor any information that is returned by an SQL statement or any operation that is performed from SQL Server, such as executing a stored procedure.

In SQL Server 6.5, "empty" stored procedures sp_user_counter1 through sp_user_counter10 correspond to the user-defined counters of the same number in SQL Performance Monitor. To create a user-defined counter, replace one of the empty stored procedures with a new stored procedure. The new stored procedure must return a single integer as its result set. The new stored procedure should have execute permission granted on it for the probe account.

To create a counter stored procedure
  1. Choose one of the stored procedures sp_user_counter1 through sp_user_counter10.
  2. Drop the selected stored procedure.

    For example, to use sp_user_counter1, enter:

    DROP PROC sp_user_counter1
go
  3. Create a new stored procedure sp_user_counter1. The results set must return only one integer.

For example, you can create the following stored procedure to count the number of machines that are connected to SQL Server:

DROP PROC sp_user_counter1
go
CREATE PROC sp_user_counter1
AS SELECT count(distinct net_address) from sysprocesses
go

The SELECT statement counts each distinct net_address that is connected to the server. As a result, the user-defined counter SQL User Counter 1 in SQL Performance Monitor will display the number of machines that are connected to SQL Server.

In the following example, user-defined counters are used to track stock prices of four stocks. For this example, assume stock_price has an int dataype and all stock prices are multiplied by 100.

DROP PROC sp_user_counter1
DROP PROC sp_user_counter2
DROP PROC sp_user_counter3
DROP PROC sp_user_counter4
go
CREATE PROC sp_user_counter1
AS SELECT stock_price from stocks where stock_name = 'A'
go
CREATE PROC sp_user_counter2
AS SELECT stock_price from stocks where stock_name = 'B'
go
CREATE PROC sp_user_counter3
AS SELECT stock_price from stocks where stock_name = 'C'
go
CREATE PROC sp_user_counter4
AS SELECT stock_price from stocks where stock_name = 'D'
go

As a result, in SQL Performance Monitor SQL User Counter1 through SQL User Counter4 will display the prices of stocks A, B, C, and D, respectively.


SQLServer-Licensing Object

The SQLServer-Licensing object contains three counters.

Counter | Description
Client Count | Specifies the number of client workstations that are connected to SQL Server.
Client Limit | Specifies the maximum number of client workstations that can connect to SQL Server. This number reflects the number of separate machines that can connect, not the number of connections that can be made.
Max Client Count | Specifies the maximum number of concurrent client connections that can be made to SQL Server during a SQL Performance Monitor monitoring session.


SQLServer-Procedure Cache Object

The SQL Server-Procedure Cache object is a link list of all procedures. The procedure cache holds entries for each procedure and other maintenance overhead. Each entry in the procedure cache points to one or more buffers in the procedure buffer. The procedure buffer is where the procedure instructions are stored.

The figure below conceptually illustrates:

  • The relationship between a procedure cache entry and a procedure buffer.
  • The different states that are possible for a procedure.
  • How the counters are affected by each state.

As previously stated, a procedure cache entry will have one or more procedure buffers associated with it.

The key at the bottom of the figure shows the possible states for both the procedure cache and the procedure buffer.

Procedure A is currently in an active and used state. As you can see from the example, the procedure cache that is labeled A has three procedure buffers associated with it. Based on its current state, Procedure A will contribute to the following counters:

  • Max Procedure Buffers Active
  • Procedure Buffers Active
  • Max Procedure Buffers Used
  • Procedure Buffers Used
  • Max Procedure Cache Active
  • Procedure Cache Active
  • Max Procedure Cache Used
  • Procedure Cache Used

Procedure B is currently in a used state. As you can see from the example, the procedure cache that is labeled B has two procedure buffers associated with it. Based on its current state, Procedure B will contribute to the following counters:

  • Max Procedure Buffers Used
  • Procedure Buffers Used
  • Max Procedure Cache Used
  • Procedure Cache Used

Procedure C will also contribute to the counters listed for Procedure B, because it is also in a used state.

The following counters are in the SQLServer-Procedure Cache object.

Counter | Description
Max Procedure Buffers Active % | Specifies the maximum percentage of procedure buffers that have been active at one time during the monitoring session. A buffer is considered to be active when it contains a procedure that is currently executing.
Procedure Buffers Active % | Specifies the percentage of procedure buffers that are currently active. When a buffer contains a currently executing procedure, the buffer is said to be active.
Max Procedure Buffers Used % | Specifies the maximum percentage of procedure buffers that have been used at one time during the monitoring session. A procedure buffer is considered used when it is associated with a procedure cache entry. A used procedure buffer may or may not be active.
Procedure Buffers Used % | Specifies the percentage of procedure buffers that are used in the procedure cache. A procedure buffer is considered used when it is associated with a procedure cache entry. A used procedure buffer may or may not be active.
Total Procedure Buffers | Specifies the number of procedure buffers that are in the procedure cache. This number is a fixed number that is based on the procedure cache that is allocated.
Max Procedure Cache Active % | Specifies the maximum percentage of procedure cache that has been active during the monitoring session. A procedure cache entry is considered to be active when its associated procedure is currently executing.
Procedure Cache Active % | Specifies the percentage of the procedure cache that is currently active. When the procedure that is associated with a procedure cache entry is currently executing, the procedure cache entry is said to be active.
Max Procedure Cache Used % | Specifies the maximum percentage of procedure cache that has been used during the monitoring session. A procedure cache entry is considered used when it is currently allocated. A used procedure cache entry may or may not be active.
Procedure Cache Used % | Specifies the percentage of procedure cache that is used. This number indicates the percentage of slots that are currently associated with any procedure.
Procedure Cache Size | Specifies the size, in 2K pages, of the procedure cache. The size of the procedure cache can fluctuate depending on the activity of other SQL Server processes that may require procedure cache slots.


Counters

Counters within an object maintain a count of some aspect of the system. New counters have been added for sizing the tempdb database and for determining the number of SQL Server users.

Counters are changed in SQL Server 6.5 for the following objects:

  • SQL Server object
  • SQL Server-Log object
  • SQL Server-Locks object


SQLServer Object

The SQLServer object includes the following counters to obtain additional statistics for SQL Server.

Counter | Description
Max TempDB Space Used (MB) | Specifies the maximum amount of space, in megabytes, that has been used in the tempdb database during the SQL Performance Monitor monitoring session.
Max Users Connected | Specifies the maximum number of concurrent users that have been connected to SQL Server during the monitoring session.


SQLServer-Log Object

The SQLServer-Log object includes the following counters to obtain additional statistics.

Counter | Description
Max Log Space Used % (per db instance) | Specifies the maximum percentage of space in a transaction log that has been used for each database during the monitoring session.
Max Log Size (MB) (per db instance) | Specifies the maximum size of the transaction log, in megabytes, that has been allocated for each database during the monitoring session.


SQL Server-Locks Object

In SQL Server 6.5, the Total Demand Lock counter has been removed. The concept of a demand lock in SQL Server no longer exists.


SQL Performance Monitor With Integrated Security

When SQL Server is running in standard or mixed security mode, the counters used by SQL Performance Monitor make a connection using the special probe login ID (with no password). When the server is running in integrated security mode, the SQL Server counters will attempt to connect as either the logged on Windows NT user (if SQL Performance Monitor is running on the same machine as SQL Server), or as the LocalSystem account (if SQL Performance Monitor is running on a remote workstation).

You can force SQL Performance Monitor to make a trusted connection to SQL Server regardless of the server security mode by adding a Registry value with the Registry Editor tool (REGEDT32.EXE). In the following key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer

add a value named PerfMonSecure, with a type of REG_DWORD and a value of 0x1. This will cause SQL Performance Monitor to request a trusted connection to SQL Server in the same security contexts, as described above, when SQL Server is running in integrated security mode. If the Registry value is not present or if the value is 0, SQL Performance Monitor will use the probe login ID.

Note that if you choose to configure SQL Server to listen on a named pipe other than the default pipe \\.\pipe\sql\query, SQL Performance Monitor will attempt to connect to SQL Server using the Windows NT-based machine name. To enable SQL Performance Monitor to access this SQL Server from a remote workstation using a trusted connection, you must add a DB-Library alias from that machine name to the alternate local pipe name. For example, if you configured SQL Server to listen on the named pipe \\.\pipe\sql\alternate, in the SQL Client Configuration Utility, use the Advanced tab to set the following:

Server: | machine_name
DLL name: | Named Pipes
Connection string: | \\.\pipe\sql\alternate

If SQL Server is not configured to listen on named pipes, you will not be able to run SQL Performance Monitor from a remote workstation via a trusted connection.


SHOWPLAN Output

SHOWPLAN describes the method that is chosen by the SQL Server optimizer to retrieve data. The SQL Server optimizer is an intelligent cost-based query optimizer that attempts to determine the best method for retrieving data that is requested through ad hoc queries. The optimizer attempts to choose the access method that incurs the lowest estimated cost in terms of page I/O. The chosen method is known as the plan. To see the plan, set the SHOWPLAN option ON via the SET statement.

In SQL Server 6.5, implementation of the ANSI SQL joined tables, the UNION in the VIEW statement, the ROLLUP operator, and the CUBE operator have significantly changed the plans that are executed by SQL Server. Furthermore, the examples of output that are produced by SHOWPLAN in "Understanding SHOWPLAN Output" in the Microsoft SQL Server Administrator's Companion have changed significantly. These changes and plans for the new features in SQL Server 6.5 are described in the following sections.


Modified Plans

The information in the following sections in the Microsoft SQL Server Administrator's Companion are changed for SQL Server 6.5:

  • EXISTS TABLE: nested iteration
  • AND NOT EXISTS: nested iteration
  • OR EXISTS: nested iteration
  • OR NOT EXISTS: nested iteration
  • SUBQUERY: nested iteration
  • AND EXISTS: nested iteration
  • WITH CHECK OPTION

These sections are replaced with the following modified or new sections:

Modified

  • EXISTS TABLE: nested iteration
  • NOT EXISTS: nested iteration
  • OR EXISTS: nested iteration
  • AND EXISTS: nested iteration
  • SUBQUERY: nested iteration
  • WITH CHECK OPTION

New

  • GROUP BY WITH CUBE
  • GROUP BY WITH ROLLUP
  • LEFT OUTER JOIN: nested iteration
  • FULL OUTER JOIN: nested iteration
  • CONSTRAINT: nested iteration
  • UNION ALL


EXISTS table: nested iteration

This SHOWPLAN step indicates a nested iteration on a subquery that is part of an existence test in a query. When the result of the subquery is false, subsequent parts of the plan are not evaluated. An existence test can be written in several ways by using Transact-SQL statements, such as EXISTS, IN, <> ANY, = ANY, < ANY, <=ANY, > ANY, or >= ANY. The plan for the subquery will immediately follow the EXISTS TABLE step, and it is indented to isolate the steps for the subquery from the steps for the outer query.

The following examples demonstrate the SHOWPLAN output with queries that test for the existence of values:

Query 1:        SELECT au_lname, au_fname
            FROM authors
            WHERE EXISTS
            (SELECT *
            FROM publishers
            WHERE authors.city = publishers.city)

SHOWPLAN 1:    STEP 1
            The type of query is SELECT
            FROM TABLE
            authors
            Nested iteration
            Table Scan
            EXISTS : nested iteration
              FROM TABLE
              publishers
              Nested iteration
              Table Scan

Query 2:        SELECT title
            FROM titles
            WHERE pub_id IN
            (SELECT pub_id
            FROM publishers
            WHERE city LIKE 'B%')

SHOWPLAN 2:    STEP 1
            The type of query is SELECT
            FROM TABLE
            titles
            Nested iteration
            Table Scan
            EXISTS : nested iteration
              FROM TABLE
              publishers
              Nested iteration
              Table Scan


NOT EXISTS: nested iteration

This SHOWPLAN step indicates a nested iteration on a subquery that is part of a non-existence test in a query. When the result of the subquery is true, subsequent parts of the plan are not evaluated. A non-existence test can be written in several ways using Transact-SQL statements, such as NOT EXISTS, NOT IN, <> ALL, = ALL, < ALL, <=ALL, > ALL, or >= ALL. The plan for the subquery will immediately follow the NOT EXISTS step and is indented to isolate the steps for the subquery from the steps for the outer query.

The following examples demonstrate the SHOWPLAN output with queries that test for the non-existence of values:

Query 1:        SELECT au_lname, au_fname
            FROM authors
            WHERE NOT EXISTS
            (SELECT *
            FROM publishers
            WHERE authors.city = publishers.city)

SHOWPLAN 1:    STEP 1
            The type of query is SELECT
            FROM TABLE
            authors
            Nested iteration
            Table Scan
            NOT EXISTS : nested iteration
              FROM TABLE
              publishers
              Nested iteration
              Table Scan

Query 2:        SELECT title
            FROM titles
            WHERE pub_id NOT IN
            (SELECT pub_id
            FROM publishers
            WHERE city LIKE 'B%')

SHOWPLAN 2:    STEP 1
            The type of query is SELECT
            FROM TABLE
            titles
            Nested iteration
            Table Scan
            NOT EXISTS : nested iteration
              FROM TABLE
              publishers
              Nested iteration
              Table Scan


OR EXISTS: nested iteration

This SHOWPLAN step indicates a nested iteration on one or more subqueries that are part of an existence test or a non-existence test, and that are also part of an OR clause. When the result of one of the existence or non-existence tests is true, subsequent parts of the plan are not evaluated and the result of the plan for the OR clause is true. The plans for the existence and non-existence tests will immediately follow the OR EXISTS step and are indented to isolate the steps for the subquery iteration from the steps for the outer query.

The following example demonstrates the SHOWPLAN output for queries with OR clauses that test for the existence or non-existence of values:

Query:     SELECT title
           FROM titles
           WHERE advance > ANY
              (SELECT advance
              FROM publishers, titles
              WHERE titles.pub_id = publishers.pub_id
                 AND pub_name = 'Algodata Infosystems')
           OR pub_id NOT IN
              (SELECT pub_id
              FROM publishers
              WHERE city LIKE 'B%')

SHOWPLAN:  STEP 1
           The type of query is SELECT
           FROM TABLE
           titles
           Nested iteration
           Table Scan
           OR EXISTS : nested iteration
             EXISTS : nested iteration
               FROM TABLE
               publishers
               Nested iteration
               Table Scan
               FROM TABLE
               titles
               Nested iteration
               Table Scan
             NOT EXISTS : nested iteration
               FROM TABLE
               publishers
               Nested iteration
               Table Scan


AND EXISTS: nested iteration

This SHOWPLAN step indicates a nested iteration on one or more subqueries that are part of an existence test or a non-existence test, and that are also part of an AND clause, which is also part of an OR clause. When the result of one of the existence or non-existence tests is false, subsequent parts of the plan are not evaluated and the result of the plan for the AND clause is false. The plans for the existence and non-existence tests will immediately follow the AND EXISTS step and are indented to isolate the steps for the subquery from the steps for the outer query.

The following example demonstrates the SHOWPLAN output for queries with AND clauses within OR clauses that test for the existence or non-existence of values:

Query:   SELECT title
         FROM titles
         WHERE pub_id IN
            (SELECT pub_id
            FROM publishers
            WHERE country <> 'USA')
         OR     (NOT EXISTS
            (SELECT *
            FROM publishers
            WHERE city LIKE 'B%'
               AND publishers.pub_id = titles.pub_id)
               AND advance > ANY
            (SELECT advance
            FROM publishers, titles
                WHERE titles.pub_id = publishers.pub_id
               AND pub_name = 'Algodata Infosystems'))

SHOWPLAN: STEP 1
          The type of query is SELECT
          FROM TABLE
          titles
          Nested iteration
          Table Scan
          OR EXISTS : nested iteration
          EXISTS : nested iteration
             FROM TABLE
             publishers
             Nested iteration
             Table Scan
                AND EXISTS : nested iteration
                NOT EXISTS : nested iteration
                FROM TABLE
                publishers
                Nested iteration
                Table Scan
                EXISTS : nested iteration
                   FROM TABLE
                   publishers
                   Nested iteration
                   Table Scan
                          FROM TABLE
                          titles
                          Nested iteration
                          Table Scan


SUBQUERY: nested iteration

This SHOWPLAN step indicates a nested iteration on a correlated subquery that involves an aggregate. The plan for the subquery will immediately follow the SUBQUERY step and is indented to isolate the steps for the subquery from the steps for the outer query. The plan for the subquery will produce a vector aggregate result in a worktable. The GROUP BY clause for the vector aggregate consists of the outer references in the subquery and the elements of the GROUP BY clause for the subquery, if such a clause exists.

The following example demonstrates the SHOWPLAN output for subqueries that involve aggregates:

Query:        SELECT ord_num, title_id, qty
            FROM sales s1
            WHERE qty <
                (SELECT avg(qty)
                FROM sales s2
                WHERE s2.title_id = s1.title_id)

SHOWPLAN:    STEP 1
            The type of query is SELECT
            FROM TABLE
            sales s1
            Nested iteration
            Table Scan
            FROM TABLE
            Worktable 1
            SUBQUERY : nested iteration
            GROUP BY
            Vector Aggregate
              FROM TABLE
              sales s2
              Nested iteration
              Table Scan
              TO TABLE
              Worktable 1


WITH CHECK OPTION

This SHOWPLAN step indicates an existence test that is generated by the optimizer when modifying a view that involves one or more subqueries, and that was created with the WITH CHECK OPTION statement. If the existence test fails, the modification will also fail.

Assume the following view:

CREATE VIEW v1 AS
SELECT *
FROM mytable
WHERE col1 IN (SELECT col1 FROM mytable2)
WITH CHECK OPTION

The following example demonstrates the SHOWPLAN output for a query that updates a view containing subqueries that were created with the WITH CHECK OPTION.

Query:        UPDATE v1 SET col1 = 2

SHOWPLAN:    STEP 1
            The type of query is UPDATE
            The update mode is deferred
            FROM TABLE
            mytable
            Nested iteration
            Table Scan
            EXISTS : nested iteration
                FROM TABLE
                mytable2
                Nested iteration
                Table Scan
            TO TABLE
            mytable
            WITH CHECK OPTION
            EXISTS : nested iteration
                FROM TABLE
                mytable2
                Nested iteration
                Table Scan


GROUP BY WITH CUBE

This statement appears in the SHOWPLAN output for a query that contains a GROUP BY clause that specifies the WITH CUBE option. Queries that contain a GROUP BY clause with the WITH CUBE option will always be at least two-step queries: one step to select the qualifying rows into a worktable, and a second step to sort and group these rows (multiple times) into a second worktable and then return the rows from the second worktable.

The following example is of a two-step query that contains GROUP BY WITH CUBE:

Query:    SELECT stor_id, title_id, sum(qty)
          FROM sales
          GROUP BY stor_id, title_id
          WITH CUBE

SHOWPLAN: STEP 1
          The type of query is INSERT
          The update mode is direct
          FROM TABLE
          sales
          Nested iteration
          Table Scan
          TO TABLE
          Worktable 1

          STEP 2
          The type of query is SELECT
          FROM TABLE
          Worktable 2
                  GROUP BY WITH CUBE
                  Vector Aggregate
                  FROM TABLE
                  Worktable 1
                  Using GETSORTED Table Scan
                  TO TABLE
                  Worktable 2


GROUP BY WITH ROLLUP

This statement appears in the SHOWPLAN output for any query that contains a GROUP BY clause that specifies the ROLLUP option. Queries that contain a GROUP BY clause with the ROLLUP option will always be at least two-step queries: one step to select the qualifying rows into a worktable, and another step that sorts and groups these rows into a second worktable and then returns the rows from the second worktable.

The following example illustrates a two-step query that contains GROUP BY WITH ROLLUP:

Query:    SELECT stor_id, title_id, sum(qty)
          FROM sales
          GROUP BY stor_id, title_id
          WITH ROLLUP

SHOWPLAN: STEP 1
          The type of query is INSERT
          The update mode is direct
          FROM TABLE
          sales
          Nested iteration
          Table Scan
          TO TABLE
          Worktable 1

          STEP 2
          The type of query is SELECT
          FROM TABLE
          Worktable 2
                  GROUP BY WITH ROLLUP
                  Vector Aggregate
                  FROM TABLE
                  Worktable 1
                  Using GETSORTED Table Scan
                  TO TABLE
                  Worktable 2


LEFT OUTER JOIN: nested iteration

This statement appears in the SHOWPLAN output for a query that includes a LEFT OUTER JOIN. The LEFT OUTER JOIN: nested iteration method is the technique used to perform left outer joins. (The optimizer always converts right outer joins into left outer joins.) LEFT OUTER JOIN indicates that SQL Server will loop over the plan for the right table for each row in the left table and will return all rows that meet the search condition that is specified for the join. If no rows meet the search condition, a single row with all columns set to NULL is returned for the right table. The plan for the right table will immediately follow the LEFT OUTER JOIN step and is indented to isolate the steps for the right table from the steps for the outer query.

The following example demonstrates the SHOWPLAN output for a query that involves a left outer join:

Query:    SELECT job_desc, lname
          FROM jobs j LEFT JOIN employee e ON j.job_id = e.job_id

SHOWPLAN: STEP 1
          The type of query is SELECT
          FROM TABLE
          jobs j
          Nested iteration
          Table Scan
          LEFT OUTER JOIN : nested iteration
              FROM TABLE
              employee e
              Nested iteration
              Table Scan


FULL OUTER JOIN: nested iteration

This statement appears in the SHOWPLAN output for a query that involves a FULL OUTER JOIN. In queries that involve FULL OUTER JOIN, the optimizer will always choose to insert the rows from one of tables in the full outer join into a worktable. (This is similar to the reformatting strategy that is used to join tables.) The optimizer then modifies the full outer join so that the worktable is the right table of the full outer join.

The FULL OUTER JOIN: nested iteration method is two-phase technique. In the first phase, SQL Server will loop over the plan for the right table for each row in the left table and will return all rows that meet the search condition that is specified for the join. SQL Server also marks each of these rows by updating a column in the row that is added to the worktable for this purpose. If no rows meet the search condition, a single row with all columns set to NULL is returned for the right table.

In the second phase, after all the rows in the left table have been processed, SQL Server loops over the plan for the right table again, and returns all rows in the right table that were not returned in the first phase and a row from the left table with all columns set to NULL.

The plan for the right table will immediately follow the FULL OUTER JOIN step and is indented to isolate the steps for the right table from the steps for the outer query.

The following example demonstrates the SHOWPLAN output for a query that involves FULL OUTER JOIN:

Query:    SELECT job_desc, lname
          FROM jobs j FULL JOIN employee e ON j.job_id = e.job_id

SHOWPLAN: STEP 1
          The type of query is INSERT
          The update mode is direct
          Worktable created for REFORMATTING
          FROM TABLE
          jobs
          Nested iteration
          Table Scan
          TO TABLE
          Worktable 1

          STEP 2
          The type of query is SELECT
          FROM TABLE
          employee e
          Nested iteration
          Table Scan
          FULL OUTER JOIN : nested iteration
              FROM TABLE
              Worktable 1
              Nested iteration
              Using Clustered Index


CONSTRAINT: nested iteration

This option appears in the SHOWPLAN output for a query that includes a constraint. The CONSTRAINT: nested iteration method is the technique used to join tables when the purpose of the join is to enforce a constraint. The following example demonstrates the SHOWPLAN output for a query that updates a row in the employee table, which has a FOREIGN KEY constraint that references the jobs table. The updated row from the employee table is joined with the jobs table. If no matching row is found in the jobs table, then the update is aborted.

Query:    UPDATE employee
          SET job_id = 14
          WHERE emp_id = 'KFJ64308F'

SHOWPLAN: STEP 1
          The type of query is UPDATE
          The update mode is direct
          FROM TABLE
          employee
          Nested iteration
          Table Scan
          FROM TABLE
          jobs
          CONSTRAINT : nested iteration
          Table Scan
          TO TABLE
          employee


UNION ALL

This option appears in the SHOWPLAN output for a query that includes a UNION ALL. When a query references a view or a derived table that contains a UNION ALL operator, the UNION ALL step separates the plan for the left side of the UNION ALL from the plan for right side of the UNION ALL. The plan for the right side is also indented to further isolate it from the plan for the left side.

Assume the following view:

CREATE VIEW v2 AS
SELECT *
FROM mytable
UNION ALL
SELECT *
FROM mytable2

The following example demonstrates the SHOWPLAN output for a query that involves view v2 containing a UNION ALL operator.

Query:    SELECT * FROM v2

SHOWPLAN: STEP 1
          The type of query is SELECT
          FROM TABLE
          mytable
          Nested iteration
          Table Scan
          UNION ALL
              FROM TABLE
              mytable2
              Nested iteration
              Table Scan


Installing Microsoft SQL Server Using Systems Management Server

You can use Microsoft Systems Management Server (SMS) to automatically install Microsoft SQL Server version 6.5 on multiple Windows NT Server computers in your organization.

The Microsoft SQL Server CD-ROM contains the following files (located at the root of the CD-ROM) to help you deploy SQL Server with SMS.

Filename | Description
SMSQL65.PDF | Is a Package Definition Format (PDF) file that automates creating a SQL Server package in SMS. The SQL Server package can then be distributed and installed on SMS computers. The PDF file also enables SMS to detect SQL Server on SMS computers and report that information in the SMS computer inventory.
SMSSQL65.CMD | Is a batch file that detects the platform of the computer and runs the appropriate version of setup. The SMSSQL65.CMD batch file installs the complete SQL Server product, including SQL Server Books Online.
SMSSQL65.INI | Is the installation script that is used for unattended setup. This file can easily be edited to specify any drive, subdirectory, or installation option. For more information, see Unattended Setup.


Requirements

The following disk space is required on the computers where SQL Server will be installed:

  • Full installation: 90 megabytes
  • Installation without SQL Server Books Online: 75 megabytes

For information about other installation requirements for SQL Server, see the Microsoft SQL Server documentation.

On the SMS site server where the job to install SQL Server is created, the site server must have 180 megabytes of free disk space.


Using the PDF File to Install Microsoft SQL Server

To install SQL Server by using the PDF file
  1. Copy all directories and files from the Microsoft SQL Server CD-ROM to a package source directory.

    To create the package source directory for SQL Server, create the package source directory (for example, D:\SQL65, if you want to put the directory on the D: drive) on a server and share it with the same name (SQL65). Then copy the directories and files from the Microsoft SQL Server CD-ROM to the package source directory (you can use the xcopy command to copy the files).

  2. If you plan to install SQL Server on a drive letter other than C:, modify the drive specifications in the SMSSQL65.INI custom installation script. If you do not want to install SQL Server Books Online, change the Books Online value to 0 in the [New Options] section of the SMSSQL65.INI file.

    For information about the format of the installation script, see "Unattended Installation" in Microsoft SQL Server Setup.

  3. Using the SMS Administrator, create the package for SQL Server by importing SMSSQL65.PDF and specifying the SQL Server package source directory as the source directory for the package.
To create a package source directory
  1. From the File menu, choose Open and select Packages.
  2. From the File menu, choose New.

    The Package Properties dialog box appears.

  3. Choose Import.
  4. Navigate to the package source directory (see the previous section).
  5. Select SMSSQL65.PDF and choose OK.

    The Package Properties dialog box now displays SQL Server 6.5 in the Name box.

  6. Choose Workstations.
  7. In the Source Directory box, specify the server and the sharename of the package source directory you created in step 1 (for example, \\myserver\sql65).
  8. Choose Close.
  9. Choose OK to close the Package Properties dialog box.

    The SQL Server package now appears in the Packages window. Use the SQL Server package to create Run Command on Workstation tasks to install SQL Server.

    Important Installation scripts must be used with the Package Command Manager client software. The installation scripts cannot be run by the Package Command Manager service.This means that you must leave the System Background Task option disabled in the Command Line Properties of the commands in the SQL Server package.

  10. Use a query to find the computers where you want to install SQL Server.

    To install SQL Server on drives other than drive C:, modify SMSSQL65.INI. We recommend that you create an SMSSQL65_drive.INI file for each target drive. Use a query to identify computers that have the customized SMSSQL65_drive.INI file and that have enough free disk space on those drives. You can also create queries that impose other requirements, such as amount of RAM or an existing SQL Server .

    For example, to find all Windows NT Server computers with enough free space on C: to fully install SQL Server and that are running Windows NT version 3.51 and greater, use the following query:

    (
MICROSOFT|DISK|1.0:Disk Index is 'C'
AND
MICROSOFT|DISK|1.0:Free Storage (MByte) is greater than or equal
        to '90'
)
AND
(
MICROSOFT|OPERATING_SYSTEM|1.0:Operating System Name is
        'Microsoft Windows NT'
AND
MICROSOFT|OPERATING_SYSTEM|1.0:Version is same as or comes after
        '3.51'
)

    After you run the query, you can add the selected computers from the query result to a machine group and then use the machine group to specify the target computers where you want to install SQL Server.

    You can also specify the query as a target. SMS will evaluate the query when it activates the job used to install the SQL Server package and will use that result as the list of target computers. For information about creating queries and machine groups, see the Microsoft Systems Management Server documentation.

  11. Using the SMS Administrator, create a Run Command on Workstation job to install SQL Server on a specified drive on specified SMS computers.
To create a Run Command on Workstation job to install SQL Server
  1. From the File menu, choose Open and select Jobs. Or from the File menu, choose New.

    The Job Properties dialog box appears.

  2. Choose Details.
  3. For Job Target, specify the query or machine group you created in step 4.
  4. Select the Run Workstation Command check box.
  5. Select SMSSQL65.
  6. Choose OK, and choose OK again to close the Job Properties dialog box.

    When the job completes, SQL Server will be installed on all target computers on drive C: by default.


Upgrading a Microsoft SQL Server for SMS Databases

SMS uses SQL Server to store its system information and computer inventory data. When you upgrade SQL Server for SMS 1.0 or 1.1 databases, additional steps are required to re-create some of the stored procedures used by SMS. If these stored procedures are not created, then the SMS Scheduler cannot activate jobs that use the Include Substitutes option. This means that jobs will remain in a pending state and will not be activated.

To re-create the stored procedures for an SMS database
  1. From the directory of the SMS site server on the drive that SMS was installed on, run the SQL script sp_site.sql against the SQL Server containing the SMS database. The sp_site.sql script is located in C:\SMSDIRECTORY\SITE.SRV\PLATFORM.BIN.

You can use ISQL/w in the SQL Server program group to execute the script file.

To use ISQL/w to execute the script file
  1. From the SQL Server 6.5 program group, click the ISQL/w icon.

    The Microsoft ISQL/w window opens and displays the Connect Server dialog box.

  2. Connect to the SQL Server that contains the SMS database.
  3. In the DB box, enter the SMS database.
  4. To open the sp_site.sql script located on the site server, click the Load SQL Script button and select the script.
  5. From the Query menu, choose Execute to run the script. The script returns the following text if it is sucessful:
    This command did not return data, and it did not return any rows.

    If the Results tab displays 'Invalid Object Name' errors, verify that you did not execute the script in the wrong database.

    Note that you do not need to manually run the sp_site.sql script for SMS version 1.2 databases. For more information, see the Microsoft Systems Management Server documentation.


Limits

SMS provides neither upgrade support nor tool-only installation. Version 6.0 SQL Servers cannot be upgraded to version 6.5 via SMS. To upgrade, use the SQL Server setup program.


Custom Server Configuration Using the Multiprotocol Networking Library

SQL Server uses a multiprotocol networking library that will listen for incoming network connections on named pipes, a TCP/IP port, and an SPX socket. The named pipe name, TCP/IP port, and SPX socket number are usually chosen dynamically.

If you want users on the internet to connect to your SQL Server using TCP/IP and your organization is using a firewall system to isolate the network containing the SQL Server from the rest of the internet, ensure that SQL Server uses a particular port number for its incoming connections. By doing this, the firewall system will forward connections to that particular port number to your SQL Server.

You can configure SQL Server to listen for incoming connections on a particular port by manually editing some Windows NT Registry keys that control the server's listening behavior. Use the REGEDT32.EXE utility (usually found in the SYSTEM32 directory under the Windows NT root directory) to find the Registry key:

HKEY_LOCAL_MACHINE
\SOFTWARE
\MICROSOFT
\MSSQLSERVER
\RPCNetlib

Note that only system administrators can edit Registry key values.

Once you have located the Registry key, create a new value named RPCprotocols, assigning it a value type of REG_MULTI_SZ. For the value, enter one or more of the following strings to control which protocols are used and the particular named pipe, TCP port, or SPX socket on which the server listens for connections.

Network connection | Description
ncacn_ip_tcp[,port] | Directs the server to listen for connections on TCP/IP. If port is specified, it is used as the number of the TCP/IP port to which the server listens for connections. The TCP/IP port number 1434 has been specifically registered with the Internet Assigned Number Authority (IANA), and should usually be used for the TCP/IP port number to avoid conflicts with other statically or dynamically assigned port numbers.
ncacn_np[,name] | Directs the server to listen for connections using LAN Manager named pipes. If name is specified, is it used as the name of the named pipe to which the server listens for connections.
ncacn_spx[,socket] | Directs the server to listen for connections using SPX sockets. If socket is specified, it is used as the number of the SPX socket to which the server listens for connections.


Connecting to SQL Server Over the Internet

In SQL Server 6.5, you can connect to SQL Server over the internet from ISQL or a client application based on ODBC or DB-Library. Make your data available to customers worldwide right now.


Requirements

The client and server machines must be directly connected to the internet. In addition, you must use the TCP/IP or Multi-Protocol Network Libraries (netlibs). If using the Multi-Protocol netlib, ensure that TCP/IP support is enabled. If the server machine is registered with DNS, you can connect using it's registered (friendly) name.


Establishing an Encrypted Connection

You can use the Multi-Protocol netlib to establish an encrypted connection with SQL Server for a specific user or for all users accessing SQL Server. The Multi-Protocol netlib will encrypt data sent to and received from SQL Server.

To set up encryption for a specific user
  1. Create an account on the machine running SQL Server that matches the account (same username and password) on the client machine.
  2. Turn on encryption for the Multi-Protocol netlib. This can be done for a specific client or through the server for all clients. For more information, see "Configuring Clients" in the Microsoft SQL Server Administrator's Companion.
To set up encryption for all users
  • On the machine running SQL Server
    1. In the Administrative Tools program group, in the User Manager utility, from the User menu choose New User.

      The New User dialog box appears.

    2. In the dialog box, establish a user account with username as token1 and as password token2.
    3. Enable the multiprotocol encryption option by following instructions described in "Configuring Clients" in the Microsoft SQL Server Administrator's Companion.
    4. Start SQL Server.
  • On the machine running the client application
    1. In the Microsoft SQL Server 6.5 program group, double-click the SQL Client Configuration Utility.

      The SQL Server Client Configuration Utility dialog box appears.

    2. Click the Advanced tab.
    3. For the machine on which you set up the user account, specify a logical name in the Server box for SQL Server.
    4. In the DLL Name list box, select Multi-Protocol.
    5. In the Connection String box, type the following:

      ncacn_ip_tcp: servername, token1, token2

      where

      servername

      Specifies the DNS name for the server machine.

      token1

      Specifies the username of the user account on the server machine.

      token2

      Specifies the password for the user account on the server machine.

    The username and password will be used by the client to establish an encrypted connection to SQL Server. Note that this user account is a valid Windows NT account and must be subject to Standard Security.

The user account established on the server machine is not a SQL Server account. The client application must specify a valid SQL Server username and password to successfully connect to SQL Server.

If the connection is unsuccessful because of an invalid username or password, the Multi-Protocol netlib will return error 5 (access denied).


System Messages

Under rare circumstances, a CONVERT function that appears in the select_list of a SELECT statement may raise an error. This can occur only if you convert data into text or image, and SQL Server attempts to store the converted data into a worktable. Worktable use is most common when requesting operations that require SQL Server to sort data.

For example, the following query would raise an error:

SELECT CONVERT (image, name) FROM sysobjects ORDER BY type

You would receive the following error message:

Text data created by the CONVERT() function cannot
be stored in worktables at this time.

To avoid this error, do not convert data to text or image in SELECT statements that may require a worktable. This includes SELECT statements containing ORDER BY, GROUP BY, and aggregate functions. Worktable use can be determined by using Showplans.


Administrator's Companion Errata

The following changes should be made to the Microsoft SQL Server Administrator's Companion for Microsoft SQL Server 6.0.

  • In the SQL Server Books Online version of the Microsoft SQL Server Administrator's Companion for Microsoft SQL Server 6.5, illustrations have been updated to match the illustrations that are in the Microsoft SQL Server Administrator's Companion for Microsoft SQL Server 6.0.

    Also, in books online, the introduction to Part 6, "Replication," should reference Chapter 13, "Replication Concepts," Chapter 14, "Setting Up Replication," and Chapter 15, "Advanced Replication."

  • On Page 62, "Configuring Servers," the listed procedure works on Windows NT server machines, but does not work on Windows NT Workstation machines. However, to hide the server on a Windows NT Workstation machine, at the command prompt, type:
    net config server /hidden: yes
  • On page 90, "NetWare Clients," in the note that begins "The instructions that follow..." the following sentence should be added: "The network number is in decimal."
  • On page 218, "Object Permissions," the following changes should be made:

    In the table in the Statement column, "REFERENCE" should be "REFERENCES" and the associated object in the Object column should be "Table, columns." "DUMP TABLE" should be added to the Statement column, along with its associated object "Table."

    Also, SELECT permission does not include REFERENCES permission.

  • On page 437, "Before You Set Up Replication," the following paragraph should be added to the subsection "Use One Character Set":

    If the character sets in use are not the same type (for example, 850 and 437), replicating extended characters between ANSI and OEM character sets is not possible unless you are using scheduled table refresh. When replicating extended characters using same-type character sets, both scheduled table refresh and log-based replication will work correctly.

  • On page 547, "To Set Up Replication Manually," step 6 for the sp_addpublisher stored procedure should read:
    sp_addpublisher 'WOLFHOUND', 'dist'
go
  • On page 597, "Setting Alerts on Forwarded Events," the following paragraph should be added to the bulleted list at the top of the page:

    Each server that participates in event forwarding must have a non-null @@servername value. Without this value, the forwarding process may not work correctly under all situations and cyclical forwarding may go undetected. The @@servername value can be set by executing the command 'sp_addserver <servername>, local' and then restarting SQL Server. For more information about using sp_addserver, see the Microsoft SQL Server Transact-SQL Reference.

  • On page 608, "Setting Up Mail," the following information should be added to step 5 at the bottom of the page: "When assigning a mail login name to the mail client, do not use a mail login that has a null password. A password is required to access a remote post office."
  • On page 616, "Setting Up a Mail Post Office," in the paragraph that begins, "When setting up the shared network directory," in the second line RWCD should be changed to RW.
  • On page 617, under "Using SQL Mail with a Netware Post Office," the first three paragraphs and step 1 should be replaced with the following:

    You can set up the SQL Server service (MSSQLServer) to run under a Windows NT user account. With appropriate permissions, SQL Server can run SQL Mail and access a NetWare Post Office.

    However, the server's LocalSystem account has no user account information that can be used when accessing remote resources. If the SQL Server service (MSSQLServer) is configured to run under the server's LocalSystem account, it cannot directly access certain server software, including Novell® NetWare®.

    When SQL Server is running under LocalSystem, it is possible to set up SQL Mail to work when the post office is on a Novell NetWare file server by going through the Gateway Services for NetWare, which is provided with Windows NT version 3.5 or later.

    The following steps describe how to set up SQL Mail running under LocalSystem to work with a NetWare post office:

    1. Set up a gateway share on the Windows NT Server to point to the post office share on the NetWare machine. Supply a valid NetWare user account and password for an account that has RW access to the post office share. For information on how to set this up, see the Windows NT documentation on the Gateway Services for NetWare.
  • On pages 619 and 620, all information under the topic "Troubleshooting SQL Mail Problems" should be replaced with the following:

    You can use certain basic troubleshooting techniques to diagnose and resolve most SQL Mail problems. Typically, errors in starting a mail session or in sending mail fall into two categories:

    • Permissions problems when accessing Shared File System (SFS) shares that are being used as a post office
    • Registry setup problems

    If you encounter SQL Mail problems, perform the following steps in the order they are presented:

    1. Ensure that the user who set up SQL Mail can successfully start a mail session and send mail by using the Windows NT Mail client application, MSMAIL32.EXE.
    2. In SQL Server 6.0 or later, SQL Mail can run when the MSSQLServer service is assigned to the LocalSystem account, and also when it is assigned to another Windows NT user account.

    Note If you are running the Windows NT Mail client application on the same machine as SQL Server, you must run the MSSQLServer service in the LocalSystem account.

    Important A service that is running under the system account has no user account information associated with it. This will prevent certain network server software from allowing the Windows NT service to access resources. Microsoft LAN Manager user-level security servers and Novell® NetWare® servers will not allow a Windows NT service that is running under the system account to access their file shares.

    In SQL Server 4.2x, the SQLServer service must be assigned the server's LocalSystem account. You can determine the assigned account by opening the Services application in Control Panel, selecting the SQLServer service, and choosing the Startup button.

    3. If SQL Server is running under a user account, proceed to step 6. If SQL Server is running under LocalSystem, proceed with step 4.
    4. When a mail session is started, mail uses information in the Windows NT Registry to determine startup information, such as the share name that is serving as a post office for the user that is logging in. This Registry information is configured for the current user. To make the information available to SQL Server, run SQL Server setup, select Set Server Options, choose the Mail Login button, and select the option Copy SQL Mail Configuration from Current User Account.

      This option creates the Registry key:

      HKEY_USERS\.DEFAULT\Software\Microsoft\Mail

      This Registry key is used by SQL Mail. If this Registry key is not set up properly, confirm that it is possible to start a mail session by using the account with which you are currently logged into Windows NT. If so, rerun SQL Server setup with the option Copy SQL Mail Configuration from Current User Account selected.

    5. If the post office resides on a Windows NT server version 3.5x-based computer, add the post office share to the list of shares that can be accessed by services that are running under the system account. To add the post office share, use the Registry Editor file REGEDT32.EXE to add the share name to the following Registry value on the Windows NT computer where the post office is located:
      HKEY_LOCAL_MACHINE\System\CurrentControlSet
\Services\LanmanServer\Parameters\NullSessionShares

      For example, if the post office is running on a computer with the name "NTServer" and the post office directory is shared as "WGPO," the value "WGPO" must be added to the NullSessionShares value.

      Because the NullSessionShares value is of the type REG_MULTI_SZ, each share name must be on a separate line from other share names.

      For this Registry change to take effect, the post office computer must be re-booted.

    6. If SQL Server is running under a user account instead of the system account, confirm that step 1 was performed while the user was logged into Windows NT under the same user account that SQL Server is using.
    7. Confirm that the MSSQLServer service has Change access permissions or RW access permissions to the post office share. If SQL Server is running under the system account, the post office share must grant these rights to the Everyone group.

      Additionally, if the post office is located on an NTFS partition, Everyone must be granted the same rights as the share permissions on the post office directory, including all subdirectories and all existing files in the post office directory.

      To test SQL Server access permissions on the post office share, execute the xp_cmdshell extended stored procedure, which runs with the same permissions as SQL Mail.

      You can use the following commands to test read and write access to the server, assuming the post office is located on a computer named "NTServer" and the post office directory is shared as "WGPO":

      xp_cmdshell 'dir \\NTServer\WGPO'

xp_cmdshell 'echo 'hello' > \\NTServer\WGPO\test.txt'

      If either of the above commands fails, step 5, 6, or 7 has not been completed correctly.

    Note An access violation can result from an attempt to execute xp_sendmail when the post office and address book are on a file share that the MSSQLServer service cannot access.

  • On page 743, in Chapter 24 "Additional Problem-Solving Techniques," in the topic "Moving a Device," the syntax diagram should be changed to:

    sp_movedevice device_name,new_path

    The stored procedure for moving a device should be replaced with the following:

    /****************************************************************/
PRINT ' '
PRINT 'Creating Stored Procedure: dbo.sp_movedevice'
PRINT 'Use this prior to moving the device or DB will be suspect'
/***************************************************************/
go
EXEC sp_configure 'allow updates', 1
RECONFIGURE WITH OVERRIDE
go
IF EXISTS (SELECT * FROM sysobjects WHERE
name = 'sp_movedevice' and type = 'P')
DROP PROCEDURE sp_movedevice
go
CREATE PROCEDURE sp_movedevice @devname varchar(30),
  @newpath varchar (127)
AS
BEGIN
BEGIN TRAN
UPDATE sysdevices set phyname = @newpath
WHERE name = @devname
IF @rowcount <> 1
BEGIN
PRINT '**********************ERROR**********************'
PRINT 'Moved failed - more or less than one row affected'
PRINT '**********************ERROR**********************'
ROLLBACK TRAN
END
ELSE
BEGIN
PRINT 'Device moved successfully'
PRINT 'Change will take effect next time you start SQL Server'
COMMIT TRAN
END
END
go
sp_configure 'allow updates',0
RECONFIGURE WITH OVERRIDE
go


Part 4 What's New for Transact-SQL

What's New for Transact-SQL

This part highlights additions and improvements to Microsoft Transact-SQL that are provided in Microsoft SQL Server 6.5, and it supplements the information that is presented in the Microsoft SQL Server Transact-SQL Reference for SQL Server 6.0. The following table identifies Transact-SQL features as new or enhanced in SQL Server 6.5. Features are in alphabetical order.

Feature | New | Enhanced
@@OPTIONS global variable | · |
ANSI-standard null handling | · |
Bound connections | · |
Catalog stored procedures |  |
sp_column_privileges |  | ·
sp_columns |  | ·
sp_datatype_info |  | ·
sp_fkeys |  | ·
sp_sproc_columns |  | ·
sp_table_privileges |  | ·
Composite indexes |  | ·
CUBE operator | · |
Data definition language in transactions |  | ·
Disabling constraints | · |
Distributed transactions | · |
Extended stored procedures |  |
xp_cmdshell |  | ·
xp_readmail |  | ·
xp_sendmail |  | ·
xp_snmp_getstate | · |
xp_snmp_raisetrap | · |
xp_sqlinventory | · |
xp_sqltrace | · |
float datatype |  | ·
Functions |  |
APP_NAME built-in | · |
USER | · |
Insert row-level locking (IRL) | · |
Joins |  | ·
Replication stored procedures |  |
sp_addsubscriber |  | ·
sp_addsubscription |  | ·
sp_changearticle |  |
sp_changesubscriber |  | ·
sp_dsninfo | · |
sp_enumdsn | · |
sp_helpsubscriberinfo |  | ·
sp_replcmds |  | ·
Replication of text and image datatypes | · |
ROLLUP operator | · |
SQL Executive stored procedures |  |
sp_addtask |  | ·
sp_helphistory |  | ·
sp_helptask |  | ·
sp_runtask |  | ·
sp_updatetask |  | ·
Statements |  |
ALTER TABLE |  | ·
BEGIN DISTRIBUTED TRANSACTION | · |
CREATE INDEX |  | ·
CREATE SCHEMA | · |
CREATE TABLE |  | ·
DECLARE CURSOR |  | ·
DBCC DBREINDEX | · |
DBCC PROCCACHE | · |
DBCC ROWLOCK | · |
DBCC UPDATEUSAGE | · |
DISK INIT |  | ·
DUMP |  | ·
EXECUTE |  | ·
FETCH |  | ·
GRANT |  | ·
INSERT |  | ·
ISDATE and ISNUMERIC | · |
LOAD |  | ·
RAISERROR |  | ·
REVOKE |  | ·
SELECT |  | ·
SET |  | ·
UPDATE |  |
System stored procedures |  | ·
sp_addlogin | · |
sp_bindsession |  | ·
sp_certify_removable | · |
sp_change_users_login | · |
sp_coalesce_fragments |  | ·
sp_configure |  | ·
sp_dboption | · |
sp_dropwebtask | · |
sp_fallback_activate_svr_db | · |
sp_fallback_deactivate_svr_db | · |
sp_fallback_enroll_svr_db | · |
sp_fallback_help | · |
sp_fallback_permanent_svr | · |
sp_fallback_upd_dev_drive | · |
sp_fallback_withdraw_svr_db | · |
sp_getbindtoken | · |
sp_helplogins |  | ·
sp_helprotect | · |
sp_help_revdatabase |  | ·
sp_helpserver | · |
sp_makewebtask | · |
sp_rename | · |
sp_runwebtask |  | ·
sp_serveroption | · |
sp_setnetname |  | ·
sp_tableoption | · |
sp_who |  |
Tables |  | ·
MSsubscriber_info | · |
sysbackupdetail | · |
sysbackuphistory |  | ·
syscolumns |  | ·
sysindexes |  | ·
sysprocesses |  | ·
sysprotects | · |
sysrestoredetail | · |
sysrestorehistory |  | ·
text datatype |  | ·
Trace flags |  |
Utilities |  | ·
isql options |  | ·
ISQLPASSWORD | · |
PRINTDMP.EXE command-prompt utility | · |
SQLMAINT.EXE command-prompt utility | · |
Web pages |  |


@@OPTIONS Global Variable

@@OPTIONS Global Variable (version 6.5)

The @@OPTIONS global variable provides information about the current values of query-processing SET options. The SET options can be modified as a whole by using the sp_configure 'user options' configuration option. Each user has an @@OPTIONS global variable that represents the configuration environment. When first logging in, all users are assigned a default configuration environment that is set by the system administrator.

You can change the query-processing options by using the SET statement.

Values within @@OPTIONS are the same as the configuration values for 'user options' in sp_configure.

For more information, see SET Statement .

For more information about sp_configure 'user options', see sp_configure.

Example

This example switches on the NOCOUNT option and then tests the value of @@OPTIONS. The NOCOUNT ON option prevents the number of rows affected message from being sent back to the requesting client for every statement in a session. The value of @@OPTION is set to 512 (0x0200), which represents the NOCOUNT option. The following statement tests whether the NOCOUNT option has been enabled on the client. For example, it can help to track down performance differences on a client machine.

SET NOCOUNT ON
IF @@OPTIONS & 512 > 0
    RAISERROR ('Current user has SET NOCOUNT turned on.',1,1)


ANSI-standard Null Handling

ANSI-standard Null Handling (version 6.5)

The American National Standards Institute (ANSI) provides standards throughout the trade and communications industries to promote compatibility among products and establish common behavior in related products.

Microsoft SQL Server 6.5 complies with ANSI standards and retains backward compatibility with configuration options that can be switched on or off by using the SET statement. These options enforce data manipulation behavior for the duration of a user's work session or for the duration of a running trigger or a stored procedure.

These are the new configuration options.

Enabling options | Description
SET ANSI_NULLS ON | Specifies ANSI-standard behavior of the comparison operators, EQUAL (=) and NOT EQUAL (< >). ANSI-standards require that a null value in any statement evaluates to NULL. Default is OFF.
SET ANSI_WARNINGS ON | Specifies warnings are generated when null values appear in aggregate functions when data is truncated during an update or when arithmetic overflows occur. Default is OFF.
SET ANSI_PADDING ON | In varchar and varbinary columns, trailing spaces and NULLS are not deleted. When this option is set to OFF, trailing spaces and NULLS are deleted in these columns. Default is OFF.
SET ANSI_DEFAULTS ON | Turns on all ANSI-standard behaviors. This option includes setting to ON these options: ANSI_NULLS, ANSI_NULL_DFLT_ON, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, CURSOR_CLOSE_ON_COMMIT, IMPLICIT_TRANSACTIONS, and QUOTED_IDENTIFIER. Default is OFF.

For information about the SET statement, comparison operators, and aggregate functions, see SET Statement.


Bound Connections

Bound Connections (version 6.5)

Bound connections allow two or more connections to share the same transaction lock space and the same transaction, and to work on the same data without lock conflicts. Bound connections can be created from multiple connections within the same application, from multiple applications on the same computer with separate connections, or from multiple applications on different computers with separate connections.

By using bound connections, an extended stored procedure can share the transaction space of the connection that called it by invoking the extended stored procedure. Bound connections make coordinating actions across multiple connections easier.

To participate in a bound connection, the first connection gets a bind token, a character string that SQL Server uses to keep track of the bound transaction and that uniquely identifies each bound transaction, by using sp_getbindtoken or srv_getbindtoken (Open Data Services). The bind token is then transmitted or passed to the other connections that will participate in the same bound connection. The other participating connections call sp_bindsession by using the bind token received from the first connection.

Think of a bound connection as a conference call. Person P1 places a telephone call or connection to person P2. To add person P3 to the existing call or connection, P1 uses a conference mechanism. Only one person involved in the conference call can talk at a time. Now replace the people in the conference call with database connections where bound connections use bind tokens. Only one connection involved in a bound connection can interact with the server at a time.

The following example of bound connections illustrates how two connections can access the same transaction: A customer decides to purchase a product at a local department store. The salesperson accesses a sales transaction system that inserts a row into the sales transaction table, including a credit card authorization number. Two connections are made to the same server: connection C1 and connection C2. C1 begins a transaction that adds a product sale row to the sales table. A credit card authorization number must be added to the new sales transaction row. During the credit card authorization process, the extended stored procedure creates connection C2 to dial out across a telephone line to the credit card company and modifies the sales transaction row with the credit card authorization number. Only by using bound connections can both connections access the same row without locking conflicts.

Once the two or more connections are bound together by using bind tokens, only one connection at a time can actively use the bound connection. If one connection is executing a statement on the server or has results pending from the server, no other connections that share the same transaction space can access the server until the current connection finishes executing the current statement. If the server is busy, an error occurs indicating that the transaction space is in use and that the connection should retry later.

Note The application developer should add the appropriate recovery code for a server busy error.

There are two types of bound connections: local and distributed. A local bound connection allows two or more connections to share the same transaction space of a single transaction on a single server until the entire transaction is either committed or rolled back. A distributed bound connection allows two servers to participate in the same transaction until the entire transaction is either committed or rolled back by using Microsoft Distributed Transaction Coordinator (MS DTC). For more information about distributed transactions, see Distributed Transactions and the Guide to Microsoft Distributed Transaction Coordinator.

If a bound connection is involved in a local transaction and executes a remote procedure call (RPC) on a remote server with SET REMOTE_PROC_TRANSACTIONS ON, the local bound transaction is automatically promoted to a distributed bound transaction by MS DTC and an MS DTC session is started. When the transaction is promoted, the bind token changes to a distributed token identification number. This new token identification number should be used with any future calls to sp_bindsession. For more information about using RPC calls and the SET REMOTE_PROC_TRANSACTIONS ON statement, see the Guide to Microsoft Distributed Transaction Coordinator.

Bound connections are also useful in developing extended stored procedures that can use ODBC or DB-LIBRARY to call back to the server and share the same transaction lock space as the connection calling the extended stored procedure. This method allows an extended stored procedure more flexibility when performing database functions.

Bound connections can also be used to develop three-tier applications where business logic is represented in separate programs that can work cooperatively on a single business transaction.

For more information about bound connections, see sp_bindsession and sp_getbindtoken.

For more information about using bound connections with Open Data Services, see sp_getbindtoken.


Composite Indexes

Composite Indexes (version 6.5)

Composite indexes can now contain 900 bytes in the index. The order and number of columns in a composite index affect performance. Listing a greater number of columns in the index improves performance for covered queries that benefit by having a column or search criteria listed in the composite index. However, indexes that cover fewer columns require less I/O to update and insert rows.


CUBE Operator

CUBE Operator (version 6.5)

In SQL Server 6.5, there is an aggregate operator called CUBE, which can be used to produce results sets that typically are used for reports.

The CUBE operator is an additional switch in the GROUP BY clause in the SELECT statement. For additional information about the SELECT statement, see SELECT Statement in this document and in the Microsoft SQL Server Transact-SQL Reference.

The CUBE operator is used with an aggregate function to generate additional rows in a results set. Columns included in the GROUP BY clause are cross-referenced to produce a superset of groups. The aggregate function specified in the select_list is applied to these groups to produce summary values for the additional super-aggregate rows. The number of extra groups in the results set is determined by the number of columns included in the GROUP BY clause.

The aggregate function used in the SELECT statement is applied to the cross-referenced columns for the super-aggregate calculation. The CUBE operator can be applied to all aggregate functions, including AVG, SUM, MAX, MIN, and COUNT.

In fact, every possible combination of the columns or expressions in the GROUP BY clause is used to produce super-aggregates. If you have n columns or expressions, there are 2 (n) -1 possible super-aggregate combinations. Mathematically, these combinations form an n-dimensional cube, which is how the operator got its name.

The ROLLUP operator, which produces a summary of aggregates, has also been added in SQL Server 6.5. It is useful when only summary information is needed and a full CUBE provides extraneous data. For more information about the ROLLUP operator, see ROLLUP Operator.

The following are guidelines for using the CUBE operator:

  • The maximum size of a GROUP BY column list is 900 bytes.
  • A maximum of 10 columns or expressions are permitted when WITH CUBE or WITH ROLLUP is specified.
  • Columns or expressions must be specified in the GROUP BY clause; GROUP BY ALL is not permitted.
  • The CUBE and ROLLUP operators are disabled when trace flag 204 is ON.

You can use the CUBE operator to present cross-referenced information without having to write additional procedures. Consider a personnel department report that includes information such as job titles, home addresses, and modes of transportation to work. The SELECT statement reports on these records for each employee. By introducing the CUBE operator and the COUNT aggregate function, you can obtain statistics such as the number of people who drive to work and from what locations, and whether their jobs may be related to where they live or how they get to work.

You might also apply the CUBE operator to a company sales management report that records sales personnel, customers, products, and quantities sold of each product. A SELECT statement used with the SUM aggregate function produces a report of how many of each product were sold, to which customers, and by which sales persons.

The CUBE operator expands the information returned by cross-referencing and reporting data such as the products that particular customers frequently buy, which sales personnel sell the most of a particular product, and which products are the most popular. By using application or programming tools, this information can then be fed into charts and graphs that convey results and relationships visually and effectively.

Examples

A. Use the SELECT Statement with the CUBE Operator

This example demonstrates the results set from a SELECT statement that uses the CUBE operator. The SELECT statement covers a one-to-many relationship between book titles and the quantity sold of each book. By using the CUBE operator, the statement returns an extra row.

SELECT title, "qty" = SUM(qty)
FROM sales, titles
WHERE sales.title_id = titles.title_id
GROUP BY title
WITH CUBE

This is the results set:

title                                              qty
-------------------------------------------------- -----------
But Is It User Friendly?                                    30
Computer Phobic AND Non-Phobic Individuals: Behavi          20
Cooking with Computers: Surreptitious Balance Shee          25
Emotional Security: A New Algorithm                         25
Fifty Years in Buckingham Palace Kitchens                   20
Is Anger the Enemy?                                        108
Life Without Fear                                           25
Onions, Leeks, and Garlic: Cooking Secrets of the           40
Prolonged Data Deprivation: Four Case Studies               15
Secrets of Silicon Valley                                   50
Silicon Valley Gastronomic Treats                           10
Straight Talk About Computers                               15
Sushi, Anyone?                                              20
The Busy Executive's Database Guide                         15
The Gourmet Microwave                                       40
You Can Combat Computer Stress!                             35
(null)                                                     493

(17 row(s) affected)

The null value represents all values in the title column. The results set returns values for the quantity sold of each title and the total quantity sold of all titles. For this particular example, applying the CUBE operator or ROLLUP operator returns the same result.

B. Use the CUBE Operator on a Results Set with Three Columns

The SELECT statement returns the publication name, title, and quantity of books sold. The GROUP BY clause in this example includes two columns called pub_name and title. There are also two one-to-many relationships between publishers and titles and between titles and sales.

By using the CUBE operator, the results set contains more detailed information about the quantities of titles sold by publishers. The null value represents all values in the title column.

SELECT pub_name, title, "qty" = SUM(qty)
FROM sales, titles, publishers
WHERE sales.title_id = titles.title_id
AND publishers.pub_id = titles.pub_id
GROUP BY pub_name, title
WITH CUBE

This is the results set:

pub_name             title                                      qty
-------------------- ---------------------------------------- ------
Algodata Infosystems But Is It User Friendly?                    30
Algodata Infosystems Cooking with Computers: Surreptitious Ba    25
Algodata Infosystems Secrets of Silicon Valley                   50
Algodata Infosystems Straight Talk About Computers               15
Algodata Infosystems The Busy Executive's Database Guide         15
Algodata Infosystems (null)                                     135
Binnet & Hardley     Computer Phobic AND Non-Phobic Individu     20
Binnet & Hardley     Fifty Years in Buckingham Palace Kitche     20
Binnet & Hardley     Onions, Leeks, and Garlic: Cooking Secr     40
Binnet & Hardley     Silicon Valley Gastronomic Treats           10
Binnet & Hardley     Sushi, Anyone?                              20
Binnet & Hardley     The Gourmet Microwave                       40
Binnet & Hardley     (null)                                     150
New Moon Books       Emotional Security: A New Algorithm         25
New Moon Books       Is Anger the Enemy?                        108
New Moon Books       Life Without Fear                           25
New Moon Books       Prolonged Data Deprivation: Four Case St    15
New Moon Books       You Can Combat Computer Stress!             35
New Moon Books       (null)                                     208
(null)               (null)                                     493
(null)               But Is It User Friendly?                    30
(null)               Computer Phobic AND Non-Phobic Individua    20
(null)               Cooking with Computers: Surreptitious Ba    25
(null)               Emotional Security: A New Algorithm         25
(null)               Fifty Years in Buckingham Palace Kitche     20
(null)               Is Anger the Enemy?                        108
(null)               Life Without Fear                           25
(null)               Onions, Leeks, and Garlic: Cooking Secre    40
(null)               Prolonged Data Deprivation: Four Case St    15
(null)               Secrets of Silicon Valley                   50
(null)               Silicon Valley Gastronomic Treats           10
(null)               Straight Talk About Computers               15
(null)               Sushi, Anyone?                              20
(null)               The Busy Executive's Database Guide         15
(null)               The Gourmet Microwave                       40
(null)               You Can Combat Computer Stress!             35

(36 row(s) affected)

Increasing the number of columns in the GROUP BY clause illustrates why the CUBE operator is an n-dimensional operator. A GROUP BY clause that has two columns returns three more groups when the CUBE operator is used.

The results set is grouped by the publisher name and then by the book title. The quantity of each title sold by each publisher is listed in the right-hand column.

The (null) value in the title column stands for "all titles." See the GROUPING function later in this section for information about how to differentiate specific values and all values in the results set. The CUBE operator returns these groups of information from one SELECT statement:

  • The quantity of each title that each publisher has sold.
  • The quantity of each title sold.
  • The quantity of titles sold by each publisher.
  • The total number of titles sold by all publishers.

Each column referenced in the GROUP BY clause has been cross-referenced with all other columns in the GROUP BY clause and the SUM aggregate has been reapplied, which produces additional rows in the results set. Information returned in the results set grows n-dimensionally along with the number of cross-referenced columns in the GROUP BY clause.

Note Ensure that the columns following the GROUP BY clause have meaningful, real-life relationships with each other. For example, if you were to use au_fname and au_lname, the CUBE operator would return irrelevant information such as the number of books sold by authors with the same first name. Using the CUBE operator on a real-life hierarchy, such as yearly sales and quarterly sales, produces meaningless rows in the results set and it is more efficient to use the ROLLUP operator.

C. Use the CUBE Operator on a Results Set with Four Columns

In this example, the GROUP BY clause contains three columns that are cross-referenced by the CUBE operator. Three one-to-many relationships exist between publishers and authors, between authors and titles, and between titles and sales.

By using the CUBE operator, more detailed information is returned about the quantities of titles sold by publishers.

SELECT pub_name, au_lname, title, SUM(qty)
FROM publishers, authors, titles, titleauthor, sales
WHERE publishers.pub_id = titles.pub_id
AND authors.au_id = titleauthor.au_id
AND titleauthor.title_id = titles.title_id
AND titles.title_id = sales.title_id
GROUP BY pub_name, au_lname, title
WITH CUBE

The CUBE operator returns the following information based on the cross-referenced groupings that are returned with the CUBE operator.

  • The quantity of each title that each publisher has sold for each author.
  • The quantity of all titles each publisher has sold for each author.
  • The quantity of all titles each publisher has sold.
  • The total quantity of all titles sold by all publishers for all authors.
  • The quantity of each title sold by all publishers for each author.
  • The quantity of all titles sold by all publishers for each author.
  • The quantity of each title sold by each publisher for all authors.
  • The quantity of each title sold by all publishers for each author.

Note The super-aggregate for all publishers, all titles, and all authors is greater than the total number of sales, because a number of books have more than one author.

A pattern emerges as the number of relationships grows. The pattern of values and nulls in the report shows which groups have been formed for a summary aggregate. Explicit information about the groups is provided by the GROUPING function.

The GROUPING function is used to distinguish between real NULL values in the results set and (null) values (that represent all values for a column) in the results set.

The GROUPING function can be used with the GROUPING function or with the CUBE operator. The GROUPING function is applied to a column_name in the select_list. The column_name must be one of the columns that appears in the GROUP BY clause. A value of 1 is returned when there is a (null) representing all values in the column; 0 is returned when the column contains a value. The 1 or 0 returned is a tinyint datatype.

D. Use the GROUPING Function with the CUBE Operator

In this example, the SELECT statement uses the SUM aggregate, the GROUP BY clause, and the CUBE operator. It also uses the GROUPING function on the two columns that are listed after the GROUP BY clause.

SELECT pub_name, GROUPING(pub_name),title, GROUPING(title),
"qty" = SUM(qty)
FROM sales, titles, publishers
WHERE sales.title_id = titles.title_id
AND publishers.pub_id = titles.pub_id
GROUP BY pub_name, title
WITH CUBE

The results set has two columns containing 0 and 1 values, which are produced by the GROUPING(pub_name) and GROUPING(title) expressions. The value 1 appears when the column contains a (null). The GROUPING function returns a 1 when the values in that particular column have been grouped together by the CUBE operator.

This is the results set:

pub_name                 title                         qty
-------------------- --- ------------------------- --- -----------
Algodata Infosystems   0 But Is It User Friendly?    0          30
Algodata Infosystems   0 Cooking with Computers: S   0          25
Algodata Infosystems   0 Secrets of Silicon Valley   0          50
Algodata Infosystems   0 Straight Talk About Compu   0          15
Algodata Infosystems   0 The Busy Executive's Data   0          15
Algodata Infosystems   0 (null)                      1         135
Binnet & Hardley       0 Computer Phobic AND Non-P   0          20
Binnet & Hardley       0 Fifty Years in Buckingham   0          20
Binnet & Hardley       0 Onions, Leeks, and Garlic   0          40
Binnet & Hardley       0 Silicon Valley Gastronomi   0          10
Binnet & Hardley       0 Sushi, Anyone?              0          20
Binnet & Hardley       0 The Gourmet Microwave       0          40
Binnet & Hardley       0 (null)                      1         150
New Moon Books         0 Emotional Security: A New   0          25
New Moon Books         0 Is Anger the Enemy?         0         108
New Moon Books         0 Life Without Fear           0          25
New Moon Books         0 Prolonged Data Deprivatio   0          15
New Moon Books         0 You Can Combat Computer S   0          35
New Moon Books         0 (null)                      1         208
(null)                 1 (null)                      1         493
(null)                 1 But Is It User Friendly?    0          30
(null)                 1 Computer Phobic AND Non-P   0          20
(null)                 1 Cooking with Computers: S   0          25
(null)                 1 Emotional Security: A New   0          25
(null)                 1 Fifty Years in Buckingham   0          20
(null)                 1 Is Anger the Enemy?         0         108
(null)                 1 Life Without Fear           0          25
(null)                 1 Onions, Leeks, and Garlic   0          40
(null)                 1 Prolonged Data Deprivatio   0          15
(null)                 1 Secrets of Silicon Valley   0          50
(null)                 1 Silicon Valley Gastronomi   0          10
(null)                 1 Straight Talk About Compu   0          15
(null)                 1 Sushi, Anyone?              0          20
(null)                 1 The Busy Executive's Data   0          15
(null)                 1 The Gourmet Microwave       0          40
(null)                 1 You Can Combat Computer S   0          35

(36 row(s) affected)


Data Definition Language in Transactions

Data Definition Language in Transactions (version 6.5)

Data definition language (DDL) statements can appear within a user transaction. This allows the new CREATE SCHEMA statement to function. You can build a batch of schema-building statements and they will all be committed simultaneously. This eases the strict instruction order that was required by earlier releases.

The following statements can appear in transactions:

ALTER TABLE | DROP PROCEDURE
CREATE DEFAULT | DROP RULE
CREATE INDEX | DROP TABLE
CREATE PROCEDURE | DROP TRIGGER
CREATE RULE | DROP VIEW
CREATE TABLE | GRANT
CREATE TRIGGER | REVOKE
CREATE VIEW | SELECT INTO
DROP DEFAULT | TRUNCATE TABLE
DROP INDEX |

A database object (including a global temporary table) cannot be dropped while it is in use. If the object is in use and a drop is attempted, the transaction will be rolled back. The only exception to this is the implicit drop that is done to a global-temporary object when the creating connection disconnects.

The SELECT INTO statement is now supported within a transaction. This means that tables can be created by using SELECT INTO within a transaction. The data is removed and the table is dropped if the transaction is rolled back.

User transactions are not rolled back when a batch contains a syntax or compile-time error. A batch with this type of error will not execute. This situation can cause unexpected behavior if the BEGIN TRANSACTION statement was executed in a previous batch, because the transaction will be active even though the rest of the batch will not run.

If an uncommitted procedure or trigger is executed and causes a rollback, it will drop itself but continue executing the cached copy. This copy will be removed when the procedure or trigger completes execution.

The sp_bindrule, sp_unbindrule, sp_bindefault, and sp_unbindefault stored procedures can also be used within a transaction whether or not the rule or table has been modified within that transaction or within another transaction.

All resources (such as pages, extents, and locks) used by a transaction are freed only at the end of the transaction. For DDL statements on large tables, this can affect a significant number of pages.

Important While implicit drops of temporary tables can occur successfully at any time, the resources for the temporary table (including locks on system tables in tempdb) are not freed until the end of the transaction.

Use caution when you create temporary tables inside a transaction. Until the transaction commits or rolls back, exclusive locks are held on several system tables in the tempdb database to ensure recovery. These locks are held even if the temporary tables are dropped, and they can block other users' attempts to create temporary tables or other objects in tempdb.

This caution also applies to stored procedures that create temporary tables. If the stored procedure is executed within a transaction, the locks are held on the system tables until the transaction completes, even though the temporary table is automatically dropped when the procedure completes execution.

When invoked inside a user transaction, SELECT INTO has the ACID transaction properties (atomicity, consistency, isolation, durability): either the transaction is completely committed or it is completely rolled back.

Examples

A. Create a Table and Insert Values in One Transaction

This example creates and fills a table in a single transaction. The table is created and filled with data simultaneously. Either the table is not created and the transaction is rolled back, or the table is created, filled with data, and then committed.

BEGIN TRAN
CREATE TABLE pay_type_table (pay_id int, pay_type varchar(20))
INSERT pay_type_table (1, 'Cash')
INSERT pay_type_table (2, 'Check')
INSERT pay_type_table (3, 'Credit Card')
INSERT pay_type_table (4, 'Electronic Wire')
INSERT pay_type_table (5, 'Banker Draft')
COMMIT TRAN
B. Demonstrate Exclusive Locks on a Temporary Table in a Transaction

This example attempts a second session to access a newly created but uncommitted object; it results in the second session waiting until the creating transaction is complete. If the first transaction results in the object being removed and also creates another object by the same name and the waiting session is attempting to open the object by name, the waiting session will open the second (and newest) object.

This table illustrates the relationship between the two connections.

User One User Two
BEGIN TRAN
CREATE TABLE test (c1 int)
INSERT test VALUES (1)
go

SELECT * FROM test

DROP TABLE test
go
CREATE TABLE test (c1 int, c2 int)
INSERT test VALUES (1,2)
go
COMMIT TRAN

Results Set
c1    c
------------
1     2
(1 row(s) affected)

C.    Use SELECT INTO Within a Transaction

Before running this example, sp_dboption select into\bulk copy must be set to TRUE.

The SELECT INTO statement creates a new table called authors2, into which the records in the authors table are copied. After the transaction is rolled back the authors2 table has been dropped and the final SELECT statement causes an error.

GO
BEGIN TRANSACTION
SELECT * INTO authors2 FROM authors
SELECT * FROM authors2
ROLLBACK TRANSACTION
SELECT * FROM authors2
GO


Disabling Constraints

Disabling Constraints (version 6.5)

You can disable constraints by using:

  • SET DISABLE_DEF_CNST_CHK option

    Disables deferred constraint checking for the session. Constraints that have been disabled by using the NOCHECK option or NOT FOR REPLICATION option are checked individually.

  • NOCHECK option in ALTER TABLE statement

    Temporarily disables constraint checking for a foreign key or a check constraint. The constraint is disabled and can be re-enabled rather than re-created.

  • NOT FOR REPLICATION in ALTER TABLE or CREATE TABLE statements

    Disables foreign key constraint checks on data inserted by distribution during replication.

Disabling constraints can improve performance and streamline replication processes. For example, when rebuilding or replicating databases at a remote site there is no need to repeat constraint checks because the integrity of the data was checked when it was entered into the original database.

For more information about disabling constraints, see SET Statement, ALTER TABLE Statement, and CREATE TABLE Statement.


Distributed Transactions

Distributed Transactions (version 6.5)

Distributed transactions are transactions that update data on two or more network-connected computer systems and are available as part of Microsoft Distributed Transaction Coordinator (MS DTC). Distributed transactions provide an interface to applications that update distributed data. MS DTC provides this by employing the "ACID" properties: atomicity, consistency, isolation, and durability.

Atomicity provides an all or nothing property to a transaction. At any point before the transaction is committed, either the application or the system can terminate the transaction. If the transaction is terminated, the system ensures that all effects of the transaction are undone. If the transaction is committed, the system ensures that all targets of the transaction are committed.

Consistency is preserved if a transaction transforms the data from one correct state to another. The application programmer can write procedures that ensures that the work done within a transaction preserves consistency.

Isolation prevents concurrent updates from interfering with one another. Generally, data read for a transaction cannot be updated by other concurrent transactions. Also, data written by a transaction cannot be read or updated by other concurrent transactions until the transaction is committed.

Durability ensures that committed transactions remain permanent even in the event of hardware, software, or network failures.

Distributed transactions are an essential tool for building robust, scalable, distributed applications. Distributed applications are vulnerable to hardware, software, and network failure. In the absence of distributed transactions, the application must detect and recover from these failures. Distributed transactions, however, permit distributed data to be updated while providing simple failure recovery semantics to the application.

For example, consider an order-entry system for compact discs. When an order is placed at headquarters, it is entered into the local (headquarter) database. The order details are transmitted to the database at the warehouse where the compact disc distribution actually occurs. All orders committed locally must have a parallel order committed remotely at the warehouse. Distributed transactions ensure that the order transaction is committed or rolled back in both databases. To ensure consistency in the headquarters database and the warehouse database, the server-to-server procedure calls will be in a single atomic transaction.

To participate in a transaction that is distributed by MS DTC in an MS DTC distributed transaction, the server must be instructed to participate in a distributed transaction and to inform MS DTC of that participation. SQL Server's participation in an MS DTC transaction can be started by any of the following:

  • By a client application calling API functions from a DB-Library or an ODBC program.
  • By using the BEGIN DISTRIBUTED TRANSACTION statement. This statement begins a new MS DTC transaction.
  • By enabling the remote REMOTE_PROC_TRANSACTIONS option in the SET statement. For more information, see Set Statement.

Important Connected servers need a time-out period to shut down an inactive connection. Otherwise, the servers remain connected until the originating user's session is terminated.

To set a time-out period before you begin a transaction, use the sp_configure stored procedure with the 'remote conn timeout' option.

A BEGIN DISTRIBUTED TRANSACTION affects subsequent Transact-SQL statements.

These are the statements that are affected by MS DTC.

Statement | Description
BEGIN TRANSACTION | The statements included between BEGIN DISTRIBUTED TRANSACTION and COMMIT TRANSACTION can include nested pairs of BEGIN TRANSACTION and COMMIT TRANSACTION statements. The transactions are not committed until the outermost transaction is committed. The nesting level of transactions is stored in the @@TRANCOUNT global variable. Each call to BEGIN TRANSACTION increases the outstanding transaction count by one.
BEGIN DISTRIBUTED TRANSACTION | BEGIN DISTRIBUTED TRANSACTION statements cannot be nested. SQL Server will detect such calls, reject them, and report an error.
COMMIT TRANSACTION | If the outstanding transaction count is one and this SQL Server session initiated the distributed transaction, then SQL Server calls MS DTC and commits the distributed transaction. Each call to COMMIT TRANSACTION decreases the outstanding transaction count by one.
PREPARE TRANSACTION | The PREPARE TRANSACTION statement is not permitted in a distributed transaction and will return an error.
ROLLBACK TRANSACTION | A distributed transaction can be rolled back when the ROLLBACK TRANSACTION statement is executed before the COMMIT TRANSACTION. MS DTC aborts the entire distributed transaction when the outstanding transaction count is one.
SAVE TRANSACTION | MS DTC does not support distributed savepoints. If an MS DTC transaction is aborted or rolled back, the entire transaction is rolled back to the beginning of the distributed transaction, regardless of any savepoints.

Any user involved in a distributed transaction can roll back the transaction. However, only the user who started the transaction can commit the transaction.

For more information about distributed transactions, see the Guide to Microsoft Distributed Transaction Coordinator.

Example

This example updates the author's last name on the local and remote databases. Both the local and remote databases will either commit or roll back the transaction.

BEGIN DISTRIBUTED TRANSACTION
UPDATE authors
    SET au_lname = 'McDonald' WHERE au_id = '409-56-7008'
EXECUTE remote.pubs.dbo.changeauth_lname '409-56-7008','McDonald'
COMMIT TRAN


float Datatype

float Datatype (version 6.5)

The precision of the float datatype uses less storage space for different ranges of precision. For example, consider the following declaration of float (n):

Declare @mf float(n)

These are the ranges of precision values permitted.

Where n = | Version 6.0 and earlier | Version 6.5
1-7 | real, 4 bytes | real, 4 bytes
8-15 | float, 8 bytes | real, 4 bytes
16-23 | float, 8 bytes | real, 4 bytes
24-53 | float, 8 bytes | float, 8 bytes


Insert Row-level Locking (IRL)

By default, the locking granularity in Microsoft SQL Server is a page, which can contain several rows. In SQL Server 6.5, the lock manager has been enhanced to provide row-level locking (IRL) for most INSERT operations. IRL improves performance in situations where access contention and hotspots, which are areas of unusually high access, occur.

While row-level locking is not a substitute for a well-designed application, there are specific scenarios where it is especially useful. Row-level locking is useful when a hotspot develops on tables structured as a sequential file. With SQL Server, hotspots can occur when records are inserted at the end of a table and one of the following conditions exists:

  • A table does not have an index.
  • A table has a nonclustered index.
  • A table has a clustered index with a monotonically increasing key (for example, a clustered index on an identity column).

When concurrent users try to insert data into the table's last page and contend for exclusive page access, a hotspot results. To alleviate these performance bottlenecks, enhancements to the lock manager in SQL Server 6.5 provide row-level concurrency for INSERT operations. Properly implemented IRL increases the speed of multiuser INSERT operations.

Note If a clustered index exists on a table, it must be a unique clustered index to take advantage of IRL. (Typically, a unique clustered index is created by default on the column or columns that form the primary key when the primary key is defined.)

For more information about enabling IRL, see sp_tableoption, later in this document.

Two new lock modes provide increased concurrency for IRL.

Lock mode | Description
Insert_page | Multiple transactions can obtain an Insert_page lock on a page while concurrently inserting data. An Insert_page lock is compatible only with other Insert_page locks and is held until the transaction completes.
Link_page | A Link_page lock is obtained by the first transaction that detects that the current page is full and that a new page needs to be allocated and linked to the current page. The transaction's Insert_page lock is upgraded to a Link_page lock. Subsequent requests for Insert_page locks are blocked until the transaction owning the Link_page lock completes.

The following table describes the compatibility of the new types of locks. "Y" means that the requested lock is compatible with the granted lock. "N" means that the requested lock is not compatible with the granted lock.

IRL is OFF by default. IRL can be enabled on individual tables or on an entire database by using the sp_tableoption stored procedure. The following example shows how the database owner can turn on the insert row lock option for all tables in the current database:

EXECUTE sp_tableoption '%.%', 'insert row lock', 'true'

Note The new value for insert row lock takes immediate effect on existing tables in the current database. For each table subsequently created, IRL must be explicitly set.

This example shows how a user other than the system administrator or database owner can turn off the insert row lock option for the sales table:

EXECUTE sp_tableoption 'sales', 'insert row lock', 'false'

For more information about enabling table options, see sp_tableoption, later in this document.

For recovery purposes, additional information must be logged into the transaction log each time a transaction that uses the IRL concurrency option rolls back. This additional information consists of compensating log records, which are used during recovery to bring the database back to a consistent state. To account for a potential rollback operation, SQL Server reserves enough space in the transaction log for all concurrent IRL operations.

Important If you intend to use IRL, and your application performs many concurrent INSERT operations, you should monitor the size of the log using the Windows NT Performance Monitor. Increase the size of the log space or dump the transaction log more frequently if your database is running low.

Reducing the locking granularity can result in deadlocks in some applications. It is possible for existing applications to encounter deadlocks if IRL is implemented without adequate testing. For example, consider a transaction that inserts a row on a page and then updates the row within the same transaction. For the INSERT operation, the transaction must acquire an Insert_page lock, and for the subsequent UPDATE operation, it needs an exclusive page lock. If there are several such transactions running concurrently, each transaction can have its own Insert_page lock on the page. When attempting to update the page, each transaction requests an exclusive page lock, which blocks on the Insert_page lock of another transaction and results in a deadlock. To achieve maximum benefit from IRL and to avoid deadlocks, it is recommended that you extensively test existing applications before changing to this new locking level.


Joins

Joins (version 6.5)

ANSI-standard join clauses are supported and include:

  • JOIN
  • CROSS JOIN
  • INNER JOIN
  • LEFT OUTER JOIN
  • RIGHT OUTER JOIN
  • FULL OUTER JOIN

Earlier versions of SQL Server joins continue to be supported although they will be discontinued in a future release.

For more information about implementing joins, SELECT Statement.


Replication of text and image Datatypes

Replication of text and image Datatypes (version 6.5)

For a published replication article, text and image columns are now replicated as text or image datatypes.

The synchronization process initializes NULL pointers in tables loaded by BCP by default. The process first obtains the names of nullable text and image columns and subsequently issues an UPDATE statement to initialize all columns with uninitialized pointers. The statement is issued repeatedly for columns with ROWCOUNT set to 1000.

Potentially, the synchronization process can cause a large number of records to be written to the transaction log of the subscriber database. To switch off the initialization of NULL pointers for text and image coumns, do one of the following:

  • Use automatic transaction log backups provided in Windows NT Performance Monitor. See the Microsoft SQL Server Administrator's Companion for more information.
  • Reduce the number of NULL text and image datatype columns in the published table.
  • Add the -N switch to the distribution process and ensure that applications modifying text or image columns in the published table initialize pointers using some value other than NULL in the UPDATE statement.

For more information, see What's New for Administrators, earlier in this document.


ROLLUP Operator

ROLLUP Operator (version 6.5)

The ROLLUP operator is an aggregate operator that delivers aggregates and super-aggregates for elements within a GROUP BY statement. The ROLLUP operator is applicable to cumulative aggregates such as running sums or running averages. It differs from the CUBE operator only in that it is sensitive to the column's position in the GROUP BY clause. Aggregate groupings are made up of columns to the right of the current column value.

The ROLLUP operator can be used by report writers to extract statistics and summary information from results sets. The cumulative aggregates, such as running sums, can be used in reports, charts, and graphs.

The ROLLUP operator creates groupings by moving in only one direction, from right to left, along the list of columns in the GROUP BY clause. It then applies the aggregate function to these groupings. The CUBE operator creates all combinations of groupings from the list of columns in the GROUP BY clause.

Example

This example uses a SELECT query that contains an aggregate function and a GROUP BY clause, which lists pub_name, au_lname, and title, in that order.

SELECT pub_name, au_lname, title, "SUM" = SUM(qty)
FROM publishers, authors, titles, titleauthor, sales
WHERE publishers.pub_id = titles.pub_id
AND authors.au_id = titleauthor.au_id
AND titleauthor.title_id = titles.title_id
AND titles.title_id = sales.title_id
GROUP BY pub_name, au_lname, title
WITH ROLLUP

By using the ROLLUP operator, these groupings are created by moving right to left along the list of columns:

pub_name      au_lname          title       SUM(qty)
pub_name      au_lname      (null)      SUM(qty)
pub_name      (null)        (null)      SUM(qty)
(null)        (null)        (null)      SUM(qty)

The (null) value represents all values for that column.

If you use the SELECT statement without the ROLLUP operator, the statement creates a single grouping. The query returns a sum value for each unique combination of pub_name, au_lname, and title.

pub_name           au_lname          title          SUM(qty)

Compare these examples with the groupings created by using the CUBE operator on the same query:

pub_name        au_lname        title        SUM(qty)
pub_name        au_lname        (null)        SUM(qty)
pub_name        (null)        (null)        SUM(qty)
(null)        (null)        (null)        SUM(qty)
(null)        au_lname        title        SUM(qty)
(null)        au_lname        (null)        SUM(qty)
pub_name        (null)        title        SUM(qty)
(null)        (null)        title        SUM(qty)

The groupings correspond to the information returned in the results set. Where you see (null) in the results set, it represents all values in the column. The ROLLUP operator returns the following data when the columns (pub_name, au_lname, title) are in the order listed in the GROUP BY clause:

  • The quantity of each title that each publisher has sold for each author.
  • The quantity of all titles each publisher has sold for each author.
  • The quantity of all titles each publisher has sold.
  • The total quantity of all titles sold by all publishers for all authors.

This is the results set returned by the SELECT query:

pub_name          au_lname     title                                SUM
----------------- ------------ ------------------------------------ ---
Algodata Infosys  Bendit       The Busy Executive's Database Guide  15
Algodata Infosys  Bendit       (null)                               15
Algodata Infosys  Carson       (null)                               30
Algodata Infosys  Dull         Secrets of Silicon Valley            50
Algodata Infosys  Dull         (null)                               50
Algodata Infosys  Green        The Busy Executive's Database Guide  15
Algodata Infosys  Green        (null)                               15
Algodata Infosys  Hunter       Secrets of Silicon Valley            50
Algodata Infosys  Hunter       (null)                               50
Algodata Infosys  MacFeather   Cooking with Computers: Surre        25
Algodata Infosys  MacFeather   (null)                               25
Algodata Infosys  O'Leary      Cooking with Computers: Surre        25
Algodata Infosys  O'Leary      (null)                               25
Algodata Infosys  Straight     Straight Talk About Computers        15
Algodata Infosys  Straight     (null)                               15
Algodata Infosys  (null)       (null)                              225
Binnet & Hardley  Blotchet-Hal Fifty Years in Buckingham Palace Ki  20
Binnet & Hardley  Blotchet-Hal (null)                               20
Binnet & Hardley  DeFrance     The Gourmet Microwave                40
Binnet & Hardley  DeFrance     (null)                               40
Binnet & Hardley  del Castillo Silicon Valley Gastronomic Treats    10
Binnet & Hardley  del Castillo (null)                               10
Binnet & Hardley  Gringlesby   Sushi, Anyone?                       20
Binnet & Hardley  Gringlesby   (null)                               20
Binnet & Hardley  Karsen       Computer Phobic AND Non-Phobic Indiv 20
Binnet & Hardley  Karsen       (null)                               20
Binnet & Hardley  MacFeather   Computer Phobic AND Non-Phobic Indiv 20
Binnet & Hardley  MacFeather   (null)                               20
Binnet & Hardley  O'Leary      Sushi, Anyone?                       20
Binnet & Hardley  O'Leary      (null)                               20
Binnet & Hardley  Panteley     Onions, Leeks, and Garlic: Cooking   40
Binnet & Hardley  Panteley     (null)                               40
Binnet & Hardley  Ringer       The Gourmet Microwave                40
Binnet & Hardley  Ringer       (null)                               40
Binnet & Hardley  Yokomoto     Sushi, Anyone?                       20
Binnet & Hardley  Yokomoto     (null)                               20
Binnet & Hardley  (null)       (null)                              250
New Moon Books    Green        You Can Combat Computer Stress!      35
New Moon Books    Green        (null)                               35
New Moon Books    Locksley     Emotional Security: A New Algorithm  25
New Moon Books    Locksley     (null)                               25
New Moon Books    Ringer       Is Anger the Enemy?                 216
New Moon Books    Ringer       Life Without Fear                    25
New Moon Books    Ringer       (null)                              241
New Moon Books    White        Prolonged Data Deprivation: Four     15
New Moon Books    White        (null)                               15
New Moon Books    (null)       (null)                              316
(null)            (null)       (null)                              791

(49 row(s) affected)

For more information about the ROLLUP operator, see SELECT Statement.

The GROUPING function can be used with the ROLLUP operator or with the CUBE operator. You can apply this function to one of the columns in the select_list and it returns either 1 or 0 depending upon whether the column is grouped by the ROLLUP operator. For more information about the GROUPING function, see SELECT Statement or CUBE Operator.


text Datatype

text Datatype (version 6.5)

Literal strings longer than 255 bytes are automatically converted to the text datatype. This may require stricter datatype checking in applications because a char or varchar variable cannot be directly compared to a text variable. In earlier releases of SQL Server, literal strings longer than 255 bytes were truncated and treated as a varchar datatype.


Trace Flags

Trace Flags (version 6.5)

Trace flags are used to temporarily set specific server characteristics. For example, if you set the trace flag 8501 when you start SQL Server, detailed information is logged about MS DTC transactions.

Trace flags are generally used to switch off a particular behavior. SQL Server 6.5 introduces many new features, some of which can be switched off by using a trace flag. Often trace flags are used to diagnose performance issues and to debug stored procedures or complex systems.

This is how to start a trace flag by using the DBCC command:

DBCC TRACEON (8501)

These flags are new or enhanced in SQL Server 6.5.

Flag | Description
110 | Disables ANSI SELECT characteristics. For more information, see SELECT Statement.
204 | Supports queries that contain sort columns in the ORDER BY clause that are not in the select list when the DISTINCT keyword is supplied. For more information, see the Microsoft SQL Server Transact-SQL Reference.
237 | Disables the requirement for REFERENCES permission to create a foreign key on a table that is not owned by the key creator, and when disabled ensures ANSI-standard behavior. When enabled, this flag needs only SELECT permission and SQL Server 6.0 behavior is ensured.
246 | Disables error reporting when no column name is given to a column created by a SELECT INTO or a CREATE VIEW statement.
330 | Enables full output when using the SET SHOWPLAN option, which gives detailed information about joins.
506 | Enforces ANSI standards regarding null values for comparisons between variables and/or parameters. Any comparison of variables and/or parameters that contain a NULL will always result in a NULL. This flag is disabled if ANSI_NULLS is enabled (set to True).
1081 | Sets a flag in index pages that prevents index pages from being removed from the cache the first time the cache tries to remove them to make space for new data. Unless the index page is reused and the flag is reset, the index page is received next time the cache requires space for new data pages. This flag extends the life of the index page within the cache. Use this flag on databases where performance gained by retaining the index pages in the cache outweighs the performance lost by the increase in data page I/O.
2701 | Sets the global variable @@ERROR to 50000 for RAISERROR messages with severity levels of 10 and under. When disabled, sets the global variable @@ERROR to 0 for RAISERROR messages with severity levels of 10 and under.
3002 | Backups will have SQL Server 6.0 DUMP format. To use this option the database must be running in stand-alone mode by setting the database option "DBO UseOnly" to TRUE.
4022 | In SQL Server 6.5, bypasses automatically started procedures.
7501 | In SQL Server 6.5, dynamic cursors are used by default on forward-only cursors. Dynamic cursors are faster in version 6.5 and no longer require unique indexes. This flag disables the dynamic cursor enhancements and reverts to version 6.0 behavior.
7502 | Disables the caching of cursor plans for extended stored procedures.
8501 | Performs detailed logging that describes all MS DTC-related context and state changes.

Trace flags are set when SQL Server is started at the command prompt. For more information about "sqlservr command-line executable," see the Microsoft SQL Server Transact-SQL Reference. This is how to start SQL Server with a trace flag at the command prompt:

sqlservr /dc:\mssql\data\master.dat /T8501


Utilities

Utilities (version 6.5)

SQL Server contains several utilities, such as isql and SQLMAINT, that are included for performing certain maintenance, administration, and debugging tasks.

isql is a command-line query tool that is used for MS-DOS®-based connectivity and batch processing.

SQLMAINT is a command-line utility that is used to run automated consistency checks and backups. For example, it can create status reports and send them to an e-mail account.


isql Options

isql Options (version 6.5)

isql /b
The /b option specifies that isql exits and returns a DOS ERRORLEVEL value when an error occurs. The value returned to the DOS ERRORLEVEL variable is 1 when the SQL Server error message has a severity of 10 or greater, otherwise the value returned is 0. DOS batch files can test the value of DOS ERRORLEVEL and handle the error appropriately.
isql /O
The /O option specifies that the behavior of earlier versions of isql is required and disables the following:
  • EOF batch processing
  • Auto console width scaling
  • Wide messages
  • Default DOS ERRORLEVEL value is -1
isql /l timeout
The /l option specifies the number of seconds before an isql login times out. If no timeout is specified, a command runs indefinitely; the default timeout for login to isql is eight seconds.


ISQLPASSWORD

ISQLPASSWORD (version 6.5)

The isql ISQLPASSWORD environment variable allows you to set a default password for the current session. Therefore, you do not have to hard code a password into batch files.

If you do not specify a password with the /P qualifier, isql first checks for the ISQLPASSWORD variable. If no value is set, isql uses the default password, NULL. The following example sets the ISQLPASSWORD variable at the command prompt and then accesses the isql utility:

C:\>SET ISQLPASSWORD=abracadabra
C:\> isql


PRINTDMP.EXE Command-prompt Utility

The PRINTDMP.EXE command-prompt utility provides formatted output of stack traces for specific debugging purposes. Use this only when instructed to do so by your Primary Support Provider.


SQLMAINT.EXE Command-prompt Utility

SQLMAINT.EXE Command-prompt Utility (version 6.5)

The SQLMAINT.EXE command-prompt utility performs routine database maintenance. Use SQLMAINT.EXE to run DBCC checks, to dump a database and its transaction log, to update statistics, and to rebuild indexes. All database maintenance activities generate a report that can be sent to a designated e-mail account.

Syntax

SQLMAINT
[-?] | [-S server_name]
[-U login_ID [-P password]]
-D database_name
-Rpt output_file
[-To operator_name]
[-CkDB | -CkDBNoIdx]
[-CkAl | -CkAlNoIdx]
[-CkTxtAl]
[-CkCat]
[-UpdSts]
[-RebldIdx free_space]
[-BkUpDB backup_path | -BkUpLog backup_path]
[-BkUpOnlyIfClean]
[-BkUpMedia {DISK [-DelBkUps number_of_weeks] | TAPE}]

where

-?
Specifies that the syntax diagram for SQLMAINT.EXE utility be returned. This parameter must be used alone.
-D database_name
Specifies the target database name. This parameter is required if the -? parameter is not used.
-Rpt report_file
Specifies the full path and name of the file into which the report is to be generated. The report is also generated on the screen. This parameter is required if the -? parameter is not used. The report maintains version information by adding a date to the filename. The date is generated as follows: at the end of the filename but before the period, in the form _YYYYMMDD.

If you run the utility on Dec. 1, 1996 and this is the report_file value:

c:\mssql\backups\pubs_maint.rpt

Then it becomes:

c:\mssql\backups\pubs_maint_19961201.rpt

The full UNC filename is required for the -Rpt file when SQLMAINT.EXE accesses a remote server.

-S server
Specifies the target server. If this parameter is not supplied, SQL Server is assumed to be on the local machine. The SQL Server must be version 6.0 or later, though it is recommended that you run the utility on version 6.5. This parameter is optional.
-U login_ID
Specifies the login ID to use when connecting to the server. If this parameter is not supplied SQLMAINT.EXE will attempt to log in by using a trusted connection. This parameter is optional.
-P password
Specifies the password for the login ID. Only valid if the -U parameter is also supplied. This parameter is optional.
-To operator_name
Specifies the operator to whom the generated report will be sent through SQL Mail. The operator can be defined by using SQL Enterprise Manager. This parameter is optional.
-CkDB | -CkDBNoIdx
Specifies page checking against extent structures. The CkDB checks data and index pages against allocation units. CkDBNoIdx will check only the data pages against the extent structures.

Data storage is held in pages, 256 of which are grouped into one extent structure. At the beginning of each allocation unit, a page is dedicated to keeping track of the pages within the extent. Also, the pages are linked by pointers stored on the pages. This check tests to see that the pages linked by pointers match the pages listed on the first page in the extent structure.

A warning is written to an output file if the database is in use when SQLMAINT.EXE runs. This parameter is optional.

These parameters are equivalent to DBCC NEWALLOC and DBCC NEWALLOC with the NOINDEX option. For more information, see the DBCC statement.

-CkAI | -CkAlNoIdx
Is to check the allocation of text and image columns in the database and generates a report of allocation errors. This parameter is optional.
-CkCat
Is to check for consistency of the system tables and generates a report of all consistency errors. This parameter is optional.
-UpdSts
Is to update statistics about the distribution of key values in specified indexes for all tables in the target database. This parameter is optional.
-Rebldldx free_space
Specifies that indexes on tables in the target database should be rebuilt by using the Free Space percent value as the inverse of the fillfactor. For example, if Free Space percentage is 30 then the fillfactor used is 70. If the Free Space percentage value of 100 is specified, then the indexes are rebuilt with the original fillfactor value.

This parameter is optional and is available only with SQL Server version 6.5.

-BkUpDB backup_path | -BkUpLog backup_path
Specifies a backup action. BkUpDb backs up the entire database. BkUpLog backs up only the transaction log.

The backup_path specifies the directory for the backup. The backup can be placed in a directory or a tape device address (For example, \\.\TAPE0). The filename for a database backup is automatically generated as follows:

dbname_db_dump.yyyymmdd

The filename for a transaction backup is automatically generated as follows:

dbname_log_dump.yyyymmdd

If you use the -BkUpDB parameter you must also specify the media using the -BkUpMedia parameter.

-BkUpMedia {TAPE | DISK [DelBkUps num_weeks]}
Specifies the media type of the backup as either TAPE or DISK.
-DelBkUps number_of_weeks
Specifies the number of weeks to retain disk backup files. Backup files older than the specified number of weeks are deleted. This parameter can be used only if -BkUpType DISK is also specified.
-BkUpOnlyIfClean
Specifies that the backup occurs only if any specified -CK checks did not find problems with the data. Maintenance actions run in the same sequence as they appear on the command line. Specify the parameters -CkDB, -CkDBNoIdx, -CkAL, -CkAlNoIDX, -CkTxtAL, or -CkCat before the -BkUpDB/-BkUpLog parameter(s) if you are also going to specify -BkUpOnlyIfClean, or the backup will occur whether or not the check reports problems.

Remarks

SQLMAINT.EXE is a SQL-DMO application, which makes it necessary to register SQL-DMO on the machine where you intend to run SQLMAINT.EXE. If SQL Server or SQL Enterprise Manager are installed on the machine, SQL-DMO is already registered.

Type the following to register SQL-DMO at the command line:

regsvr32 c:\mssql\binn\sqlole65

SQLMAINT.EXE returns 0 if it runs successfully or 1 if it fails. Failure is reported:

  • If any of the maintenance actions fail.
  • If -CkDB, -CkDBNoIdx, -CkAL, -CkALNoIdx, -CkTxtAL, or -CkCat checks find problems with the data.
  • If a general failure is encountered.

For example, SQLMAINT.EXE returns 1 if SQL-DMO has not been registered.


Web Pages

Web Pages (version 6.5)

By using three new SQL Server stored procedures, you can generate HTML documents for web pages. Other than the information needed to use these stored procedures, no programming knowledge is required to create a web page. In addition, the SQL Server Web Assistant provides an interface for using the sp_makewebtask stored procedure.

For more information about creating web pages with the Web Assistant, see SQL Server Web Assistant earlier in this document.

For more information about creating web pages with the new SQL Server stored procedures, see sp_dropwebtask, sp_makewebtask, and sp_runwebtask, later in this document.

Important The Web Assistant can be run only on Intel-based computer systems. The sp_dropwebtask, sp_makewebtask, and sp_runwebtask stored procedures can be run only on Microsoft SQL Server version 6.5 databases and on any supported platform. Running these procedures on earlier version databases will result in errors.

You can use the sp_dropwebtask, sp_makewebtask, and sp_runwebtask stored procedures to:

  • Create standard HTML pages from your SQL Server data.
  • Improve performance and scalability compared to CGI applications.
  • Generate HTML pages automatically through powerful scheduling options.
  • Generate trigger-based HTML pages.

These are example uses for generating dynamic web pages in SQL Server:

  • With your inventory information stored in a Microsoft SQL Server database, you can keep track of what items are in stock, what items are on order, and what items are on back order. By using these stored procedures, you can create a web page that displays current inventory levels. This web page can be updated every hour so customers can see your up-to-date inventory status.
  • An investments firm can use a Microsoft SQL Server database to store prices of stocks, mutual funds, and precious metals, and to store performance statistics associated with each investment. Current and potential customers can browse a web page that displays the weekly top ten recommended investments.

Before you use sp_dropwebtask, sp_makewebtask, and sp_runwebtask, consult your web browser or HTML documentation for more information.


Statements and Functions

ALTER TABLE Statement

APP_NAME Built-in Function

BEGIN DISTRIBUTED TRANSACTION Statement

CREATE INDEX Statement

CREATE SCHEMA Statement

CREATE TABLE Statement

DBCC DBREINDEX Statement

DBCC UPDATEUSAGE

DECLARE CURSOR Statement

DUMP Statement

EXECUTE Statement

FETCH Statement

GRANT Statement

INSERT Statement

ISDATE and ISNUMERIC Functions

LOAD Statement

RAISERROR Statement

REVOKE Statement

SELECT Statement

SET Statement

UPDATE Statement

User Function


ALTER TABLE Statement

ALTER TABLE Statement (version 6.5)

Disables a foreign key constraint and defers constraints during replication. Constraints can be deferred without being dropped.

For additional syntax information for the ALTER TABLE statement, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

ALTER TABLE [database.[owner.]]table_name
[WITH {CHECK | NOCHECK}]
{{CHECK | NOCHECK} CONSTRAINT {constraint_name | ALL}
|
[ADD
{col_name column_properties [column_constraints]
| [[, ] table_constraint]}
[, {next_col_name | next_table_constraint}]...]
|
[DROP CONSTRAINT]
constraint_name [, constraint_name2]...]}

where

table_name
Specifies which table to alter. You can specify local or global temporary tables, but FOREIGN KEY constraints are not enforced on temporary tables.
WITH {CHECK | NOCHECK}
Allows CHECK and FOREIGN KEY constraints to be added to a table without verifying existing data for constraint violations.
{NOCHECK | CHECK} CONSTRAINT
Turns the constraint checking on or off for foreign key and check constraints.
constraint_name | ALL
Specifies an individual constraint or all constraints to modify.

You can defer constraints for the table, including CHECK and FOREIGN KEY constraints, by using the ALL keyword. However, you cannot defer primary and unique key constraints; these constraints must be dropped.

Important Deferring constraints on a table does not defer constraints on other tables that refer to the altered tables. Updates to the table can still raise constraint violation errors.

ADD
Specifies that a column- or table-level constraint be added to an existing table.
col_name
Is a new column for the table. Column names must conform to the rules for identifiers and must be unique in the table.
column_properties =
datatype [NULL | IDENTITY[(seed, increment)]]
datatype
Specifies the datatype of the column. System or user-defined datatypes are acceptable. Columns added to a table must be defined as NULL.
IDENTITY(seed, increment)
Specifies values for existing rows based on the seed and increment parameters.
table_constraints=
Specifies up to one PRIMARY KEY constraint per table, one DEFAULT constraint per column, and any number of FOREIGN KEY, UNIQUE, or CHECK constraints on any column or columns. All can be entered within the same ALTER TABLE statement.

For a table-level constraint:

[CONSTRAINT constraint_name]
{ PRIMARY KEY [CLUSTERED | NONCLUSTERED]
(col_name [, col_name2[..., col_name16]])
| UNIQUE [CLUSTERED | NONCLUSTERED]
(col_name [, col_name2[..., col_name16]])
[WITH FILLFACTOR = fillfactor]
| FOREIGN KEY (col_name[, col_name2[..., col_name16]])
REFERENCES [owner.] ref_table (ref_col[, ref_col2[..., ref_col16]])
[NOT FOR REPLICATION]
| CHECK [NOT FOR REPLICATION] (expression)}

CONSTRAINT constraint_name
Specifies the constraint within the database. Constraint names must follow the rules for identifiers, except that the name cannot begin with a number sign (#). If this clause is omitted, a system-generated name is assigned to the constraint.
PRIMARY KEY | UNIQUE [CLUSTERED | NONCLUSTERED]
Specifies entity integrity for a given column or columns, which can be used as primary keys.
WITH FILLFACTOR
Specifies how full SQL Server makes each index page when creating an index with existing data.
SORTED_DATA | SORTED_DATA_REORG
Specify that the sort that is performed when a clustered index is created be eliminated. Both options verify that the data has been sorted by checking each index value to determine whether it is higher than the previous one. If any row fails this check, the ALTER TABLE statement terminates. You can either fix the data or rerun the ALTER TABLE statement without the SORTED_DATA option (the data will be sorted but not reorganized).

When the data satisfies the checks, the SORTED_DATA option will always be faster than the SORTED_DATA_REORG because the data is not copied and nonclustered indexes will not be rebuilt.

SORTED_DATA_REORG differs from SORTED_DATA because it physically reorganizes the data. This option is useful when a FILLFACTOR is specified to compact or expand the pages on which a table is stored. The effects of these options change slightly if used with the ON segment_name option.

Reorganizing the data is a good idea when a table becomes fragmented. To determine whether or not a table is contiguous, use the DBCC statement's SHOW_CONTIG. For details about what causes table fragmentation and recommended solutions, see the DBCC statement.

ON segment_name
Specifies the segment on which to create the index.
column_constraints=
Is up to one unique or foreign key constraint, one DEFAULT constraint, and any number of check constraints for each new or existing column.

For a column-level constraint:

[CONSTRAINT constraint_name]
{ PRIMARY KEY [CLUSTERED | NONCLUSTERED] [(col_name)]
| UNIQUE [CLUSTERED | NONCLUSTERED] [(col_name)]
[WITH FILLFACTOR = fillfactor]
| FOREIGN KEY [(col_name)]
REFERENCES [(ref_col)]
[NOT FOR REPLICATION]
| CHECK [NOT FOR REPLICATION] (expression)}

FOREIGN KEY [NOT FOR REPLICATION]
Specifies single column or multicolumn referential integrity. When defined, the number of columns and datatypes of each column specified in the FOREIGN KEY clause must identically match the columns in the REFERENCES clause. Values entered in this column or columns must exist in the table, and column(s) defined in the REFERENCES clause and the referenced table's columns must have a PRIMARY KEY or UNIQUE constraint defined on them. For column-level constraints, using the FOREIGN KEY and col_name identifiers are optional.
NOT FOR REPLICATION
Specifies that column-level constraints be suspended during replication.

Remarks

The ALTER TABLE NOCHECK statement allows replication to take place without permanently removing referential integrity constraints. Replication needs deferred constraints because constraints are sometimes violated by modifying a database with INSERT and DELETE statements. Use the ALTER TABLE statement to temporarily suspend constraints checking.

Two conditions cause an error to be returned: when ALL is specified and no constraints exist and when the specified constraint does not exist.

Once all data modifications are made, you can use the ALTER TABLE statement to reestablish constraint checking.

For more information about foreign keys or the ALTER TABLE statement, see the Microsoft SQL Server Transact-SQL Reference.

Examples

A. Add a Constraint

This example reviews adding a constraint. The foreign key constraint pub_id is added to the titles table.

ALTER TABLE titles
ADD
CONSTRAINT FK_pub_id FOREIGN KEY (pub_id)
REFERENCES publishers(pub_id)
B. Disable a Constraint

This example disables the ssn_constraint in the authors table.

ALTER TABLE authors
    NOCHECK CONSTRAINT ssn_constraint
C. Enable a Constraint

This example enables the ssn_constraint in the authors table.

ALTER TABLE authors
    CHECK CONSTRAINT ssn_constraint

Permission

Only the system administrator, the database owner, and the table owner can use the ALTER TABLE statement.


APP_NAME Built-in Function

APP_NAME Built-in Function (version 6.5)

Returns the program name for the current session. This function is useful for tracking which client applications are running processes in SQL Server or to limit access to specific applications.

Syntax

APP_NAME()

Remarks

This built-in function returns the program name for the current session if one has been set by the program.

Note The value returned must have a char or varchar datatype and can be a maximum length of 30 characters.

Example

This example checks that the client application that initiated this process is the correct one.

DECLARE @ThisApp varchar(35)
SELECT @ThisApp = APP_NAME()
IF @ThisApp <> 'Log3'
PRINT "This process was not started with the current
version of the Log program"


BEGIN DISTRIBUTED TRANSACTION Statement

BEGIN DISTRIBUTED TRANSACTION Statement (version 6.5)

Begins a distributed transaction.

Syntax

BEGIN DISTRIBUTED TRANsaction [transaction_name]

where

BEGIN DISTRIBUTED TRANSACTION
Specifies that a distributed transaction managed by Microsoft Distributed Transaction Coordinator (MS DTC) starts.
transaction_name
Specifies a user-defined transaction name is used to track the distributed transaction within MS DTC utilities.

Remarks

The BEGIN DISTRIBUTED TRANsaction statement is used instead of the BEGIN TRANsaction statement when a transaction is to be processed on one or more remote servers. The command alerts MS DTC to manage the transaction processing on the local and remote servers.

For example, suppose a company has several marketing departments in different physical locations. At each location a server is running a database. The company headquarter database records the company marketing budget and the amounts of money that subsidiary offices have to produce events and run their various departments. Each subsidiary's database allocates budget and costs. When the company's headquarters issues a check to the subsidiary, headquarters records the debit to its local database and also credits the database on the remote subsidiary's server. If the transaction fails, then the transaction must not be recorded on one server and not the other. The BEGIN DISTRIBUTED TRANsaction statement protects the transaction so that records of the budget cannot be lost between servers.

The BEGIN DISTRIBUTED TRANsaction statement requests that the MS DTC begin a new transaction and enlist the requester in that transaction.

The requester who issued the BEGIN DISTRIBUTED TRANsaction statement is the transaction originator, and a subsequent COMMIT TRANsaction statement causes the server to ask the MS DTC to start the commit sequence. The MS DTC transactions started by SQL Server cannot be exported to other servers because the client is not able to pass the transaction object from one server to another server.

To protect server-to-server remote procedure calls (RPCs) under MS DTC control without changing existing applications, a server configuration option is provided, remote proctrans in sp_configure, to implicitly create MS DTC transactions that cover server-to-server RPCs.

The session-level SET option, REMOTE_PROC_TRANSACTIONS, overrides the server default established by sp_configure. With this option in effect, an MS DTC transaction is created to cover an RPC if an MS DTC transaction does not exist. The server that creates the MS DTC transaction becomes the originating site for the transaction. Provided any nested transactions have been committed, the COMMIT TRANsaction initiates an MS DTC coordinated commit.

For more information about the distributed transaction environment and process, see the Guide to Microsoft Distributed Transaction Coordinator.

Example

This example updates the author's last name on the local and remote databases. The local and remote databases will both either commit or roll back the transaction.

BEGIN DISTRIBUTED TRANSACTION
UPDATE authors
    SET au_lname = 'McDonald' WHERE au_id = '409-56-7008'
EXECUTE remote.pubs.dbo.changeauth_lname '409-56-7008','McDonald'
COMMIT TRAN
GO


CREATE INDEX Statement

CREATE INDEX Statement (version 6.5)

Creates an index on a given table. The CREATE INDEX statement either changes the physical ordering of the table or provides the optimizer with a logical ordering of the table to increase efficiency for queries. When you create an index for the primary key, use the table- and column-level Primary Key constraint provided with the CREATE TABLE or ALTER TABLE statements.

For additional syntax information for the CREATE INDEX statement, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

CREATE [UNIQUE] [CLUSTERED | NONCLUSTERED] INDEX index_name
ON [[database.]owner.]table_name (column_name [, column_name]...)
[WITH
[PAD_INDEX, ]
[[,] FILLFACTOR = fillfactor]
[[,] IGNORE_DUP_KEY]
[[,] SORTED_DATA | SORTED_DATA_REORG]
[[,] IGNORE_DUP_ROW | ALLOW_DUP_ROW]]
[ON segment_name]

where

PAD_INDEX
Specifies that the FILLFACTOR setting should be applied to the index node pages as well as to the data pages in the index.

Note The number of items on an index page is never less than two, regardless of how low the value of FILLFACTOR.

Remarks

Indexes are made up of pages that form a branching structure known as a B-tree. The starting page records ranges of values within the table. Each range on the starting page branches to another page that contains a more detailed range of values in the table. In turn, these index pages branch out to more layers, which increase the number of pages in the layer and narrow the range of data on each page.

The branching index pages are called node pages. The final layer in the branching structure is called the leaf layer. In a unique, non-clustered index, the ranges on each leaf layer page point to a specific row of data in the table. In a clustered index, the leaf layer is the data pages because the data is stored in the physical order specified in the index.

Setting FILLFACTOR to 100 in SQL Server version 6.5 has the same behavior as it does in SQL Server 6.0. Index node pages are filled completely and have no space for additional items.

Example

This example creates an index on the author's identification number in the authors table. Without the PAD_INDEX option, SQL Server version 6.5 creates leaf pages that are 10 percent full, but the node pages are filled almost completely. With PAD_INDEX the node pages are also 10 percent full.

Note At least two entries appear on the index pages of unique clustered indexes when PAD_INDEX is not specified.

CREATE INDEX au_id_ind
    ON authors (au_id)
    WITH PAD_INDEX, FILLFACTOR=10


CREATE SCHEMA Statement

CREATE SCHEMA Statement (version 6.5)

Creates a schema that can be thought of as a conceptual container object, which is the definition of the database without any data in it.

Syntax

CREATE SCHEMA
[AUTHORIZATION owner]
[schema_element [schema_element2[...schema_elementn]]]

where

AUTHORIZATION owner
Specifies the ID of the schema object owner. This identifier must begin with a letter and can have as many as 30 characters. Hyphens are not supported.
schema_element = {table_definition | view_definition | grant_statement}
table_definition = CREATE TABLE statement
Creates a table within this defined schema. For more information about the CREATE TABLE statement, see the Microsoft SQL Server Transact-SQL Reference.
view_definition = CREATE VIEW statement
Creates a view for this schema. For more information about the CREATE VIEW statement, see the Microsoft SQL Server Transact-SQL Reference.
grant_statement = GRANT statement
Grants permissions to a user or group of users. For more information, see GRANT statement later in this document.

Remarks

Often database developers find it useful to keep a script or procedure, which creates the database schema for creating a copy of the database for testing or installation. Database administrators can set up a database and use the CREATE SCHEMA statement to set up all of the objects and permissions in a single batch.

CREATE SCHEMA provides a way to create database objects such as tables and views and to grant privileges on the objects, all within a single batch. The created objects do not need to appear in logical order. For example, a GRANT statement can grant permission to an object before the object itself has been created.

In another example, a CREATE VIEW statement can appear before the CREATE TABLE statement is created as long as all necessary objects are in the same CREATE SCHEMA statement. Also, the CREATE TABLE statement can declare foreign keys to tables that have not yet been created. Because objects are created at the same time, it is possible to create two tables that have mutually dependent foreign keys.

This statement complies with ANSI SQL standards. There are other ways to achieve the same results (DDL in transaction or add foreign key after creating both tables), and there are no restrictions to the objects created with CREATE SCHEMA other than that they are created under the current database user. In SQL Server, using the owner qualifier on database objects or on a separate database is usually preferable to using the CREATE SCHEMA statement.

ANSI-standards require that an AUTHORIZATION owner be included in the CREATE SCHEMA statement. Because a user must be signed on under a particular username in order to issue statements, the AUTHORIZATION owner is optional.

The tables and view can be specified in any order. For example, a view can appear before the table on which it is defined.

Note Errors from other statements in the CREATE SCHEMA statement, such as REVOKE or ALTER TABLE, will be ignored and not return error messages.

Examples

A. Grant Access to Objects Before Object Creation

This example shows permission being granted before the objects have been created.

CREATE SCHEMA AUTHORIZATION ross
GRANT SELECT on v1 TO public
CREATE VIEW v1(c1) AS SELECT c1 from t1
CREATE TABLE t1(c1 int)
B. Create Mutually Dependent Foreign Key Constraints

This example creates mutually dependent foreign key constraints. Other methods would take several steps to accomplish what is enabled by this CREATE SCHEMA example.

CREATE SCHEMA AUTHORIZATION ross
CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT REFERENCES t2(c1))
CREATE TABLE t2 (c1 INT PRIMARY KEY, c2 INT REFERENCES t1(c1))


CREATE TABLE Statement

CREATE TABLE Statement (version 6.5)

Defers constraints during replication by using the NOT FOR REPLICATION clause. The current user must have REFERENCES permission to the table(s) to which any foreign key constraints refer.

For additional syntax information for the CREATE TABLE statement, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

CREATE TABLE table_name
(
{col_name column_properties[constraint [constraint [...constraint]]]
| [[, ] constraint]}
[[, ] {next_col_name | next_constraint}
)
[ON segment_name]

where

table_name
Is the name of the new table.
col_name
Is the name of a column in the table.
column_properties
Specifies the datatype, null values, or identity values for the column.

Note Using the IDENTITY column property implies a value of NOT NULL. Because IDENTITY requires that a column have a value, NOT NULL is superfluous.

constraint
Specifies a table-or column-level constraint. The NOT FOR REPLICATION clause suspends column-level, foreign key, and check constraints during replication.

The REFERENCES permission must be placed on tables where non-table owners must create foreign keys.

Note Table-level default constraints are not supported within the CREATE TABLE statement.

Note The datatypes of the primary key and the foreign must match exactly.

ON segment_name
If specified with a PRIMARY KEY or UNIQUE constraint, creates only the index on the named segment.

Remarks

REFERENCES permissions are not checked during data manipulation language (DML) operations.

For example, suppose table country_table already exists and you are creating table city_table with a FOREIGN KEY constraint to the country_table table. You must have REFERENCES permission to country_table in order to create the FOREIGN KEY constraint.

Users who need access only to city_table must only have SELECT permission to city_table; they do not need access to country_table.

For information about disabling the REFERENCES permission, see Trace Flags .

Example

This example defines a table with a foreign key constraint called p1_constraint that can be deferred during replication.

CREATE TABLE employee
(
    emp_id    integer
        CONSTRAINT p1_constraint PRIMARY KEY NONCLUSTERED,
    fname         CHAR(20) NOT NULL,
    minitial        CHAR(1) NULL,
    lname        VARCHAR(30) NOT NULL,
    job_id         SMALLINT NOT NULL
        DEFAULT 1
        REFERENCES jobs(job_id) NOT FOR REPLICATION
)

Permission

You must have REFERENCES permission to create a FOREIGN KEY constraint to a table you do not own.


DECLARE CURSOR Statement

DECLARE CURSOR Statement (version 6.5)

Allows individual row operations to be performed on a given results set. There are several cursor improvements in SQL Server 6.5:

  • Dynamic cursors allow updates on underlying tables without requiring a unique index on the table.
  • Forward-only cursors are significantly faster on large tables.
  • Cursors automatically close upon COMMIT when SET CURSOR_CLOSE_ON_COMMIT option is set to ON.
  • Forward-only cursors are dynamic by default, which allows faster cursor opening and also allows the results set to display updates made to the underlying tables.
  • The results sets from read-only dynamic cursors no longer use temporary tables in tempdb.

DECLARE CURSOR cannot be used on a table that was created in the same batch or stored procedure.

If you need to use these statements in the same batch or stored procedure, you must put the DECLARE CURSOR statement inside a dynamic EXECUTE. Using a dynamic EXECUTE enables the cursor to benefit from any indexes on the temporary table, which allows a sensitive scrollable cursor.

An exception to this is when the created table is a temporary table (indicated by a leading number sign (#)). You can create a temporary table and declare a cursor on it in the same batch or stored procedure. However, the cursor will not recognize any of the table's indexes. Scroll cursors and any cursor with an ORDER BY statement will be created as INSENSITIVE and READ ONLY. Forward-only cursors (those that do not require an interim work table) will be dynamic and can be updated.

Note If the definition of the forward-only cursor contains interim work tables for outer joins or aggregate functions, then the forward-only cursor does not default to a dynamic cursor.

Example

This example illustrates the dynamic behavior of a forward-only cursor. There are two processes: User One declares and opens a cursor, then User Two makes a change to the underlying table, which affects the first row of the cursor. Finally, the update is displayed when User One fetches the first row.

These are the connections that illustrate the dynamic behavior of a forward-only cursor.

User One User Two
DECLARE forwardcursor CURSOR FOR
SELECT au_lname FROM authors
OPEN forwardcursor

UPDATE authors
SET au_lname = 'Whittacker'
WHERE au_lname = 'White'

FETCH NEXT FROM forwardcursor

This is the results set for User One:

--------------------------------
au_lname
--------------------------------
Whittacker

(1 row(s) affected)


DBCC DBREINDEX Statement

DBCC DBREINDEX Statement (version 6.5)

Rebuilds one or more indexes for a table.

For additional syntax information for the DBCC statement, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

DBCC DBREINDEX (['database.owner.table_name' [, index_name
[, fillfactor [, {SORTED_DATA | SORTED_DATA_REORG}]]]])
[WITH NOINFOMSGS]

where

database.owner.table_name
Specifies the table for which to rebuild the index. If you specify the database name or owner the entire name must be enclosed in single quotation marks. If only the table name is specified then the quotes are optional.
index_name
Specifies the name of the index to rebuild. Specifying ' ' or no index_name rebuilds all indexes.
fillfactor
Specifies how full each index page is to be created. If 0 (zero) is entered for this parameter then the original fillfactor is used.
SORTED_DATA | SORTED_DATA_REORG
Specify that the sort performed when a clustered index is created can be eliminated because the data is sorted. Both options verify that the data has been sorted by checking each index value to determine whether it is a higher value than the previous one.

If any row fails this check, the DBCC DBREINDEX statement terminates. You can either fix the data or rerun the DBCC DBREINDEX statement without the SORTED_DATA or SORTED_DATA_REORG options.

When the data satisfies the checks, the SORTED_DATA option will always be faster than the SORTED_DATA_REORG option because the data is not copied and nonclustered indexes are not rebuilt.

SORTED_DATA_REORG differs from SORTED_DATA because it physically reorganizes the data. This option is useful when a FILLFACTOR is specified to compact or expand the pages on which a table is stored. The effects of these options change slightly if used with the ON segment_name option.

Reorganizing the data is a good idea when a table becomes fragmented. To determine whether or not a table is fragmented, use the DBCC SHOWCONTIG statement.

Important If you specify one of the optional parameters (ind_name, fillfactor, or SORTED_DATA), you must specify all the parameters preceding it in the parameter list.

WITH NO_INFOMSGS
Prevents the printing of informational messages (severity 1 through 10).

Remarks

The DBCC DBREINDEX statement rebuilds an index for a table or all indexes defined for a table. By allowing an index to be rebuilt dynamically, indexes that enforce PRIMARY KEY or UNIQUE constraints can be rebuilt without having to drop and re-create constraints. This means that an index can be rebuilt without having to know the table's structure or constraints. This could occur after a bulk copy of data into the table.

If the index is a clustered index, all nonclustered indexes will also be reindexed with the same supplied fillfactor. This statement is completely recoverable and atomic for all of the indexes being rebuilt.

The DBCC DBREINDEX statement is not supported for system tables.

Examples

A. Rebuild an Index

This example rebuilds the au_nmind index with a fillfactor of 80 on the authors table in the pubs database.

DBCC DBREINDEX ('pubs.dbo.authors', UPKCL_auidind, 80)
B. Rebuild All Indexes

This example rebuilds all indexes on a table by using the existing fillfactor values and physically reorganizes the data.

DBCC DBREINDEX (authors, '', 0, SORTED_DATA_REORG)

Permission

Only the system administrator, database owner, and table owner can use this statement.


DBCC PROCCACHE Statement

Used by SQL Performance Monitor to interrogate the procedure cache.

For additional syntax information for the DBCC command, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

DBCC PROCCACHE

The following values are returned:

num proc buffs | The number of possible procedures that could be in cache.
num proc buffs used | The number of slots that have a procedure in them.
num proc buffs active | The number of slots that have a procedure in them and are executing.
proc cache size | The total size of the procedure cache.
proc cache used | The amount of procedure cache containing procedures.
proc cache active | The amount of procedure cache containing procedures that are executing.

Note The size of the procedure cache can grow and shrink as other operations, such as cursors and the query parser, start.


DBCC ROWLOCK

Enables Insert Row Locking (IRL) operation on tables dynamically.

For additional syntax information for the DBCC command, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

DBCC ROWLOCK (dbid, tableid, set)

where

dbid
Specifies a unique identifier for the database. This value is stored in the sysdatabases system table in the master database.
tableid
Specifies a unique identifier for the table within the database. This value is stored in the sysobjects table within each database.
set
Specifies to enable Insert Row Locking (IRL) when the value of set is 1 and to disable it when the value is 0.


DBCC UPDATEUSAGE Statement

DBCC UPDATEUSAGE Statement (version 6.5)

Reports and corrects inaccuracies in the counts contained in the sysindexes table and includes the new WITH COUNT_ROWS syntax.

For additional syntax information for the DBCC statement, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

DBCC UPDATEUSAGE ({0 | database_name} [, table_name [, index_id]])
[WITH COUNT_ROWS]

where

UPDATEUSAGE ({0 | database_name} [, table_name [, index_id]])
Reports and corrects inaccuracies in the sysindexes table that can result in incorrect space usage reports by the sp_spaceused system stored procedure.

This statement corrects the used, reserved, and dpages columns of the sysindexes table for any clustered indexes on objects of the type U (user-defined table) or S (system table). Size information is not maintained for nonclustered indexes. You can use this statement to synchronize space usage counters in sysindexes, which will result in accurate usage information being returned. When you use 0 instead of the database_name, the update is performed in the current database.

When processing, UPDATEUSAGE acquires a shared table lock on the table being processed, so updates to the sysindexes row for syslogs can be performed only if the database is in single-user mode and the syslogs table is specified. This prevents any logging during the update and ensures accurate changes. All other changes to sysindexes are fully logged.

Note The stored procedure sp_spaceused used with the @updateusage qualifier provides the same functionality as DBCC UPDATEUSAGE. The sp_spaceused stored procedure takes longer to execute. Using this option on large tables may take longer to complete because every row in the table is counted.

WITH COUNT_ROWS
Specifies that the rows column of sysindexes is updated with the current count of the number of rows in the table. This only applies to sysindexes rows that have an index_id of 0 or 1. This option can affect performance on large tables.

Remarks

When the DBCC UPDATEUSAGE statement is executed with the WITH_COUNT_ROWS clause, inaccuracies are reported and corrected in the counts contained in the sysindexes table. The counts for rows, used, reserved, and dpages columns of the sysindexes table for any clustered indexes on objects of the type U (user-defined) or S (system table) are updated.

If there are inaccuracies in sysindexes, DBCC UPDATEUSAGE returns data that shows what rows and columns are being updated in sysindexes. Otherwise, no data is returned.

Example

This example corrects all of the page and row counts in the sysindexes table for all the indexes on the authors table.

DBCC UPDATEUSAGE (pubs, authors) WITH COUNT_ROWS


DISK INIT Statement

SQL Server 6.5 supports the use of raw partitions for creating devices with the DISK INIT statement. Raw partitions are disk partitions that have not been formatted with a Windows NT file system, such as FAT and NTFS. In some cases, using devices created on raw partitions can yield a slight performance gain over NTFS or FAT. However, for most installations the preferred method is to use devices on NTFS or FAT partitions.

Syntax

DISK INIT
NAME = 'logical_name',
PHYSNAME = 'physical_name',
VDEVNO = virtual_device_number,
SIZE = number_of_2K_block
[, VSTART = virtual_address]

where

NAME
Is the logical name of the database device.
PHYSNAME
Is the drive letter, path, and filename of the database device. To create a device on a raw partition, use only the partition drive letter for the physname parameter in the DISK INIT statement.
VDEVNO
Is the virtual device number.
SIZE
Specifies the size of the database in 2K blocks.
VSTART
Is the starting virtual address.

Example

This example creates a 200 MB device named Inventory_Dev on the raw partition corresponding to the G: drive.

DISK INIT
NAME = 'Inventory_Dev',
PHYSNAME = 'G:',
VDEVNO = 16,
SIZE = 102400

Remarks

There are several limitations to consider when using raw partitions:

  • Only one device can be created on each raw partition. The logical partition must be configured as a single device, because there is no file system on the raw partition.
  • Normal file system operations such as copy, move, and delete cannot be used with raw partitions.
  • Devices located on raw partitions cannot be backed up using the Windows NT Backup utility; however, databases or transaction logs stored on raw partitions can still be backed up using the Transact-SQL DUMP statement or through SQL Enterprise Manager.
  • File system services such as bad block replacement are not available with raw partitions.


DUMP Statement

DUMP Statement (version 6.5)

Allows an individual table to be backed up.

For additional syntax information for the DUMP statement, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

Dumping a table:

DUMP TABLE [[database.]owner.]table_name
TO dump_device [, dump_device2 [..., dump_device32]]
[WITH options]

where

dump_device =
{dump_device_name | @dump_device_namevar}
| {DISK | TAPE | FLOPPY | PIPE} =
{'temp_dump_device' | @temp_dump_device_var}
[VOLUME = {volid | @volid_var}]
options =
[[, ] {UNLOAD | NOUNLOAD}]
[[, ] {INIT | NOINIT}]
[[, ] {SKIP | NOSKIP}]
[[, ] {EXPIREDATE = {date | @date_var}
| RETAINDAYS = {days | @days_var}}]
[[, ] STATS [= percentage]]
TABLE
Specifies that a table is to be backed up.
database
Specifies the database that contains the table being dumped.
owner
Specifies the owner of the table to dump.
table_name
Specifies the table to dump.
STATS = percentage
Specifies the percentage of pages backed up in increments specified at the time of the dump. If the percentage is not specified, statistics are shown for each 10 percent of the dump. This option is supported for DUMP DATABASE and DUMP TABLE. If you do not specify the STATS option then no statistics are shown.

Remarks

This statement backs up a single database table. By backing up specific tables, you can conserve system resources, save time by backing up only tables that have changed, and target high-volume tables for regular backups.

When you anticipate loading individual tables, use DUMP TABLE. DUMP TABLE locks the table and provides an exact snapshot of the table data. When tables have FOREIGN KEY constraints, you can cause the database to be logically inconsistent if conflicting transactions have occurred since the time of the backup.

Important If data manipulation transactions were occurring on the table when the dump was performed, the data in the table may be logically inconsistent because outstanding transactions would not be reapplied.

Load a full table from a database dump only in disaster recovery situations.

A striped dump is created when more than one dump device is specified. Dumping to multiple devices can improve the performance of the dump because pages can be written to multiple dump devices at the same time. For DISK and FLOPPY devices, you must load from the same number of devices as you dumped to . For TAPE and PIPE devices, you can load from fewer devices than were dumped to. For example, if a database is dumped to four tape drives, you can load from one tape drive. The tapes can be loaded in any order, and a message will prompt you to change tapes.

For compatibility, database dumps from SQL Server 6.0 can be loaded into SQL Server 6.5 when the same sort order is running on both SQL Servers. The dump must be a full database dump and must occur when there is no update activity in the database. For this reason, it is recommended that the dump occur when SQL Server is started in single-user or read-only mode. After the database is successfully loaded, the database is upgraded.

The trace flag 3002 causes a SQL Server 6.5 to dump databases that can be loaded into SQL Server 6.0, Service Pack 3. It is recommended that the SQL Server 6.5 database be started in single-user or read-only mode before making the dump. A SQL Server 6.5 master database cannot be restored to a SQL Server 6.0 server.

A disk backup uses WITH INIT. A tape backup uses WITH NOSKIP and WITH NOUNLOAD, but not WITH INIT.

For more information about the DUMP statement, see the Microsoft SQL Server Transact-SQL Reference.

Example

This example creates the disk_dev1 dump device and then dumps the employees table to the disk_dev1 disk.

EXECUTE sp_addumpdevice 'disk','disk_dev1','c:\MSsql\dumps\diskdev1.dmp'
DUMP TABLE employees TO disk_dev1 WITH STATS

Permission

SELECT permission is required to dump a table.


EXECUTE Statement

EXECUTE Statement (version 6.5)

Specifies the keyword DEFAULT in place of a parameter.

For additional syntax information for the EXECUTE statement, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

EXECute procedure_name [parameter [, parameter2 [..., parameterN ]]]

where

procedure_name
Specifies the name of the procedure to call.
@parameter=
parameter_value
| @parameter_name = parameter_value
| @parameter_name = DEFAULT
| DEFAULT
@parameter_value
Is the value that is supplied to the procedure.
parameter_name
Is the name of the parameter.
DEFAULT
Supplies the default value of the parameter as defined in the procedure.

Remarks

The DEFAULT keyword allows you to generically specify that a parameter's default value be used.

When the procedure expects a value for a parameter that does not have a defined default and either a parameter is missing or the DEFAULT keyword is specified, an error occurs.

Example

This example creates a stored procedure with default values for the first and third parameters. When the procedure is run, these defaults are inserted for the first and third parameters if no value is passed in the call or if the default is specified. Note the various ways the DEFAULT keyword can be used.

--- create the stored procedure ---
CREATE PROC proc_calculate_taxes (@p1 SMALLINT = 42, @p2 CHAR(1), @p3 VARCHAR(8) = 'CAR')

The proc_calculate_taxes stored procedure can be executed in many combinations:

EXECUTE proc_calculate_taxes @p2 = 'A'
EXECUTE proc_calculate_taxes 69, 'B'
EXECUTE proc_calculate_taxes 69, 'C', 'House'
EXECUTE proc_calculate_taxes @p1 = DEFAULT, @p2 = 'D'
EXECUTE proc_calculate_taxes DEFAULT, @p3 = 'Local', @p2 = 'E'
EXECUTE proc_calculate_taxes 69, 'F', @p3 = DEFAULT
EXECUTE proc_calculate_taxes 95, 'G', DEFAULT
EXECUTE proc_calculate_taxes DEFAULT, 'H', DEFAULT
EXECUTE proc_calculate_taxes DEFAULT, 'I', @p3 = DEFAULT


FETCH Statement

FETCH Statement (version 6.5)

Accepts variables and procedure parameters for the row number arguments to the ABSOLUTE and RELATIVE keywords.

For additional syntax information for the FETCH statement, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

FETCH [[NEXT | PRIOR | FIRST | LAST
| ABSOLUTE {n | @nvar} | RELATIVE {n | @nvar}]
FROM] cursor_name
[INTO @variable_name1, @variable_name2, ...]

where

NEXT
Specifies that the first row of the results set is returned if this is the first fetch against the cursor; otherwise, it moves the cursor one row forward within the results set. NEXT is the primary method to move through the results set; it is also the default cursor fetch action.
PRIOR
Specifies that the previous row within the results set is returned.
FIRST
Specifies that the cursor is moved to the first row within the results set and returns the first row.
LAST
Specifies that the cursor is moved to the last row within the results set and returns the last row.
ABSOLUTE {n | @nvar}
Specifies that the nth row within the results set is returned. If n is a negative value, the returned row will be the nth row counting backward from the last row of the results set. Only the smallint, tinyint and int datatypes are supported for n.
RELATIVE {n | @nvar}
Specifies that the nth row after the currently fetched row is returned. If n is a negative value, the returned row will be the nth row counting backward from the relative position of the cursor. Only the smallint, tinyint and int datatypes are supported for n.
FROM cursor_name
Specifies the cursor from which the fetch should be made. Multiple cursors are allowed within any session provided that each has a unique name.
INTO @variable_name1, @variable_name2, ...
Specifies a variable in which to place data that is returned by a fetch. Each of the variable datatypes must match the datatype returned by the fetch. Errors occur when the datatypes are incompatible.

Remarks

This statement retrieves a specific row from the cursor. Variables can be used for row number arguments. For example, the FETCH ABSOLUTE statement can be used with a variable to find a particular row within the cursor. For example, the row this statement retrieves depends upon the value of the @row_num variable:

FETCH ABSOLUTE @row_num FROM customer_cursor

By using variables for row number argument names, the program can provide the value at run time. This is useful because the row number value can be dependent upon run-time data that is available only at run time. This offers greater flexibility for programming the FETCH statement.

Example

This example calculates the median number of personnel in the various departments of a specific company. The company name is specified in the procedure. To calculate the median number of employees in a specific department, follow these steps:

  1. For the company specified, order the departments by population into a department list.
  2. Determine if the number of departments is odd or even.
    • If the number of departments is even, the median value is derived from the two departments' population values that appear on either side of the middle of the department list. Add the two population values together and divide by two.
    • If the number of departments is odd, the median value is derived from the population value that appears in the middle of the company list.

For this example, assume that a database exists that holds all departments' populations for all companies in the Algodata Infosystems conglomerate.

/*Create procedure*/
CREATE PROCEDURE find_median_population @company varchar(25)
AS
DECLARE @num_departments int
DECLARE @value1 int
DECLARE @value2 int
DECLARE @middle int

/* Declare cursor on population table */
DECLARE population_cursor SCROLL CURSOR
FOR select population
FROM population_table
WHERE company = @company
ORDER BY population

OPEN population_cursor

SELECT @num_departments=@@cursor_rows

SELECT @middle=@num_departments /2

IF (@num_departments % 2)=0
BEGIN
FETCH ABSOLUTE @middle FROM population_cursor INTO @value1
FETCH NEXT FROM population_cursor INTO @value2
SELECT "Company population median for " + @company + " is: " + CONVERT(char(10), (@value1 + @value2) / 2)
END
ELSE
BEGIN
SELECT @middle = @middle + 1
FETCH ABSOLUTE @middle FROM population_cursor INTO @value1
SELECT "Company population median for " + @company + " is: " +     CONVERT(char(10), @value1)
END
CLOSE population_cursor
DEALLOCATE population_cursor

The find_median_population stored procedure can be executed in these ways:

EXECUTE find_median_population 'New Moon Books'
EXECUTE find_median_population 'Five Lakes Publishing'
EXECUTE find_median_population 'Scootney Books'


GRANT Statement

GRANT Statement (version 6.5)

Provides ANSI-compliant syntax for column-level grants and the ability to confer grant permissions to others.

For additional syntax information for the GRANT statement, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

To grant permission to access database objects:

GRANT {ALL [PRIVILEGES][column_list] | permission_list [column_list]}
ON {table_name [(column_list)]
| view_name [(column_list)]
| stored_procedure_name}
TO {PUBLIC | name_list }
[WITH GRANT OPTION]

To grant permission to execute specific SQL statements in the current database:

GRANT {ALL | statement_list}
TO { PUBLIC | name_list}

where

ALL
When used to grant permission to access database objects, specifies that all permissions possessed by the current user (grantor) will be granted to the grantee. When used to assign statement permissions, only the system administrator can use ALL, because only the system administrator can grant or revoke CREATE DATABASE permission.
permission_list
Is the list of permissions granted. When permissions are granted on a column, the permission list can include only SELECT, REFERENCES, and/or UPDATE.

When permissions are granted on a table or view, the permission list can include: SELECT, INSERT, DELETE, and/or UPDATE. Permissions on a table can also include REFERENCES. To grant REFERENCES permission, you must specify REFERENCES because it is not automatically included in the SELECT permission.

When permissions are granted on stored procedures, the permission list can include only EXECUTE.

table_name
Is a table in the current database. Only one table can be listed for each GRANT statement.
column_list
Is a list of columns names delimited by commas, to which the permissions apply. If columns are specified, only SELECT and UPDATE permissions can be granted.
view_name
Is a view in the current database. Only one view can be listed for each GRANT statement.
stored_procedure_name
Is the name of a stored procedure or extended stored procedure in the current database. Only one stored procedure can be listed for each GRANT statement.
PUBLIC
Is all users, including those who are members of a user-defined group.
name_list
Is a list of user names and/or group names delimited by commas. These names are stored in the sysusers table of the database.
WITH GRANT OPTION
Extends the ability to grant the specified permission or statement to the grantee.

Note Users can neither grant the WITH GRANT OPTION permission to a group nor use it with statement permissions.

statement_list
Is a list of statements granted. The statement list can include: CREATE DATABASE, CREATE DEFAULT, CREATE PROCEDURE, CREATE RULE, CREATE TABLE, CREATE VIEW, DUMP DATABASE, and DUMP TRANSACTION.

Remarks

You can confer, along with a permission, the ability to confer that permission to another user. For example, suppose the owner of an object grants Bob INSERT permission and trusts Bob to determine who else in his work group should get INSERT permission. By using WITH GRANT OPTION, the owner of the object gives Bob permission to grant INSERT permission to others.

Granting a permission to a user who has already received the WITH GRANT OPTION permission through a group or public grant will be recorded in the sysprotects table. If the permission is revoked for the group, the user will still retain the permission.

Important The WITH GRANT OPTION should be managed carefully. Security can be compromised when the option is used improperly.

Users may need SELECT permission in addition to UPDATE permission to update a column or view. SELECT permissions are required only when there are column names after SET or WHERE in the UPDATE statement.

For more information about the GRANT statement, see the Microsoft SQL Server Transact-SQL Reference.

For more information about the sysprotects table, see sysprotects System Table.

Examples

A. Use New ANSI Syntax for Column-level GRANT

This example grants SELECT permissions on population_table and UPDATE permissions on the census_org column of the population_table to the admin_group.

Users in the admin_group can view the entire population_table and can change the values in the census_org column.

GRANT SELECT, UPDATE(census_org) ON population_table TO admin_group
B. Use WITH GRANT OPTION

In this example, the object owner grants UPDATE permission to user zachary on the city_statistics table.

User zachary then gives SELECT permission to user matthew. Note that because user matthew does not have the WITH GRANT OPTION, he cannot confer this permission to anyone else.

GRANT SELECT ON city_statistics TO zachary WITH GRANT OPTION
GRANT ALL ON city_statistics TO matthew


INSERT Statement

INSERT Statement (version 6.5)

Populates a local table with results returned from a procedure and makes it easier to import data from remote systems to the local server.

For additional syntax information for the INSERT statement, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

INSERT [INTO]
{table_name | view_name} [(column_list)]
EXECute { procedure_name | @procedure_name_var}
 [[@parameter_name=] {value | @variable [OUTPUT] | DEFAULT}
[, [@parameter_name =] {value | @variable [OUTPUT] | DEFAULT}]...]

where

table_name
Is the existing table in the local database to populate.
column_list
Is a list of one or more columns in which to insert data. The columns can be listed in any order, but the incoming data must be in the same order as the listed columns. The column_list must be enclosed in parentheses and delimited by commas.

The column_list is necessary only when some, but not all, columns in the table are to receive data. You can leave out items in the column_list as long as the omitted columns permit null values or the columns are associated with a default.

If column_list is not specified, all columns in the receiving table (in CREATE TABLE order) are assumed to be included.

procedure_name = {[[[server.]database.]owner.]procedure_name[;number] }
Is a user-defined procedure name.
procedure_name
Is a stored procedure. You can execute a local procedure, or you can execute a procedure that has been created in another database if you are its owner or have permission to execute it in that database. You can execute a procedure on another SQL Server if you have permission to use that server (remote access) and to execute the procedure in that database. If you specify a server name but do not specify a database name, SQL Server looks for the procedure in your default database.
;number
Is an optional integer used to differentiate procedures created by using the same name.
@procedure_name_var
Is the name of a locally defined variable that represents a stored procedure name.
@parameter_name
Specifies the parameter for a procedure, as defined in the CREATE PROCEDURE statement. Parameter names must be preceded by the "at" symbol (@). When used with the @parameter_name = value form, parameter names and constants need not be supplied in the order defined in CREATE PROCEDURE statement. However, if the @parameter_name = value form is used for any parameter, it must be used for all subsequent parameters.
value
Is the value of the parameter to the procedure. If you do not use a parameter name, parameter values must be supplied in the order defined in the CREATE PROCEDURE statement.
@variable
Specifies the variable that stores a parameter value.
OUTPUT
Indicates that the stored procedure returns a parameter. The matching parameter in the stored procedure must also have been created with the keyword OUTPUT.
DEFAULT
Specifies that the default value is used.

Remarks

This statement allows you to run procedures on local or remote systems and store the returned information in a local table. The procedures can be system procedures, user-defined procedures, or extended procedures.

Specify the system and procedure you want to run by specifying the procedure name. To specify a remote system, the procedure name will begin with the server name followed by the database name, the owner of the procedure, and the procedure name. Each element of the procedure name is followed by a period except for the procedure name itself. For example, the remote procedure get_latest_sales owned by jake on the accounts server would look like this:

accounts.acct_db.jake.get_latest_sales

The local table is loaded with data returned from SELECT statements. The local table must already exist. Data returned from the PRINT statement, RAISERROR statement, FETCH statement, or other output is not stored in the table.

A procedure that returns multiple results sets appends the data to the table.

Data returned from the SELECT statement must conform to the datatypes in the existing local table's columns. For example, inserting varchar data into a tinyint data column is not permitted.

All INSERT statement rules apply to this operation. That is, table constraints, rules and triggers, and implicit datatype conversion rules are all enforced during table population. For more information about INSERT statement rules, see INSERT Statement.

For more information about writing procedures, see CREATE PROCEDURE Statement.

Errors are reported if there is a datatype mismatch between local table input columns and values returned from the procedure. Also, if the number of columns does not match the number of items returned in a row, an error is returned.

For more information about executing a procedure, see EXECUTE Statement in this document and in the Microsoft SQL Server Transact-SQL Reference.

Examples

A. Populate Local Tables with Remote Database Information

This example retrieves information from a remote database for administration purposes. The human_resource.hr.dbo.fetch_employee_data and marketing.mis.dbo.fetch_sales_figures procedures pull data from remote sites into local tables.

INSERT INTO employee_info
EXECUTE human_resource.hr.dbo.fetch_employee_data
INSERT INTO sales_info
    EXECUTE marketing.mis.dbo.fetch_sales_figures
B. Assign the Current Value of the SET Option to a Variable

This example shows how to use the new INSERT EXECUTE feature to enable Transact-SQL code to assign the current value of a SET option to a variable.

SET NOCOUNT on
CREATE TABLE #tb_setopts
(SetOptName varchar(35) NOT NULL ,SetOptValue varchar(35) null)
INSERT INTO #tb_setopts (SetOptName,SetOptValue)
EXEC('dbcc useroptions')
DECLARE @CurrentValue varchar(35)
SELECT @CurrentValue=case min(SetOptValue) WHEN 'SET'
THEN 'on' else 'off' END
FROM #tb_setopts WHERE SetOptName='ansi_padding'
IF @CurrentValue='on'
RAISERROR('The SET opt ''ansi_padding'' is''on''.' ,1,1)
ELSE
RAISERROR('The SET opt ''ansi_padding'' is''off''.',1,1)
IF object_id('tempdb..#tb_setopts') IS NOT NULL
DROP TABLE #tb_setopts

/********  Actual output....
DBCC execution completed. If DBCC printed error messages, see your
System Administrator.
The SET opt 'ansi_padding' is 'off'.
********/


The ISDATE and ISNUMERIC Functions

The ISDATE and ISNUMERIC Functions (version 6.5)

ISDATE Function
Checks a variable or column with varchar datatype for valid date format. The function returns 1 when the variable or column contains a valid date, otherwise it returns 0.

In this example, the value 1 is returned:

SELECT ISNUMERIC(zipcode) FROM address
ISNUMERIC Function
Checks a variable or column with varchar datatype for valid numeric format. The function returns 1 when the variable or column contains a valid numeric value, otherwise it returns 0.

In this example, the value 1 is returned:

declare @datestring varchar(8)
SELECT @datestring ="12/21/95"
SELECT ISDATE(@datestring)

The following table is a summary of the return values for the ISDATE and ISNUMERIC functions for a selection of examples.

Column (varchar) value | ISDATE return value | ISNUMERIC return value
NULL | 0 | 0
abc | 0 | 0
100 | 0 | 1
100 | 0 | 1
100 a | 0 | 0
100.00 | 0 | 1
.01 | 0 | 1
-100.1234e-123 | 0 | 1
.231e90 | 0 | 1
$1000 | 0 | 1
$100 | 0 | 1
$100 a | 0 | 0
$100.12345 | 0 | 1
-$100.12345 | 0 | 1
$-1000.123 | 0 | 1
as100 | 0 | 0
1a00 | 0 | 0
1995-10-1 | 1 | 0
1/20/95 | 1 | 0
1995-10-1 12:00pm | 1 | 0
Feb 7 1995 11:00pm | 1 | 0
1995-10-1 | 1 | 0
13/43/3425 | 0 | 0
1995-10-1a | 0 | 0
1/23/95 | 1 | 0


LOAD Statement

LOAD Statement (version 6.5)

Loads a backup copy of one of the following:

  • User database and its transaction log (LOAD DATABASE)
  • Transaction log (LOAD TRANSACTION)
  • Table (LOAD TABLE)
  • Header information about the dump (LOAD HEADERONLY)

For additional syntax information for the LOAD statement, see the Microsoft SQL Server Transact-SQL Reference.

The LOAD TRANSACTION statement supports the STOPAT option, which stops a roll forward at a specified time.

The LOAD TABLE statement loads a backup copy of a table into a database.

The LOAD HEADERONLY statement returns additional columns.

Syntax

To load a table:

LOAD TABLE [[database.]owner.]table_name
FROM dump_device [, dump_device2 [..., dump_device32]]
[WITH options]

To load a transaction log:

LOAD TRANSACTION {dbname | @dbname_var}
FROM dump_device [, dumpdevice2 [..., dumpdevice32]]
[WITH options]

To load header information:

LOAD HEADERONLY
FROM dump_device

where

dump_device =
{dump_device_name | @dump_device_name_var}
|{DISK | TAPE | FLOPPY | PIPE} =
{'temp_dump_device' | @temp_dump_device_var}
[VOLUME = {volid | @volid_var}]
options =
[[, ] {UNLOAD | NOUNLOAD}]
[[, ] {SKIP | NOSKIP}]
[[, ] FILE = fileno]
[[, ] STOPAT = {date_time | @date_time_var}]
[[, ] SOURCE = source_name]
[[, ] APPEND]
[[, ] STATS [= percentage]]
TABLE
Specifies that a table is to be restored.
TRANSACTION
Specifies that only the transaction log is to be applied to this database. Transaction logs must be applied in sequential order. SQL Server checks the time stamps on the dumped transactions to ensure that the transactions are loaded into the correct database and in the correct sequence.
table_name
Is the name of table to be restored.
dbname | @dbname_var
Is the database from which the transaction log or complete database is being loaded. The database name can be specified as a string, char, or varchar variable.
dump_device_name | @dump_device_name_var
Is the logical name of the dump device as created by the sp_addumpdevice stored procedure. The dump device name can be specified as a string, char or varchar variable.
DISK | TAPE | FLOPPY | PIPE =
'temp_dump_device' | @temp_dump_device_var
Specifies the backup device media and is the temporary dump device from which to load the backup. These devices must exist when the load occurs; they do not have entries in sysdevices. The device types of DISK, TAPE, and FLOPPY should be specified with the complete path and filename of the device. A device type of PIPE should specify the named pipe that will be used by the client application. If specified as a variable (@temp_dump_device_var), the device name can be specified as a string or as a char or varchar variable. If you are using either a network server with a Universal Naming Convention (UNC) name or a redirected drive letter, specify a device type of DISK.

Important When specifying a striped dump, you can use both logical device names (or variables) and temporary device names (or variables). PIPE devices have been added to allow third-party vendors a flexible and powerful way to connect their own software. For typical Transact-SQL use, the PIPE device is not used.

VOLUME = volid | @volid_var
Specifies the volume ID of the backup device, a 6-byte character string. If dumping to a new tape, this value is the name of the ANSI VOL1 label. For SQL Server, the default is SQL001. For subsequent dumps, this value is used to validate the volume name of the dump device. If specified as a variable (@volid_var), the volume name can be specified as a string or as a char or varchar variable. Explicitly specifying the volume ID is not recommended.
UNLOAD
Specifies that the tape be automatically rewound and unloaded when the LOAD is finished. UNLOAD is the default setting when a new user session is started. It remains set until that user specifies NOUNLOAD. This option is used only for tape devices.
NOUNLOAD
Specifies that the tape not be automatically unloaded when the LOAD is finished. NOUNLOAD remains set until UNLOAD is specified. This option is used only for tape devices.
SKIP
Specifies that the server not read the ANSI tape device headers.
NOSKIP
Specifies that the server read the ANSI tape device headers. This is the default.
FILE
Specifies that a file from a tape or disk device will provide the database, table or transaction log to load.
FILE = fileno
Is the file number to be loaded from the tape or disk device that contains multiple database backups. Load the first dump on the device (the default, 1).
STOPAT = date_time | @date_time_var
Is the date and time to stop loading a dump onto the database. If a variable is used for STOPAT, the variable should have a varchar or a char datatype. Only log records written before the specified date and time will be applied to the database.
APPEND
Specifies that all new data will be added to a table that already contains data. For LOAD TABLE use only.
SOURCE = source_name
Is the name of the source from which to load the table. This option must be specified if the source and target table names differ. For LOAD TABLE use only.
STATS = percentage
Is the percentage of pages loaded in increments optionally set at the time of the load. If a percentage is not specified, statistics are shown for each 10 percent of the load. This option is available only for database and table loads.

Remarks

The LOAD TABLE statement loads only one table at a time, which provides more control when recovering a database. Loading a table from a database dump is discouraged because if data manipulation transactions were occurring on the table when the database dump was performed, the data in the table may be logically inconsistent. You should load a table from a database dump only in disaster recovery situations, and even then it is important that you understand that the data loaded from the dump may be inconsistent.

When loading a table, use a target table and data source table. The data source table holds the data to be loaded to the target table; it can be a full database backup or an individual table backup.

For example, a company maintains a mailing list that is updated quarterly by an outside agency. The mailing list table has no index. The company wants to replace the existing mailing list with the new, agency-supplied mailing list. You could use a procedure that deletes all of the rows of the old table and inserts new rows, but a more efficient approach is to load the new table from a backup.

When loading a table, an EXCLUSIVE TABLE lock is placed on the table. No one else can read or modify the table while it is being loaded.

Important It is recommended that you load a table only from a table dump file because a table dump file is generated from a locked table. It provides an up-to-date snapshot of the table. If you load a table from a database dump file, you will not get any outstanding transactions because the LOAD TABLE statement does not load transactions from the transaction log.

The schema for the data source table and the target table must match for the load to be successful. The names of the tables can be different if the SOURCE option is specified, but the underlying table structure must be the same in terms of base system types, lengths, and nullability.

Note Once you have performed a load table operation, you must do a full database dump. Until you dump the full database, the transaction log cannot be dumped.

Using LOAD TABLE on a populated table is permitted if you use the APPEND option.

During load operations, triggers, rules, defaults, and declarative referential integrity (FOREIGN KEY, CHECK, PRIMARY KEY) are not enforced.

Important Table loads are not permitted on tables that have text columns, indexes, or are published for replication. Table loads from mixed platforms are not supported. For example, you cannot dump a table on an Alpha-based server and load it into a table on an Intel-based server.

When a transaction log is not completely correct (because of possible user error) and you want to apply transactions up to a certain point in time, use the LOAD TRANSACTION statement with the STOPAT clause. If you are unsure which transaction log contains the stopping time, specify the STOPAT clause for all transaction logs that are being loaded.

For example, suppose a user mistakenly deletes the rows in a table on Sunday, Aug. 4, 1996 at 1:00 p.m. The transaction log's last transaction time was Sunday, Aug. 4, 1996 at 1:30 p.m. The STOPAT option is used to stop the roll forward at 12:55 p.m. on Sunday, Aug. 4, 1996. Transactions are applied up to just prior to the deletion.

The LOAD HEADERONLY statement retrieves all the volume and dump header information for all dumps on a particular dump device. The information is returned in a tabular format. These columns have been added to the LOAD HEADERONLY results set.

New columns | Datatype | Comment
BackupStart | datetime | Date and time of the oldest committed transaction. Cannot be NULL.
BackupFinish | datetime | Date and time of the most recently committed transaction. Cannot be NULL.
ServerSort | int | Server sort order. Cannot be NULL. This column is valid for database dumps only.
ServerCodePage | int | Server code page, which is the character set used by the server. Value is 0 when viewing a version 6.0 or earlier dump.
TableOwner | char(30) | Table owner.
OperatorName | char(30) | Name of the user performing the dump operation. Cannot be NULL unless viewing a version 6.0 or earlier database backup.
ProcessorType | int | CPU architecture number. Cannot be NULL.
SQLVersionMajor | int | Major version number of server that made the dump. Cannot be NULL. Value is 0 when viewing a version 6.0 or earlier dump.
SQLVersionMinor | int | Minor version number of server that made the dump. Cannot be NULL. Value is 0 when viewing a version 6.0 or earlier dump.
SQLVersionBuild | int | Build number of server that made the dump. Cannot be NULL. Value is 0 when viewing a version 6.0 or earlier dump.

Examples

A. Load a Table

This example loads the employee_table from the disk file dump1 into the personnel table.

LOAD TABLE personnel FROM dump1 WITH source='employee_table', APPEND
B. Load a Transaction

This example loads a transaction log for the corporate database and stops it on Nov. 4, 1996 at 2:00 p.m..

LOAD TRANSACTION corporate FROM TAPEDUMP1
    WITH STOPAT='1996 110414:00:00'
C. Load a Header Only

This example loads the header only from a predefined device.

LOAD HEADERONLY FROM dump_dev1

Permission

INSERT permission is required to load a table. The target table's database must have the select into/bulkcopy database option set before loading a table.


RAISERROR Statement

RAISERROR Statement (version 6.5)

Sets @@ERROR to 0 by default for severity one through ten messages. The WITH SETERROR option sets the @@ERROR value to the msg_id argument or 50000 regardless of the severity.

For additional syntax information for the RAISERROR statement, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

RAISERROR ({msg_id | msg_str}, severity, state
[, argument1 [, argument2]])
[WITH options]

where

msg_id
Is a user-defined error message stored in the sysmessages table.
msg_str
Is an ad hoc message with formatting similar to the C PRINTF format style. The error message can have as many as 255 characters. All ad hoc messages will have one standard message ID of 50000.
severity
Is the user-defined severity level associated with this message. Severity levels 0 through 18 can be used by any user. For severity levels 19 through 25, the WITH LOG option is required. Only the system administrator can issue RAISERROR with a severity level of 19 through 25.
state
Is an integer value from 1 through 127 that represents information about the invocation state of an error. A negative value for state will default to 1.
argument
Specifies the parameter used in the substitution of variables defined in the msg_str or the message corresponding to the msg_id. There can be zero or more substitution parameters; however, the total number of substitution parameters cannot exceed 20. Each substitution parameter can be a local variable or any of these datatypes: int1, int2, int4, char, varchar, binary, or varbinary. No other datatypes are supported.
WITH options
Is one of the following values:
options | Description
LOG | Logs the error in the server error log and the event log. This option is required for messages with a severity level of 19 through 25, and it can be issued only by the system administrator.
NOWAIT | Sends messages immediately to the client server.
SETERROR | Sets @@ERROR value to msg_id or 50000 regardless of the severity level.

Remarks

This statement now sets @@ERROR to 0 if the severity is between 1 and 10 inclusive. Messages with severity levels 10 and under are not errors, but they do provide additional information.

If you set the msg_id by using the SETERROR option, the RAISERROR statement assigns the msg_id to the @@ERROR regardless of severity.

Otherwise, other behaviors of the RAISERROR statement remain the same.

Important In SQL Server version 6.0, for messages with severity levels 10 and under, @@ERROR is set to 50000. To revert to SQL Server version 6.0 behavior, use either the SETERROR option or trace flag 2701.

For more information about trace flag 2701, see Trace Flags .

Examples

A. Use msg_str

This example returns an @@ERROR value of 50000.

RAISERROR('Test Only',1,2) WITH SETERROR
B. Use msg_id

This example returns an @@ERROR value of 101.

RAISERROR (101, 1, 2) WITH SETERROR


REVOKE Statement

REVOKE Statement (version 6.5)

Requires the CASCADE option to revoke a permission granted with the WITH GRANT OPTION option.

For additional syntax information for the REVOKE statement, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

To revoke permission to database objects:

REVOKE [GRANT OPTION FOR]
{ALL [PRIVILEGES] | permission_list } [(column_list)]
ON { table_name [(column_list)]
| view_name [(column_list)]
| stored_procedure_name | extended_stored_procedure_name}
FROM {PUBLIC | name_list}
[CASCADE]

To revoke permission to create database objects:

REVOKE {ALL | statement_list}
FROM {PUBLIC | name_list}

where

GRANT OPTION FOR
Revokes the ability to confer the permission to another user but leaves the user with the permission still granted.
ALL
Specifies that all permissions possessed by all the users in the group or name_list to the specified object be revoked. When used to revoke statement permissions, specifies that all statement permissions possessed by the user be revoked.
permission_list =
{SELECT [(column_list)] | UPDATE [(column_list)]
| REFERENCES | DELETE | INSERT}
[, {SELECT [(column_list)] | UPDATE [(column_list)] | REFERENCES
| DELETE | INSERT} ...]
Lists permissions to revoke.
table_name
Is the name of the table in the current database to which the permissions apply.
column_list
Is a list of column names, delimited by commas, to which the permissions apply. If columns are specified, only SELECT and UPDATE permissions can be revoked.
view_name
Is the name of the view in the current database to which the permissions apply.
stored_procedure_name
Is the name of a stored procedure in the current database to which permissions apply.
extended_stored_procedure_name
Is the name of an extended stored procedure in the current database to which the permissions apply.
PUBLIC
Represents all users, including those who are members of other groups.
name_list
Is a list of user names and/or group names, delimited by commas. These names are stored in the database's sysusers table.
CASCADE
Revokes WITH GRANT privileges that were granted by the specified user, including those of the specified user. The specified user is either a name_list or PUBLIC.
statement_list
Is a list of statements that have already been granted. The statement list can include: CREATE DATABASE, CREATE DEFAULT, CREATE PROCEDURE, CREATE RULE, CREATE TABLE, CREATE VIEW, DUMP DATABASE, and DUMP TRANSACTION.

Remarks

You must use the CASCADE option when revoking a permission that is grantable. By using the CASCADE option, not only is the specified user's permission revoked, permission is revoked for all those to whom the specified user granted permission. If the CASCADE option is not specified and the specified user was granted WITH GRANT OPTION permission, an error is returned.

For example, suppose the owner of the table population_stats grants access permissions to a user, Matthew, by using WITH GRANT OPTION. The table owner enters the following statement:

GRANT SELECT ON population_stats TO matthew WITH GRANT OPTION

This gives the user Matthew permission to grant the same access privileges to another user, Jake. Matthew enters the following statement:

GRANT SELECT ON population_stats TO jake

If the owner attempts to revoke Matthew's SELECT permission with the following statement the owner receives an error:

REVOKE SELECT ON population_stats FROM matthew

The owner cannot revoke Matthew's access privilege because users would have access to tables of which the owner is not aware.

However, if the owner revokes Matthew's privileges by using CASCADE, then Matthew and Jake both lose their access to population_stats.

REVOKE SELECT ON population_stats FROM matthew WITH CASCADE

When the owner revokes Matthew's WITH GRANT OPTION privilege, then only the right to grant access privilege to other users is revoked. Users who have been granted access privileges, such as Jake, lose their access privilege. Matthew still has access privilege on the population_stats table:

REVOKE GRANT OPTION FOR SELECT ON population_stats FROM matthew

For more information about the REVOKE statement, see the Microsoft SQL Server Transact-SQL Reference.

Example

This example revokes the SELECT and UPDATE permissions on the population_stats table for user jake.

REVOKE SELECT, UPDATE(city) ON population_stats FROM jake


SELECT Statement

SELECT Statement (version 6.5)

Provides the WITH CUBE and WITH ROLLUP options as part of the GROUP BY clause. These operators produce an n-dimensional results set rather than the typical zero or one-dimensional results set.

In SQL Server 6.5, the LIKE operator will search on strings that contain wildcard characters by using an ESCAPE option.

For additional syntax information for SELECT statement, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

SELECT [ALL | DISTINCT] select_list
INTO [new_table_name]
[FROM table_name [, table_name2 […, table_name16]]
[WHERE clause]
[GROUP BY clause]
[HAVING clause]
[ORDER BY clause]
[COMPUTE clause]
[FOR BROWSE]]

where

ALL
Specifies that duplicate rows can appear in the results set.
DISTINCT
Specifies that only unique rows can appear in the results set. Null values are considered equal for the purposes of the DISTINCT keyword; only one NULL is selected no matter how many are encountered.
select_list
Is the list of columns to select and can be one or more of the following.
Column | Description
Asterisk (*) | Represents all columns in the order in which they were specified in the CREATE TABLE statement. Affects all tables in the FROM clause.
A list of column names | Specifies the order in which you want to see column names. If the select_list contains multiple column names, separate the names with commas.
A column name and column heading Specifies a heading to replace the default column heading (the column name), in the following form:

column_heading = column_name

Or

column_name column_heading

Or

column_name AS column_heading
An expression Specifies a column name, constant, function, or any combination of column names, constants, and functions connected by an operator(s), or a subquery.

The expression can be used to set up an identity column by using the IDENTITY() function with SELECT INTO. For example, ID = IDENTITY(int,1,1).
IDENTITYCOL keyword | Specifies the IDENTITYCOL keyword instead of the name of a column that has the IDENTITY property.
Local or global variable | Specifies a local or global variable.
Local variable assignment Specifies a local variable assignment in the form:

@variable = expression

INTO new_table_name
Is the name of a new table to be created based on the columns specified in the select_list and the rows chosen in the WHERE clause.
FROM
Specifies the table(s) and view(s) used in the SELECT statement.
table_name =
{simple_table_name | derived_table | joined_table}

where

simple_table_name =
[[database.] owner.] {table_name | view_name} [[AS] alias_name]
[(optimizer_hints)]
Specifies the name of the table or view used in the SELECT statement.

where

table_name | view_name
Is the name(s) of the table(s) and view(s) used in the SELECT statement. If the list contains more than one table or view, separate the names with commas. If the table(s) or view(s) exist in another database(s), use a fully qualified table or view name, such as database.owner.object_name.

In SQL Server 6.5, errors are reported when redundant table names appear in the FROM clause. For example, these SELECT statements were supported in earlier releases but generate errors in SQL Server 6.5. In the first SELECT statement the tables were treated as two different tables. In the second SELECT statement the second authors reference is discarded.

SELECT * FROM pubs..authors,pubs.dbo.authors

SELECT * FROM authors,authors

To avoid generating these errors, use trace flag 110. This flag causes SQL Server to revert to the table resolution methods of earlier releases. For more information about trace flag 110, see Trace Flags.

alias_name
Is the name of an alias. Each table_name or view_name can be given an alias, either for convenience or to distinguish a table or view in a self-join or subquery.
optimizer_hints
Specify a locking method, an index, or no index (table scan) be used by the optimizer with this table and for this SELECT. Although this is an option, the optimizer can usually pick the best optimization method without hints being specified.
derived_table =
(select_statement) [AS] alias_name
Is a subquery as specified in select_statement and uses the results set of the subquery as the input to the query being executed.

where

select_statement
Is the statement that retrieves rows from the database.
joined_table =
{table_name CROSS JOIN table_name
| table_name [join_type] JOIN table_name ON search_conditions}
Is the results set that is the product of two or more tables being combined.
join_type =
{INNER | LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER]}

The following types of ANSI joins are permitted:

CROSS JOIN
Is the cross product of two tables. Returns the same rows as if no WHERE clause was specified in an old-style join.
INNER
Specifies that all inner rows be returned. Discards unmatched rows.
LEFT [OUTER]
Specifies that all left outer rows be returned. Specifies that all rows from the left table that did not meet the condition specified be included in the results set, and output columns from the other table be set to NULL.
RIGHT [OUTER]
Specifies that all rows from the right table that did not meet the condition specified will be included in the results set, and output columns that correspond to the other table be set to NULL.
FULL [OUTER]
If a row from either table does not match the selection criteria, specifies the row be included in the results set and its output columns that correspond to the other table be set to NULL.

Earlier versions of SQL Server outer joins are supported in the following examples:

Right Outer Join (*=)
Select authors.au_name, titleauthor.title_id
FROM authors.titleauthor
WHERE authors.au_id *=titleauthor.au_id
Left Outer Join (=*)
SELECT authors.au_lname, titleauthor.title_id
FROM authors, titleauthor
WHERE titleauthor.au_id =* authors.au_id

Note Earlier versions of SQL Server joins cannot be used within the same statement as ANSI-style joins.

WHERE clause =
WHERE search_conditions

Specifies the conditions for the rows returned in the results set. There is no limit to the number of search_conditions that can be included in an SQL statement.

The LIKE operator has an ESCAPE option, which allows wildcard characters to be searched for in strings.

Consider the column description in a table, finances contains the value 'lending_rate%'.

The characters '%' and '_' are wildcard characters. If you want to search for rows where the column contains the sequence 'g_', you need to use the ESCAPE option because '_' is a wildcard character.

SELECT * FROM finances
WHERE description LIKE 'gS_' ESCAPE 'S'

The ESCAPE clause uses "S" as an escape character and if the search comes across "S" in the pattern string, it will take the next character "_" as a normal character rather than a wildcard character.

GROUP BY clause =
GROUP BY [ALL] aggregate_free_expression
[, aggregate_free_expression]...[, aggregate_free_expression]
[WITH {CUBE | ROLLUP}]
Specifies the groups into which the table will be partitioned and, if aggregate functions are included in the select_list, finds a summary value for each group.

The maximum number of bytes allowed in the GROUP BY clause is 900.

When the CUBE operator is specified, in addition to the usual aggregate rows, super-aggregate rows are introduced into the results set. A super-aggregate row is a summary row for all of the aggregate rows produced for one of the aggregate-free expressions in the GROUP BY clause.

For example, if your query was computing the average price of an automobile, grouped by manufacturer, a single super-aggregate row would be added that contained the average price of all cars. Suppose your query was grouped instead by manufacturer and color. The results set would then contain super-aggregates for each manufacturer, regardless of color, and separate super-aggregates for each color, regardless of manufacturer.

If the WITH ROLLUP clause is specified, a subset of super-aggregates is computed along with the usual aggregate rows. This is useful when you have sets within sets. Consider grouping by the expressions, column1, column2, and column3. Applying the ROLLUP operator results in these rows:

column1        column2        column3
column1        column2        (null)
column1        (null)        (null)
(null)        (null)        (null)

A maximum of 10 grouping expressions are permitted in a GROUP BY clause when WITH CUBE or WITH ROLLUP is specified. Otherwise, 16 grouping expressions are permitted.

You cannot specify the GROUP BY ALL clause when you use the CUBE or ROLLUP operators.

The CUBE and ROLLUP operators can be disabled when trace flag 204 is ON.

HAVING clause =
HAVING search_conditions

Specifies the conditions for aggregate functions in the select_list; the search_conditions restrict the rows returned by the query but do not affect the calculations of the aggregate function(s).

ORDER BY clause
Is the sort order used on columns returned.
COMPUTE clause =
COMPUTE row_aggregate(column_name)
[, row_aggregate(column_name)...]
[BY column_name [, column_name]...]

where

COMPUTE
Specifies that control-break summary changes be generated for row aggregate functions (SUM, AVG, MIN, MAX, and COUNT).
BY
Specifies that the values for row-aggregate functions be calculated for subgroups.
FOR BROWSE
Specifies that updates be allowed while viewing data in client applications that use DB-Library.

Remarks

Important When creating a derived table, the SELECT statement does not support the use of the INTO, ORDER BY, COMPUTE, or COMPUTE BY clauses.

The FROM clause has been changed to support the ANSI-SQL syntax for joined tables and derived tables. ANSI-SQL syntax provides the INNER, LEFT OUTER, RIGHT OUTER, and FULL OUTER join operators.

Although the outer join operators *= and =* from earlier versions of SQL Server are supported, you cannot use both outer join operators and ANSI-SQL style joined tables in the same query.

When trace flag 204 is enabled, only the SQL Server version 6.0 and earlier SELECT statement syntax is permitted: joined tables, derived tables, and other ANSI features are not. Trace flag 204 is otherwise unchanged. Also, trace flag 330 enables full output that contains information about joins when you are using SHOWPLAN. For more information about trace flags 204 and 330, see Trace Flags .

UNION and JOIN within a FROM clause are supported within views as well as in derived tables and subqueries.

A self-join is a table that joins upon itself. Inserts or updates that are based on a self-join follow the order in the FROM clause.

Note In SQL Server version 6.5, an error occurs if no column name is given to a column created by a SELECT INTO or CREATE VIEW statement. For more information, see the discussion of trace flag 246 in Trace Flags.

The CUBE operator provides a superset of data in the results set. Not only is the typical joined data returned, each operand (column) in the GROUP BY clause is bound under the NULL keyword and applied to all other operands (columns).

The NULL keyword in this case represents all the values in a particular column.

Note Using the HAVING clause in the SELECT statement does not effect the way the CUBE operator groups the results set and returns summary aggregate rows.

Examples

A. Use an Aggregate Function in a SELECT Statement

This example uses the following table to demonstrate how the CUBE operator affects the results set.

product_ID

customer_ID

number_of_orders

----------

-----------

----------------
10 | a | 10
20 | b | 10
10 | a | 20
30 | b | 10
30 | a | 10
20 | b | 20
10 | b | 30
10 | c | 40
20 | c | 10
30 | b | 40
30 | a | 10
10 | a | 50

First, issue a typical query with a GROUP BY clause and the results set.

SELECT product_ID, customer_ID, SUM(number_of_orders)
FROM sales
GROUP BY product_ID, customer_ID

The GROUP BY causes the results set to form groups within groups. This is the results set:

product_ID

customer_ID

Sum
(number_of_orders)

---------

---------

---------------

10

a

80

10

b

30

10

c

40

20

b

30

20

c

10

30

a

20

30

b

50

B. Use the CUBE Operator

Next, do a query with a GROUP BY clause by using the CUBE operator. The results set should include the same information plus super-aggregate information for each of the GROUP BY columns.

SELECT product_ID, customer_ID, SUM(number_of_orders)
FROM sales
GROUP BY product_ID, customer_ID
WITH CUBE

The results set for the CUBE operator holds the values from the simple GROUP BY result set above and adds the super-aggregates for each column in the GROUP BY clause. (null) represents all values in the set from which the aggregate is computed.

product_ID

customer_ID

SUM
(number_of_orders)

-----------

------------

------------------

10

a

80

10

b

30

10

c

40

10

(null)

150

20

b

30

20

c

10

20

(null)

40

30

a

20

30

b

50

30

(null)

70

(null)

(null)

260

(null)

a

100

(null)

b

110

(null)

c

50

C. Use the ROLLUP Operator with the COUNT Aggregate

This example performs a ROLLUP operation on the company and department columns and totals the number of employees.

The ROLLUP operator produces a summary of aggregates. This is useful in situations where summary information is needed but a full CUBE provides extraneous data. This is also useful when you have sets within sets. For example, you could think of departments within a company as a set within a set.

SELECT company, department COUNT(*) FROM personnel GROUP BY company, department WITH ROLLUP

This is the results set:

company

department

Number of Employees

abc

finance

10

abc

engineering

40

abc

marketing

40

abc

(null)

90

def

accounting

20

def

personnel

30

def

payroll

40

def

(null)

90

(null)

(null)

180

D.    Use the ROLLUP Operator

This example modifies the SELECT statement above to use the ROLLUP operator.

SELECT product_ID, customer_ID, SUM(number_of_orders)
AS 'Sum number_of_orders'
FROM sales
GROUP BY product_ID, customer_ID
WITH ROLLUP

This is the results set:

product_ID

customer_ID

Sum
number_of_orders

----------

-----------

----------------

10

a

80

10

b

30

10

c

40

10

(null)

150

20

b

30

20

c

10

20

(null)

40

30

a

20

30

b

50

30

(null)

70

(null)

(null)

260

The GROUPING function allows you to discriminate between a true null value and a null value representing an ALL value.

Expression evaluation | GROUPING returns | Description
(null) | 1 | Represents the set of all values.
any other value | 0 | Represents a particular value.

A new function GROUPING can be used only with CUBE or ROLLUP. The GROUPING function returns 1 when an expression evaluates to NULL because the column value is (null) and represents the set of all values. The GROUPING function returns 0 when the column has a value other than (null). The returned value has a tinyint datatype.

E.    Use the GROUPING Function

This example modifies the SELECT statement that was used in the previous example.

SELECT product_ID, customer_ID, SUM(number_of_orders)
AS 'Sum number_of_orders',
GROUPING(product_ID) AS 'Grouping product_ID',GROUPING(customer_ID) AS 'Grouping customer_ID'
FROM sales
GROUP BY product_ID, customer_ID
WITH ROLLUP

This is the results set:

product_ID

customer_ID

Sum number
_of_orders

Grouping
product_ID

Grouping
customer_ID

----------

-----------

----------

----------

----------

10

a

80

0

0

10

b

30

0

0

10

c

40

0

0

10

(null)

150

0

1

20

b

30

0

0

20

c

10

0

0

20

(null)

40

0

1

30

a

20

0

0

30

b

50

0

0

30

(null)

70

0

1

(null)

(null)

260

1

1

F.    Use Left Outer Join

This example joins two tables on au_id and preserves the unmatched rows from the left table. The authors table is matched with the titleauthor table on the au_id columns in each table. All authors appear in the results set, whether or not they have published any books.

SELECT authors.au_lname, authors.au_fname, titleauthor.title_id
FROM authors LEFT OUTER JOIN titleauthor
ON authors.au_id =titleauthor.au_id

G.    Use Inner Join with Three Tables

This example joins three tables: authors, titleauthors and titles. The results set contains a list of authors and royalties paid to date.

SELECT authors.au_fname, authors.au_lname, sum(titles.royalty * titles.ytd_sales/100)
FROM authors
JOIN titleauthor ON authors.au_id=titleauthor.au_id
JOIN titles ON titleauthor.title_id = titles.title_id
GROUP BY authors.au_lname, authors.au_fname
ORDER BY authors.au_lname

H.    Use Full Outer Join

This example returns the book title and its corresponding publisher in the titles table. It also returns any publishers who have not published books listed in the titles table, and any book titles with a publisher other than the one listed in the publishers table.

SELECT titles.title, publishers.pub_name
FROM publishers FULL OUTER JOIN titles
ON titles.pub_id = publishers.pub_id
WHERE titles.pub_id IS NULL OR publishers.pub_id IS NULL

I.    Use Right Outer Join

This example joins two tables on pub_id and preserves the unmatched rows from the right table. The publishers table is matched with the titles table on the pub_id column in each table. All publishers appear in the results set, whether or not they have published any books.

SELECT publishers.pub_id, titles.title, titles.title_id
FROM titles RIGHT OUTER JOIN publishers
ON publishers.pub_id = titles.pub_id

J.    Use Cross Join

This example returns the cross product of the two tables authors and publishers. A list of all possible combinations of au_lname rows and all pub_name rows are returned.

SELECT au_lname, pub_name
FROM authors CROSS JOIN publishers


SET Statement

SET Statement (version 6.5)

Sets SQL Server query-processing options for the duration of the user's work session or for the duration of a running trigger or a stored procedure.

For additional syntax information for the SET statement, see the Microsoft SQL Server Transact-SQL Reference.

The SET statement provides these options.

Options | Description
ANSI_DEFAULTS | Sets options that control ANSI-compliant behavior.
ANSI_NULLS | Controls NULL handling by using equality operators.
ANSI_PADDING | Controls padding of variables.
ANSI_WARNINGS | Controls truncation and NULL in aggregate warnings.
CURSOR_CLOSE_ON_COMMIT | Controls behavior of cursors once a commit has been performed.
DISABLE_DEF_CNST_CHK | Controls interim constraint checking.
FIPS_FLAGGER level | Specifies the level of ANSI compliance that triggers a warning message. The level parameter can be ENTRY, INTERMEDIATE, FULL, or OFF.
IMPLICIT_TRANSACTIONS | Controls whether a transaction is started implicitly when a statement is executed.
NUMERIC_ROUNDABORT | Controls transaction behavior once a loss-of-precision condition has occurred.
REMOTE_PROC_TRANSACTIONS | When enabled, specifies that if a user-defined transaction is active, an MS DTC transaction will start if a remote stored procedure is executed.
ROWCOUNT | Accepts int, tinyint, and smallint variables for the parameter that sets the number of rows to be returned in the results set.
XACT_ABORT | Controls whether a full transaction termination occurs when an error condition is raised.

Syntax

Option syntax:

SET {
ANSI_DEFAULTS {ON | OFF}
| ANSI_NULLS {ON | OFF}
| ANSI_PADDING {ON | OFF}
| ANSI_WARNINGS {ON | OFF}
| CURSOR_CLOSE_ON_COMMIT {ON | OFF}
| DISABLE_DEF_CNST_CHK {ON | OFF}
| FIPS_FLAGGER {level | OFF}
| IMPLICIT_TRANSACTIONS {ON | OFF}
| NUMERIC_ROUNDABORT {ON | OFF}
| REMOTE_PROC_TRANSACTIONS {ON | OFF}
| ROWCOUNT {number | @int_variable}
| XACT_ABORT{ON | OFF}}

where

ANSI_DEFAULTS
Specifies ANSI-standard behavior.

When enabled, this option enables all the ANSI options, including:
ANSI_NULLS | ARITHABORT
ANSI_NULL_DFLT_ON | CURSOR_CLOSE_ON_COMMIT
ANSI_PADDING | IMPLICIT_TRANSACTIONS
ANSI_WARNINGS | QUOTED_IDENTIFIER

All of these ANSI-standard SET options define the query processing environment for the duration of the user's work session, a running trigger, or a stored procedure.

ANSI_NULLS
Specifies ANSI-standard behavior of the comparison operators, EQUAL (=) and NOT EQUAL (<>).

When ANSI_NULLS is enabled, the equal and not equal comparison operators exhibit new behavior. ANSI standards require that a null behaves like a null value in any mathematical context. That is, NULL in any statement causes the statement to evaluate to NULL.

Once you enable the ANSI_NULLS option, you must use the comparison operators IS NULL and IS NOT NULL to compare for a null value.

When ANSI_NULLS is enabled, the SELECT statement syntax will not accept NULL as an argument. For example, if ANSI_NULLS is enabled, this statement does not work if NULL is passed as the department parameter:

CREATE PROCEDURE get_employees (@department CHAR(30)) AS
SELECT * FROM department WHERE department.name=@department

This procedure returns rows where the department column matches the @department parameter. When ANSI_NULLS is enabled, the procedure must be rewritten for the instances where the @department parameter is a null value, as follows:

CREATE PROCEDURE get_employees (@department CHAR(30)) AS
IF (@department IS NULL)
SELECT * FROM department WHERE department.name IS NULL
ELSE
SELECT * FROM department WHERE department.name=@department
ANSI_PADDING
Specifies padding of values.

When enabled, the ANSI_PADDING causes varchar and varbinary values to be padded with spaces or nulls. It also affects fixed-length datatypes such as char or int. If the user specifies that columns of fixed-length datatypes (char, int, tinyint, smallint) can be NULL, ANSI_PADDING causes these columns to be padded in the event of a null value.

Note If a table is created while ANSI_PADDING is enabled, the table column will exhibit the padding behavior. Disabling ANSI_PADDING has no effect on existing columns.

ANSI_WARNINGS
Specifies that warnings be generated when:
  • Null values appear in aggregate functions such as SUM, AVG, MAX, MIN, or COUNT.
  • An insert or update is attempted on a character (or binary) column and the current length of the new value exceeds the maximum allowed by that column. The insert or update is aborted as specified by the ANSI SQL-92 standard. Trailing blanks are ignored for character columns and trailing nulls are ignored for binary columns.
  • Divide-by-zero and arithmetic overflow errors occur.

For more information about controlling ANSI_WARNINGS, see sp_configure.

CURSOR_CLOSE_ON_COMMIT
Specifies that the cursor be closed once a transaction has been committed or rolled back. Closes any open cursors on commit or rollback and permits procedures to comply with ANSI NIST standards.
DISABLE_DEF_CNST_CHK
Specifies interim deferred violation checking.

An interim violation occurs when constraints are being violated during data modifications. Sometimes these violations are temporary and will no longer exist by the time the data modification concludes. This option suspends reporting of these temporary violations.

This option also can enhance performance. In rare cases, users cannot modify multiple rows because the query runs out of work tables. Work tables are used by the system to resolve suspect constraint violations while processing data modifications. By turning ON the DISABLE_DEF_CNST_CHK option, you can turn off interim constraint checking, which in turn prevents the query from generating interim work tables.

Once DISABLE_DEF_CNST_CHK is set, its new setting is used for the duration of the user's work session or until its value is changed.

FIPS_FLAGGER
Specifies checking for compliance with ANSI SQL-92 FIPS 127-2 standards.
level | OFF
Is the level of compliance to ANSI SQL standards that is checked for in all database operations. If a database operation conflicts with the level of ANSI SQL standards chosen, a warning is generated.

The level must be ENTRY, INTERMEDIATE, or FULL as described in the following table.
Level | Description
ENTRY | Standards checking for ANSI SQL entry-level compliance.
INTERMEDIATE | Standards checking for ANSI SQL intermediate-level compliance.
FULL | Standards checking for full ANSI SQL compliance.

If checking is turned OFF, no standards checking occurs.

IMPLICIT_TRANSACTIONS
Specifies implicit transactions.

Setting IMPLICIT_TRANSACTIONS opens an implicit transaction when the following statements are used:
FETCH | ALTER TABLE
DELETE | INSERT
CREATE | OPEN
GRANT | REVOKE
DROP | TRUNCATE TABLE
SELECT | UPDATE

When this option is turned on and if there are no outstanding transactions already, every ANSI SQL statement will automatically start a transaction. If there is an open transaction, no new transaction will be started. This transaction has to be explicitly committed by the user by using the command COMMIT TRANSACTION for the changes to take effect and locks released.

NUMERIC_ROUNDABORT
Specifies rounding characteristics when a loss of precision has occurred.

Loss of precision occurs when dividing or multiplying. It can also occur in other operations, such as addition and subtraction when the number is too large or too small to represent.

Setting NUMERIC_ROUNDABORT ON terminates any transaction that causes a loss of precision. When it is set to OFF, numeric data is rounded and the transaction continues normally.

REMOTE_PROC_TRANSACTIONS
Specifies that when a user-defined transaction is active, an MS DTC transaction will be started when a remote stored procedure is executed.
XACT_ABORT
Specifies termination handling for the current procedure.

Setting XACT_ABORT ON terminates the transaction if any error is encountered. If one statement raises an error, the entire transaction is terminated and rolled back.

Setting XACT_ABORT option is set to OFF terminates only the SQL statement that raised the error. The transaction will continue.

Remarks

Using the SET statement inside a trigger or stored procedure causes the option to revert to its previous setting after a trigger or stored procedure is executed.

Options changed with the SET statement take effect at the end of the batch. You can combine SET statements and queries in the same batch, but the SET options won't apply to queries in the batch.

Many of these SET options define the query processing environment for the duration of the user's work session or for the duration of a running trigger or stored procedure.

You can also set these options by using sp_configure 'user options'. For information about using sp_configure 'user options', see sp_configure.

For information about viewing these option settings, see @@OPTIONS Global Variable.

Example

SET ANSI_WARNINGS ON


UPDATE Statement

UPDATE Statement (version 6.5)

Changes data in existing rows, either by adding new data or by modifying existing data. You must use aliases to distinguish between updates of tables and columns with the same names.

For additional syntax information for the UPDATE statement, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

UPDATE {table_name | view_name}
SET
[column_name = {column_list | variable_list | variable_and_column_list}
[, column_name2 = {column_list2 | variable_list2 |
variable_and_column_list2}
...[, column_nameN = {column_listN | variable_listN
| variable_and_column_listN}]]
| expression]
[FROM {table_name1 | view_name1}[(optimizer_hints)]
[, {table_name2 | view_name2}[(optimizer_hints)]
[..., {table_name16 | view_name16}[(optimizer_hints)]]]]

where

table_name | view_name =
[[database_name.]owner.]{table_name | view_name}
Specifies the name of the table or view used in the UPDATE statement.
SET
Is a required keyword used to introduce the list of column or variable clauses to be updated.
column_name =
Specifies a column from the table (table_name) or view (view_name).
column_list =
column_name = {expression | DEFAULT | NULL}
variable_list =
variable_name = {expression | NULL}
expression
Is a column_name, constant, function (aggregate functions are not allowed), or any combination of column_names, constants, and functions connected by an operator(s) or a subquery.
DEFAULT
Specifies the default value for that column.
variable_and_column_list =
variable_name = column_name = {expression | NULL | DEFAULT}
Specifies local variables as well as columns.
WHERE clause =
WHERE {search_conditions | CURRENT OF cursor_name}
Is used to do a searched update (using search_conditions) or a positioned update (using CURRENT OF cursor_name).
search_conditions
Specifies the criteria for a searched update.
CURRENT OF cursor_name
Specifies the criteria for a positioned update against the current row within the specified cursor_name.
FROM
Specifies the table(s) and view(s) that are used in the SELECT statement. FROM is required except when the table_name or view_name contains only constants, variables, and arithmetic expressions (no column names). The FROM clause supports a maximum of 16 tables and views. Tables in subqueries are included in this total.
table_name1 | view_name1 =
[[database.]owner.]{table_name. | view_name.}
Specifies the name(s) of the table(s) and view(s) that are used in the UPDATE statement. If the list contains more than one table or view, delimit the names with commas. If the table(s) or view(s) exist in another database(s), use a fully qualified table or view name (database_name.owner.object_name).

Each table_name or view_name can be given an alias, either for convenience or to distinguish a table or view in a self-join or subquery. Aliases (when defined) must be used for ambiguous column references and must match the alias reference (the full table name cannot be used if an alias has been defined). To use an alias, specify the object name, a space, and then the alias name as follows:

UPDATE titles
SET t.ytd_sales = t.ytd_sales + qty
FROM titles t, sales s
WHERE t.title_id = s.title_id

The order of the tables and views after the FROM keyword does not affect the results set returned.

optimizer_hints
Specify that a locking method, an index, or no index (table scan) be used by the optimizer with this table and for this UPDATE. Although this is an allowable option, the optimizer will usually pick the best optimization method.

An optimizer_hint can be one or more of the following.
Option | Description
TABLOCK | Performs an exclusive lock on the table that is held until the end of command. TABLOCKX can be substituted for TABLOCK.
PAGLOCK | Performs exclusive page locks where a single exclusive table lock would normally be taken.
TABLOCKX | Performs an exclusive lock on the table that is held until the end of command. TABLOCK may be substituted for TABLOCKX.

Important Some of the optimizer hints can be used in combination. (For example, TABLOCK and PAGLOCK). When multiple options are specified, separate them with a space; the more restrictive option will take precedence.

Remarks

The update table must be unambiguous for updates to occur. If two tables in a query have the same column name, use aliases to distinguish them.

If aliases are used, the UPDATE statement will cause an error when the table that should be updated is ambiguous. Trace flag 110 will disable these changes.

For more information about trace flag 110, see Trace Flags.

Examples

A. Reference the Same Table Twice in the UPDATE Statement

This example references the same table twice in the WHERE clause or different tables with the same name. In earlier versions, changes were made to the first occurrence of the table. In version 6.5 an error message is returned.

Table stockref
id

qty

type

1

10

'a'

2

10

'a'

3

10

'a'

4

10

'a'

1

30

'b'

2

40

'b'

3

50

'b'

4

60

'b'

update stockref
set s2.qty = s1.qty
from stockref s1, stockref s2
where s1.id = s2.id and
      s1.type = 'a' and
      s2.type = 'b'

This SELECT statement divides the stockref table into two parts, the 'a' range and the 'b' range, matches them on the id field and then copies the qty value from the 'b' range and replaces the qty values in the 'a' range. The UPDATE stockref section of the syntax is ambiguous because it does not specify whether to update the 'a' range or the 'b' range.

The SET s2.qty = s1.qty section of syntax specifies which range to update. In order to avoid an error, use an alias on the ambiguous table reference to indicate which range of the stockref table to update.

UPDATE s2
SET s2.qty = s1.qty
FROM stockref s1, stockref s2
WHERE s1.id = s2.id AND
s1.type = 'a' AND
s2.type = 'b
B. Use Optimizer Hints

This example uses the PAGLOCK optimizer_hint to use a shared page lock when updating the author's last name from Yokohama to Yokomoto in the authors table.

UPDATE authors
SET au_lname = 'Yokohama'
FROM authors(PAGLOCK)
WHERE au_lame = 'Yokomoto'


USER Function

USER Function (version 6.5)

Returns the user's database username.

Syntax

USER

Remarks

This statement provides the same functionality as the USER_NAME() system function.


Stored Procedures

Microsoft SQL Server version 6.5 includes new and enhanced stored procedures for the following:

  • Catalog Stored Procedures
  • Extended Stored Procedures
  • Replication Stored Procedures
  • SQL Executive Stored Procedures
  • System Stored Procedures

Unless otherwise noted, all system stored procedures return a value of 0 to indicate success. Failure is indicated by any non-zero return value, usually greater than zero.

Important All extended stored procedures written in the C programming language must be recompiled from the C source code and relinked under Microsoft SQL Server version 6.5 to OPENDS60.LIB.


Catalog Stored Procedures

Catalog Stored Procedures (version 6.5)

The following catalog stored procedures are described in this section:

  • sp_column_privileges
  • sp_columns
  • sp_datatype_info
  • sp_fkeys
  • sp_sproc_columns
  • sp_table_privileges


sp_column_privileges

sp_column_privileges (version 6.5)

Returns column privilege information for a single table in the current environment. The GRANTOR column can be either the database owner (TABLE_OWNER) or someone to whom the database owner granted permission by using the WITH GRANT OPTION clause in the GRANT statement.

For additional syntax information for sp_column_privileges, see the Microsoft SQL Server Transact-SQL Reference.


sp_columns

sp_columns (version 6.5)

Returns column information for the specified table(s) that can be queried in the current environment. The columns returned belong to a table or view.

For additional syntax information for sp_columns, see the Microsoft SQL Server Transact-SQL Reference.

The ORDINAL_POSITION column replaces the COLID column of earlier releases. In addition, the following columns have been inserted after the REMARKS column and before the SS_DATA_TYPE column.

Column | Datatype | Description
COLUMN_DEF | varchar(254) | The default value of the column.
SQL_DATA_TYPE | smallint | The value of the SQL datatype as it appears in the TYPE field of the descriptor. This column is the same as the DATA_TYPE column, except for the datetime and ANSI interval datatypes. NOT NULL.
SQL_DATETIME_SUB | smallint | The subtype code for datetime and ANSI interval datatypes. For other datatypes, this column returns a NULL.
CHAR_OCTET_LENGTH | int | The maximum length in bytes of acharacter or integer datatype column. For all other datatypes, this column returns a NULL.
ORDINAL_POSITION | int | The ordinal position of the column in the table. The first column in the table is number 1. NOT NULL.
IS_NULLABLE | varchar(254) | The nullability of the column in the table. ISO rules are followed to determine nullability. An ISO SQL-compliant DBMS cannot return an empty string. Displays YES if the column can include NULLS and displays NO if the column cannot include NULLS. This column returns a zero-length string if nullability is unknown. The value returned for this column is different than the value returned for the NULLABLE column.

The return value for the PRECISION column is in base 10.


sp_datatype_info

sp_datatype_info (version 6.5)

Returns information about the datatypes supported by the current environment.

For additional syntax information for sp_datatype_info, see the Microsoft SQL Server Transact-SQL Reference.

The following columns have been inserted after the MAXIMUM_SCALE column and before the USERTYPE column.

Column | Datatype | Description
SQL_DATA_TYPE | smallint | The value of the SQL datatype as it appears in the TYPE field of the descriptor. This column is the same as the DATA_TYPE column, except for the datetime and ANSI interval datatypes. NOT NULL.
SQL_DATETIME_SUB | smallint | The datetime or ANSI interval subcode if the value of SQL_DATA_TYPE is SQL_DATETIME or SQL_INTERVAL. For datatypes other than datetime and ANSI interval, this field is NULL.
NUM_PREC_RADIX | int | The number of bits or digits for calculating the maximum number that the column can hold. If the datatype is an approximate numeric type, then this column contains the value 2 to indicate that COLUMN_SIZE specifies a number of bits. For exact numeric types, this column contains the value 10 to indicate that the COLUMN_SIZE specifies a number of decimal digits. Otherwise, this column is NULL. By combining the precision with radix, the application can calculate the maximum number that the column can hold.
INTERVAL_PRECISION | smallint | The value of interval leading precision if interval datatype; otherwise NULL.

In addition, the return value for the PRECISION column is in base 10.


sp_fkeys

sp_fkeys (version 6.5)

Returns logical foreign key information for the current environment. This procedure shows foreign key relationships including disabled foreign keys. Application coding that includes tables with disabled foreign keys could be implemented as follows:

  • Temporarily disable constraint checking (ALTER TABLE NOCHECK or CREATE TABLE NOT FOR REPLICATION) while working with the tables, and enable again later.
  • Use triggers or application code to enforce relationships.

For additional syntax information for sp_fkeys, see the Microsoft SQL Server Transact-SQL Reference.

For more information on disabling constraints, see Disabling Constraints.


sp_sproc_columns

sp_sproc_columns (version 6.5)

Returns column information for a single stored procedure in the current environment.

For additional syntax information for sp_sproc_columns, see the Microsoft SQL Server Transact-SQL Reference.

The ORDINAL_POSITION column replaces the COLID column of earlier releases. In addition, the following columns have been inserted after the REMARKS column and before the SS_DATA_TYPE column.

Column | Datatype | Description
COLUMN_DEF | varchar(254) | The default value of the column.
SQL_DATA_TYPE | smallint | The value of the SQL datatype as it appears in the TYPE field of the descriptor. This column is the same as the DATA_TYPE column, except for the datetime and ANSI interval datatypes. NOT NULL.
SQL_DATETIME_SUB | smallint | The datetime ANSI interval subcode if the the value of SQL_DATA_TYPE is SQL_DATETIME or SQL_INTERVAL. For datatypes other than datetime and ANSI interval, this field is NULL.
CHAR_OCTET_LENGTH | int | The maximum length in bytes of a character or binary datatype column. For all other datatypes, this column returns a NULL.
ORDINAL_POSITION | int | The ordinal position of the column in the table. The first column in the table is 1. NOT NULL.
IS_NULLABLE | varchar(254) | The nullability of the column in the table. ISO rules are followed to determine nullability. An ISO SQL-compliant DBMS cannot return an empty string. Displays YESif the column can include NULLS and displays NO if the column cannot include NULLS. This column returns a zero-length string if nullability is unknown. The value returned for this column is different that the value returned for the NULLABLE column.

In addition, the return value for the PRECISION column is in base 10.


sp_table_privileges

sp_table_privileges (version 6.5)

Returns a list of tables and the privileges associated with each table in the current environment. Also, the GRANTOR column may be either the database owner (TABLE_OWNER) or someone to whom the database owner granted permission by using the WITH GRANT OPTION clause in the GRANT statement.

For additional syntax information for sp_table_privileges, see the Microsoft SQL Server Transact-SQL Reference.


Extended Stored Procedures

Extended Stored Procedures (version 6.5)

The following extended stored procedures are described in this section:

  • xp_cmdshell
  • xp_readmail
  • xp_sendmail
  • xp_snmp_getstate
  • xp_snmp_raisetrap
  • xp_sqlinventory
  • xp_sqltrace

Extended stored procedures provide a way to dynamically load and execute a function within a dynamic link library (DLL). Any non-interactive console-based program written in the C/C++ programming language can also be written as an extended stored procedure.

Important Because of changes to underlying structures, all extended stored procedures written in the C programming language must be recompiled from the C source code and relinked under Microsoft SQL Server version 6.5 to OPENDS60.LIB.


xp_cmdshell

xp_cmdshell (version 6.5)

Grants non-administrative users permission to execute xp_cmdshell.

For complete syntax information for xp_cmdshell, see the Microsoft SQL Server Transact-SQL Reference.

For more information about enabling more flexible security management, see What's New for Administrators earlier in this document.

Remarks

Generally, xp_cmdshell executes Windows NT commands in SQL Server's security context, which by default is a user account with local administrator authority. When a non-system administrator executes xp_cmdshell with the new configuration option set, the requested command runs in the SQLExecutiveCmdExec user account, which is the same account used by SQL Executive for scheduled tasks entered by non-system administrators.

When you grant execute permission for xp_cmdshell to users, the users can execute any operating-system command at the Windows NT command shell that the account running SQL Server (usually a local system account) has privilege to execute.

To restrict xp_cmdshell access to users who have administrator permission on the Windows NT-based computer where SQL Server is running, configure your SQL Server at the Server Options tab: Select the "xp_cmdshell - Use SQLExecutiveCmdExecAccount for Non-SAs" option.

Note If you select the "xp_cmdshell - Use SQLExecutiveCmdExec Account for NonSAs" option and the client logs on to SQL Server as the system administrator, the command is executed under SQL Server's security context instead of the SQLExecutiveCmdExec security context.


xp_readmail

xp_readmail (version 6.5)

Reads a mail message from the SQL Server mail inbox. This procedure supports an additional output parameter, @originator_address, that returns the resolved mail address of the originator of the mail message.

For additional syntax information for xp_readmail see the Microsoft SQL Server Transact-SQL Reference.

Syntax

xp_readmail ([@msg_id = msg_id] [, @type = type [OUTPUT]] [, @peek = {'true' | 'false'}]
[, @suppress_attach = {'true' | 'false'}]
[, @originator = @sender OUTPUT]
[, @subject = @subject_line OUTPUT]
[, @message = @body_of_message OUTPUT]
[, @recipients = @recipient_list OUTPUT]
[, @cc_list = @cc_list OUTPUT]
[, @bcc_list = @bcc_list OUTPUT]
[, @date_received = @date OUTPUT]
[, @unread = {'true' | 'false'} OUTPUT]
[, @attachments = @temp_file_paths OUTPUT])
[, @skip_bytes = @bytes_to_skip OUTPUT]
[, @msg_length = @length_in_bytes OUTPUT]
[, @originator_address = @originator_address OUTPUT])

where

@originator_address
Specifies the resolved mail address of the originator of the mail message. The @originator_address variable must be varchar(255).


xp_sendmail

xp_sendmail (version 6.5)

Sends a message, and/or a query results set, and/or an attachment to specified recipients. The xp_sendmail extended stored procedure uses a bound connection for the @query parameter. The @query connection made by SQL Mail is not blocked by locks held by the client that issues the xp_sendmail request. This makes xp_sendmail easier to use from within triggers. The @query statement, however, cannot refer to the logical inserted and deleted tables that are only available within a trigger.

For additional syntax information for xp_sendmail, see the Microsoft SQL Server Transact-SQL Reference.


xp_snmp_getstate

xp_snmp_getstate (version 6.5)

Returns the state of the SQL Server Simple Network Management Protocol (SNMP) agent. The state of the SNMP agent indicates whether the agent is available to have the Microsoft SQL Server server queried by an SNMP client.

For more information about Simple Network Management Protocol (SNMP), consult your Microsoft Windows NT operating-system documentation.

Syntax

xp_snmp_getstate [return_status OUTPUT]

where

return_status OUTPUT
Specifies the status returned from the SNMP agent. The return status must have an int datatype. Executing the procedure with no parameters returns a results set that indicates the status and the definition of the SNMP agent's state.

Remarks

The SQL Server SNMP agent interacts between SQL Server and SNMP clients that are running an operating system, including Windows NT, UNIX®, or another mainframe computer operating system. Stored procedures that depend upon the SNMP agent can query the SNMP agent to make sure it is available and in a normal state before proceeding.

For more information about SNMP agents, see, What's New for Administrators earlier in this document.

If xp_snmp_getstate is executed with no parameters (for example, EXECUTE xp_snmp_getstate), a status and its meaning are returned. Status indicates the status code integer and meaning explains the status code. For a complete list of all statuses, see xp_snmp_raisetrap later in this document.

Examples

A. Return SNMP Agent Status

This example returns the state of the SNMP agent.

DECLARE @retval INT
EXECUTE xp_snmp_getstate @retval OUTPUT
SELECT 'status'=@retval
B. Return SNMP Agent Status and Meaning

This example returns status and status meaning for the current SNMP agent.

EXECUTE xp_snmp_getstate

Status            Meaning
--------------     --------------------------------
3                The network has not been started.

Permission

The system administrator and users granted execute permission by the system administrator can execute this procedure.


xp_snmp_raisetrap

xp_snmp_raisetrap (version 6.5)

Permits a client to define and send a trap (an SNMP alert) to an SNMP client.

Syntax

xp_snmp_raisetrap server, database, error_message, message_id, severity, user, comment, date_and_time, return_status OUTPUT

where

server
Is the name of the server where the trap (SNMP alert) originated. The server string can have a maximum of 30 characters and must have a varchar datatype.
database
Is the name of a database where the trap originated. The database string can have a maximum of 30 characters and must have a varchar datatype.
error_message
Is the message for the trap. The error_message string can have a maximum of 255 characters and must have a varchar datatype.
message_id
Is the message error number for the trap. It corresponds to an error number in the sysmessages table, which is associated with the error_message. The message_id must have an int datatype.

For more information about message_id, see sp_addmessage in the Microsoft SQL Server Transact-SQL Reference.

severity
Is the severity of message_id.. The SNMP client views this value as the trap number. The severity must have an int datatype.

For more information on severity, see sp_addmessage in the Microsoft SQL Server Transact-SQL Reference.

user
Is the name of the user raising the trap. The user string can have a maximum of 30 characters and must have a varchar datatype.
comment
Is additional text associated with the trap. The comment string often will include information that is important to interpreting the trap event. The comment string can have a maximum of 255 characters and must have a varchar datatype.
date_and_time
Specifies the date and the time the trap occurred. The date_and_time column must have a datetime datatype.
return_status OUTPUT
Returns the completion status of the statement. This parameter must have an int datatype. These are the possible status values.
Status | Description
0 | The SQL agent is running and the trap was sent successfully.
2 | A memory error occurred.
3 | The network has not been started.
4 | The SQL SNMP agent has timed out while waiting for a response from the SNMP client.
5 | The SQL SNMP agent is not running.

Remarks

This procedure provides communication about SQL Server conditions to SNMP management workstation(s). You can create your own error messages, message error numbers, and severity levels, although it is recommended that you use the error messages, message error numbers, and severity levels provided in the sysmessages or sysservermessages system tables. In the Network control panel, you can define which SNMP management workstations (clients) will receive traps under SNMP service. Clients are set up on a per SQL Server basis.

Traps are usually administrative alerts about conditions or events within the SQL Server. Applications may also raise traps to notify SNMP clients of application specific conditions. For example, this procedure allows the system administrator to alert an SNMP workstation of an action that the system administrator needs to fix.

For more information about SNMP, consult your Microsoft Windows NT operating-system documentation.

Example

This example sends a trap to the SNMP management workstation.

DECLARE @db varchar(30)
DECLARE @user varchar(30)
DECLARE @dt datetime
DECLARE @retval int
SELECT @dt = getdate()
SELECT @user = user_name()
SELECT @db = db_name()
EXECUTE xp_snmp_raisetrap @@servername, @db,
'The authors table was updated',
50001, 10, @user, 'This trap could have been raised by  an update
trigger on the authors table', @dt, @retval OUTPUT
SELECT Status = @retval


xp_sqlinventory

xp_sqlinventory (version 6.5)

Captures SQL Server configuration and inventory information asynchronously on the SQL Server computer and stores it in the specified database and table.

Syntax

xp_sqlinventory {'DbName', 'TableName', Interval | stop}

where

DbName
Specifies the database in which to store inventory information. The DbName specified must already exist and must have enough free space to hold the retrieved inventory data. The DbName can be a maximum of 30 characters and must have a varchar datatype.
TableName
Is the name of the table in which to store the inventory information. The TableName specified will be created if it does not already exist and will store configuration information only for servers that are in the same Windows NT domain as the SQL Server running xp_sqlinventory. The TableName parameter can be a maximum of 30 characters and must be a varchar datatype.
Interval
Specifies the time (in seconds) to wait between checks for inventory messages. The Interval parameter must have an int datatype and can be a value between 1 (once per second) and 3600 (once per hour).
stop
Specifies to stop all in-progress inventory actions.

Remarks

This procedure captures SQL Server configuration and inventory information for all SQL Servers on the domain and stores the information in the specified DbName and TableName. Any SQL Server running the LocalSystem account will not be included.

Caution By default SQL Server is installed as a service in the Windows NT LocalSystem account, and the SQL Server registration and configuration information cannot be sent over the network. For this extended stored procedure to work, you must configure SQL Server to run in a valid domain user account through the Startup dialog box in Control Panel, Services.

Inventory errors are written to the Windows NT Event Log.

Note This procedure does not support named parameters.

The following inventory information is captured for each inventoried SQL Server.

Column name | Description
ReceiveDate | Specifies the date and time the message was received on the SQL Server.
ServerName | Specifies the SQL Server machine name.
ProductName | Specifies the product name of Microsoft SQL Server.
SQLRegisteredOwner | Specifies the registered owner name typed in during SQL Server Setup.
DomainName | Specifies the Windows NT domain name of the SQL Server.
MajorVersion | Specifies the major version number for the SQL Server's version. For example, the "6" in SQL Server version 6.50 is the SQLMajorVersion.
MinorVersion | Specifies the minor version number for the SQL Server version. For example, the "50" in SQL Server version 6.50 is the SQLMinorVersion.
BuildNumber | Specifies the internal build number for the SQL Server version.
ServerLogins | Specifies the total number of configured user logins obtained from the master.dbo.syslogins system table.
MaxConnections | Specifies the maximum number of people that can be simultaneously connected to SQL Server.
DBCount | Specifies the total number of databases on the server including master, tempdb, and model databases.
TotalDeviceSize | Specifies the size in megabytes of all devices allocated for SQL Server data. This number does not include dump devices.
SortOrder | Specifies the sort order and code page chosen at SQL Server Setup. For more information about the selected code page, see master.dbo.syscharsets where id = SortOrder.
SecurityMode | Specifies the SQL Server security mode. The possible values are: 0 Standard security 1 Integrated security 2 Mixed security
ProcedureCache | Specifies the percentage of memory allocated to SQL Server's procedure cache. Values may range from 1 to 99.
SMPStatus | Specifies how aggressively SQL Server will use multiple microprocessors. The default value is 0. For possible values, see "SMP concurrency" in the sp_configure system stored procedure in the Microsoft SQL Server Transact-SQL Reference.
ConfiguredMemory | Specifies the total amount of memory in megabytes allocated to SQL Server.
PriorityBoost | Specifies whether the SQL Server has been configured to run at a higher NT process priority level. For more information about priority boost, see sp_configure in the Microsoft SQL Server Transact-SQL Reference.
WorkingSet | Directs Windows NT to reserve physical memory space for SQL Server equal to the sum of the memory setting and the size of tempdb if it is in RAM. Default is 0 (no working set) and 1 (working set). For more information, see "Set working set size" in the sp_configure system stored procedure in the Microsoft SQL Server Transact-SQL Reference.
Publisher | Specifies the number of publications configured for the SQL Server.
Subscriber | Specifies the number of publications subscribed to for the SQL Server.
Distribution | Specifies whether the SQL Server is configured as a distribution server. The possible values are: 0 Not a distribution server 1 A distribution server
SupportSNMP | Specifies whether SNMP is available. For possible values, see xp_snmp_getstate, earlier in this document.
NamedPipe | Specifies whether the SQL Server can accept client connections by using the named pipe Net-Library. The possible values are: 0 No 1 Yes
MultiProtocol | Specifies whether the SQL Server can accept client connections by using the MultiProtocol Net-Library. The possible values are: 0 No 1 Yes
SPX | Specifies whether the SQL Server can accept client connections by using the Novell IPX/SPX Net-Library. The possible values are: 0 No 1 Yes
WinSocket | Specifies whether the SQL Server can accept client connections by using a WinSocket application programming interface Net-Library. The possible values are: 0 No 1 Yes
Appletalk® | Specifies whether the SQL Server can accept client connections by using an Appletalk Net-Library. The possible values are: 0 No 1 Yes
VINES | Specifies whether the SQL Server can accept client connections by using a Banyan® VINES® Net-Library. The possible values are: 0 No 1 Yes
DECnet™ | Specifies whether the SQL Server can accept client connections by using a DECnet Net-Library. The possible values are: 0 No 1 Yes
CPUBrand | Specifies the brand of the microprocessor for the SQL Server. Possible values can be Intel, Alpha, MIPS, and PowerPC.
CPUModel | Specifies the microprocessor model, such as Pentium or Alpha for the SQL Server.
CPUStepLevel | Specifies the processor stepping version.
CPUCount | Specifies the number of microprocessors for the SQL Server.
ServerTotalMemory | Specifies the total amount of physical memory in megabytes on the SQL Server.
ServerAvailableMemory | Specifies the available amount of physical memory in megabytes on the SQL Server.
OperatingSystem | Specifies the operating system for the SQL Server. An example is Microsoft Windows NT.
OperatingSystemBuild | Specifies the internal operating system build version number for the SQL Server. An example is 1057 for the 1057 build of Windows NT 3.51 or later.
TotalPhysicalDisk | Specifies the total amount of physical disk space in megabytes on non-removable storage media.
AvailablePhysicalDisk | Specifies the amount of free disk space available in megabytes on the SQL Server.

Example

This example checks every two seconds for SQL Server inventory messages. The information is loaded into the db_info table in the sql_info database. After time has passed, the capturing of configure and inventory information stops.

USE pubs
go
DECLARE @db varchar(30)
DECLARE @table varchar(30)
DECLARE @interval int
SELECT @db = 'sql_info', @table = 'db_info', @interval = 2
EXECUTE master..xp_sqlinventory @db, @table, @interval
...
...
EXECUTE master..xp_sqlinventory stop


xp_sqltrace

xp_sqltrace (version 6.5)

Allows database administrators and application developers to monitor and record database activity. Multiple instances of xp_sqltrace can be run simultaneously.

Syntax

xp_sqltrace [[@Function = ] function] [, [ @EventFilter = ] eventfilter]
[, [ @LangFilter = ] 'langfilter'] [, [ @RPCFilter = ] 'rpcfilter'] [, [ @UserFilter = ] userfilter] [, [ @AppFilter = ] appfilter] [, [ @HostFilter = ] hostfilter] [, [@BufSize = ] bufsize] [, [ @TimeOut = ] timeout] [, [ @TraceId = ] traceid] [, [@FullText = ] fulltext] [, [ @FullFilePath = ] 'outputfilename'] [, [ @IntegerEvents = ] integerevents]

where

@Function
Specifies a string that describes what action xp_sqltrace performs. These are the possible values for @Function.
@Function value | Description
audit | Logs all database activity requested by the specified filters to a file specified by @FullFilePath. Returns program control immediately. If @TraceId, @BufSize, or @TimeOut parameters are specified, they are ignored. If audit is used without any parameters, generates a results set that displays the current audit settings for xp_sqltrace. Only one instance of audit can be executed at any time. A permanent connection is not necessary to execute an audit. For example, the system administrator can be connected, start the audit, and then disconnect. You can use audit in automatically started procedures.
control | Changes the settings for a running instance from a separate connection. You must run xp_sqltrace without parameters to obtain an @TraceId before starting a trace session. The @TraceId parameter is required.
remove | Unloads all event handlers. Stops all data from being sent t o trace sessions until trace handlers are loaded again. Using remove does not stop currently executing trace sessions. Starting or stopping a trace session also loads or unloads relevant handlers. You can use remove to temporarily pause all trace sessions. No other parameters are required.
stop | Stops either a single trace session or all trace sessions for the current server. It is recommended that you execute xp_sqltrace stop, @traceid = <traceid> to stop a specific trace session. Using xp_sqltrace stop is useful if the server is under heavy load and the system administrator must stop all trace activities.
trace | Captures all database activity requested by the specified filters and generates a log file or a results set. The @TraceId parameter has no effect.

@EventFilter
Specifies an integer (int datatype) that describes what server activity to monitor. To specify more than one @EventFilter value, add together the @EventFilter values. For example, @EventFilter = 31 means that xp_sqltrace should monitor CONNECT, DISCONNECT, POST_LANGUAGE, POST_RPC, and ATTENTION events. These are the possible values for @EventFilter.
@EventFilter value | Description
0 | PAUSE. Temporarily pauses the trace session. Must be the only @EventFilter specified.
1 | CONNECT. Trace CONNECT events to SQL Server.
2 | DISCONNECT. Trace DISCONNECT events from SQL Server.
4 | POST_LANGUAGE. Trace completed language events on SQL Server (for example, INSERT, SELECT).
8 | POST_RPC. Trace completed RPC events on SQL Server.
16 | ATTENTION. Trace ATTENTION events on SQL Server.
32 | PRE_LANGUAGE. Trace language batches immediately prior to execution. Not currently used by SQLTRACE.EXE.
64 | PRE_RPC. Trace RPC events immediately before execution. Not currently used by SQLTRACE.EXE.

@LangFilter
Specifies a string that specifies a batch pattern of language statements to be monitored. Use the wildcard character (%) to indicate any sequence of characters. Delimit multiple filter strings with a semi-colon (;) for the OR condition (%INSERT%;%SELECT%).
@RPCFilter
Specifies a string pattern of remote stored procedure calls for which to monitor events. Delimit multiple filter strings with a semi-colon (;) for the OR condition. Use the wildcard character (%) to indicate any sequence of characters. Delimit multiple filter strings with a semi-colon (;) for the OR condition (%sp_cursors%;sp_run%).
@UserFilter
Specifies the login name(s) of users for whom to monitor events as a string. Delimit multiple filter strings with a semi-colon (;) for the OR condition. Use the wildcard character (%) to indicate any sequence of characters. For example, specify Chan% as the login name to find login names Chan and Channing.
@AppFilter
Specifies the application name(s) for which to monitor events as a string. Delimit multiple filter strings with a semi-colon (;) for the OR condition. Use the wildcard character (%) to indicate any sequence of characters. For example, specify the application name Acc% to find the Access application.
@HostFilter
Specifies the host(s) for which to monitor events as a string. Delimit multiple filter strings with a semi-colon (;) for the OR condition. Use the wildcard character (%) to indicate any sequence of characters. For example, specify the host name air% to find the airedale host.
@BufSize
Specifies the number of rows of data the server will buffer when the client is busy. The @BufSize parameter is of int datatype and can be a value 1 to 20,000. The default is 1,000.
@TimeOut
Specifies the amount of time in seconds that the server will wait when the row buffer specified in @BufSize is full before terminating the trace session. The @TimeOut parameter is of int datatype and can be 1 to 10 seconds (the default is five seconds).
@TraceId
Specifies the trace identification number used for the trace session. Each @TraceId value is static for a connection as long as you retain your current connection. The @TraceId parameter is of int datatype.
@FullText
Specifies whether the language or RPC strings should be returned as varchar(255) (The default is 0) or as text (1). The @FullText parameter is of int datatype.
@FullFilePath
Specifies the file to send the output to as a string (for example, 'C:\selects.txt'). This parameter uses the standard Microsoft SQL Trace log format for output.

For more information about the SQL Trace log format, see the online Help for SQL Trace.

@IntegerEvents
Specifies whether the event column should be text (The default is 0) or integer (1). The @IntegerEvents parameter is of int datatype.

Remarks

When using xp_sqltrace, an @Function = trace does not return program control until explicitly stopped. No other commands should be issued before the call to xp_sqltrace in an isql or ISQL/w batch. After you choose the stop button in ISQL/w, another output row must be received for the trace to stop. This is a limitation of the ISQL/w interface.

Note The recommended way to stop a trace session is to specify the trace identification number. For example:

xp_sqltrace stop, @traceid = <traceid>

Data can be captured to a table by using the INSERT statement's EXECute clause. Using the INSERT statement this way places xp_sqltrace within a transaction. If xp_sqltrace is used in a transaction, the transaction will not complete until the application stops xp_sqltrace. If the trace is not terminated before the server is stopped or if the database fills completely during a transaction, all changes are rolled back.

These are the events that are specific to trace session output.

Event | Description
PAUSE (0) | Indicates that the trace session was paused temporarily.
START (254) | Indicates a START trace event.
ACTIVE (255) | Indicates an ACTIVE connection event. A row appears in the output for every user who meets the criteria specified in the xp_sqltrace command line. For example, if the system administrator already has three connections, three ACTIVE rows will appear in the output. The trace session will report an ACTIVE row for pre-existing connections.

For more information about monitoring database activity, see the online Help for SQL Trace.

Examples

A. Trace SELECT Statements for sa and probe

This example begins a trace session that displays the event, the username, the application, the data or language statement, and other columns. All SELECT statements executed by either sa or probe users are included in the trace. Events included in the trace are attention, connect, disconnect, post-language, and post-rpc events.

xp_sqltrace trace, @eventfilter = 31, @userfilter = 'sa;probe',
@langfilter = '%select%'

These are the columns generated in the results set.

Column name | Datatype | Description
Event | varchar(12) or int | Specifies the event (for example START, PAUSE, ACTIVE, Connect, Disconnect, SQL, Attention) as varchar(12) unless @IntegerEvents = 1.
UserName | char(30) NULL | Specifies the username of the user that generated the event.
ID | int | Specifies a unique, increasing identifier for connections.
SPID | int | Specifies the SQL Server process identification number.
StartTime | datetime NULL | Specifies the time that the language statement or remote stored procedure call started executing. For connect and disconnect events, specifies the time the user logged in.
EndTime | datetime NULL | Specifies the time that the language statement or remote stored procedure call stopped executing. For disconnect events, specifies the disconnect time.
Application | char(30) NULL | Specifies the application that generated the event.
Data | varchar(255) NULL or text NULL | Specifies the language statement or remote stored procedure call as varchar(255) unless @FullText = 1.
Duration | int NULL | Specifies the amount of time in milliseconds that the language statement or remote stored procedure call took to execute. For disconnect events, specifies the elapsed time in seconds since the user logged in.
CPU | in NULLt | Specifies the amount of CPU time used in milliseconds.
Reads | int NULL | Specifies the number of disk reads.
Writes | int NULL | Specifies the number of synchronous disk writes.
NT_Domain | char(30) NULL | Specifies the NT Domain name of the user that generated the event.
NT_User | char(30) NULL | Specifies the NT User name of the user that generated the event.
HostName | char(30) NULL | Specifies the name of the host that generated the event.
HostProcess | int | Specifies the host process ID number for the host that generated the event.

B. Audit SELECT Statements to a Text File

This example audits batches that contain SELECT statements executed by sa or probe users and places the output in a text file called C:\SELECTS.TXT.

xp_sqltrace audit, @eventfilter = 31, @userfilter = 'sa;probe',
@langfilter = '%select%', @FullFilePath = 'C:\SELECTS.TXT'
C. Obtain and Use a Specific @TraceId

This example starts a trace session for the first connection, and it allows the second connection to control the same trace session by using the trace identification number obtained and passed by the first connection.

Connection One Connection Two
--obtain a traceid
xp_sqltrace
--start the trace
xp_sqltrace trace,
@eventfilter = 31
--pause the trace session
xp_sqltrace control,
@TraceId = <TraceId>

--begin trace session
xp_sqltrace control
@TraceId = <TraceId>,
@EventFilter = 4,
@LangFilter = '%select%'

--stop the trace session
xp_sqltrace stop,
@traceid = <traceid>

D. Stop All Current Trace Sessions

The following two xp_sqltrace command examples stop all trace sessions executing on the current server while the third example stops only the specified trace session.

-- stops all trace sessions
xp_sqltrace stop, @traceid = 0
-- OR
xp_sqltrace stop

--recommended way to stop a single trace session
xp_sqltrace stop @TraceId = <TraceId>
E. Configure SQL Server to Automatically Audit All Sessions at Disconnect

This example creates a stored procedure to automatically start an audit session that audits disconnections.

print 'Creating auditing stored procedure'
-- create stored procedure to enable xp_sqltrace run at startup
go
USE master
go
IF exists(SELECT * FROM sysobjects WHERE type = 'P' AND name = 'sp_sqlaudit')
    DROP PROCEDURE sp_sqlaudit
go
CREATE PROCEDURE sp_sqlaudit AS
BEGIN
-- @FullFilePath can be any file that SQL Server has write
-- permissions
EXECUTE master.dbo.xp_sqltrace audit, 2, @FullFilePath = 'C:\MSSQL\LOG\AUDIT.LOG'
END
go
sp_makestartup 'sp_sqlaudit'
go
F. Capture Server Activity to Table

This example uses the EXECUTE statement to capture all of the server activity to a table named sqltrace in the pubs database. Note that the transaction is not committed until you execute "xp_sqltrace stop" from another connection.

USE pubs
GO
IF EXISTS(SELECT * FROM sysobjects WHERE name = 'SQLTrace' AND type = 'U')
BEGIN
    DROP TABLE SQLTrace
END
GO
CREATE TABLE SQLTrace
(
    Event         CHAR(12) NOT NULL,
    UserName     CHAR(30) NOT NULL,
    ID int         NOT NULL,
    SPID int     NOT NULL,
    StartTime     DATETIME NULL,
    EndTime         DATETIME NULL,
    Application     CHAR(30) NOT NULL,
    Data         VARCHAR(255) NULL,
    Duration     INT NULL,
    CPU             INT NULL,
    Reads         INT NULL,
    Writes         INT NULL,
    NT_Domain     VARCHAR(30) NULL,
    NT_User       VARCHAR(30) NULL,
    HostName      VARCHAR(30) NULL,
    HostProcess     INT NULL
)
GO

EXEC master..xp_sqltrace
GO

INSERT INTO SQLTrace EXECUTE master..xp_sqltrace TRACE, @eventfilter = 31

From another connection, execute the following statement.

EXEC master..xp_sqltrace STOP, 1358560

/* where 1358560 is the trace session returned from xp_sqltrace */

G. BCP SQL Trace Activity Log

You can easily load an activity log into SQL Server using BCP. First create a log and capture the server activity to an activity log file. Next, create a table with the following structure:

IF EXISTS(SELECT * FROM sysobjects WHERE name = 'SQLTrace' AND type = 'U')
BEGIN
    DROP TABLE SQLTrace
END
GO
CREATE TABLE SQLTrace
(
    Event         CHAR(12) NOT NULL,
    UserName     CHAR(30) NOT NULL,
    ID             INT NOT NULL,
    SPID         INT NOT NULL,
    StartTime     datetime NULL,
    EndTime         datetime NULL,
    Application     CHAR(30) NOT NULL,
    Data         VARCHAR(255) NULL,
    Duration     INT NULL,
    CPU             INT NULL,
    Reads         INT NULL,
    Writes         INT NULL,
    NT_Domain     VARCHAR(30) NULL,
    NT_User       VARCHAR(30) NULL,
    HostName      VARCHAR(30) NULL,
    HostProcess     INT NULL
)
GO

Finally, load the data using BCP.

bcp pubs..SQLTrace in c:\activity.log -Usa -Psecret -S -c

Permission

Execute permission defaults to the system administrator. It is recommended that the system administrator be the only login permitted to execute this procedure.


Replication Stored Procedures

Replication Stored Procedures (version 6.5)

The following replication stored procedures are described in this section:

  • sp_addsubscriber
  • sp_addsubscription
  • sp_changearticle
  • sp_changesubscriber
  • sp_dsninfo
  • sp_enumdsn
  • sp_helpsubscriberinfo
  • sp_replcmds


sp_addsubscriber

sp_addsubscriber (version 6.5)

Adds a new subscriber server. An optional description parameter has been added and is used as a description for ODBC and SQL Server subscribers to determine what version of Microsoft SQL Server is being used for replication.

For additional syntax information for sp_addsubscriber, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

sp_addsubscriber subscriber [, type] [, login] [, password] [, commit_batch_size]
[, status_batch_size] [, flush_frequency] [, frequency_type] [, frequency_interval]
[, frequency_relative_interval] [, frequency_recurrence_factor]
[, frequency_subday] [, frequency_subday_interval] [, active_start_time_of_day]
[, active_end_time_of_day] [, active_start_date] [, active_end_date]
[, description]

where

description
Specifies an optional text description. When upgrading to SQL Server 6.5, existing MSsubscriber_info tables are modified to include a description column, which is initialized to SQL Server 6.0. The description parameter can have a maximum of 255 characters and must have a varchar datatype.

Example

This example sets up ACCOUNTS as a subscription server and includes a comment as a description.

sp_addsubscriber ACCOUNTS, @description = 'Temporary Subscriber'

Permission

Execute permission defaults to the system administrator.


sp_addsubscription

sp_addsubscription (version 6.5)

Adds a subscription to an article and sets the subscriber's status. sp_addsubscription prevents DSN subscribers to publications that:

  • Were created with the native @sync_method in the call to the sp_addpublication stored procedure.

Or

  • Contain articles that were added to the publication with an sp_addarticle stored procedure that had a pre_creation_cmd parameter of 3 (truncate).

For additional syntax information for sp_addsubscription, see the Microsoft SQL Server Transact-SQL Reference.


sp_changearticle

sp_changearticle (version 6.5)

Changes an article's properties.

For additional syntax information for sp_changearticle, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

sp_changearticle publication, article [, property, value]

where

property
Specifies an article property to change. Can be:

status

value
Specifies the article value. Can be used with:
include column names
Allows column names in the replicated INSERT statement.
no column names
Allows no column names in the replicated INSERT statement.
owner qualified
Allows owner-qualified table names.
not owner qualified
Allows non-owner-qualified table names.


sp_changesubscriber

sp_changesubscriber (version 6.5)

Changes the options for a subscription server. Any distribution task for the publisher's subscribers will be updated. The description parameter allows the user to add descriptive text and is used for ODBC and SQL Server subscribers to determine what version of SQL Server is being used for replication.

For additional syntax information for sp_changesubscriber, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

sp_changesubscriber subscriber [, type] [, login] [, password]
[, commit_batch_size] [, status_batch_size] [, flush_frequency] [, frequency_type]
[, frequency_interval] [, frequency_relative_interval]
[, frequency_recurrence_factor] [, frequency_subday]
[, frequency_subday_interval] [, active_start_time_of_day]
[, active_end_time_of_day] [, active_start_date] [, active_end_date]
[, description]

where

description
Specifies an optional text description. When upgrading to SQL Server 6.5, existing MSsubscriber_info tables are modified to include a description column that is initialized to SQL Server 6.0. The description parameter can have a maximum of 255 characters and must have a varchar datatype.

Example

This example sets up ACCOUNTS as a subscription server and puts in a comment as a description.

sp_changesubscriber ACCOUNTS, @description = 'Temporary Subscriber'

Permission

Execute permission defaults to the system administrator.


sp_dsninfo

sp_dsninfo (version 6.5)

Retrieves ODBC data source name (DSN) information from the replication distribution server that is associated with the current server if replication is installed. Information retrieved is the database vendor name, the database version, the database name, and whether the database permits subscribers.

Syntax

sp_dsninfo dsn [, infotype ][, login ][, password ]

where

dsn
Is the name of the ODBC DSN.
infotype
Is the type of information to return. If an infotype is not specified or if NULL is specified, all information types are returned. The infotype can be one of these.
Infotype | Description
DBMS_NAME | Specifies the returned DSN database vendor name.
DBMS_VERSION | Specifies the returned DSN database version.
DATABASE_NAME | Specifies the returned DSN database name.
SQL_SUBSCRIBER | Specifies the returned information about whether the database permits subscribers. Omitting this parameter or setting it to NULL returns rows for all infotype values.

login
Specifies the login for the DSN. If the DSN includes a login, specify NULL or omit the parameter.
password
Specifies the password for the login. If the DSN includes a login, specify NULL or omit the parameter.

Remarks

This stored procedure retrieves ODBC DSN information that shows what other databases can be used for replication or querying.

Example

This example returns all infotype data for the DSN northwind.

Note To receive the output shown, you must have Microsoft Access installed on your computer.

sp_dsninfo 'northwind'

Information Type      Value
--------------------- -----------------------------------
DBMS Name             ACCESS
DBMS Version          3.0
Database Name         D:\MSOFFICE\Access\Samples\Northwind
SQL Subscriber        TRUE


sp_enumdsn

sp_enumdsn (version 6.5)

Reports all defined ODBC DSNs for a server running under a specific Windows NT user account.

Syntax

sp_enumdsn

Remarks

Every SQL Server service has a user context. A user context is a set of Registry entries that includes the definitions of the ODBC data sources for the user. The user context is provided by the username under which the SQL Server is running.

For example, if the server is running under the system account user context, the DSNs that are returned will all be system DSNs that are associated with the system account. If the server is running under a private user account, only the DSNs defined for that user's private account are returned.

A two-column result set is returned with the DSN name and description.

Example

This example returns all the defined ODBC DSNs for a server running under a specific Windows NT user account.

sp_enumdsn

Data Source Name       Description
-----------------------------------------------------
northwind             Microsoft Access Driver (*.mdb)
sql_pubs                  SQL Server

Permission

Only the system administrator can execute this procedure.


sp_helpsubscriberinfo

sp_helpsubscriberinfo (version 6.5)

Returns description parameters as a results column, which is used for ODBC and SQL Server subscribers to determine what version of SQL Server is being used for replication. Lists subscription information about a specified database or about a list of publication databases on the server.

For additional syntax information for sp_helpsubscriberinfo, see the Microsoft SQL Server Transact-SQL Reference.


sp_replcmds

sp_replcmds (version 6.5)

Treats the first client who runs sp_replcmds within a given database as the logreader. Clients who attempt to run sp_replcmds within the same database receive error 18752 until the first client disconnects. After the first client disconnects, another client can run sp_replcmds and becomes the new logreader.

For additional syntax information for sp_replcmds, see the Microsoft SQL Server Transact-SQL Reference.

Remarks

This procedure can generate commands for owner-qualified tables or not qualify the table name (the default). Adding qualified table names allows replication of data from tables owned by a specific user in one database to tables owned by the same user in another database.

Note Because the table name in the source database will be qualified by the owner name, the owner of the table in the target database must be the same owner name.

The error message 18752 is:

Msg 18752, Level 16, State 1, Server <SERVERNAME>, Line 1
Another logreader is replicating the database

Note The sp_replcmds procedure should be run only to troubleshoot problems with replication.

A warning message number 18759 will be added to both the SQL Server error log and the Windows NT Event Log if sp_replcmds is unable to replicate a text command because the text pointer was not retrieved in the same transaction. The 18759 error message text is: Unable to replicate a text command because the corresponding TEXTPTR was not found in the replicated transaction (%ld, %ld).

For more information about distribution processes, see the Microsoft SQL Server Administrator's Companion.


SQL Executive Stored Procedures

SQL Executive Stored Procedures (version 6.5)

The following SQL Executive stored procedures are described in this section:

  • sp_addtask
  • sp_helphistory
  • sp_helptask
  • sp_runtask
  • sp_updatetask

SQL Executive stored procedures give system administrators the ability to create tasks for replication, event scheduling, and alert management.


sp_addtask

sp_addtask (version 6.5)

Creates a scheduled task. The @cmdexecsuccesscode parameter has been added.

For additional syntax information for sp_addtask, see SQL Server Books Online or the Microsoft SQL Server Transact-SQL Reference.

Syntax

sp_addtask name[, subsystem] [, server] [, username] [, databasename]
[, enabled] [, freqtype] [, freqinerval] [, freqsubtype] [, freqsubinterval]
[, freqrelativeinterval] [, freqrecurrencefactor] [, activestartdate]
[, activeenddate] [, activestarttimeofday] [, activeendtimeofday]
[, nextrundate] [, nextruntime] [, runpriority] [, emailoperatorname]
[, retryattempts] [, retrydelay] [, command] [, loghistcompletionlevel]
[, emailcompletionlevel] [, description] [, tagadditionalinfo] [, tagobjectid]
[, tagobjecttype] [, @newid OUTPUT] [, @cmdexecsuccesscode]

where

@cmdexecsuccesscode
Specifies an int value meaningful only for tasks whose @subsystem is CmdExec. This parameter is used by SQL Executive to determine if the CmdExec task failed or succeeded. If @cmdexecsuccesscode does not match the actual process exit code of the program involved in the task, the task is considered to have failed.


sp_helphistory

sp_helphistory (version 6.5)

Returns history only for those tasks owned by the calling user. This procedure prevents sensitive information stored in the systasks table from being displayed to all users.

The system administrator retains the ability to view the histories of all scheduled tasks.

For additional syntax information for sp_helphistory, see the Microsoft SQL Server Transact-SQL Reference.


sp_helptask

sp_helptask (version 6.5)

Provides information about one or more tasks that the user owns. This procedure prevents sensitive information stored in the systasks table from being displayed to all users.

The system administrator retains the ability to view all tasks.

For additional syntax information for sp_helptask, see the Microsoft SQL Server Transact-SQL Reference.


sp_runtask

sp_runtask (version 6.5)

Immediately executes a SQL Executive scheduled task either from a command batch or from a user-defined stored procedure.

Syntax

sp_runtask {'task_name' | @task_id = n }

where

task_name
Is the SQL Executive task name.
@task_id = n
Is the numeric ID of the task.

Remarks

This procedure must be run from the msdb database.

Example

A. Run a Task from a Batch
PRINT 'Running sp_runtask...'
EXECUTE msdb.dbo.sp_runtask @taskid = 56
PRINT 'Finished'
B. Run a Task from a Stored Procedure
CREATE PROC RunTask56 AS
BEGIN
    EXECUTE msdb.dbo.sp_runtask @taskid = 56
END

Permission

Execute permission defaults to the public group.


sp_updatetask

sp_updatetask (version 6.5)

Updates information about a task. The @cmdexecsuccesscode parameter has been added.

For additional syntax information for sp_updatetask, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

sp_updatetask {currentname | id} [, name] [, subsystem] [, server] [, username] [, databasename] [, enabled] [, freqtype] [, freqinterval] [, freqsubtype] [, freqsubinterval] [, freqrelativeinterval] [, freqrecurrencefactor] [, activestartdate] [, activeenddate] [, activestarttimeofday] [, activeendtimeofday] [, nextrundate] [, nextruntime] [, runpriority] [, emailoperatorname] [, retryattempts] [, retrydelay] [, command] [, loghistcompletionlevel] [, emailcompletionlevel] [, description] [, tagadditionalinfo] [, tagobjectid] [, tagobjecttype] [, @cmdexecsuccesscode]

where

@cmdexecsuccesscode
Specifies an int value meaningful only for tasks whose @subsystem is CmdExec. This parameter is used by SQL Executive to determine if the CmdExec task failed or succeeded. If @cmdexecsuccesscode does not match the actual process exit code of the program involved in the task, the task is considered to have failed.


System Stored Procedures

System Stored Procedures (version 6.5)

The following system stored procedures are described in this section:

sp_addlogin | sp_fallback_upd_dev_drive
sp_bindsession | sp_fallback_withdraw_svr_db
sp_certify_removable | sp_getbindtoken
sp_change_users_login | sp_helplogins
sp_coalesce_fragments | sp_helprotect
sp_configure | sp_helpserver
sp_dboption | sp_help_revdatabase
sp_dropwebtask | sp_makewebtask
sp_fallback_activate_svr_db | sp_rename
sp_fallback_deactivate_svr_db | sp_runwebtask
sp_fallback_enroll_svr_db | sp_serveroption
sp_fallback_help | sp_setnetname
sp_fallback_permanent_svr | sp_who


sp_addlogin

sp_addlogin (version 6.5)

Creates a new SQL Server user by adding an entry to the master.dbo.syslogins system table. A fifth parameter specifies a login suid for the syslogins table to repair an orphan user that occurs as a result of a database load.

For additional syntax information for sp_addlogin, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

sp_addlogin login_id [, password [, defdb [, deflanguage [, login_suid]]]]

where

login_suid
Is the login suid in the syslogins table. If login_suid is NULL the suid is not affected. Use this parameter only when a database user in the sysusers table is an orphan to the syslogins table.

Example

This example creates a SQL Server login for the login ID Victoria. Victoria's password is citybythewater, her default database is products, her language defaults to the system language, and the new login suid in the syslogins table is 44882.

sp_addlogin 'Victoria','citybythewater','products',default,44882

Permission

Only the system administrator can use this stored procedure.


sp_bindsession

sp_bindsession (version 6.5)

Binds or unbinds a connection to other connections. A bound connection allows two or more connections to participate in the same transaction and share the transaction space until a ROLLBACK TRANSACTION or COMMIT TRANSACTION is issued.

For more information about bound connections, see Bound Connections earlier in this document.

Syntax

sp_bindsession {'bind_token' | 'NULL'}

where

bind_token
Specifies the token that identifies the transaction space originally obtained by using the sp_getbindtoken stored procedure or the srv_getbindtoken Open Data Services function. The bind_token supports a maximum of 255 characters and must have a varchar datatype.

For more information, see srv_getbindtoken later in this document.

Remarks

This procedure uses a bind token to bind two or more existing client connections together. A connection is a client executing a command. Multiple cooperating database connections allow sharing of a common transaction lock space by being bound together to share a transaction context and lock space.

Note If a connection involved in a local transaction executes a remote procedure call (RPC) on a remote server with SET REMOTE_PROC_TRANSACTIONS ON, the local transaction is promoted to a distributed transaction by Microsoft Distributed Transaction Coordinator (MS DTC) and an MS DTC session starts. When the transaction is promoted, the bind token changes to a distributed token identification number. Use the changed token identification number.

Unbind from a session either by omitting the bind_token parameter or by passing NULL as the bind_token parameter.

This procedure can be executed through ODBC, DB-LIBRARY functions, or isql.

Important Prior to executing sp_bindsession, you must obtain a bind token by running sp_getbindtoken or the Open Data Services srv_getbindtoken function.

For information about obtaining a bind token, see sp_getbindtoken, later in this document.

For more information about the Microsoft Distributed Transaction Coordinator (MS DTC), see the Guide to Microsoft Distributed Transaction Coordinator.

Permission

To obtain and pass a bind token, run sp_getbindtoken prior to executing sp_bindsession for sharing the same lock space. If you obtain a bind token, sp_bindsession will run correctly.


sp_certify_removable

sp_certify_removable (version 6.5)

Verifies that a database is configured properly for distribution on removable media and writes returned information to a file.

For additional syntax information for sp_certify_removable, see the Microsoft SQL Server Transact-SQL Reference.

Remarks

This procedure writes verification information to a text file that has the following filename format:

CertifyR_[dbname].txt

Note The permissions on xp_cmdshell must permit this file write.

The verification log file is written to the C:MSSQL\LOG directory under the SQL Server installation directory. The information is delimited by commas. Records preceded by two hyphens (--) are considered comments.

Example

This example certifies that the inventory database is ready to be removed.

sp_certify_removable inventory, AUTO

Permission

Only the system administrator can use this stored procedure.


sp_change_users_login

sp_change_users_login (version 6.5)

Reestablishes foreign key relationships from the syslogins to sysusers and sysalternates tables in cases where cross-server DUMP or LOAD database activity has broken these relationships. Without reestablishing relationships, orphan users may exist.

Syntax

sp_change_users_login {Auto_Fix | Report | Update_One}
[, 'UserNamePattern' [, 'LoginName']]

where

Auto_Fix | Report | Update_One
Specifies the action to take.
Action | Description
Auto_Fix | Links existing orphan usernames to logins of the same name. If an alternate username exists, each entry in the sysusers table is linked with an entry in the syslogins and sysalternates table. It is recommended that you monitor the outcome from the Auto_Fix statement. When linking rows, the Auto_Fix option makes assumptions that may be incorrect.
Report | Lists all usernames in sysusers that have no link to any login name in syslogins. This is the default.
Update_One | Links a specified orphan username in sysusers to an existing login name in syslogins. An orphan username has an entry in the sysusers table that does not have a matching entry in the syslogins table.

Important Avoid using Auto_Fix in security-sensitive situations. The procedure makes best estimates on links, which could allow a user more access privileges than intended.

UserNamePattern
Is one of the following patterns.
UserNamePattern must be: Action
Any non-NULL user-name pattern that is compatible with the LIKE operator. | Auto_Fix
NULL (the default). | Report
One username. | Update_One

LoginName
Is an existing login name. A login name is supported only when Update_One is specified. The default LoginName is NULL.

Remarks

It is suggested that you use this stored procedure after running the LOAD DATABASE statement because sp_change_users_login eliminates the need for manual updates for aliases or alternate usernames.

This stored procedure corrects a potential violation of referential integrity between syslogins and sysusers after DUMP and/or LOAD DATABASE activity. If the LOAD DATABASE statement runs and entries in the sysusers table do not have matching entries in the syslogins table, the tables have missing links. Missing links can prevent some users from using the database.

Missing links are created when login or user modifications occur between the DUMP and LOAD statements or if the dump and load are performed on different servers. For example, if a database is loaded from a database backup from six months ago that had only 100 users and the current version of the database has 130 users, the most recently added 30 users may not be able to access the database loaded from the backup. Reestablishing links by using sp_change_users_login can synchronize the entries in syslogins to the corresponding entries in sysusers and sysalternates, where aliases are used.

This procedure can also relink entries in the syslogins table to entries in the sysalternates table by using the Auto_Fix option.

Users such as guest, public, sa, probe, repl_publisher, repl_subscriber, and any group are not processed by this procedure. User logins that meet the conditions specified in UserNameorPattern (Auto_Fix) or LoginName (Update_One) will be processed with this procedure.

If this procedure completes normally, 0 is returned. If this procedure raises an error, 1 is returned.

Permission

Only the system administrator can run Auto_Fix. The public group can run Report. Only the system administrator or the database owner can run Update_One.


sp_coalesce_fragments

sp_coalesce_fragments (version 6.5)

Deletes and updates rows in the sysusages system table and combines sysusage entries where possible.

Syntax

sp_coalesce_fragments [DBNamePattern]

where

DBNamePattern
Specifies the database name pattern. The name pattern must adhere to the LIKE operator standards for string arguments. The default is '%' (all databases will be affected).

For more information about the LIKE operator, see Wildcard Characters in the Microsoft SQL Server Transact-SQL Reference.

Remarks

System administrators sometimes load a database or table backup file from a production database into a database on another server. Requirements for cross-database dump and load activities are documented under the LOAD Statement in the Microsoft SQL Server Transact-SQL Reference. One requirement is that two databases must have compatible lpage (logical page) and segmap (segment map) column information in the sysusages table. The target database must be created so the segmap for each range of logical pages (lpage) is compatible with the same information in the dumped database.

Two databases have compatible lpage and segmap structures if for every lpage number they have the same segmap value. If one database is larger than the other, some of the larger database's lpage numbers will not exist for the smaller database. A smaller database can be dumped into a larger database, but a larger database cannot be dumped into a smaller database.

Important If the target and destination databases have different segmap structures, dump or load operations can cause data access problems, error messages can appear, or the load can fail if recovery must run.

For more information about logical pages, see the Microsoft SQL Server Administrator's Companion.

The sp_coalesce_fragments procedure simplifies the output from sp_help_revdatabase by replacing multiple rows in the sysusages system table with one row. For every row in the sysusages system table, sp_help_revdatabase produces an ALTER DATABASE statement. With fewer rows in the sysusages system table, fewer ALTER DATABASE statements are produced by sp_help_revdatabase, and fewer rows in sysusages makes it easier to verify compatible logical page and segment map combinations between databases. System administrators can execute sp_coalesce_fragments after ALTER DATABASE statements are issued.

This stored procedure is used with sp_help_revdatabase. Output from sp_help_revdatabase can help create a compatible database.

For more information about creating a compatible database, see sp_help_revdatabase later in this document.

The sysusages system table records the device fragments defined for each database during the CREATE DATABASE and ALTER DATABASE statements. Sometimes several fragments for a database on one device are physically contiguous. The sysusages rows for these contiguous fragments can be reduced to one row by running sp_coalesce_fragments. This reduction is safe because the fragments for a database on any device always have the same value for sysusages.segmap.

For more information about creating a database script that can replicate an existing database structure, see sp_help_revdatabase later in this document.

For more information about altering a database, see the ALTER DATABASE statement in the Microsoft SQL Server Transact-SQL Reference.

For more information about performing a database load, see the LOAD statement in the Microsoft SQL Server Transact-SQL Reference.

For more information about performing a database backup, see the DUMP statement in the Microsoft SQL Server Transact-SQL Reference.

Example

This example compares the output of a SELECT statement before and after sp_coalesce_fragments is run. Comments delimited by two hyphens (--) are interspersed throughout this example.

SELECT
'dbname'=substring(db_name(ug.dbid),1,10)
,ug.segmap,ug.lstart -- page number within a database
,ug.size,ug.vstart -- page number within dv
,'(vstart+size)' = ug.vstart + ug.size
,'device'=substring(dv.name,1,10)
FROM
master.dbo.sysusages ug,master.dbo.sysdevices dv
WHERE ug.vstart between dv.low and dv.high     AND
dv.status & 2 = 2 --physical disk
AND
db_name(ug.dbid) in ('DB1','DB22','db_junk3')
ORDER BY ug.vstart

This is the results set:

dbname      segmap  lstart  size  vstart       (vstart+size)  device
----------  ------  ------  ----  -----------  -------------  ----------
DB1              3       0  2048    352321536      352323584  dvdata1
DB22             3       0  1024    352323584      352324608  dvdata1
DB22             3    1024  1024    352324608      352325632  dvdata1
DB22             4    2048  1024    369098752      369099776  dvlog1
db_junk3         7       0  1024    369099776      369100800  dvlog1
DB22             4    3072  1024    369100800      369101824  dvlog1
DB1              4    2048  1024    369101824      369102848  dvlog1
DB1              4    3072   768    369102848      369103616  dvlog1

Note In the results set the size of 768 for one of the DB1 fragments is not an even multiple of 512. These fragment sizes are difficult to mimic when building compatible work databases for dump and load activities.

Compare the two results sets after sp_coalesce_fragments is executed:

EXECUTE sp_coalesce_fragments

This is the results set:

dbname      segmap  lstart  size  vstart       (vstart+size)  device
----------  ------  ------  ----  -----------  -------------  ----------
DB1              3       0  2048    352321536      352323584  dvdata1
DB22             3       0  2048    352323584      352325632  dvdata1
DB22             4    2048  1024    369098752      369099776  dvlog1
db_junk3         7       0  1024    369099776      369100800  dvlog1
DB22             4    3072  1024    369100800      369101824  dvlog1
DB1              4    2048  1792    369101824      369103616  dvlog1

The number of sysusages fragments is reduced by two.

Note The two DB22 fragments that have segment map 4 cannot be coalesced because they are not contiguous. The lpage 1029 for database DB22 was in a coalesced fragment, and note that its corresponding segmap value remained 3 (system tables and data usage). Similarly, lpage 3081 in DB1 remained on a fragment where segmap is 4 (log usage).

Permission

Only the system administrator can run this procedure.


sp_configure

sp_configure (version 6.5)

Displays or changes global configuration settings for the current server.

The sp_configure stored procedure offers these options for the config_name parameter: affinity mask, max text repl size, remote conn timeout, remote proc trans, and user options.

For additional syntax information for sp_configure, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

sp_configure ['config_name'[, config_value]]

where

config_name
Specifies a configuration option that must be enclosed in single quotation marks ('). These are the options:
affinity mask
Specifies which processor(s) the Symmetric Multiprocessor (SMP) SQL Server will use and allows the system administrator to associate a thread with a processor.
max text repl size
Specifies the maximum size in bytes of text and image data that can be added to a replicated column in a single INSERT, UPDATE, WRITETEXT or UPDATETEXT statement.
remote conn timeout
Specifies a time limit to break a server-to-server connection. The connection will be broken only when the connection has been inactive for the user-defined time. Without this timeout mechanism any server-to-server procedure call results in the connection between servers staying alive until the originating session terminates.

Note If a connection is involved in an MS DTC-coordinated distributed transaction, the connection will not be timed out even if its inactivity period has expired.

remote proc trans
Allows users to protect the actions of a server-to-server procedure through an MS DTC - coordinated distributed transaction. When set to true, provides an MS DTC - coordinated distributed transaction that protects the ACID properties of transactions. Sessions begun after this option is set will inherit the configuration setting as their default. For more information about distributed transactions, see Distributed Transactions or see the Guide to Microsoft Distributed Transaction Coordinator.
user options
Specifies that the user options system configuration parameter is to be queried or modified.

For information about other config_name options for sp_configure, see the Microsoft SQL Server Transact-SQL Reference.

config_value
Is a value associated with a specific config_name. These are the values for the configuration options.
config_name | Minimum | Maximum | config_value | run_value
affinity mask | 0 | 2147483647 | 0 | 0
max text repl size | 0 | 2147483647 | 65536 | 65536
remote conn timeout | -1 | 32767 | 10 | 10
remote proc trans | 0 | 1 | 0 | 0
user options | 0 | 4095 | 0 | 0

affinity mask
Specifies a bit mask in which each bit represents the processors on which the thread is run. Use decimal values to specify affinity mask settings.
max text repl size
Specifies a number of bytes that can be added to a replicated column.
remote conn timeout
Specifies a number in minutes for breaking server-to-server connections.
remote proc trans
Specifies whether server-to-server connections are protected by an MS DTC coordinated distributed transaction (1) or not (0, the default).
user options
Specifies the global defaults for all users. A list of default query-processing options is established for the duration of a user's work session. A user can override these defaults by using the SET statement. The user options option can be dynamically configured for new logins. When the value is changed, new logins will use the new option; current logins will not be affected.

user options is one or a combination of the following.
Configuration
value
Description
1 | DISABLE_DEF_CNST_CHK. Controls interim constraint checking.
2 | IMPLICIT_TRANSACTIONS. Controls whether a transaction is started implicitly when a statement is executed.
4 | CURSOR_CLOSE_ON_COMMIT. Controls behavior of cursors once a commit has been performed.
8 | ANSI_WARNINGS. Controls truncation and NULL in aggregate warnings.
16 | ANSI_PADDING. Controls padding of variables.
32 | ANSI_NULLS. Controls NULL handling by using equality operators.
64 | ARITHABORT. Terminates a query when an overflow or divide-by-zero error occurs during query execution.
128 | ARITHIGNORE. Returns NULL when an overflow or divide-by-zero error occurs during a query.
256 | QUOTED_IDENTIFIER. Differentiates between single and double quotation marks when evaluating an expression.
512 | NOCOUNT. Turns off the message returned at the end of each statement that states how many rows were affected by the statement.
1024 | ANSI_NULL_DFLT_ON. Alters the session's behavior to use ANSI compatibility for nullability. New columns defined without explicit nullability will be defined to allow NULLs.
2048 | ANSI_NULL_DFLT_OFF. Alters the session's behavior to not use ANSI compatibility for nullability. New columns defined without explicit nullability will be defined not to allow NULLS.

Note Not all configuration values for user options are compatible. For example, ANSI_NULL_DFLT_ON cannot be enabled when ANSI_NULL_DFLT_OFF is enabled.

The bit positions in this option match those in @@OPTIONS. Each connection has its own @@OPTIONS variable. When logging into SQL Server, a user receives a default environment that specifies the @@OPTIONS value equal to the config_value. SET statements for several options will affect the value in @@OPTIONS.

For more information about user options, see the SET Statement, earlier in this document.

For information about bit positions, see @@OPTIONS Global Variable earlier in this document.

Remarks

Generally, Windows NT does not guarantee that any thread in a process will run on a given processor. A thread may migrate from processor to processor, which causes reloading of the the processor's cache. Under heavy system loads, specifying which processor should run which thread can improve performance by reducing the reloading of processor cache. The association between a processor and a thread is called processor affinity.

Processor affinity is determined by using an affinity mask. An affinity mask is a bit mask in which each bit represents a processor. By setting a bit that represents a processor to 1, that processor is selected for thread assignment. An affinity mask of 0, the default, specifies that SQL Server should not set the thread's affinity and instead should allow normal Windows NT scheduling algorithms to apply. A non-zero value is interpreted as a bit mask that specifies the processors eligible for selection.

By using the affinity mask option, symmetric multiprocessor (SMP) systems with more than four microprocessors operating under heavy load offer the best prospects for a performance increase. The affinity mask option can exclude SQL Server activity from processors given specific workload assignments by the Windows NT operating system. Excluding SQL Server threads from running on particular processors helps evaluate the system's handling of NT-specific processes. For example, to evaluate whether an additional network interface card (NIC) increases performance or to assess NIC performance with increasing loads, use the affinity mask option.

Before applying the affinity mask option to a computer system, however, consider that Windows NT assigns all I/O handling to processor 0, the first processor in the system. Changes in disk I/O, for example, will be reflected in the usage level of processor 0. Windows NT assigns delayed process call (DPC) activity associated with NICs to the highest numbered processor in the system. In systems with more than one installed and active NIC, each additional card's activity is assigned to the next higher numbered processor. For example, in an eight-processor system with one NIC, Windows NT assigns I/O to processor 0 and DPCs to processor 7. The same eight-processor system with two NICs will have I/O assigned to processor 0 and DPCs for each NIC assigned to processor 7 and to processor 6.

Note Use either the WPERF.EXE utility included in the Windows NT Resource Kit or the SQL Server Performance Monitor to view and analyze individual processor usage.

For example, if processors 1, 2, and 5 are selected as available with bits 1, 2, and 5 set to 1, a hexadecimal value of 0x13 or the decimal equivalent of 19 is specified. Number the bits from the right to left. The right-most bit is bit 1. Set bits 1, 2, and 5 (the first, second, and fifth bits) to 1. The number calculated from setting the specified bits is binary 00010011, which is decimal 19 or hexadecimal 0x13.

These are affinity mask options for an eight-processor system.

Decimal value | Binary bit mask | Allow SQL Server threads on processor(s)
1 | 00000001 | 0
3 | 00000011 | 0 and 1
7 | 00000111 | 0, 1, and 2
15 | 00001111 | 0, 1, 2, and 3
31 | 00011111 | 0, 1, 2, 3, and 4
63 | 00111111 | 0, 1, 2, 3, 4, and 5
126 | 01111110 | 1, 2, 3, 4, 5, and 6 (isolates SQL Server activity from I/O and DPC processors)
127 | 01111111 | 0, 1, 2, 3, 4, 5, and 6 (isolates SQL Server activity from DPC processor only)
254 | 11111110 | 1, 2, 3, 4, 5, 6, 7 (isolates SQL Server activity from I/O processor only)

Because using SQL Server processor affinity is a specialized operation, it is recommended that SQL Server processor affinity be used only when necessary. In most cases, the Windows NT default affinity provides the best performance. Unlike earlier releases of SQL Server, if a config_value is 0, defaults will not be automatically reapplied.

Important After using sp_configure, the system administrator must execute the RECONFIGURE statement to install the changed value.

Examples

A. Enable ANSI_WARNINGS and IMPLICIT_TRANSACTIONS

This example enables ANSI warnings (ANSI_WARNINGS) and implicit transaction (IMPLICIT TRANSACTIONS) options and disables all the others.

sp_configure 'user options', 10
B. Define Timeout Period

This example defines a timeout period of 90 minutes for server-to-server connections.

sp_configure 'remote conn timeout', 90
C. Set Processor Affinity Mask

This example sets processors 1, 2, 3, and 4 as available for threads. Each bit in the decimal represents a processor, so 15 = 0xf =1111(binary) meaning processors 1, 2, 3, and 4. You can also pass 0xf as the affinity mask argument.

sp_configure 'affinity mask', 15
D. Set Bits for ANSI Compatibility

This example sets all bits necessary for ANSI-level compatibility.

sp_configure 'user options', 1406

Permission

All users in the users group can execute this procedure with no parameters, or with only one parameter, to obtain the current parameter value(s). Only system administrators can use this stored procedure with two parameters.


sp_dboption

sp_dboption (version 6.5)

Displays or changes the database options.

Syntax

sp_dboption [ dbname , 'optname' ] [ , {TRUE | FALSE } ]

In earlier releases of SQL Server, omitting the optname parameter qualifier (true or false) resulted in a runtime error. In SQL Server 6.5, if the optname parameter is not qualified by true or false, the current setting of the optname option specified is returned.

For additional syntax information for sp_dboption, see the Microsoft SQL Server Transact-SQL Reference.

Remarks

The sp_dboption stored procedure returns current settings if the optname parameter setting is omitted. Otherwise, sp_dboption functions as in earlier releases.

Example

This example returns the current setting for the published column from the pubs database.

sp_dboption pubs, 'published'

This is the results set:

OptionName             Current Setting
--------------------   --------------
published              off

Second example:
sp_dboption pubs, 'published', false


sp_dropwebtask

sp_dropwebtask (version 6.5)

Deletes a previously defined web task. The task to be deleted is identified by the output filename, by the procedure name, or by both parameters.

Syntax

sp_dropwebtask {@procname = procname | @outputfile = outputfile | @procname = procname, @outputfile = outputfile}

where

@outputfile
Specifies the name of the web task to be deleted. The outputfile variable is of varchar datatype and has a maximum of 255 characters.
@procname
Specifies the name of the web task procedure to delete. The named procedure describes the query for the web task. The procname variable is of varchar datatype and has a maximum of 28 characters.

Remarks

This stored procedure must be executed in the database specified in the @dbname parameter of sp_makewebtask.

Important The sp_dropwebtask, sp_makewebtask, and sp_runwebtask stored procedures can be run only on Microsoft SQL Server version 6.5 databases. Running these procedures on a database of a previous version will return errors.

For more information about creating and running a web task, see sp_makewebtask and sp_runwebtask later in this document.

Example

This example deletes a web task by using the @outputfile of C:\WEB\MYFILE.HTML and an @procname of MYHTML.

sp_dropwebtask @procname = MYHTML, @outputfile = 'C:\WEB\MYFILE.HTML'

Permission

The user deleting the web task must be the owner of the specified procedure.


sp_fallback_activate_svr_db

sp_fallback_activate_svr_db (version 6.5)

Activates fallback support for the specified fallback enrolled databases for a primary server.

Syntax

sp_fallback_activate_svr_db [PrimarySvrName] [, DBNamePattern]

where

PrimarySvrName
Specifies the name of the primary server for which the local fallback server should provide fallback support. Executing this procedure without a PrimarySvrName (the default) indicates that there is one primary server with databases enrolled and to use the implied primary server name.
DBNamePattern
Specifies the name pattern of a database for which to activate the fallback support. The default is '%'. This parameter can be any pattern appropriate for the LIKE operator.

For more information about the LIKE operator, see Wildcard Characters in the Microsoft SQL Server Transact-SQL Reference.

Remarks

A database can be enrolled on its primary server and on its fallback support server for the same primary server. In the case where the primary server acts as both a primary server and fallback support server this enrollment strategy can be useful for load balancing schemes.

This procedure should be executed on the fallback server. If the hardware fallback changes are in place, then the activated databases is available approximately two seconds after this procedure is executed.

For more information about fallback support, see Fallback Support in "What's New for Administrators," earlier in this document.

Permission

Only the system administrator can execute this procedure.

Tables Used

master.dbo.spt_fallback_usg

See Also

sp_addremotelogin | sp_helplogins
sp_addserver | sp_serveroption
sp_change_users_login |


sp_fallback_deactivate_svr_db

sp_fallback_deactivate_svr_db (version 6.5)

Deactivates fallback support for the specified activated databases on a primary server. Deactivation leaves the databases enrolled.

Syntax

sp_fallback_deactivate_svr_db [PrimarySvrName]
[, DBName Pattern]

where

PrimarySvrName
Specifies the name of the primary server for which the local fallback server should stop active fallback support. Executing this procedure without a PrimarySvrName (the default) indicates there is one primary server with databases enrolled and to use the implied primary server name.
DBNamePattern
Specifies the name pattern of a database for which to activate the fallback support. The default is '%'. This parameter can be any pattern appropriate for the LIKE operator.

For more information about the LIKE operator, see Wildcard Characters in the Microsoft SQL Server Transact-SQL Reference.

Remarks

This procedure should be executed on the fallback server.

For more information about fallback support, see Fallback Support in "What's New for Administrators," earlier in this document.

Permission

Only the system administrator can execute this procedure.

Tables Used

master.dbo.spt_fallback_usg

See Also

sp_addremotelogin | sp_helplogins
sp_addserver | sp_serveroption
sp_change_users_login |


sp_fallback_enroll_svr_db

sp_fallback_enroll_svr_db (version 6.5)

Enrolls a primary server's database into the staging tables of a fallback server, which prepares the server for future fallback support activation.

Syntax

sp_fallback_enroll_svr_db {PrimarySvrName, DBName}

where

PrimarySvrName
Specifies the name of the server that is ready to provide fallback support. If no value is specified, the implied value is the fallback server that is defined on the primary server.
DBName
Specifies the name of a database to enroll in fallback support. This database will be enrolled on the remote fallback server and must be owned by the local or primary server.

Remarks

This procedure should be run locally on the fallback server. The primary server must already be locally defined on the fallback server.

When a server enrolls its own active database and uses itself as the fallback server, the enrolled database is immediately recorded as being actively supported in the spt_fallback tables. In this case, the primary server acts as its own fallback support server. This enrollment strategy can be useful for activating or deactivating a database on the primary server.

For more information about fallback support, see Fallback Support in "What's New for Administrators," earlier in this document.

Permission

Only the system administrator can execute this procedure on the local primary server.

Tables Used

master.dbo.spt_fallback_usg

See Also

sp_addremotelogin |
sp_addserver |
sp_change_users_login | sp_helplogins
 | sp_serveroption


sp_fallback_help

sp_fallback_help (version 6.5)

Reports about enrollments and activations for fallback support and provides integrity checking.

Syntax

sp_fallback_help [PrimarySvrNamePattern]

where

PrimarySvrNamePattern
Specifies the name of the primary server. The default is '%'. This parameter can be any pattern appropriate for the LIKE operator.

For more information about the LIKE operator, see Wildcard Characters in the Microsoft SQL Server Transact-SQL Reference.

Remarks

This procedure provides useful information only if executed on the fallback server. If a return value is greater than 0, the integrity check detects a problem.

Permission

Only the system administrator can execute this procedure on the local primary server.

Tables Used

master.dbo.spt_fallback_usg

See Also

sp_addremotelogin | sp_helplogins
sp_addserver | sp_serveroption
sp_change_users_login |


sp_fallback_permanent_svr

sp_fallback_permanent_svr (version 6.5)

Establishes the local fallback support server as the sole owner of the active databases for an obsolete primary server.

Syntax

sp_fallback_permanent_svr {'PrimarySvrName,' 1}

where

PrimarySvrName
Specifies the name of an enrolled and active primary server in fallback support on the local fallback server.
1
Specifies an override. This parameter guards against an accidental execute of this procedure.

Remarks

This procedure should be run only on the fallback support server. This procedure deletes rows from spt_fallback tables. Formerly enrolled databases and databases originally stored on the local server can be distinguished only by drive letters stored in the sysdevices table in the phyname column.

Example

This example brings all active databases for the obsolete primary server MyPrimaryServer under the permanent control of the local fallback server.

sp_fallback_permanent_svr 'MyPrimaryServer', 1

Permission

Only the system administrator can execute this procedure on the local primary server.

Tables Used

master.dbo.spt_fallback_usg

See Also

sp_addremotelogin | sp_helplogins
sp_addserver | sp_serveroption
sp_change_users_login |


sp_fallback_upd_dev_drive

sp_fallback_upd_dev_drive (version 6.5)

Creates cross references to the drive letters used by the primary and fallback support servers so both servers refer to the same physical drive.

Syntax

sp_fallback_upd_dev_drive {'PrimarySvrName', 'PrimaryDrive', 'FallbackDrive'}

where

PrimarySvrName
Specifies the name of the primary server that contains inactive enrolled databases.
PrimaryDrive
Specifies the drive letter found in the phyname column of the sysdevices system table. This parameter consists of one character and a colon (:) and indicates the physical drive on the primary server for enrolled devices.
FallbackDrive
Specifies the drive letter to be used by the fallback support server. This parameter consists of one character and a colon (:).

Remarks

This procedure must be executed on the fallback support server by using a direct connection to the fallback support server, or by using a remote stored procedure call to the fallback support server while connected to the primary server.

Permission

Only the system administrator can execute this procedure on the local primary server.

Tables Used

master.dbo.spt_fallback_usg

See Also

sp_addremotelogin | sp_helplogins
sp_addserver | sp_serveroption
sp_change_users_login |


sp_fallback_withdraw_svr_db

sp_fallback_withdraw_svr_db (version 6.5)

Erases the enrollment of inactive databases for a primary server.

Syntax

sp_fallback_withdraw_svr_db {'PrimarySvrName' [, DBNamePattern]}

where

PrimarySvrName
Specifies the name of a primary server that contains inactive enrolled databases.
DBNamePattern
Specifies the name pattern for enrolled databases. The default is '%'. This parameter can be any pattern appropriate for the LIKE operator.

For more information about the LIKE operator, see Wildcard Characters in the Microsoft SQL Server Transact-SQL Reference.

Remarks

This procedure must be executed on the fallback support server by using a direct connection to the fallback support server, or by using a remote stored procedure call to the fallback support server while connected to the primary server.

When executing this procedure for troubleshooting problems with fallback support, supply only PrimarySvrName so DBNamePattern defaults to '%' for all enrolled databases on a primary server.

Permission

Only the system administrator can execute this procedure on the local primary server.

Tables Used

master.dbo.spt_fallback_usg

See Also

sp_addremotelogin | sp_helplogins
sp_addserver | sp_serveroption
sp_change_users_login |


sp_getbindtoken

sp_getbindtoken (version 6.5)

Creates a bound connection context and returns a unique identifier for the created context. This unique identifier is referred to as a bind token. This system stored procedure returns a string representation to use as a token for a shared transaction between two clients.

Syntax

sp_getbindtoken return_value OUTPUT [, @for_xp_flag]

where

return_value OUTPUT
Is the token to use to share a transaction context. This parameter can have a maximum of 255 characters and must have a varchar datatype.
@for_xp_flag
Specifies a literal constant. If equal to 1, creates a bind token that can be passed to an extended stored procedure to call back into the server.

Remarks

The bind token can be used with sp_bindsession to bind new sessions to the same transaction context. Sessions on one SQL Server that are bound to the same transaction context share a single-transaction lock space during each session.

To obtain and pass a bind token, you must run sp_getbindtoken prior to executing sp_bindsession for sharing the same lock space. If you obtain a bind token, sp_bindsession will run correctly.

If a literal constant is not used for the @for_xp_flag parameter, you will receive the following error message:

Msg 214, Level 16, State 1, Server <server_name>, Procedure <procedure_name>, Line 5
Cannot convert parameter @for_xp_flag to type constant expected by procedure.

Note It is recommended that you use the srv_getbindtoken Open Data Services API to obtain a bind token to be used from an extended stored procedure.

For more information about sharing a transaction context and binding connections, see sp_bindsession.

For more information about the srv_getbindtoken Open Data Services API, see What's New for Open Data Services later in this document.

Examples

A. Obtain Bind Token

This example obtains a bind token and displays the bind token name.

DECLARE @bind_token varchar(255)
EXECUTE sp_getbindtoken @bind_token OUTPUT
SELECT @bind_token AS Token

This is the results set:

Token
----------------------------------------------------------
\0]---5^PJK51bP<1F<-7U-]ANZ

Note Your bind token name will differ from the results displayed above.

B. Use @for_xp_flag Parameter

This example specifies a literal constant to use for calling back to the server.

DECLARE @bind_token varchar(255)
EXECUTE sp_getbindtoken @bind_token OUTPUT, 1
SELECT @bind_token AS Token

For more information about binding connections, see sp_bindsession, earlier in this document.


sp_helplogins

sp_helplogins (version 6.5)

Provides information about current logins and the associated users.

Syntax

sp_helplogins [LoginNamePattern]

where

LoginNamePattern
Is a login username. This value can be any pattern understandable to the LIKE operator. The default is '%'.

For more information about the LIKE operator, see Wildcard Characters in the Microsoft SQL Server Transact-SQL Reference.

Remarks

This procedure reports information on logins. The output consists of two reports. The first report contains information about each login name, including whether a login is associated with a remote login. The second report contains information about users and aliases associated with each login name. The second report gathers information from all databases.

In most cases the width of each column in the output reports is reduced to the length of the longest data value under each column. No data values are truncated.

Example

This example reports on all logins that begin with repl.

sp_helplogins 'repl%'

LoginName       SUID   DefDBName DefLangName AUser ARemote
--------------- ------ --------- ----------- ----- -------
repl_publisher  16382  master    us_english  NO    no
repl_subscriber 16383  master    us_english  yes   no

(2 row(s) affected)

LoginName        DBName          UserName         UserOrAlias
---------------  --------------  ---------------  ------------
repl_subscriber  master          repl_subscriber  User
repl_subscriber  msdb            repl_subscriber  User

(2 row(s) affected)

Note In the first report of Logins, repl_publisher has an AUser of NO, which indicates that it is unusual not to be a user.

Permission

Only the system administrator can execute this procedure.


sp_helprotect

sp_helprotect (version 6.5)

Reports on user permissions for an object and includes SELECT, execute, and access permissions for a given object.

For additional syntax information for sp_helprotect, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

sp_helprotect [OwnerObject_Statement_Name_Pattern [, GranteeName [, GrantorName [, PermissionsCategories]]]]

where

OwnerObject_Statement_Name_Pattern
Is the name of an object and/or statement for which permissions can be granted: the parameter PermissionCategories determines which permissions will be granted to the object or statement. The name can be any pattern understandable to the LIKE operator.

For more information on the LIKE operator, see Wildcard Characters in the Microsoft SQL Server Transact-SQL Reference.

An object name of 'tb217[_]Customer' can be used to focus on one table. For a broader report use 'tb%' or '%cust%'. An owner name can be used to qualify the object name, such as in 'dbo.vwBudget' or 'Patia%.pc%'. A database name cannot be used as a qualifier in this parameter; instead, rely upon the current database context. The default is '%'.

GranteeName
Is the name of the person who has permission to access the database object. This value can be any pattern that is understood by the LIKE operator (NULL is not accepted). As the GRANT statement syntax implies, users, guest, groups, and public can all be grantees. The default is '%'.
GrantorName
Is the name of the grantor to the database object. The grantor is anyone who has authority to grant another person (the grantee) access to an object. This value can be any pattern that is understood by the LIKE operator (NULL is not accepted). Only members of the users group can be grantors. The default is '%'.
PermissionsCategories
Is a string of single letters that determines which categories will be reported. This determines the interpretation of the first parameter. These are the supported categories of permissions.
Categories | Permissions
O | Object.
S | Statement.
OS | All categories are available (the default).

Remarks

The output report is sorted by permission category, owner, object, grantee, grantor, protection type category, protection type, action, and column sequential ID.

These are the special values that can appear in the report.

Value | Description
(All) | Indicates that the privilege covers all current columns of the object.
(New) | Indicates that the privilege covers any new columns that might be altered (by using the ALTER statement) on the object in the future.
(All+New) | Indicates a combination of All and New.

The width of each column in the output report will be reduced to the length of the longest data value under each column. No data values are truncated.

If this procedure completes successfully, 0 is returned. If an error occurs, 1 is returned.

Example

This example reports all permissions except those for DBO objects that begin with the letter T and grantor names that begin with the letter d.

sp_helprotect 'dbo.[^Tt]%',default,'[^d]%','O'

Permission

Execute permission is granted to the public group during installation or upgrade.


sp_helpserver

sp_helpserver (version 6.5)

Provides the server name, the server's network name, the server's replication status, and the server's identification number. dsn or fallback are possible return values for status.

For additional syntax information for sp_helpserver, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

sp_helpserver [server_name]

where

server_name
Specifies the server for which to display information. When no server_name is supplied, provides information about all servers of both types stored in master.dbo.sysservers.

Remarks

This procedure returns the server name, network name, status, and ID. Status can be:

dist | Distribution server
dpub | Remote publisher to this distribution server
dsn | DSN server
fallback | Fallback server
pub | Publication server
rpc | Remote server
sub | Subscription server

A server can have more than one status.

This procedure is useful if you have access to a server as a DSN through ODBC.

Permission

Execute permission defaults to the public group.


sp_help_revdatabase

sp_help_revdatabase (version 6.5)

Analyzes an existing database and creates a script that can be used to replicate the database structure on another server.

Syntax

sp_help_revdatabase [DBNamePattern]

where

DBNamePattern
Specifies a database name pattern. The name pattern must adhere to the LIKE operator standards for string arguments. The default is '%' (all databases will be affected).

For more information about the LIKE operator, see Wildcard Characters in the Microsoft SQL Server Transact-SQL Reference.

Remarks

The purpose of the sp_help_revdatabase stored procedure is to ease the task of building a database by ensuring the lpage (logical page) and segmap (segment map) structures are compatible with an existing database.

The output of this system stored procedure is a script of CREATE/ALTER DATABASE statements that match an existing database. The output also contains any necessary invocations of sp_logdevice to update sysusages.segmap. For every row in the sysusages system table, sp_help_revdatabase produces an ALTER DATABASE statement. With fewer rows in the sysusages system table, fewer ALTER DATABASE statements are produced by sp_help_revdatabase and fewer rows in sysusages make it easier to verify compatible logical page and segment map combinations between databases.

The database and device names in the generated script output can be edited in preparation for creating another database with compatible lpage and segmap structures. The output script might be unable to achieve compatible lpage and segmap structures when any fragment size in the original database is not an even multiple of 512 2K pages. When this procedure detects fragments with a size not evenly divisible by 512, sp_help_revdatabase includes in the output a cautionary comment indicating that the ALTER size in 1 MB units represents a rounded-up representation of the size as recorded in 2K pages in sysusages. You can avoid this problem if you code size-parameter values in even multiples of 512 2K pages when you issue DISK INIT statements.

System administrators sometimes load a database or table backup file from a production database into a database on another server. Requirements for successful cross-database dump and load activities are documented under the LOAD statement in the Microsoft SQL Server Transact-SQL Reference. One requirement is that the two databases have compatible lpage and segmap column information in the sysusages table. The target database must be created so the segmap for each range of logical pages (lpage) is compatible with the same information in the dumped database.

Important If the target and destination databases have different segmap structures, dumped or loaded databases can experience data access problems.

Two databases have compatible lpage and segmap structures if for every given lpage number they have the same segmap value. Fragment sizes and sequences are not an issue. If one database is larger than the other, some of the larger database's lpage numbers will not exist for the smaller database. A smaller database can be loaded into a larger database, but a larger database cannot be loaded into a smaller database.

For more information about logical pages, see the Microsoft SQL Server Administrator's Companion.

For more information about preparing to run sp_help_revdatabase, see sp_coalesce_fragments, earlier in this document.

For more information about altering a database, see the ALTER DATABASE statement in the Microsoft SQL Server Transact-SQL Reference.

For more information about performing a database load, see the LOAD statement in the Microsoft SQL Server Transact-SQL Reference.

For more information about performing a database backup, see the DUMP statement in the Microsoft SQL Server Transact-SQL Reference.

Example

This example shows the results of running sp_help_revdatabase after executing sp_coalesce_fragments. Since sp_coalesce_fragments does not generate any output, this example only shows the output from running sp_help_revdatabase.

SELECT
'dbname'=substring(db_name(ug.dbid),1,10)
,ug.segmap,ug.lstart -- page number within a database
,ug.size,ug.vstart -- page number within dv
,'(vstart+size)' = ug.vstart + ug.size
,'device'=substring(dv.name,1,10)
FROM
master.dbo.sysusages ug,master.dbo.sysdevices dv
WHERE ug.vstart between dv.low and dv.high     AND
dv.status & 2 = 2 --physical disk
AND
db_name(ug.dbid) in ('DB1','DB22','db_junk3')
ORDER BY ug.vstart

This is the results set:

dbname segmap lstart size vstart    (vstart+size) device
------ ------ ------ ---- --------- ------------- ------
DB5         3      0 1024 520093696     520094720 dv9
DB66        3      0 1536 520094720     520096256 dv9
DB5         3   1024  512 520096256     520096768 dv9
DB5         4   1536  512 536870912     536871424 dv8
DB66        4   1536 1024 536871424     536872448 dv8
DB5         4   2048  512 536872448     536872960 dv8
DB777       3      0 1024 687865856     687866880 dv7
DB777       3   2048  512 687866880     687867392 dv7
DB777       4   1024 1024 704643072     704644096 dv6

This is the output from running sp_help_revdatabase:

-- This is the command for executing sp_help_revdatabase
EXECUTE sp_help_revdatabase
-- This is the output generated by executing sp_help_revdatabase
CREATE Database DB5 on dv9 = 2 --  2 Mb = 1024 2Kb pages
go
ALTER  Database DB5 on dv9 = 1
go
ALTER  Database DB5 on dv8 = 1
go
Execute sp_logdevice DB5,dv8
go
ALTER  Database DB5 on dv8 = 1
go
Execute sp_logdevice DB5 ,dv8
go
-- - - - - -
CREATE Database DB66  on dv9 = 3
go
ALTER  Database DB66  on dv8 = 2
go
Execute sp_logdevice DB66 ,dv8
go
-- - - - - -
CREATE Database DB777 on dv7 = 2
go
ALTER  Database DB777 on dv6 = 2
go
Execute sp_logdevice DB777 ,dv6
go
ALTER  Database DB777 on dv7 = 1

The output this procedure generated differs for databases DB5 and DB66. However, both of these databases can be safely loaded with a dump from the other. However, DB777 cannot be involved with dump and load activity along with DB5 or DB66. The following SELECT statement example shows the lpage and segmap combinations for all of these databases after running sp_coalesce_fragments.

SELECT
         'DBName'=substring(db_name(ug.dbid),1,6),
        'FromLPage'=ug.lstart,
        'ToLPage'  =ug.lstart + ug.size - 1,
        ug.segmap
FROM
         master.dbo.sysusages ug
ORDER BY
         DBName,FromLPage

DBName FromLPage   ToLPage     segmap
------ ----------- ----------- -----------
DB5              0        1023           3
DB5           1024        1535           3
DB5           1536        2047           4
DB5           2048        2559           4
DB66             0        1535           3
DB66          1536        2559           4
DB777            0        1023           3
DB777         1024        2047           4
DB777         2048        2559           3

Note lpage 1029 corresponds to a segmap of 3 for databases DB5 and DB66, but to a segmap of 4 for DB777. Because the lpage and segmap combinations are in agreement between DB5 and DB66, dump and load activity between the two databases is safe. This dump and load activity is safe even though DB5 and DB66 have different numbers of fragments after sp_coalesce_fragments has been run.

This procedure does not update or change anything on the server.

Permission

Execute permissions default to permissions of the public group.


sp_makewebtask

sp_makewebtask (version 6.5)

Creates a task that produces an HTML document. This HTML document contains data returned by executed queries.

Syntax

sp_makewebtask {@outputfile = 'outputfile', @query = 'query'}
[, [@fixedfont = fixedfont,] [@bold = bold,] [@italic = italic,]
[@colheaders = colheaders,] [@lastupdated = lastupdated,]
[@HTMLHeader = HTMLHeader,] [@username = username,]
[@dbname = dbname,] [@templatefile = 'templatefile',]
[@webpagetitle = 'webpagetitle',] [@resultstitle = 'resultstitle',]
[[@URL = 'URL', @reftext = 'reftext'] |
[@table_urls = table_urls, @url_query = 'url_query',]]
[@whentype = whentype,] [@targetdate = targetdate,] [@targettime = targettime,]
[@dayflags = dayflags,] [@numunits = numunits,] [@unittype = unittype,]
[@procname = procname, ] [@maketask = maketask,] [@rowcnt = rowcnt,]
[@tabborder = tabborder,] [@singlerow = singlerow,] [@blobfmt = blobfmt]]

@outputfile
Specifies the location of the generated HTML file on the computer that is running SQL Server and can be a UNC name if the file is to be created on a remote computer. This parameter is required and must be unique for each task created with sp_makewebtask. The outputfile variable is of varchar datatype and has a maximum of 255 characters.
@query
Specifies the query to be run. This parameter is required. Query results are displayed in the HTML document in a table format when the task is run with sp_runwebtask. Multiple SELECT queries can be specified and will result in multiple tables being displayed in the @outputfile. The @query parameter is of text datatype.
@fixedfont
Specifies that the query results be displayed in a fixed font (1) or a proportional font (0). Fixed font (1) is the default. The fixedfont variable is of tinyint datatype.
@bold
Specifies that the query results be displayed in a bold font (1) or non-bold font (0). Non-bold (0) is the default. The bold variable is of tinyint datatype.
@italic
Specifies that the query results be displayed in an italic font (1) or non-italic font (0). Non-italic (0) is the default. The italic variable is of tinyint datatype.
@colheaders
Specifies that the query results be displayed with column headers (1) or no column headers (0). Column headers (1) is the default. The colheaders variable is of tinyint datatype.
@lastupdated
Specifies whether the generated HTML document displays a Last Updated: timestamp indicating the last updated date and time (1) or no timestamp (0). Timestamp (1) is the default. The timestamp appears one line before the query results in the HTML document. The lastupdated variable is of tinyint datatype.
@HTMLHeader
Specifies the HTML formatting code for displaying the text contained in the @resultstitle variable. The HTMLHeader variable is of tinyint datatype. These are the values.
Value | HTML formatting code
1 | H1
2 | H2
3 | H3
4 | H4
5 | H5
6 | H6

@username
Specifies the username for executing the query. The default is the current user. The username variable is of varchar datatype and has a maximum of 30 characters. The sa or dbo can specify another @username.
@dbname
Specifies the database name to run the query on. If a database name is not given, @dbname defaults to the current database. The dbname variable is of varchar datatype and has a maximum of 30 characters.
@templatefile
Specifies the path of the template file used to generate the HTML document. The template file contains information about formatting characteristics for HTML documents and contains the tag <%insert_data_here%>, which indicates the position to add the query results in an HTML table. There are no spaces between the less than sign (<) and the "%i" of "%insert" and between the "e%" of "here%" and the greater than sign (>). The templatefile variable is of varchar datatype and has a maximum of 255 characters.

There are two ways to specify the location of the results of a query in a template file:

  1. Include the tag <%insert_data_here%>, which indicates the position to add the query results in an HTML table. There are no spaces between the less than sign (<) and the "%i" of "%insert" and between the "e%" of "here%" and the greater than sign (>).
  2. Specify a complete row format between the keywords <%begindetail%> and <%enddetail%> including <TR>, </TR>, <TD>, and </TD> HTML tags. For each column to display in the results set, include the tag <%insert_data_here%> inside the row format keywords. Specifying the complete row format produces a more precise layout of the results set. When used with this complete row format, @colheaders is ignored.

If @templatefile is specified, the following parameters are ignored when the HTML file is generated:
@bold | @singlerow
@fixedfont | @tabborder
@HTMLHeader | @table_urls
@italic | @URL
@lastupdated | @url_query
@reftext | @webpagetitle
@resultstitle

@webpagetitle
Specifies the title of the HTML document. The default is SQL Server Web Assistant. The webpagetitle variable is of varchar datatype and has a maximum of 255 characters.
@resultstitle
Specifies the title displayed above the query results in the HTML document. The default title is Query Results. The resultstitle variable is of varchar datatype and has a maximum of 255 characters.
@URL
Specifies a hyperlink to another HTML document. The hyperlink is placed after the query results and at the end of the HTML document. If this parameter is specified, @reftext must also be specified, and @table_urls and @url_query cannot be specified. The URL variable is of varchar datatype and has a maximum of 255 characters.

Important If @table_urls = 1, then @url_query must be included to specify the query to be executed for retrieving hyperlink information, and @URL and @reftext cannot be specified. Information is specified either in @URL and @reftext, or in @url_query and @table_urls.

@reftext
Specifies the hyperlink that describes to what HTML document the hyperlink should take the user. The hyperlink text describes the destination and the hyperlink address comes from the URL in the @URL parameter. The reftext variable is of varchar datatype and has a maximum of 255 characters.
@table_urls
Specifies whether hyperlinks will be included on the HTML document (1) and whether the hyperlinks will come from a SELECT statement executed on Microsoft SQL Server. A value of 0 (the default) indicates that there is no query that will generate hyperlinks for the HTML. @URL and @reftext may still be specified for a single hyperlink. A value of 1 indicates that a list of hyperlinks will be created by using @url_query. The table_urls variable is of tinyint datatype.

Important If @table_urls = 1, then @url_query must be included to specify the query to be executed for retrieving hyperlink information, and @URL and @reftext cannot be specified. Information is specified either in @URL and @reftext, or in @url_query and @table_urls.

@url_query
Specifies the SELECT statement to create the URL and its hyperlink text. URLs and hyperlink text come from a SQL Server table. With this parameter, it is possible to generate multiple URLs with associated hyperlinks. Use @url_query with @table_urls. The url_query variable is of varchar datatype with a maximum of 255 characters. The url_query variable must return a results set containing two columns: The first column is the address of a hyperlink and the second column describes the hyperlink. The number of hyperlinks inserted into the HTML document equals the number of rows returned by executing @url_query.
@whentype
Specifies when to run the task that creates the HTML document. The whentype variable is of tinyint datatype. These are the possible values.
Value | Description
1 | Create page now. The web task will be created, executed immediately, and deleted immediately after execution. This is the default.
2 | Create page later. The stored procedure for creating the HTML document will be created immediately, but execution of the web task is deferred until the date and time specified by @targetdate and @targettime (optional). If no @targettime is specified, the web task will be executed at 12:00 a.m. @targetdate is required when @whentype = 2. This web task will be deleted automatically after the targeted date and time has passed.
3 | Create page every n day(s) of the week. The HTML document will be created on day(s) specified in @dayflags and at the time specified by @targettime (optional), beginning with the date in @targetdate. If no @targettime value is specified, the default is 12:00 a.m. The @targetdate parameter is required when @whentype = 3. The day(s) of the week are specified in the @dayflags parameter. More than one day of the week can be specified with the @dayflags parameter. Web tasks created with @whentype = 3 will not be deleted automatically and continue to run on the specified day(s) of the week until the user deletes them by using sp_dropwebtask.
4 | Create page every n minutes, hours, days, or weeks. The HTML document is created every n time period beginning with the date and time specified in @targetdate and @targettime (optional). If no @targettime is specified, the Web task will be executed at 12:00 a.m. The @targetdate parameter is required in this case. The task will run automatically every n minutes, hours, days, or weeks as specified by the @numunits and @unittype parameters. The tasks will run until the user deletes them by using sp_dropwebtask.
5 | Create page upon request. The procedure is created without automatic scheduling. The user creates a HTML document by running sp_runwebtask and deletes it only by using sp_dropwebtask.
6 | Create page now and later. The HTML document is created immediately and re-created according to @whentype = 2.
7 | Create page now and every n day(s) of the week. The HTML document is created immediately and re-created according to @whentype = 3, except no @targetdate is required.
8 | Create page now and periodically thereafter. The HTML document is created immediately and re-created according to @whentype = 4, except no @targetdate is required.
9 | Create page now and upon request. The HTML document is created immediately and re-created according to @whentype = 5. The task must be deleted manually.

@targetdate
Specifies the date the page should be built. The format is YYYYMMDD. In @whentype > 3 cases where @targetdate is important but not supplied, the current date is used. For @whentype = 2 (later), 3 (dayofweek), 4 (periodic), and 6 (now and later), the @targetdate parameter is required. The targetdate variable is of int datatype.
@targettime
Specifies the time the HTML document should be created. When a starting time is important but not supplied, 12:00 a.m. is the default. The format is HHMMSS. The targettime variable is of int datatype.
@dayflags
Specifies what days to update the HTML document. To specify certain days, add the values together. To specify Monday and Thursday, for example, use @dayflags = 18. The dayflags variable is of tinyint datatype. This parameter is required for @whentype = 3 (dayofweek), @whentype = 7 (now and dayofweek); and in cases in which @whentype = 4 (periodic) and @whentype = 8 (now and periodic) where the @unittype = 3 (weeks). These are the values and their descriptions.
Value | Day of the week
1 | Sunday
2 | Monday
4 | Tuesday
8 | Wednesday
16 | Thursday
32 | Friday
64 | Saturday

@numunits
Specify how often to update the HTML document. Values range from 1 to 255. This parameter is used only when @whentype = 4 (periodic) or @whentype = 8 (now and periodically thereafter). For example, if @whentype = 4, @numunits = 6, and @unittype = 1 (hours), the specified HTML document will be updated every six hours. The numunits variable is of tinyint datatype.
@unittype
Specifies how often the HTML document should be updated for @numunits = 4 (periodic) or @whentype = 8 (now and later). Use 1 (hours), 2 (days), 3 (weeks), or 4 (minutes). The unittype variable is of tinyint datatype.
@procname
Specifies the procedure or task name for the HTML document. If no @procname is specified, the procedure name generated by sp_makewebtask is in the form of Web_YYMMDDHHMMSS<spid>. If it is user-specified, the procedure name must meet the conditions for valid procedure names and the procedure name must be unique. The procname variable is of varchar datatype and has a maximum of 28 characters.
@maketask
Specifies whether a task should be created to execute an internal stored procedure that generates an HTML document. The default is to build the task (1). A value of 0 creates the stored procedure. The maketask variable is of tinyint datatype.
@rowcnt
Specifies the maximum number of rows to display in the generated HTML document. The default is to specify that all rows that satisfy the given query will be displayed in the HTML document (0). The rowcnt variable is of int datatype.
@tabborder
Specifies whether a border should be drawn around the results table (1, the default) or no border should be drawn around the results table (0). The taborder variable is of tinyint datatype.
@singlerow
Specifies whether the results are to be displayed as one row per page. If @singlerow is 0 (the default) all results appear on the same page and in the same table. With a value of 1, @singlerow causes a new HTML page to be generated for every qualifying row in the results set. Successive HTML pages are generated with a number appended to the specified output_filename. For example, if web.html is specified as the output filename, by using @singlerow = 1, pages are called web1.html, web2.html, and so on. The singlerow variable is of tinyint datatype.
@blobfmt
Specifies whether all columns of text or image datatypes should be embedded in the same results page (NULL, the default) or whether these fields should be saved in another page and linked to the main HTML document by an URL. To place the text or image data in a separate HTML page, use the following format:
"%n% FILE=output_filename TPLT=template_filename
URL=url_link_name..."

where

n
Is the column number in the results list corresponding to a text field, and n+1 is the URL hyperlink text to the separate text or image HTML file. If a template_filename is provided, the <%insert_data_here%> marker should be used to indicate the data insertion point.

Output filenames end with a number indicating successive rows similar to @singlerow. The output_filename parameter is required, but the template_filename and url_link_name parameters are optional. The FILE output_filename is the full path to the output_file location. If provided, the url_link_name is the http:// link to the file that is accessible through the World Wide Web. If the url_link_name parameter is not provided, then the full physical filename preceeded with the "file:///" tag will be used as the url_link_name. The same syntax in @blobfmt ("%n% FILE=...") can be repeated for multiple text or image columns.

Note Do not add spaces before or after the equal sign (=) and do not put filenames in quotation marks (').

The URL text is part of the results set and is always the column after the original text or image column. This URL text column will not be displayed as a separate column in the results set. The blobfmt variable is of text or image datatype.

Remarks

For scheduled tasks, all errors are reported in the Windows NT event log on the computer running SQL Server and will have a source of xpsqlweb.

Important The sp_dropwebtask, sp_makewebtask, and sp_runwebtask stored procedures can be run only on Microsoft SQL Server version 6.5 databases. Running these procedures on a database of a previous version will return errors.

The SQL Server Web Assistant provides an interface for using the sp_makewebtask stored procedure. For more information about creating web pages with the Web Assistant, see SQL Server Web Assistant earlier in this document.

Fonts available for HTML documents depend upon the capabilities of your web browser software. Consult your browser software for information about font availability and HTML formatting.

Examples

A. Create Multiple Queries Using a Template File

This example creates an HTML document now and upon request and retrieves five book titles and prices, five author first and last names, five publisher names, and five author first and last names. In this document, placement of data is specified by the <%insert_data_here%> marker.

This is the template file:

<HTML>

<HEAD>

<TITLE>SQL Server Multiple Queries with Template Web Sample</TITLE>

<BODY>

<H1>Books For Sale</H1>
<HR>

<P>
<TABLE BORDER>
<TR> <TH><I>Title</I></TH> <TH><B>Price</B></TH> </TR>
<%begindetail%>
<TR> <TD><I> <%insert_data_here%> </I> </TD>
    <TD ALIGN=RIGHT><B> $<%insert_data_here%></B></TD> </TR>
<%enddetail%>
</TABLE>
<P>

<HR>

<%insert_data_here%>

<P>

<TABLE BORDER>
<TR> <TH ALIGN=CENTER>ID</TH> <TH ALIGN=LEFT><I>Publiher's Name</I></TH> </TR>
<%begindetail%>
<TR> <TD> <%insert_data_here%> </TD>
    <TD ALIGN=LEFT><I> <%insert_data_here%></I></TD> </TR>
<%enddetail%>
</TABLE>

<HR>

<%insert_data_here%>

<P>

<A HREF = "http://www.w3.org.pub/WWW/">The World Wide Web Consortium</A><P>
<A HREF = "http://www.w3.org/hypertext/WWW/MarkUp/html3/contents.html">HTML 3 specs</A><P>
<A HREF = "http://www.microsoft.com">MICROSOFT</A><P>

</BODY>

</HTML>

This is the query:

USE pubs
go
EXECUTE sp_makewebtask @outputfile = 'C:\WEB\MULTIPLE.HTM',
@query = 'SELECT title, price FROM titles SELECT au_lname, au_fname
FROM authors SELECT pub_id, pub_name FROM publishers SELECT au_lname,
au_fname FROM authors', @templatefile = 'C:\WEB\MULTIPLE.TPL',
@dbname = 'PUBS', @rowcnt = 5, @whentype = 9
go

This is the results set:

<HTML>

<HEAD>

<TITLE>SQL Server Multiple Queries with Template Web Sample</TITLE>

<BODY>

<H1>Books For Sale</H1>
<HR>

<P>
<TABLE BORDER>
<TR> <TH><I>Title</I></TH> <TH><B>Price</B></TH> </TR>

<TR> <TD><I> The Busy Executive's Database Guide </I> </TD>
    <TD ALIGN=RIGHT><B> $19.99</B></TD> </TR>

<TR> <TD><I> Cooking with Computers: Surreptitious Balance Sheets </I> </TD>
    <TD ALIGN=RIGHT><B> $11.95</B></TD> </TR>

<TR> <TD><I> You Can Combat Computer Stress! </I> </TD>
    <TD ALIGN=RIGHT><B> $2.99</B></TD> </TR>

<TR> <TD><I> Straight Talk About Computers </I> </TD>
    <TD ALIGN=RIGHT><B> $19.99</B></TD> </TR>

<TR> <TD><I> Silicon Valley Gastronomic Treats </I> </TD>
    <TD ALIGN=RIGHT><B> $19.99</B></TD> </TR>

</TABLE>
<P>

<HR>

<P>
<P><TABLE BORDER=1>
<TR><TH ALIGN=LEFT>au_lname</TH><TH ALIGN=LEFT>au_fname</TH></TR>
<TR><TD NOWRAP><TT>White</TT></TD><TD NOWRAP><TT>Johnson</TT></TD></TR>
<TR><TD NOWRAP><TT>Green</TT></TD><TD NOWRAP><TT>Marjorie</TT></TD></TR>
<TR><TD NOWRAP><TT>Carson</TT></TD><TD NOWRAP><TT>Cheryl</TT></TD></TR>
<TR><TD NOWRAP><TT>O'Leary</TT></TD><TD NOWRAP><TT>Michael</TT></TD></TR>
<TR><TD NOWRAP><TT>Straight</TT></TD><TD NOWRAP><TT>Dean</TT></TD></TR>
</TABLE>
<HR>

<P>

<TABLE BORDER>
<TR> <TH ALIGN=CENTER>ID</TH> <TH ALIGN=LEFT><I>Publiher's Name</I></TH> </TR>

<TR> <TD> 0736 </TD>
    <TD ALIGN=LEFT><I> New Moon Books</I></TD> </TR>

<TR> <TD> 0877 </TD>
    <TD ALIGN=LEFT><I> Binnet & Hardley</I></TD> </TR>

<TR> <TD> 1389 </TD>
    <TD ALIGN=LEFT><I> Algodata Infosystems</I></TD> </TR>

<TR> <TD> 1622 </TD>
    <TD ALIGN=LEFT><I> Five Lakes Publishing</I></TD> </TR>

<TR> <TD> 1756 </TD>
    <TD ALIGN=LEFT><I> Ramona Publishers</I></TD> </TR>

</TABLE>

<HR>

<P>
<P><TABLE BORDER=1>
<TR><TH ALIGN=LEFT>au_lname</TH><TH ALIGN=LEFT>au_fname</TH></TR>
<TR><TD NOWRAP><TT>White</TT></TD><TD NOWRAP><TT>Johnson</TT></TD></TR>
<TR><TD NOWRAP><TT>Green</TT></TD><TD NOWRAP><TT>Marjorie</TT></TD></TR>
<TR><TD NOWRAP><TT>Carson</TT></TD><TD NOWRAP><TT>Cheryl</TT></TD></TR>
<TR><TD NOWRAP><TT>O'Leary</TT></TD><TD NOWRAP><TT>Michael</TT></TD></TR>
<TR><TD NOWRAP><TT>Straight</TT></TD><TD NOWRAP><TT>Dean</TT></TD></TR>
</TABLE>
<HR>

<P>

<A HREF = "http://www.w3.org.pub/WWW/">The World Wide Web Consortium</A><P>
<A HREF = "http://www.w3.org/hypertext/WWW/MarkUp/html3/contents.html">HTML 3 specs</A><P>
<A HREF = "http://www.microsoft.com">MICROSOFT</A><P>

</BODY>

</HTML>
B. Create Hyperlinks

This example creates a two-column table called my_favorite_sites. The first column url_def is the URL to a specific web location, and the second column display_text, is the hyperlink text for the corresponding URL. After creating the table and filling it with values, the HTML document is created.

This is the query:

USE pubs
go
CREATE TABLE my_favorite_web_sites(url_def varchar(255), display_text varchar(255) NULL)
go
INSERT my_favorite_web_sites(url_def, display_text)
VALUES ('http://www.micsosoft.com', 'Microsoft Home Page')
INSERT my_favorite_web_sites(url_def) VALUES ('http://www.yahoo.com')
INSERT my_favorite_web_sites(url_def, display_text)
VALUES ('http://www.w3.org.pub/WWW/', 'The World Wide Web Consortium')
INSERT my_favorite_web_sites(url_def, display_text)
VALUES ('http://www.nasa.gov', 'NASA  Home Page')
go
EXECUTE sp_makewebtask @outputfile = 'C:\WEB\URL.HTM',
@query='SELECT title, price FROM titles ORDER BY price desc',
@table_urls = 1, @tabborder = 0, @lastupdated=0, @colheaders = 0,
@url_query= 'SELECT url_def, display_text FROM
my_favorite_web_sites', @whentype = 9
go

This is the results set:

<HTML>

<HEAD>

<TITLE>Microsoft SQL Server Web Assistant</TITLE>

<BODY>

<H1>Query Results</H1>
<HR>

<P>
<P><TABLE BORDER=0>
<TR><TD NOWRAP><TT>But Is It User Friendly?</TT></TD><TD NOWRAP><TT>22.95</TT></TD></TR>
<TR><TD NOWRAP><TT>Computer Phobic AND Non-Phobic Individuals: Behavior Variations</TT></TD><TD NOWRAP><TT>21.59</TT></TD></TR>
<TR><TD NOWRAP><TT>Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean</TT></TD><TD NOWRAP><TT>20.95</TT></TD></TR>
<TR><TD NOWRAP><TT>Secrets of Silicon Valley</TT></TD><TD NOWRAP><TT>20.00</TT></TD></TR>
<TR><TD NOWRAP><TT>The Busy Executive's Database Guide</TT></TD><TD NOWRAP><TT>19.99</TT></TD></TR>
<TR><TD NOWRAP><TT>Straight Talk About Computers</TT></TD><TD NOWRAP><TT>19.99</TT></TD></TR>
<TR><TD NOWRAP><TT>Silicon Valley Gastronomic Treats</TT></TD><TD NOWRAP><TT>19.99</TT></TD></TR>
<TR><TD NOWRAP><TT>Prolonged Data Deprivation: Four Case Studies</TT></TD><TD NOWRAP><TT>19.99</TT></TD></TR>
<TR><TD NOWRAP><TT>Sushi, Anyone?</TT></TD><TD NOWRAP><TT>14.99</TT></TD></TR>
<TR><TD NOWRAP><TT>Cooking with Computers: Surreptitious Balance Sheets</TT></TD><TD NOWRAP><TT>11.95</TT></TD></TR>
<TR><TD NOWRAP><TT>Fifty Years in Buckingham Palace Kitchens</TT></TD><TD NOWRAP><TT>11.95</TT></TD></TR>
<TR><TD NOWRAP><TT>Is Anger the Enemy?</TT></TD><TD NOWRAP><TT>10.95</TT></TD></TR>
<TR><TD NOWRAP><TT>Emotional Security: A New Algorithm</TT></TD><TD NOWRAP><TT>7.99</TT></TD></TR>
<TR><TD NOWRAP><TT>Life Without Fear</TT></TD><TD NOWRAP><TT>7.00</TT></TD></TR>
<TR><TD NOWRAP><TT>You Can Combat Computer Stress!</TT></TD><TD NOWRAP><TT>2.99</TT></TD></TR>
<TR><TD NOWRAP><TT>The Gourmet Microwave</TT></TD><TD NOWRAP><TT>2.99</TT></TD></TR>
<TR><TD NOWRAP><TT>The Psychology of Computer Cooking</TT></TD><TD NOWRAP>n/a</TD></TR>
<TR><TD NOWRAP><TT>Net Etiquette</TT></TD><TD NOWRAP>n/a</TD></TR>
</TABLE>
<HR>
<A HREF = "http://www.microsoft.com">Microsoft Home Page</A><P>
<A HREF = "http://www.yahoo.com">http://www.yahoo.com</A><P>
<A HREF = "http://www.w3.org.pub.WWW/">The World Wide Web Consortium</A><P>

</BODY>

</HTML>
C. Execute Multiple Queries with Single Row Mode

This example creates four HTML documents from multiple queries and uses the single row mode.

This is the query:

USE pubs
go
EXECUTE sp_makewebtask @outputfile = 'C:\WEB\SROW.HTM',
@query = 'SELECT title, price FROM titles ORDER BY price desc
SELECT au_lname, au_fname FROM authors WHERE state = "CA" ',
@fixedfont = 0, @webpagetitle = 'Single row SQL Web Assistant',
@resultstitle = 'One row per page results', @singlerow = 1,
@rowcnt = 4,@URL = "http://www.microsoft.com",
@reftext = 'Microsoft Home Page'
go

This is the first file of the results set called C:\WEB\SROW1.HTM:

<HTML>

<HEAD>

<TITLE>Single row SQL Web Assistant</TITLE>

<BODY>

<H1>One row per page results</H1>
<HR>

<PRE>Last updated: Jun 5 1996  3:15PM</PRE>

<P>
<P><TABLE BORDER=1>
<TR><TH ALIGN=LEFT>title</TH><TH ALIGN=LEFT>price</TH></TR>
<TR><TD NOWRAP>But Is It User Friendly?</TD><TD NOWRAP>22.95</TD></TR>
</TABLE>
<HR>
<A HREF = "http://www.microsoft.com">Microsoft Home Page</A><P>

</BODY>

</HTML>

This is the second file of the results set called C:\WEB\SROW2.HTM:

<HTML>

<HEAD>

<TITLE>Single row SQL Web Assistant</TITLE>

<BODY>

<H1>One row per page results</H1>
<HR>

<PRE>Last updated: Jun 5 1996  3:15PM</PRE>

<P>
<P><TABLE BORDER=1>
<TR><TH ALIGN=LEFT>title</TH><TH ALIGN=LEFT>price</TH></TR>
<TR><TD NOWRAP>Computer Phobic AND Non-Phobic Individuals: Behavior Variations</TD><TD NOWRAP>21.59</TD></TR>
</TABLE>
<HR>
<A HREF = "http://www.microsoft.com">Microsoft Home Page</A><P>

</BODY>

</HTML>

This is the third file of the results set called C:\WEB\SROW3.HTM:

<HTML>

<HEAD>

<TITLE>Single row SQL Web Assistant</TITLE>

<BODY>

<H1>One row per page results</H1>
<HR>

<PRE>Last updated: Jun 5 1996  3:15PM</PRE>

<P>
<P><TABLE BORDER=1>
<TR><TH ALIGN=LEFT>au_lname</TH><TH ALIGN=LEFT>au_fname</TH></TR>
<TR><TD NOWRAP>White</TD><TD NOWRAP>Johnson</TD></TR>
</TABLE>
<HR>
<A HREF = "http://www.microsoft.com">Microsoft Home Page</A><P>

</BODY>

</HTML>

This is the fourth file of the results set called C:\WEB\SROW4.HTM:

<HTML>

<HEAD>

<TITLE>Single row SQL Web Assistant</TITLE>

<BODY>

<H1>One row per page results</H1>
<HR>

<PRE>Last updated: Jun 5 1996  3:15PM</PRE>

<P>
<P><TABLE BORDER=1>
<TR><TH ALIGN=LEFT>au_lname</TH><TH ALIGN=LEFT>au_fname</TH></TR>
<TR><TD NOWRAP>Green</TD><TD NOWRAP>Marjorie</TD></TR>
</TABLE>
<HR>
<A HREF = "http://www.microsoft.com">Microsoft Home Page</A><P>

</BODY>

</HTML>
D. Execute Multiple Queries Using Data Insert Markers and a Template

This example creates two HTML documents from multiple queries by using a template that places each book title and price in separate HTML files.

This is the template file:

<HTML>

<HEAD>

<TITLE>SQL Server Multiple Queries, Data Insert Markers, & Template Web Sample</TITLE>

<BODY>

<H1>Books For Sale</H1>
<HR>

<P>
<TABLE BORDER>
<TR> <TH><I>Title</I></TH> <TH><B>Price</B></TH> </TR>
<%begindetail%>
<TR> <TD><I> <%insert_data_here%> </I> </TD>
    <TD ALIGN=RIGHT><B> $<%insert_data_here%></B></TD> </TR>
<%enddetail%>
</TABLE>
<P>

<HR>

<A HREF = "http://www.w3.org.pub/WWW/">The World Wide Web Consortium</A><P>
<A HREF = "http://www.w3.org/hypertext/WWW/MarkUp/html3/contents.html">HTML 3 specs</A><P>
<A HREF = "http://www.microsoft.com">MICROSOFT</A><P>

</BODY>

</HTML>

This is the query:

USE pubs
go
EXECUTE sp_makewebtask @outputfile = 'C:\WEB\DATAINS.HTM',
@query = 'SELECT title, price FROM titles',
@templatefile = 'C:\WEB\DATAINS.TPL', @dbname = 'PUBS',
@rowcnt = 2, @whentype = 9, @singlerow = 1
go

This is the first file of the results set called C:\WEB\DATAINS1.HTM:

<HTML>

<HEAD>

<TITLE>SQL Server Multiple Queries, Data Insert Markers, & Template Web Sample</TITLE>

<BODY>

<H1>Books For Sale</H1>
<HR>

<P>
<TABLE BORDER>
<TR> <TH><I>Title</I></TH> <TH><B>Price</B></TH> </TR>

<TR> <TD><I> The Busy Executive's Database Guide </I> </TD>
    <TD ALIGN=RIGHT><B> $19.99</B></TD> </TR>

</TABLE>
<P>

<HR>

<A HREF = "http://www.w3.org.pub/WWW/">The World Wide Web Consortium</A><P>
<A HREF = "http://www.w3.org/hypertext/WWW/MarkUp/html3/contents.html">HTML 3 specs</A><P>
<A HREF = "http://www.microsoft.com">MICROSOFT</A><P>

</BODY>

</HTML>

This is the second file of the results set called C:\WEB\DATAINS2.HTM:

<HTML>

<HEAD>

<TITLE>SQL Server Multiple Queries, Data Insert Markers, & Template Web Sample</TITLE>

<BODY>

<H1>Books For Sale</H1>
<HR>

<P>
<TABLE BORDER>
<TR> <TH><I>Title</I></TH> <TH><B>Price</B></TH> </TR>

<TR> <TD><I> Cooking with Computers: Surreptitious Balance Sheets </I> </TD>
    <TD ALIGN=RIGHT><B> $11.95</B></TD> </TR>

</TABLE>
<P>

<HR>

<A HREF = "http://www.w3.org.pub/WWW/">The World Wide Web Consortium</A><P>
<A HREF = "http://www.w3.org/hypertext/WWW/MarkUp/html3/contents.html">HTML 3 specs</A><P>
<A HREF = "http://www.microsoft.com">MICROSOFT</A><P>

</BODY>

</HTML>
E. Execute Query Using @blobfmt

This example executes a single query and places the information into HTML documents. The publishers table is linked with the pub_info table to provide company logos in the HTML documents.

This is the template file called C:\WEB\BLOBSMP.TPL:

<HTML>

<HEAD>

<TITLE>Publishers PR Info</TITLE>

</HEAD>

<BODY>

<HR>

<PRE>

<%insert_data_here%>

</PRE>

</BODY>

</HTML>

This is the query:

USE pubs
go
EXECUTE sp_makewebtask @outputfile = 'C:\WEB\BLOBSMP.HTM',
@query = 'SELECT pr_info, pub_name, city, state, country, logo,
pub_info.pub_id FROM pub_info, publishers
WHERE pub_info.pub_id = publishers.pub_id',
@webpagetitle = 'Publishers Home Page',
@resultstitle = 'Premier Publishers and Their Home Page Links',
@whentype = 9, @blobfmt='%1% FILE=C:\WEB\BLOBSMP.HTM
TPLT=C:\WEB\BLOBSMP.TPL %6% FILE=C:\WEB\PUBLOGO.BMP', @rowcnt = 2
go

This is the main HTML document BLOBSMP.HTM, which contains hyperlinks to the logo bitmaps and to the publisher's home web pages.

<HTML>

<HEAD>

<TITLE>Publishers Home Page</TITLE>

<BODY>

<H1>Premier Publishers and Their Home Page Links</H1>
<HR>

<PRE><TT>Last updated: Jun 28 1996  3:15PM</TT></PRE>

<P>
<P><TABLE BORDER=1>
<TR><TH ALIGN=LEFT>pr_info</TH><TH ALIGN=LEFT>city</TH><TH ALIGN=LEFT>state</TH><TH ALIGN=LEFT>country</TH><TH ALIGN=LEFT>logo</TH></TR>
<TR><TD NOWRAP><A HREF = "file:///c:\web\blobfmt1.htm">New Moon Books</A></TD><TD NOWRAP><TT>Boston</TT></TD><TD NOWRAP><TT>MA</TT></TD><TD NOWRAP><TT>USA</TT></TD><TD NOWRAP><A HREF = "file:///c:\web\publogo1.bmp">0736</A></TD></TR>
<TR><TD NOWRAP><A HREF = "file:///c:\web\blobfmt2.htm">Binnet & Hardley</A></TD><TD NOWRAP><TT>Washington</TT></TD><TD NOWRAP><TT>DC</TT></TD><TD NOWRAP><TT>USA</TT></TD><TD NOWRAP><A HREF = "file:///c:\web\publogo2.bmp">0877</A></TD></TR>
</TABLE>
<HR>

</BODY>

</HTML>

This is the first file of the results set called C:\WEB\BLOBSMP1.HTM:

<HTML>

<HEAD>

<TITLE>Publishers PR Info</TITLE>

</HEAD>

<BODY>

<HR>

<PRE>

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.

This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Boo

</PRE>

</BODY>

</HTML>

This is the second file of the results set called C:\WEB\BLOBSMP2.HTM:

<HTML>

<HEAD>

<TITLE>Publishers PR Info</TITLE>

</HEAD>

<BODY>

<HR>

<PRE>

This is sample text data for Binnet & Hardley, publisher 0877 in the pubs database. Binnet & Hardley is located in Washington, D.C.

This is sample text data for Binnet & Hardley, publisher 0877 in the pubs database. Binnet & Hardley is located in Washington, D.C.

This is sample text data for Binnet & Hardley, publisher 0877 in the pubs database. Binnet & Hardley is located in Washington, D.C.

This is sample text data for Binnet & Hardley, publisher 0877 in the pubs database. Binnet & Hardley is located in Washington, D.C.

This is sample text data for Binnet & Hardley, publisher 0877 in the pubs database. Binnet & Hardley is located in Washington, D.C.

</PRE>

</BODY>

</HTML>

Permission

The user must have SELECT permissions to run the specified query and CREATE PROCEDURE permissions in the database in which the query will run. The SQL Server account must have privileges to write the generated HTML document to the specified location. Only the system administrator can impersonate other users.


sp_rename

sp_rename (version 6.5)

Changes the name of a user-created object (for example, table, column, user datatype) in the current database.

For additional syntax information for sp_rename, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

sp_rename oldname, newname [, COLUMN | INDEX | OBJECT | USERDATATYPE]

where

oldname
Is the name of the object to rename. The database owner or system administrator can change the name of user-created objects without using SETUSER. A fully qualified object can be specified.
newname
Is the new name for the specified object. The database owner or system administrator can change the name of user-created objects without using SETUSER. A fully qualified object name can be specified.
COLUMN | INDEX | OBJECT | USERDATATYPE]
Specifies whether the object being renamed is a column, index, object, or user-defined datatype.
Value | Definition
OBJECT | An item of a type tracked in sysobjects. For example, OBJECT could be used to rename objects including constraints (Check, Foreign Key, Primary/Unique Key), user tables, views, stored procedures, triggers, and rules.
USERDATATYPE | A user-defined datatype added by executing sp_addtype.

Remarks

This procedure automatically renames the associated index whenever a primary key or unique constraint is renamed. If a renamed index is tied to a primary key constraint, the primary key is also automatically renamed by sp_rename.

Important After renaming stored procedures and views, consider dropping and re-creating all dependent stored procedures and views. Some patterns of renaming may confuse the behavior of the dependent objects.

Stored procedures and views can be dropped and re-created quickly because neither object stores data. For best results renaming textual objects, drop and re-create the object by its new name.

Caution Using sp_rename to rename textual objects may put the new object name in the name column of the sysobjects system table and leave the previous name for the object in the text column of the syscomments system table.

Example

In this example, the database owner renames a Primary Key constraint owned by another user.

IF user_id()=1
    EXECUTE sp_rename 'dab32.usr_sally.cns_tab44_pky', 'pky44', 'object'

Permission

The system administrator, the database owner, or the object owner can execute this system stored procedure.


sp_runwebtask

sp_runwebtask (version 6.5)

Executes a previously defined web task and generates the HTML document. The task to run is identified by the output filename, by the procedure name, or by both parameters.

Syntax

sp_runwebtask {@procname = procname | @outputfile = outputfile |
@procname = procname, @outputfile = outputfile}

where

@outputfile
Specifies the name of the web task to run. The outputfile variable is of varchar datatype and has a maximum of 255 characters.
@procname
Specifies the name of the web task procedure to run. The named procedure defines the query for the web task. The procname variable is of varchar datatype and has a maximum of 28 characters.

Remarks

This stored procedure must be executed in the same database specified in the @dbname parameter of sp_makewebtask.

Output produced by sp_runwebtask is the actual HTML source. You can view the source document with most word processing software.

Important The sp_dropwebtask, sp_makewebtask, and sp_runwebtask stored procedures can be run only on Microsoft SQL Server version 6.5 databases. Running these procedures on a database of an earlier version will return errors.

Example

This example runs a web task by using the @outputfile of C:\WEB\MYFILE.HTML and an @procname of MYHTML.

sp_runwebtask @procname = MYHTML, @outputfile = 'C:\WEB\MYFILE.HTML'

Permission

The user must have SELECT permissions to run the specified query.


sp_serveroption

sp_serveroption (version 6.5)

Sets server options. You can set the server as a DSN server.

For additional syntax information for sp_serveroption, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

sp_serveroption [server_name, optname, {true | false}]

where

optname
Is the type of server. Can be one of these:
dist | Distribution server
dpub | Remote publisher to this distribution server
dsn | DSN server
fallback | Fallback server
pub | Publication server
rpc | Remote server
sub | Subscription server

The default is rpc.

true | false
Specifies whether to set the option. Choose true to set the option; choose false to turn it off.

Remarks

The DSN is the ODBC data source name for the server. A DSN is a server that receives replication data through ODBC. This DSN can be accessed only through Microsoft SQL Server because replication is being used.

Example

This example identifies the ACCOUNTS server as a DSN server.

sp_serveroption ACCOUNTS, dsn, true

Permission

Only the system administrator can use this procedure to set server options.


sp_setnetname

sp_setnetname (version 6.5)

Sets the network names in sysservers to their actual network machine names for remote computers running SQL Server. Names can include hyphens and other non-alphabetic characters. This procedure can be used to enable execution of remote stored procedure calls to machines that have network names containing invalid SQL Server identifiers.

Syntax

sp_setnetname @server [ = 'server'], @netname [ = 'netname']

where

@server
Is the name of the remote server as referenced in user-coded remote stored procedure call syntax. Exactly one row in sysservers must already exist to use this @server.
@netname
Is the network name of the computer to which remote stored procedure calls will be made. This name must match the Windows NT machine name, and it can include characters, such as hyphens, that are not allowed in SQL Server identifiers. In most cases, setting the @netname to the network machine name enables remote stored procedure calls to a SQL Server running on a remote machine with a name that is not legal in SQL Server.

If a DB-Library alias matching the @netname is defined on the SQL Server machine, the connection string information in that alias is used to connect to the remote SQL Server.

Remarks

Because Transact-SQL syntax does not usually recognize characters such as a hyphen in an object name, some remote stored procedure calls to Windows NT computers that have a machine name containing a hyphen can cause problems. Use this procedure to differentiate the values in sysservers.srvname versus sysservers.srvnetname.

For example, if your Windows NT Server machine name is MY-NT-PC, SQL Server Setup warns you that this computer name contains an invalid identifier, the hyphen (-). If your network system administrator requires MY-NT-PC to remain the machine name, then the system administrator can use sp_addserver and sp_setnetname to keep the server's network name MY-NT-PC while the computer's local name is another name that contains valid SQL Server identifiers.

For example:

sp_addserver 'MY_NT_PC', 'local'
sp_setnetname 'MY_NT_PC', 'MY-NT-PC'

This procedure aids replication in situations where Windows NT machines with invalid SQL Server names are involved.

Example

This example is a typical administrative sequence on the SQL Server that issues the remote stored procedure call.

EXECUTE sp_addserver 'Win_NT1'
EXECUTE sp_setnetname 'Win_NT1','Win-NT1'
EXECUTE Win_NT1.master.dbo.sp_who

Permissions

Only the system administrator can execute this procedure.


sp_tableoption

Sets option values for user-defined tables.

Syntax

sp_tableoption @TableNamePattern [, '@OptionName'] [, '@OptionValue']

where

@TableNamePattern
Specifies the qualified or non-qualified name of a user-defined database table. This parameter can be any pattern appropriate for the LIKE operator. Use single quotation marks (') if specifying @TableNamePattern with the LIKE operator. Quotation marks are not necessary if a single tablename is specified. If a fully qualified table name, including a database name, is provided the database name must be the name of the current database.
@OptionName
Specifies a table option name. The default is NULL, which lists all available table options and the corresponding default values assigned to new tables (0 = false, 1 = true). These are the possible values for @OptionName.
@OptionName | Default | Description
insert row lock | false | Disables (false) or enables (true) the insert row locking (IRL) feature for the specified table.
pintable | false | Marks the table either as either no longer RAM-resident (false) or as RAM-resident (true).

@OptionValue
Specifies whether @OptionName is enabled or disabled. The possible values are true or false. The default is NULL, which lists the current settings for all matching tables.

Examples

A. Enable insert row lock Option for All Tables of the Current Database
EXECUTE sp_tableoption '%.%', 'insert row lock', 'true'
B. Disable insert row lock Option for sales Table
EXECUTE sp_tableoption 'sales', 'insert row lock', 'false'
C. Report on insert row locking Status for All Tables of the Current Database
EXECUTE sp_tableoption '%.%', 'insert row lock'

Permissions

Only the system administrator can modify the pintable table option.

The system administrator or database owner can modify the insert row lock option for any user-defined table. Users other than the system administrator or database owner can modify options only for tables they own.

Any user can run sp_tableoption to generate a report listing table option values for all user-defined tables.


sp_who

sp_who (version 6.5)

Provides information about current SQL Server users and processes. The information returned can be filtered to return only those processes that are not idle.

For additional syntax information for sp_who, see the Microsoft SQL Server Transact-SQL Reference.

Syntax

sp_who [login_name | 'spid' | active]

where

active
Returns information on active processes. Specifying active will exclude idle processes from the report. Idle processes are sleeping and are not involved in blocking.

For more information about blocking, see the Microsoft SQL Server Administrator's Companion.

Remarks

This procedure reports information about a specific user, a specified SQL Server process, all users currently running a process, or all active processes. Executing sp_who without parameters reports which users are running what processes in all databases.

Example

A. Display All Active Processes
sp_who active
B. Display a Specific Process with Process ID
sp_who '10' --specifies the process_id

Permission

Execute permission defaults to the public group.


msdb Tables

In SQL Server 6.5, tables have been added to the msdb database to aid in maintaining backup information. These are the new tables.

Table name | Description
sysbackupdetail | Specifies a summary of the devices used to backup (dump).
sysbackuphistory | Specifies a summary of each backup operation (dump).
sysrestoredetail | Specifies a summary of the devices used to restore (load).
sysrestorehistory | Specifies a summary of each restore operation (load).

SQL Server automatically maintains a complete online backup and restore history in the msdb database. This information includes who performed the backup, at what time, and on which devices or files it is stored.

Backup and restore events are recorded even if they were created with custom applications or third-party tools. A Visual Basic application that calls SQL-DMO objects to perform backup and restore operations will cause the events to be logged in these tables.

After each DUMP statement is executed, a description of the dump is saved in sysbackuphistory and the dump device details are saved in sysbackupdetail as part of a single transaction.

After each LOAD statement is executed, a description of the restore is saved in sysrestorehistory and the device details are saved in sysrestoredetail. If for any reason the history cannot be written to msdb database, a message is written to the Windows NT event log and to the SQL Server error log.


sysbackupdetail

sysbackupdetail (version 6.5)

Contains a row for each device comprising a dump.

These are the columns in the sysbackupdetail table.

Column | Datatype | Description
backup_id | int | Specifies the foreign key corresponding to the sysbackuphistory record. Cannot be NULL.
device_type | smallint | Represents a device type. Cannot be NULL. These are the supported numerical values: 2 Disk 3 Floppy 5 Tape 6 Pipe +100 if backing up to a named device.
device_name | varchar(255) | Specifies the device name. Cannot be NULL.
backup_size | int | Specifies the size of the backup on this device in kilobytes.
volume_name | varchar(6) | Specifies a volume ID or label.
expiration_date | datetime | Specifies the expiration date for the volume.

Foreign Key

In the sysbackupdetail table there is a Foreign Key constraint, fk_backup_id, on the backup_id column of the sysbackuphistory table.


sysbackuphistory

sysbackuphistory (version 6.5)

Contains one row for each completed dump operation.

These are the columns in the new sysbackuphistory table.

Column | Datatype | Description
backup_id | int identity(1,1) | Specifies the primary key.
id_number | smallint | Specifies the position of the backup on the volume.
backup_type | smallint | Represents the type of backup. The supported numerical values are: 1 Database 2 Transaction 3 Table
database_name | varchar(30) | Specifies the database name.
table_owner | varchar(30) | Specifies the table owner for table backups.
table_name | varchar(30) | Specifies the table name for table backups.
operator_name | char(30) | Specifies the name of the person who performed the backup.
backup_start | datetime | Specifies the date and time of the oldest committed transaction for TRANSACTION dumps. Otherwise, specifies the date and time the dump was performed.
backup_finish | datetime | Specifies the date and time of the last committed transaction for TRANSACTION dumps. Otherwise, specifies the date and time the dump was performed.
server_sort | smallint | Specifies the sort order for the database server that performed the dump.
server_code_page | smallint | Specifies the character code page for the database server that performed the dump.
striped_backup | smallint | Specifies whether the backup is striped. These are the supported numerical values: 1 striped 0 not striped Cannot be NULL
stripe_count | smallint | Specifies the number of devices in the stripeset. Cannot be NULL.
stripe_set_name | varchar(30) | Specifies the stripeset name.
total_backup_size | int | Specifies the size of the backup in kilobytes. Cannot be NULL.
current_sequence | char(14) | Specifies the current or old sequence number. This number matches the Curseq column number returned by the LOAD HEADERONLY statement. Cannot be NULL.
new_sequence | char(14) | Specifies the new sequence number. This number matches the Newseq column number returned by the LOAD HEADERONLY statement.

Index

The clustered index, pk_backup_id, is created on the primary key, backup_id, of the sysbackuphistory table.


sysrestorehistory

sysrestorehistory (version 6.5)

Contains one row for each completed load operation. The columns match those of sysbackuphistory except that the identity column is called restore_id rather than backup_id and an additional column is added.

These are the columns in the sysrestorehistory table.

Column | Datatype | Description
restore_id | int | Specifies the foreign key that corresponds to the sysbackuphistory record.
id_number | smallint | Specifies the position of the backup on the volume.
backup_type | smallint | Represents the type of backup. These are the supported numerical values: 1 Database 2 Transaction 3 Table
source_database_name | varchar(30) | Specifies the source, original, database name. Cannot be NULL.
new_database_name | varchar(30) | Specifies the new destination database name.
table_owner | varchar(30) | Specifies the name of the person who is the owner of this specific table.
table_name | varchar(30) | Specifies the name of the table to be used for table backups.
operator_name | char(30) | Specifies the name of the person who performed the last backup.
backup_start | datetime | Specifies the date and time of the oldest committed transaction. Cannot be NULL.
backup_finish | datetime | Specifies the date and time of the last committed transaction. Cannot be NULL.
server_sort | smallint | Specifies the database server's sort order. Cannot be NULL.
server_code_page | smallint | Specifies the database server's code page. Cannot be NULL.
striped_backup | smallint | Specifies whether the backup is striped. These are the supported numerical values: 1 striped 0 not striped Cannot be NULL.
stripe_count | smallint | Specifies the number of devices in the stripeset. Cannot be NULL.
stripe_set_name | varchar(30) | Specifies the stripeset name.
total_backup_size | int | Specifies the size of the backup in kilobytes. Cannot be NULL.
current_sequence | char(14) | Specifies the current or old sequence number. This number matches the Curseq column number returned by the LOAD HEADERONLY statement. Cannot be NULL.
new_sequence | char(14) | Specifies the new sequence number. This number matches the Newseq column number returned by the LOAD HEADERONLY statement.
restore_date | datetime | Specifies the date and time that the restore operation was performed. Cannot be NULL.

Index

The clustered index pk_restore_id is created on the primary key restore_id of the sysrestorehistory table.


sysrestoredetail

sysrestoredetail (version 6.5)

Contains a row for each device that comprises a dump.

Note that the columns are the same as for sysbackupdetail except that the backup_id column is called restore_id, and it refers to the corresponding row in sysrestorehistory.

These are the columns in the sysrestoredetail table.

Column | Datatype | Description
restore_id | int | Specifies the foreign key that corresponds to the sysbackuphistory record.
device_type | smallint | Represents a device type. The supported numerical values: 2 Disk 3 Floppy 5 Tape 6 Pipe +100 if restoring from a named device. Cannot be NULL.
device_name | varchar(255) | Specifies the device or Universal Naming Convention (UNC) name.
backup_size | int | Specifies, in kilobytes, the size of the backup on this device. Cannot be NULL.
volume_name | varchar(6) | Specifies a volume ID or label.
expiration_date | datetime | Specifies the expiration date for the volume.

Foreign Key

In the sysrestoredetail table there is a Foreign Key constraint fk_restore_id on the restore_id column of the sysrestorehistory table.


MSsubscriber_info Table

MSsubscriber_info Table (version 6.5)

A description column has been added to the distribution table MSsubscriber_info.

Column | Datatype | Description
description | varchar(255) | A description column that can hold user-generated descriptions. The description column has a maximum of 255 characters and a varchar datatype. Existing rows in the MSsubscriber_info table will initialize the description column to SQL Server 6.0.


syscolumns System Table

syscolumns System Table (version 6.5)

In SQL Server 6.5, two status bits have been added to the status column in syscolumns.

New status bits | Description
16 | Indicates ANSI_PADDING was in affect when a varchar or a varbinary column was created. Indicates that trailing blanks are preserved when varchar data is updated or inserted; and that trailing zeroes are preserved when varbinary data is updated or inserted.
32 | Indicates that a varchar or a varbinary column is a fixed-length datatype that accepts NULLS. varchar data is padded with blanks to the maximum length and varbinary data is padded with zeroes.


sysindexes System Table

sysindexes System Table (version 6.5)

An updatestamp column has been added to the sysindexes table.

Column | Datatype | Description
UpdateStamp | varbinary | This column is used for internal synchronization of changes to row and page counts.


sysprocesses System Table

sysprocesses System Table (version 6.5)

Columns have been added to the sysprocesses table. The sysprocesses table holds information about processes running on the SQL Server. These processes can be client processes or system processes.

These are the columns in the sysprocesses table.

Column | Datatype | Description
last_batch | char(8) | The last time a client process executed a remote stored procedure call or an EXECUTE statement. For system processes, the time at which SQL Server startup occurred is stored.
login_time | char(8) | The time at which a client process logged into the server. For system processes, the time at which SQL Server startup occurred is stored.
nt_domain | char(30) | The Windows NT domain for the client (if using integrated security) or a trusted connection.
nt_username | char(30) | The Windows NT username for the process if (if using integrated security) or a trusted connection.
net_address | char(12) | The assigned unique identifier for the network interface card on each user's workstation. When the user logs in, this identifier is inserted in the net_address column.
net_library | char(12) | The column in which the client's network library is stored. Every client process comes in on a network connection. Network connections have a network library associated with them that allows them to make the connection.


sysprotects System Table

sysprotects System Table (version 6.5)

The protecttype column in sysprotects adds a new value for granting permission to grant permissions. This is referred to as GRANT WITH GRANT. The new value for GRANT WITH GRANT is 204.

The system table sysprotects now has an additional column called grantor. This column has a smallint datatype.

The sysprotects table also has a clustered index on the columns id, action, grantor, uid, and protecttype. The value of grantor defaults to that of the object owner. The create database objects privilege is NULL.

Column | Datatype | Description
protecttype | tinyint | The protecttype column can have these values: 204 GRANT_W_GRANT 205 GRANT 206 REVOKE
grantor | smallint | The user_id of the user who issued the GRANT or REVOKE permission.


Errata

The information in this section outlines changes to these Microsoft SQL Server 6.0 documents:

  • Microsoft SQL Server Database Developer's Companion
  • Microsoft SQL Server Transact-SQL Reference


Database Developer's Companion Errata

The following changes should be made to the Microsoft SQL Server Database Developer's Companion for Microsoft SQL Server 6.0.

  • On page 47, the example for deleting records with the DELETE statement should be:
    DELETE titles
FROM authors, titles, titleauthor
WHERE titles.title_id = titleauthor.title_id
AND authors.au_id = titleauthor.au_id
AND city = 'Oakland'
  • On page 58, the SELECT statement example before the "Choosing Specific Columns" topic should be:
    SELECT pub_id, pub_name, city, state, country
FROM publishers
  • On page 66, in the "Datatype Precedence in Mixed-mode Arithmetic" section, the sentence that begins with "The only execption" should be:

    The only exeception to this rule is when converting money and other number datatypes such as float, real, decimal, and numeric; money takes precedence, even though its type is lower, except when using float where the result is float.

  • On page 72, the "Note" about WHERE conditions should be:

    Note The only WHERE conditions that you can use on text columns with certain functions such as patindex() are IS NULL, IS NOT NULL, LIKE, and NOT LIKE.

  • On page 72, in the WHERE clause of the SELECT statement, the list of search_condition should be:
  • Comparison Operators (such as =, <>, <, and >)
  • All records (=ALL, >ALL)
    SELECT au_lname, au_fname, zip FROM authors where zip = all
(SELECT zip FROM authors WHERE zip = '94609')

SELECT  t1.title, t1.advance
FROM  titles t1
WHERE t1.advance > ALL
(SELECT ISNULL(t2.advance,$0.0)
FROM publishers p2, titles t2
WHERE t2.pub_id = p2.pub_id
AND p2.pub_name = 'Algodata Infosystems')
  • Ranges (BETWEEN and NOT BETWEEN)
  • Lists (IN, NOT IN)
  • Pattern Matches (LIKE and NOT LIKE)
  • Unknown values (IS NULL and IS NOT NULL)
  • Combinations of these conditions (AND, OR)
  • On page 78, the IS NOT NULL clause supports Wildcards and the LIKE clause. For example, the following query retrieves telephone numbers from the authors table where the telephone number begins with 415 and IS NOT NULL:
    SELECT phone
FROM authors
WHERE phone LIKE '415%' and phone IS NOT NULL
  • On page 175, the sentence that begins "Narrow indexes are often more effective" should be:

    Narrow indexes are often more effective than multicolumn, composite indexes.

  • On page 175, the sentence that begins "Note that if the first column" should be:

    Note that if the first column of a composite index has poor selectivity, the optimizer may not use the index for some queries.

  • On page 184, add the following text to the "Analyzing Locks" topic:

    Intent locks are used to let high-level lock granules such as table locks know about the intentions of those, such as page locks, placing locks at lower levels in the lock hierarchy.

    Two transactions A and B execute concurrently. Transaction A uses page locking, acquires page locks, and does not encounter any lock conflicts. Transaction B protects its activity in the same table with a table lock and requests the table lock without lock conflict because Transaction A is placing locks on pages and Transaction B is placing a lock on the entire table object. Because both transactions believe they have exclusive access to the table, incorrect behavior results. To prevent problems, Transaction A, which locks at the page level, acquires an intent lock on the table. Transaction A's table intent lock is incompatible with transaction B's table lock request.

    Note There are different types of intent locks: Intent Share (IS), Intent Exclusive (IX), and Share with Intent Exclusive (SIX).

    Update locks prevent a common form of deadlock. A typical update pattern consists of a transaction reading a record, acquiring a share mode lock (S) on the resource (page or row), and then modifying the row, which requires lock conversion to an exclusive lock (X). Share mode locks are compatible with other share mode locks, so if the two transactions acquire share mode locks on a resource and then attempt to update data concurrently, both transactions will get the share mode lock and one transaction attempts the lock conversion to an exclusive lock. The share mode to exclusive lock conversion must wait since the exclusive lock for the one transaction is not compatible with the other transaction's share mode lock. A lock wait occurs. The second transaction involved attempts to acquire an exclusive lock for its update. Because both transactions converting to exclusive locks are waiting for the other transaction to release their share mode lock, a deadlock occurs.

    To resolve the deadlock problem, update locks are used. Because an update lock in one transaction is not compatible with an update lock in another transaction, only one transaction can obtain an update lock to a resource at a time. If a transaction modifies a resource, the update lock is converted to an exclusive lock. Otherwise, the lock is converted to a share mode lock.

  • On page 203, under Stored Procedure Rules, the sixth bullet should be:
    • If you execute a procedure that calls another procedure, the called procedure can access all objects created by the first procedure, including temporary tables.


Transact-SQL Reference Errata

The following changes should be made to the Microsoft SQL Server Transact-SQL Reference for Microsoft SQL Server 6.0.

  • On page 5, the description for datatype of the ALTER TABLE statement should be:
    datatype
    Specifies the datatype of the column. System or user-defined datatypes are acceptable. Columns added to a table must be defined as NULL. When a column is added, the initial value of the column will be set to NULL. This restriction forces the ALTER TABLE statement to fail if the bit datatype is used.
  • On page 7, add the following sentence after the sentence that begins with "A table can have":

    There is a limit to the number of FOREIGN KEY constraints which is restricted by the number of unique joins between the tables involved in the join.

  • On page 15, the syntax for the simple CASE expression should be:

    CASE expression

    WHEN search_condition1 THEN result1

    [[WHEN search_condition2 THEN result2] [...]]

  • On page 17, example A of the CASE expression should be:
    -- Comment describing usage of the generic CASE expression
-- WHEN search condition THEN result

SELECT    Category =
CASE type
WHEN 'popular_comp' THEN 'Popular Computing'
WHEN 'mod_cook' THEN 'Modern Cooking'
WHEN 'business' THEN 'Business'
WHEN 'psychology' THEN 'Psychology'
WHEN 'trad_cook' THEN 'Traditional Cooking'
ELSE 'Not yet categorized'
END,
'Shortened Title' = CONVERT(varchar(30), title),
Price = price
FROM titles
WHERE price IS NOT NULL
ORDER BY type
COMPUTE AVG(price) BY type
go
  • On page 29, the syntax for the IF...ELSE Block should be:

    IF Boolean_expression

    {sql_statement | statement_block}

    [ELSE

    {sql_statement | statement_block}]

  • On page 29, add the following sentence to the definition of the sql_statement | statement_block parameter for the IF...ELSE Block:

    CREATE TABLE statements or SELECT INTO statements must refer to the same table name if the CREATE TABLE or SELECT INTO statements are used in both the IF and ELSE areas of the IF...ELSE Block.

  • On page 29, the syntax for the RETURN statement should be:

    RETURN [(integer_expression)]

  • On page 46, FILLFACTOR values must be 1 to 100. Zero is not a valid FILLFACTOR value.
  • On page 48, add the following "Note" to the SORTED_DATA definition for the CREATE INDEX Statement:

    Note If duplicate rows exist in the table, the CREATE TABLE command will fail.

  • On page 48, the sentence that begins with "To determine whether or not a table is contiguous" should be:

    To determine whether or not a table is contiguous, use the DBCC statement's SHOWCONTIG.

  • On page 52, OUTPUT should be added as an option in the CREATE PROCEDURE syntax:

    CREATE PROC[EDURE] [owner.]procedure_name[;number]

    [(parameter1 [, parameter2]...[, parameter255])]

    [{FOR REPLICATION WITH RECOMPILE} |

    [{[WITH] | [,]} ENCRYPTION]]

    [OUTPUT]

    AS sql_statements

  • On page 66, the syntax of the column_properties clause of the CREATE TABLE statement should be:
    column_properties =
    datatype [IDENTITY[(seed, increment)]]
  • On page 67, the syntax of the constraint clause of the CREATE TABLE statement should add [NULL | NOT NULL] as a possible constraint value.
  • On page 69, add the following sentence after the sentence that begins with "A table can have":

    There is a limit to the number of FOREIGN KEY constraints, which is restricted by the number of unique joins between the tables involved in the join.

  • On page 75, for the CREATE TABLE statement, the code examples should be:
A. Show Generic Syntax

This example shows the generic syntax for using the IDENTITY property.

SET IDENTITY_INSERT tablename ON
go
DECLARE @minidentval column_type
DECLARE @nextidentval column_type
SELECT @minidentval = MIN(IDENTITYCOL) FROM tablename
IF @minidentval = IDENT_SEED('tablename')
    SELECT @nextidentval = MIN(IDENTITYCOL) + IDENT_INCR('tablename')
    FROM tablename t1
    WHERE IDENTITYCOL BETWEEN IDENT_SEED('tablename') AND
        MAX(column_type) AND
        NOT EXISTS (SELECT * FROM tablename t2
            WHERE t2.IDENTITYCOL = t1.IDENTITYCOL +
                IDENT_INCR('tablename'))
ELSE
    SELECT @nextidentval = IDENT_SEED('tablename')
SET IDENTITY_INSERT tablename OFF
B. Check image Table for Gaps

This example shows how to use the IDENTITY property on a table called image that has two columns: the first column called id_num, which is an increasing identification number, and the second column called company_name.

-- Create the image table
CREATE TABLE image (id_num int IDENTITY(1,1), company_name varchar)
INSERT image(company_name) VALUES ('A Company Name')
INSERT image(company_name) VALUES ('Another Company Name')
-- Set IDENTITY_INSERT on and utilize in image table
SET IDENTITY_INSERT image ON
go
DECLARE @minidentval smallint
DECLARE @nextidentval smallint
SELECT @minidentval = MIN(IDENTITYCOL) FROM image
 IF @minidentval = IDENT_SEED('image')
     SELECT @nextidentval = MIN(IDENTITYCOL) + IDENT_INCR('image')
     FROM image t1
     WHERE IDENTITYCOL BETWEEN IDENT_SEED('image') AND 32766 and NOT EXISTS (SELECT * FROM image t2
         WHERE t2.IDENTITYCOL = t1.IDENTITYCOL + IDENT_INCR('image'))
 ELSE
     SELECT @nextidentval=IDENT_SEED('image')
SET IDENTITY_INSERT image OFF
  • On page 75, add another example for the IDENTITY syntax of the CREATE TABLE statement:
    SELECT pkid = IDENTITY(int,1,1), type, name
INTO #t1
FROM sysobjects
WHERE type = 'U'
  • On page 81, the CREATE TRIGGER syntax should be:

    CREATE TRIGGER [owner.]trigger_name

    ON [owner.]table_name

    [WITH ENCRYPTION]

    FOR {INSERT, UPDATE, DELETE}

  • On page 84, in "Trigger Limitations," the last sentence should be:

    The WRITETEXT and UPDATETEXT statements, whether logged or unlogged, do not activate a trigger.

  • On page 102, example C, the comment for the stored procedure should include the word "user" as follows:
    This procedure will generate a short report of the DBCC output for
all user tables within this database.
  • On page 103, the procedure call should be dbcc_all_tables, not dbcc_all_tables 'U'.
  • On page 111, in the "Date Formats" topic, the fourth alphabetic format in the first paragraph of alphabetic formats,
    Apr[il] [19]96 15

    is no longer supported.

  • On page 113, the title for the "Using Data and Time Datatypes" topic should be "Using Date and Time Datatypes."
  • On page 114, the sentence that begins with "The clause" in the "Using Date and Time Datatypes" topic should be:

    The clause LIKE 'May 2%' (with one space between May and 2) finds all dates from May 20 through May 29, but not May 2.

  • On page 114, the first sentence of the description of the decimal and numeric datatypes for the "Exact Numeric Data" topic should be:

    Are exact numeric datatypes that hold values from 1038 - 1 through - 1038 - 1.

  • On page 115, the second sentence of the description of the float datatype for the "Approximate Numeric Data" topic should be:

    Specify the binary precision with n, which must be from 1 through 15.

  • On page 115, the sentence that begins with "Storage size is 8 bytes" in the float description for the "Approximate Numeric Data" topic should be:

    Storage size is 8 bytes unless n is 7 or less. If n is 7 or less, then storage size is only 4 bytes.

  • On page 116, the negative limit for the money datatype should be
    -922,337,203,685,477.5807.
  • On page 117, the sentence that begins with "For example" under the description for the bit datatype for the "Special Datatypes" topic should be:

    For example, 8 one-bit columns fit into 1 byte; 9 one-bit columns take 2 bytes.

  • On page 117, under the "Special Datatypes" timestamp topic, the sentence that begins with "Values in timestamp columns" should be:

    Values in timestamp columns are not datetime data, but either binary(8) or varbinary(8) data and indicate the sequence of SQL Server activity on the row.

  • On page 118, the sentence that begins with "When image" in the "Text and Image Data" topic should be:

    When image is data entered with an odd number of characters (but less than 255), it is padded with a leading zero.

  • On page 121, the syntax for the SHOWCONTIG parameter for the DBCC statement should be:

    SHOWCONTIG (table_id [, index_id]) |

  • On page 121, the syntax for TEXTALL and TEXTALLOC in the DBCC statement should be:

    TEXTALL [({database_name | database_id}[, 'FULL' | FAST])] |

    TEXTALLOC [({table_name | table_id}[, 'FULL' | FAST])] |

  • On page 121, add the following sentence to the description of the database_id parameter for the DBCC statement:

    To find the database_id of a database, specify the database name (db_name) in the following query:

    SELECT dbid FROM sysdatabases
WHERE name = 'db_name'
  • On page 121, the syntax for the SHOWCONTIG parameter for the DBCC statement should be:

    SHOWCONTIG (table_id [, index_id]) |

  • On page 121, add the following sentence and example to the description of the database_id parameter for the DBCC statement:

    To find the database_id of a database, specify the database name (db_name) in the following query:

    SELECT dbid FROM sysdatabases
WHERE name = 'db_name'
  • On page 122, add the following sentence and example to the description of the index_id parameter for the DBCC statement:

    To find the index_id of a nonclustered index, specify the nonclustered index name (nc_index_name) in the following query:

    SELECT indid FROM sysindexes
WHERE name = 'nc_index_name'
  • On page 122, add the following sentence and example to the description of the table_id parameter for the DBCC statement:

    To find the table_id of a table, specify the table name (tbl_name) in the following query:

    SELECT id FROM sysobjects
WHERE name = 'tbl_name'
  • On page 123, add the following sentences and examples in the CHECKTABLE parameter description for the DBCC statement:

    To find the database_id of a database, specify the database name (db_name) in the following query:

    SELECT dbid FROM sysdatabases
WHERE name = 'db_name'

    To find the index_id of a nonclustered index, specify the nonclustered index name (nc_index_name) in the following query:

    SELECT indid FROM sysindexes
WHERE name = 'nc_index_name'

    To find the table_id of a table, specify the table name (tbl_name) in the following query:

    SELECT id FROM sysobjects
WHERE name = 'tbl_name'
  • On page 123, the last sentence of the description of the dllname (FREE) parameter for the DBCC statement should be:

    This statement allows a DLL to be unloaded without shutting down SQL Server.

  • On page 125, the sentence that begins with "If you are not careful" in the description of the PINTABLE parameter for the DBCC statement should be:

    If you are not careful, a large table could consume all the data cache, the server would need to be restarted, and then the table unpinned.

  • On page 125, the sentence that begins with "To understand the output of SHOW_STATISTICS" in the SHOW_STATISTICS parameter for the DBCC statement should be:

    To understand the output of SHOW_STATISTICS, see the examples later in this topic, and the UPDATE STATISTICS statement.

  • On page 126, add the following sentences and examples before the DBCC SHOWCONTIG table for the DBCC statement:

    To find the database_id of a database, specify the database name (db_name) in the following query:

    SELECT dbid FROM sysdatabases
WHERE name = 'db_name'

    To find the table_id of a table, specify the table name (tbl_name) in the following query:

    SELECT id FROM sysobjects
WHERE name = 'tbl_name'
  • On page 127, the sentence that begins with "That is" in the Important note for the SHRINKDB clause of the DBCC statement should be:

    That is, new_size must be equal to or greater than the minimum size returned by DBCC SHRINKDB plus any number of 512K increments (each of which is 256 2K pages).

  • On page 127, the syntax for the SQLPERF clause of the DBCC statement should be:

    SQLPERF ({IOSTATS | LRUSTATS | NETSTATS | RASTATAS [, CLEAR]} | {THREADS} | {LOGSPACE})

  • On page 128, the Definition for the Log Logical IO Average for the IOSTATS clause of the DBCC statement should be:

    Logical pages written per physical write for transaction log.

  • On page 130, the definition for SQLPERF (LOGSPACE) should be:

    Shows the logspace percentages for all databases. This statement is meaningful only if the log is on a separate device from its database. In the output from SQLPERF (LOGSPACE), a status of 0 indicates that the log device is separate from the database device. A status of 1 indicates that the log device is on the same device as the database.

  • On page 131, the definition for the UNPINTABLE clause of the DBCC statement should be:

    Marks the table as no longer being RAM resident; however, the pages of the table will remain in cache until they are aged out of cache (and flushed to disk, if necessary).

  • On page 131, add the following sentences and examples in the UPDATEUSAGE parameter description for the DBCC statement:

    To find the database_id of a database, specify the database name (db_name) in the following query:

    SELECT dbid FROM sysdatabases
WHERE name = 'db_name'

    To find the index_id of a nonclustered index, specify the nonclustered index name (nc_index_name) in the following query:

    SELECT indid FROM sysindexes
WHERE name = 'nc_index_name'

    To find the table_id of a table, specify the table name (tbl_name) in the following query:

    SELECT id FROM sysobjects
WHERE name = 'tbl_name'
  • On page 133, the paragraph after example A should be:

    This database contains six allocation units of 256 2K pages (0.5 MB) each, giving 1536 2K pages in all (3 MB). Of that 3 MB, 75 extents (75 * 16K = 1200K) is reserved and 137 pages (or 137 * 2K = 274K) are used by data and indexes. The reserved 75 extents include objects that have been created but not yet completely populated with data. Ref pages refer to those pages that do contain actual data or index pages.

  • On page 134, the numbers 4.72 and 95.28 in the output for example D for the DBCC statement should indicate 4.72% of space is used on the log segment, and 95.28% of space is free on the log segment.
  • On page 136, the last sentence of the first paragraph for example F of the DBCC statement should be:

    This example shows the DBCC output for each index after 1500 rows are inserted and the statistics have been updated by using UPDATE STATISTICS.

  • On page 138, example G for the DBCC statement should be:
    1. Change your current database to the database you want to shrink.
    2. Set the database to single-user mode using the sp_dboption system stored procedure.
    3. Verify how small you can make the database. (Run DBCC SHRINKDB without specifying new_size.)
    4. Shrink the database.
    USE sales
go
sp_dboption 'sales', 'single user', true
go
DBCC SHRINKDB(sales)
go
  Current size of database Size database can be shrunk to
  ------------------------ ------------------------------
  5376                     1024

  (1 row(s) affected)

  DBCC execution completed. If DBCC printed error messages, see your
  System Administrator.

    DBCC SHRINKDB reported a minimum size of 1024 pages. Because the absolute minimum is not always necessary, shrink the sales database to a new size of 6 MB.

    DBCC SHRINKDB(sales, 3072)
go
  DBCC SHRINKDB running on database "sales"...
  DBCC execution completed. If DBCC printed error messages, see your
  System Administrator.
  • On page 139, add the following sentence to the end of the description for the datatype parameter for the DECLARE statement:

    Datatypes that cannot be created by using the DECLARE statement are text and image datatypes.

  • On page 141 in the Transact-SQL Extension paragraph for the DELETE statement, the last sentence should be:

    The functionality provided is similar to that of using a correlated subquery such as a search_condition in the WHERE clause of a standard delete.

  • On page 143, the last sentence in the description for the DISK INIT statement should be:

    A device is an operating system file that SQL Server pre-allocates for database use.

  • On page 143, the description of the PHYSNAME parameter for the DISK INIT statement should be:

    Is the drive letter, full path, and filename of the database device. Paths for database devices must follow the rules for the operating system paths and filenames. Directories will not be created if they do not already exist. They must be enclosed with single quotation marks (').

  • On page 143, the last sentence of the description for the SIZE parameter for the DISK INIT statement should be:

    If you are planning to use the new database device to create a new database, the minimum size is 1 MB (512 2K blocks).

  • On page 147, the last sentence of the description of the MIRROR parameter for the DISK REMIRROR statement should be:

    It cannot be an existing file but the path must already exist.

  • On page 149, the description of the NAME parameter for the DISK REMIRROR statement should be:

    Is the logical name of the database device that you want to resume mirroring on.

  • On page 149, add a note for example A:

    Note The path to the G: drive and the SQLIMAGE directory must both exist before running the DISK REMIRROR example.

  • On page 150, the Note for the DISK REFIT statement should be:

    Note If this statement is not run immediately after the DISK REINIT statement, DISK REFIT will fail. To see the complete recovery steps (DISK REINIT and then DISK REFIT), see the DISK REINIT statement examples.

  • On page 153, the syntax for the DISK RESIZE statement should be:

    DISK RESIZE
    NAME = 'logical_device_name',
    SIZE = final_size

  • On page 153, the description for example A should be:

    This example increases the size of DEVICE1 from its initial size of 12 MB to 20 MB.

  • On page 154, the last sentence of the second paragraph in the "Remarks" section should be:

    To drop a database in recovery (sysdatabases..status & 128 = 128), use the sp_dbremove system stored procedure.

  • On page 155, in the "Remarks" section of the DROP DEFAULT statement, the second paragraph should be:

    After you drop a default from a column that allows null values, NULL is inserted in that position when rows are added and no value is explicitly supplied. After you drop a default from a NOT NULL column, an error message is returned when rows are added and no value is explicitly supplied. These rows are added later as part of the normal INSERT behavior.

  • On page 155, in the "Permission" topic of the DROP DEFAULT statement, the sentence that begins with "However" should be:

    However, the database owner and system administrator can drop any default object by specifying the owner in the DROP DEFAULT statement.

  • On page 157, the description for the DROP PROCEDURE statement should be:

    Removes user-created stored procedures or user-created procedure groups from the current database.

  • On page 158, the description for the DROP RULE statement should be:

    Removes a user-defined rule from a database.

  • On page 158, the description for the "Example" should be:

    This example unbinds and then drops the pub_id_rule.

  • On page 159, add the following sentence to the description for the DROP TABLE statement:

    Any view on the dropped table must be explicitly dropped by using the DROP VIEW statement.

  • On page 162, add the following sentence to the description for the DROP VIEW statement:

    Any view on the dropped table (dropped by using the DROP TABLE statement) must be explicitly dropped by using the DROP VIEW statement.

  • On page 163, add the following to the Note for the DUMP statement:

    A multivolume dump is when several dumps are appended to a file or tape, as opposed to each dump erasing the previous dump when the WITH INIT option is used. Multivolume and tape dumps require extra control over the storage of the data that is supported with files and tapes, that is not offered when sending the data to the pipe.

  • On pages 163 and 164, the sentence that begins with "However" in the description for the DATABASE parameter of the DUMP statement should be:

    However, because DUMP DATABASE does not remove the inactive portion of the log, you must first use DUMP TRANSACTION WITH TRUNCATE_ONLY to purge the log of completed transactions.

  • On page 167, the sentence that begins with "These options are used with DISK" in the Important note of the RETAINDAYS parameter for the DUMP statement should be:

    These options are used with DISK and TAPE devices only and are ignored on FLOPPY and PIPE devices.

  • On page 123, the first sentence of the NOINDEX clause description for the DBCC statement should be:

    Specifies that only the clustered index (the data itself) is to be checked for user-defined tables.

  • On page 127, add the following "Note" after the first paragraph for DBCC SHRINKDB:

    Note DBCC SHRINKDB is not disk compaction. DBCC SHRINKDB provides an estimate of the smallest amount of disk space that the entire database, including indexes and user-defined objects, can occupy. Because indexes and user-defined objects such as views and tables consume disk space, the database may occupy more disk space than the data itself occupies. DBCC SHRINKDB is aware of the presence of indexes and user-defined objects and suggests what size the database can be reduced to given the index and objects in the database.

  • On page 167, in the "Remarks" section of the DUMP statement, the sentence that begins with "The dump captures" should be:

    The dump captures the state of the data as it is at any moment the statement is executed; partial transactions are reflected and will automatically roll back when the dump is loaded.

  • On page 170, in the "Database Dumping to Novell File Servers" topic of the DUMP statement, the sentence that begins with "On the Novell file server" should be:

    On the Novell file server, add the GUEST account to the NTGATEWAY Group and make sure that account has complete TRUSTEE rights to the directory where the SQL Server database dump will be written.

  • On page 170, in the "Database Dumping to Novell File Servers" topic of the DUMP statement, the sentence that begins with "In addition" should be:

    In addition, the user account must be a member of the NTGATEWAY Group and must have complete TRUSTEE rights to the directory where the SQL Server database dump will be written.

  • On page 171, example A for the DUMP statement, the EXECUTE of sp_addumpdevice should be:
EXEC sp_addumpdevice 'disk', 'disk_dev1', 'c:\\dumps\diskdev1.dmp'
  • On page 175, the description of the @variable parameter for the EXECUTE statement should be:

    Specifies the variable that stores a parameter or a return parameter.

  • On page 177, the EXEC command examples should be:
    EXEC( 'USE pubs' + ' ' +'SELECT * FROM authors')

    OR

    EXEC( 'USE pubs' + ' SELECT * FROM authors')

    OR

    EXEC('USE pubs SELECT * FROM authors')

    Note In the second EXEC example, there is a space between the left quotation mark and the "S" of SELECT.

  • On page 178, the EXEC statement in example C for the EXAMPLE statement should be:
    EXEC ('DROP TABLE ' + @tablename)
  • On page 179, the EXEC statement in example E for the EXAMPLE statement should be:
    EXECUTE xp_cmdshell 'dir *.exe'
  • On page 180, the second sentence of the description of the AND parameter for the "Expressions" topic should be:

    Returns "true" when both expressions are true.

  • On page 180, the second sentence of the description of the OR parameter for the "Expressions" topic should be:

    Returns "true" when either condition is true.

  • On page 181, add the following sentence to the "Remarks" section for the "Expressions" topic:

    All numeric values with a decimal point are treated as numeric and those values without a decimal point are treated as int.

  • On page 181, add the CASE Statement to the list in the "See Also" topic for the "Expressions" topic.
  • On page 185, add the following to the "Remarks" section for Aggregate Functions:

    This is a list of the results of promoted datatypes when you use Aggregate Functions.

Datatype | SUM or AVG is of datatype
tinyint | int
smallint | int
int | int
smallmoney | money
money | money
real | float
float | float
decimal | more precise decimal, if necessary
numeric | more precise numeric, if necessary

  • On page 206, the first two sentences in the "Result" for the SOUNDEX function should be:

    Returns a four-character (SOUNDEX) code to evaluate the similarity of two strings. The SOUNDEX function converts an alpha string to a four-character code to find similar sounding words or names.

  • On page 208, the sentence that begins with "Returning" in example G for the "SOUNDEX and DIFFERENCE Functions" should be:

    Returning the SOUNDEX for "Smith" and "Smythe" will return the same SOUNDEX result because all vowels, the letter "y," doubled letters, and the letter "h," are not included.

  • On page 220, the sentence that begins with, "To enforce or remove quoted identifier" for the "Quoted Identifiers" topic should be:

    To enforce or remove quoted identifier and string constant resolution at the session level, use the SET QUOTED_IDENTIFIER ON statement.

  • On page 221, add the following sentence to the last paragraph of the "Quoted Identifiers" topic:

    Strings passed as parameters to extended stored procedures can be enclosed in single or double quotation marks, regardless of the QUOTED_IDENTIFIER setting.

  • On page 224, the last sentence of the DEFAULT VALUES clause description should be:

    If any column of the table does not have a default and does not allow null, an error is returned and the INSERT statement is rejected.

  • On page 244, add the following "Note" to the "Remarks" section of the "Null Values" topic:

    In the following example, if you try to find NULL values in columns defined as NOT NULL, SQL Server will retrieve zero rows.

    CREATE TABLE t (x int NOT NULL)
go
INSERT INTO t VALUES (1)
go
SELECT * FROM t WHERE x IS NULL
  • On page 250, the operator precedence chart should be:
    • Primary grouping: ( )
    • Bitwise: ~
    • Mutiplicative: * / %
    • Other: + - ^ & |
    • NOT
    • AND
    • OR
  • On page 266, the IDENTITY syntax of the INTO clause for the SELECT statement should be:

    IDENTITY(datatype, n1, n2)

    where

    datatype
    Is the datatype of the column.
    n1
    Is the first number to generate.
    n2
    Is the increment for successive numbers.
  • On page 270, the third paragraph of the description of the GROUP BY clause should be:

    You can use GROUP BY for a column or expression that does not appear in the select_list. Any column referenced in the select_list must also be referenced in the GROUP BY clause unless the column is being used in an aggregate function. Null values in the GROUP BY column are put into a single group when the GROUP BY column is also contained in the select_list.

  • On page 271, add the following sentence to the description of the ORDER BY clause of the SELECT statement:

    If SELECT DISTINCT is specified, the ORDER BY items must appear in the select_list.

  • On page 274, disregard the following statement:

    To allow queries that contain aggregates or a GROUP BY clause with items in the select_list that are not in the GROUP BY clause and are not aggregate functions, set trace flag 204.

  • On page 280, for the SET statement, remove the QUOTED_IDENTIFIER option.
  • On pages 280 and 283, DEADLOCKPRIORITY should be DEADLOCK_PRIORITY.
  • On page 282, the description for STATISTICS IO should be:

    On a query-by-query basis, displays the number of scans, the number of logical reads (pages accessed in the cache), and the number of physical reads (number of times the disk was accessed) for each table referenced in the statement. Output from this procedure displays how many buffers were introduced into the cache for a particular table during a read ahead.

  • On page 290, remove the paragraph that begins with "SQL Server can also be stopped."
  • On page 290, the methods for stopping SQL Server should be:
    • SQL Enterprise Manager.
    • NET STOP MSSQLSERVER from a Win32® command prompt.
    • By using the Services application from the Windows NT Control Panel.
    • By using the Windows NT Server Manager from the Windows NT Control Panel.
    • By using the SQL Service Manager.
    • By pressing CTRL+C if sqlservr.exe was started from the command-line.

    Note The SQL Enterprise Manager, NET STOP, and Control Panel methods of stopping SQL Server produce the identical service control message of SERVICE_CONTROL_STOP to SQL Server.

  • On page 290, the sentence that begins with "Each of these" in the "Remarks" section of the SHUTDOWN statement should be:

    Each of these performs a checkpoint in all databases. All committed data from data cache is flushed, and then the server is stopped.

  • On page 308, the list of ATTRIBUTE_IDs for the sp_server_info catalog stored procedure should be:
ATTRIBUTE_ID | ATTRIBUTE_NAME description | ATTRIBUTE_VALUE
13 | TABLE_LENGTH Specifies the maximum number of characters for a table name. | 30
14 | MAX_QUAL_LENGTH Specifies the maximum length of the name for a table qualifier (the first part of a three-part table name). | 30
15 | COLUMN_LENGTH Specifies the maximum number of characters for a column name. | 30
16 | IDENTIFIER_CASE Specifies the user-defined names (table names, column names, stored procedure names) in the database (the case of the objects in the system catalogs). | MIXED or SENSITIVE, depending upon whether SQL Server is set to case-sensitive or case-insensitive.
17 | TX_ISOLATION Specifies the initial transaction isolation level the server assumes, which corresponds to an isolation level defined in ANSI SQL-92. | 2
18 | COLLATION_SEQ Specifies the ordering of the character set for this server. | charset ID
19 | SAVEPOINT_SUPPORT Specifies whether the underlying DBMS supports named savepoints. | Y
20 | MULTI_RESULT_SETS Specifies whether the underlying database or the gateway itself supports multiple results sets (multiple statements can be sent through the gateway with multiple results sets returned to the client). | Y
22 | ACCESSIBLE_TABLES Specifies whether in the sp_tables stored procedure, the gateway returns only tables, views, and so on that are accessible by the current user (that is, the user who has at least SELECT privileges for the table). | Y
100 | USERID_LENGTH Specifies the maximum number of characters for a username. | 30
101 | QUALIFIER_TERM Specifies the DBMS vendor term for a table qualifier (the first part of a three-part name). | Database
102 | NAMED_TRANSACTIONS Specifies whether the underlying DBMS supports named transactions. | Y
103 | SPROC_AS_LANGUAGE Specifies whether stored procedures can be executed as language events. | Y
104 | ACCESSIBLE_SPROC Specifies whether in the sp_stored_procedures stored procedure, the gateway returns only stored procedures that are executable by the current user. | Y
105 | MAX_INDEX_COLS Specifies the maximum number of columns in an index for the DBMS. | 16
106 | RENAME_TABLE Specifies whether tables can be renamed. | Y
107 | RENAME_COLUMN Specifies whether columns can be renamed. | Y
108 | DROP_COLUMN Specifies whether columns can be dropped. | N
109 | INCREASE_COLUMN_LENGTH Specifies whether column size can be increased. | N
110 | DDL_IN_TRANSACTION Specifies whether DDL statements can appear in transactions. | Returns Y if SQL Server version 6.5 or later is running and N for earlier releases.
111 | DESCENDING_INDEXES Specifies whether descending indexes are supported. | N
112 | SP_RENAME Specifies whether a stored procedure can be renamed. | Y
113 | REMOTE_SPROC Specifies whether stored procedures can be executed through the remote stored procedure functions in DB-Library. | Y
500 | SYS_SPROC_VERSION Specifies the version of the catalog stored procedures currently implemented. | Current version number

  • On page 330, for example D, the text
    (@result = 1) should be replaced with (@result = 0) as follows:
    DECLARE @result int
EXECUTE @result = xp_cmdshell 'dir *.exe'
IF (@result = 0)
PRINT 'Success'
ELSE
PRINT 'Failure'

    The exit code of the invoked program, 'dir *.exe' in the example above is stored in the variable @return. If @result is 0, either no exit code was returned or a 0 was returned. In the example above, 'dir *.exe' can be replaced with 'myprog.exe'.

  • On page 333, the second sentence of the definition for @unread_only for the xp_findnextmsg extended stored procedure should be:

    The default is false.

  • On page 342, the syntax for the @unread parameter for the xp_readmail extended stored procedure should be:

    [, @unread = {'true' | 'false'} OUTPUT]

  • On page 343, the definition for the @unread parameter of the xp_readmail extended stored procedure should be:

    Specifies that a message has not been previously read.

  • On page 343, add the following to the "Remarks" section for the xp_readmail extended stored procedure:

    There are two ways to use xp_readmail:

    1. Return the contents of the Inbox as a result set to the client.
    2. Read a single message from the Inbox.

    To return the contents of the Inbox as a result set to the client either set @msg_id to NULL or do not include @msg_id. In this situation, @type can be used to read specific messages. You can specify @peek and @supress_attach as input parameters to control the way the message is read.

    To read a single message from the Inbox, supply a valid @msg_id that is returned by xp_findnextmsg as an input parameter to xp_readmail. You can specify @peek and @supress_attach as input parameters to control the way the message is read. When using @peek and @supress_attach with this method, all other parameters are optional output parameters that contain specific information from the message to be read.

    You can view an example of using xp_findnextmsg as an input parameter to xp_readmail by executing the following command:

    sp_helptext 'sp_processmail'

    When used to read a single message, xp_readmail can read message text of longer than 255 bytes in sections. Use @msg_length and @skip_bytes to read message text of longer than 255 bytes in sections. Using @skip_bytes as both an input and output parameter allows easy coding of a loop to process the entire message text. The following code shows an example of such a loop, assuming @msg_id is set to a valid message identifier returned by xp_findnextmsg:

    WHILE (1=1)
BEGIN
EXECUTE @status = xp_readmail @msg_id = @msg_id,
@message = @message OUTPUT,
@skip_bytes = @skip_bytes OUTPUT,
@msg_length = @msg_length OUTPUT

IF @status <> 0 BREAK
SELECT 'msg_id' = @msg_id, 'msg_part' = @message
IF @skip_bytes = @msg_length BREAK
END
  • On page 346, the @recipient for xp_sendmail should be @recipients in both the syntax diagram and the definition for the @recipient parameter.
  • On page 348, add the following to the "Remarks" section for xp_sendmail:

    The xp_sendmail extended stored procedure runs in SQL Server's security context which is a local administrator account by default. A valid user of xp_sendmail can access files for attachment to a mail message in an administrator's security context. If non-system administrator users need access to xp_sendmail and you wish to guard against unsecured access to attachment files, the system administrator can create a stored procedure that calls xp_sendmail and provides the needed functionality but does not expose the @attachments parameter. This stored procedure must be defined in the master database. The system administrator then grants execute permission on the stored procedure to the users necessary without granting permssion to the underlying xp_sendmail procedure.

  • On page 366, the syntax for sp_addsubscription should be:

    sp_addsubscription publication [, 'article'], subscriber [, destination_db]

    [, @sync_type = {'automatic' | 'manual' | 'none'}]

    [, @status = {'inactive' | 'active' | 'subscribed'}

  • On page 371, add the following to the "Remarks" section for the sp_articleview replication stored procedure:

    If you use sp_articleview on a base table that is not vertically partitioned, the article view will be created.

  • On page 405, disregard the example for the sp_replstatus replication stored procedure.
  • On page 418, add the following sentences to the description of the server parameter of the sp_addtask executive stored procedure:

    For use with replication tasks only. Transact-SQL and CmdExec tasks are executed only locally.

  • On page 418, the sp_addtask server parameter is to be used only for replication tasks and should be so indicated in the procedure description.
  • On page 458, for sp_addtype, the nulltype argument must be enclosed in single quotation marks ('NOT NULL'). The syntax remark for nulltype must indicate the need for quotation marks and the example should be:
    sp_addtype ssn, 'VARCHAR(11)', 'NOT NULL'
  • On page 475, the time slice config_name for sp_configure has been removed.
  • On page 499, add the following sentence to the "Remarks" section for sp_defaultdb:

    It is recommended that this procedure be used to change the default database for all users other than the system administrator.

  • On page 581, the descriptions for the first two texttype column attributes in the syscomments table should be:
    1. User-supplied comment (users can add entries that describe an object or column).
    2. System-supplied comment (for views, rules, defaults, triggers, and stored procedures).
  • On page 588, the userstat column for the sysobjects system table should have a description of "Reserved."
  • On page 604, add the following description for the status column of the sysdatabases system table:

    A status of 512 indicates Offline.

  • On page 604, the emergency mode status for the sysdatabases system table description should be -32768.
  • On page 633, the description for the activestarttimeofday column in the systasks reference table should be:
    activestarttimeofday The time of day when this task is no longer active.

  •
On page 637, add the following sentence to the "Remarks" section for READTEXT:

When reading image columns, ISQL/w internally limits the length of image columns to 255 characters. Reduction of the image length reduces the likelihood that Windows 95 - based text-drawing APIs and graphics drivers will exceed their character-per-line maximum.

    •

  •
On page 648, add the following sentence to the second paragraph for the "Remarks" section of the ROLLBACK TRANSACTION statement:

A savepoint_name can be issued multiple times during a single transaction, and a rollback to that savepoint_name will roll back only to the most recent issuance point.

    •

  •
On page 661, example C, the UPDATE statement examples should be:
    UPDATE titles
SET ytd_sales = ytd_sales + qty
FROM titles, sales
WHERE titles.title_id = sales.title_id
AND sales.ord_date = (SELECT MAX(sales.ord_date) FROM sales)

UPDATE titles
SET ytd_sales =
(SELECT SUM(qty)
FROM sales
WHERE sales.title_id = titles.title_id
AND sales.ord_date IN (SELECT MAX(ord_date) FROM sales))
FROM titles, sales

    •

  •
On page 678, the last bullet for the isql utility should be:

    •
Using the RAISERROR statement with a state of 127. If RAISERROR is used within an isql script and a state of 127 is raised, isql terminates and returns the error message ID back to the client. For example:
      •

    RAISERROR('No error, but we won't send anymore batches',0,127)

This error causes the isql script to terminate and the message stated is returned to the client.

Note  It is recommended that you use a severity of 0 when printing a non-error message and that you allow SQL Server severity levels of 1 through 10.

    •

  •
On page 683, the second sentence in the description for the datatype parameter of the DECLARE statement should be:

A variable cannot be of image or text datatypes.

    •

  •
On page 692, in the System Catalog diagram, the data rows show that syscurconfigs is a superset of sysconfigures. The relationship line should be reversed to run from syscurconfigs to sysconfigures.
    •

  •
On page 693, in the System Catalog diagram, one relationship line extends from systypes to syscolumns and is labeled "type, usertype." The main normal relationship should be labeled "usertype." A second relationship from systypes to syscolumns involving "type" exists, but it is separate from the "usertype" relationship.
    •

  •
On page 693, the systypes System Catalog diagram should have "name" as an alternate key.
    •

  •
On page 693, the relationship from syscolumns to sysconstraints should be "id, colid." The "id" corresponds with the "id" column from sysobjects.
    •

  •
On pages 698 and 699, author names in the authors table should be:

Carlos Hernandez

Rita Muller

Martine Rance

Martin Sommer

    •

  •
On page 702, the state referenced in the pr_info column for pub_id 0736 in the pubs database should be Massachusetts.
    •

  •

    •


Part 6 What's New for SQL-DMO

What's New for SQL-DMO

SQL Server 6.5 includes several new and enhanced objects and events for SQL-DMO, which are listed in the table and explained in this part. Features are in alphabetical order.

Note that the SQL-DMO Help file contains version 6.0 information. Read this section for the most up-to-date version 6.5 information.

Feature | New | Enhanced
Alert |  | ·
Application |  | ·
Article |  | ·
Backup |  | ·
BackupSink | · |
BulkCopy | · |
BulkCopySink | · |
Database |  | ·
Device |  | ·
Executive |  | ·
Index |  | ·
Key |  | ·
Login |  | ·
Publication |  | ·
QueryResults |  | ·
RegisteredServer | · |
RemoteServer |  | ·
ServerGroup | · |
ServerSink | · |
SQLServer |  | ·
StoredProcedure |  | ·
SubscriberInfo |  | ·
Table |  | ·
Task |  | ·
Transfer | · |
TransferSink | · |
View |  | ·


Filenames Changed

The following SQL-DMO filenames have been changed.

SQL Server 6.0 filename SQL Server 6.5 filename

SQLOLE32.DLL | SQLOLE65.DLL
SQLOLE32.TLB | SQLOLE65.TLB
SQLOLE60.SQL | SQLOLE65.SQL


Device Methods

Script Method


Script Method

Description

Generates a series of Transact-SQL statements (script) to create the underlying device.

Visual Basic

strScript = Device.Script (
[[ScriptType :=] tScriptType,]
[[ScriptFilePath :=] strFile,]
[[NewPhysicalLocation :=] strNewDeviceFile] )

C++

HRESULT pDevice->Script (
SQLOLE_SCRIPT_TYPE tScriptType = SQLOLEScript_Default,
SQLOLE_LPCSTR strFile = NULL,
SQLOLE_LPCSTR strNewDeviceFile = NULL,
SQLOLE_LPBSTR pstrScript = NULL );

Elements

Element Type Description

strScript | String | Generated Transact-SQL script
tScriptType | SQLOLE_SCRIPT_TYPE | Type of script to generate
strFile | String | Full path and filename to use to store the Transact-SQL script
strNewDeviceFile | String | New full path and filename of the new physical device file this script will create

Remarks

The generated Transact-SQL script can be used for database recovery.


Login Lists

EnumDatabaseMappings List


EnumDatabaseMappings List

Description

Lists corresponding user information for every database that has a user mapped to this login. List is returned in a QueryResults object.

Visual Basic

QueryResults = Login.EnumDatabaseMappings

C++

HRESULT pLogin->EnumDatabaseMappings ( LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element Type Description

QueryResults QueryResults Returned QueryResults object

QueryResults

ColumnName ColumnType

LoginName | SQLOLE_DTypeChar
DBName | SQLOLE_DTypeChar
UserName | SQLOLE_DTypeChar
AliasName | SQLOLE_DTypeChar


RemoteServer Methods

ExecuteWithResultsAndMessages Method


ExecuteWithResultsAndMessages Method

Description

Executes a Transact-SQL statement on a remote server. Returns any SQL Server messages received, including output from PRINT and DBCC statements. Returns results in a QueryResults object.

Visual Basic

QueryResults = RemoteServer.ExecuteWithResultsAndMessages (
[Command :=] strSQLStatement,
[[Messages :=] strMessages] )

C++

HRESULT pRemoteServer->ExecuteWithResultsAndMessages (
SQLOLE_LPCSTR strSQLStatement,
LPSQLOLEQUERYRESULTS* ppQueryResults,
SQLOLE_LPBSTR pstrMessages = 0 );

Elements

Element Type Description

QueryResults | QueryResults | Returned QueryResults object
strSQLStatement | String | SQL statement
strMessages | String | Returned SQL Server messages

QueryResults

The contents of the QueryResults object depend on the Transact-SQL statement.

Reference

sp_sqlexec


SQLServer Properties

Property Description

NetName
String
Write: No 		The network computer name of the SQL Server computer.


SQLServer Methods

ExecuteWithResultsAndMessages Method

UninstallPublishing Method


ExecuteWithResultsAndMessages Method

Description

Executes a Transact-SQL statement on a SQL Server. Returns any SQL Server messages received, including output from PRINT and DBCC statements. Returns results in a QueryResults object.

Visual Basic

QueryResults = SQLServer.ExecuteWithResultsAndMessages (
[Command :=] strSQLStatement,
[[Messages :=] strMessages] )

C++

HRESULT pSQLServer->ExecuteWithResultsAndMessages (
SQLOLE_LPCSTR strSQLStatement,
LPSQLOLEQUERYRESULTS* ppQueryResults,
SQLOLE_LPBSTR pstrMessages = 0 );

Elements

Element Type Description

QueryResults | QueryResults | Returned QueryResults object
strSQLStatement | String | SQL statement
strMessages | String | Returned SQL Server messages

QueryResults

The contents of the QueryResults object depend on the Transact-SQL statement.

Remarks

If a ServerSink object is configured to receive SQLServer events, the SQL Server messages are also sent to the ServerSink.ServerMessage method.

Reference

EXECUTE


UninstallPublishing Method

Description

Uninstalls publishing for this SQL Server.

Visual Basic

SQLServer.UninstallPublishing

C++

HRESULT pSQLServer->UninstallPublishing ( );


SQLServer Lists

EnumLoginMappings List


EnumLoginMappings List

Description

For every login in SQL Server, lists corresponding user information for every database that has a user mapped to the login. List is returned in a QueryResults object.

Visual Basic

QueryResults = SQLServer.EnumLoginMappings

C++

HRESULT pSQLServer->EnumLoginMappings ( LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element Type Description

QueryResults QueryResults Returned QueryResults object

QueryResults

This method will return a results set for each login.

ColumnName ColumnType

LoginName | SQLOLE_DTypeChar
DBName | SQLOLE_DTypeChar
UserName | SQLOLE_DTypeChar
AliasName | SQLOLE_DTypeChar


SubscriberInfo Properties

Property Description

Description String Write: Yes | The description of the subscription server.
Type SQLOLE_SUBSCRIBERINFO _TYPE Write: Yes | The type of subscription server. This property is now an enumerated type instead of a Long.


Article Properties

Property Description

IncludeInsertColumnNames Boolean Write: Yes | Determines if INSERT statements used by replication include the column list.
OwnerQualifyTable Boolean Write: Yes | Determines if the table for this article is owner qualified. If True, the table is owner qualified, and the owner of the table in the subscribing database must be the same as the owner of the table for this article. If False, the table is not owner qualified.


Database Methods

CheckAllocationsDataOnly Method

CheckIdentityValues Method

CheckTablesDataOnly Method

ExecuteWithResultsAndMessages Method

Script Method

ScriptTransfer Method

Transfer Method

UpdateIndexStatistics Method


CheckAllocationsDataOnly Method

Description

Checks the internal allocation consistency of the database. This includes checking that data pages are consistent with the allocation information in the extent.

Visual Basic

strOutput = Database.CheckAllocationsDataOnly

C++

HRESULT pDatabase->CheckAllocationsDataOnly ( SQLOLE_LPBSTR pstrOutput );

Elements

Element Type Description

strOutput String The output returned by the internal consistency check

Reference

DBCC NEWALLOC (..., NOINDEX)


CheckIdentityValues Method

Description

For every table in the database, checks the current identity value and compares it with the maximum value in the identity column. If the current identity value is invalid, it will be reset with the maximum value in the identity column.

Visual Basic

Database.CheckIdentityValues

C++

HRESULT pDatabase->CheckIdentityValues ( );

Reference

DBCC CHECKIDENT


CheckTablesDataOnly Method

Description

Checks the internal consistency of the data pages of every table in the database.

Visual Basic

strOutput = Database.CheckTablesDataOnly

C++

HRESULT pDatabase->CheckTablesDataOnly ( SQLOLE_LPBSTR pstrOutput );

Elements

Element Type Description

strOutput String The output returned by the internal consistency check

Reference

DBCC CHECKDB (..., NOINDEX), DBCC CHECKTABLE (..., NOINDEX)


ExecuteWithResultsAndMessages Method

Description

Executes a Transact-SQL statement on a database. Returns any SQL Server messages received, including output from PRINT and DBCC statements. Returns results in a QueryResults object.

Visual Basic

QueryResults = Database.ExecuteWithResultsAndMessages (
[Command :=] strSQLStatement,
[[Messages :=] strMessages] )

C++

HRESULT pDatabase->ExecuteWithResultsAndMessages (
SQLOLE_LPCSTR strSQLStatement,
LPSQLOLEQUERYRESULTS* ppQueryResults,
SQLOLE_LPBSTR pstrMessages = 0 );

Elements

Element Type Description

QueryResults | QueryResults | Returned QueryResults object
strSQLStatement | String | SQL statement
strMessages | String | Returned SQL Server messages

QueryResults

The contents of the QueryResults object depend on the Transact-SQL statement.

Remarks

If a ServerSink object is configured to receive SQLServer events, the SQL Server messages are also sent to the ServerSink.ServerMessage method.

Reference

EXECUTE


Script Method

Description

Generates a series of Transact-SQL statements (script) to create the underlying database.

Visual Basic

strScript = Database.Script (
[[ScriptType :=] tScriptType,]
[[ScriptFilePath :=] strFile] )

C++

HRESULT pDatabase->Script (
SQLOLE_SCRIPT_TYPE tScriptType = SQLOLEScript_Default,
SQLOLE_LPCSTR strFile = NULL,
SQLOLE_LPBSTR pstrScript = NULL );

Elements

Element Type Description

strScript | String | Generated Transact-SQL script
tScriptType | SQLOLE_SCRIPT_TYPE | Type of script to generate
strFile | String | Full path and filename to use to store the Transact-SQL script

Remarks

The generated Transact-SQL script can be used for database recovery.

Reference

sp_help_revdatabase


ScriptTransfer Method

Description

Creates Transact-SQL script file(s) used by the Transfer method for creating copied objects in the destination database. Set the properties of a created Transfer object as desired, pass that Transfer object to the ScriptTransfer method with tScriptMode set to SQLOLEXfrFile_SummaryFiles to create the script files, and then pass the same Transfer object to the Transfer method to perform the database transfer.

Visual Basic

strScript = Database.ScriptTransfer (
[TransferSpec :=] Transfer,
[[ScriptFileMode :=] tScriptMode,]
[[ScriptFilePath :=] strFile] )

C++

HRESULT pDatabase->ScriptTransfer (
LPSQLOLETRANSFER pTransfer,
SQLOLE_XFRSCRIPTMODE_TYPE tScriptMode = SQLOLEXfrFile_Default,
SQLOLE_LPCSTR strFile = NULL,
SQLOLE_LPBSTR pstrScript = NULL );

Elements

Element Type Description

strScript | String | Returned Transact-SQL script
Transfer | Transfer | Created Transfer object that specifies how to execute the database transfer
tScriptMode | SQLOLE_XFRSCRIPTMODE _TYPE | The script transfer type
strFile | String | If tScriptMode is SQLOLEXfrFile_SingleFile, the full path and filename of the single script file; otherwise, the full path of the directory used to store the script files

Remarks

When tScriptMode is SQLOLEXfrFile_SummaryFiles (the default), multiple script files are created that have names of the following form:

source_server.source_database.ext

where source_server is the name of the SQL Server that contains the source database, source_database is the name of the source database, and ext is one of the following three-letter extensions that are used to create database objects...

File
extension 		Script
creates

LGN | Logins
GRP | Groups, group statement privileges
USR | Users, user statement privileges
DEF | Non-declarative referential integrity (DRI) defaults
RUL | Rules
UDT | User-defined datatypes
TAB | Tables (does not include DRI)
DR1 | Table DRI before copying data (includes clustered primary and unique keys)
DR2 | Table DRI after copying data (includes nonclustered primary and unique keys, CHECK constraints, and DRI defaults)
ID1 | Table indexes created before copying data (includes clustered non-DRI indexes)
ID2 | Table indexes created after copying data (includes nonclustered non-DRI indexes)
BND | Bindings for rules and non-DRI defaults
PRV | Table privileges
FKY | Foreign keys
TRG | Triggers
VIW | Views and view privileges
PRC | Stored procedures and stored procedure privileges

...or one of the following three-letter extensions that are used to drop database objects.

Extension Script drops

DP1 | Drops foreign keys that reference copied tables (listed in the file with the DP2 extension). The Transfer method does not run this script. After a transfer is complete, you can run the DP1 script followed by the DP2 script on the source database to drop the source objects.
DP2 | Drops all objects to be copied. (DP2 is used on the destination database only when the Transfer.DropDestObjectsFirst property is set to True).

The Database.Transfer method runs these script files in the following order: DP2, LGN, GRP, USR, DEF, RUL, UDT, TAB, DR1, ID1, bulk copy of copied tables, DR2, ID2, BND, PRV, FKY, TRG, VIW, PRC.

To create the transfer scripts for private use (and not for later use with the Transfer method) you can set tScriptMode to SQLOLEXfrFile_SingleFilePerObject or SQLOLEXfrFile_SingleFile.

When tScriptMode is SQLOLEXfrFile_SingleFilePerObject, multiple files are created that have names of the following form:

owner.object.ext

where owner is the username of the object owner, object is the name of the database object, and ext is one of the extensions listed above.

When tScriptMode is SQLOLEXfrFile_SingleFile, a single file (specified in strFile) is created that contains the entire Transact-SQL script for creating the database objects in the destination database.


Transfer Method

Description

Performs a database transfer by copying specified objects and data to the destination database. Set the properties of a created Transfer object as desired, pass that Transfer object to the ScriptTransfer method with tScriptMode set to SQLOLEXfrFile_SummaryFiles to create the script files, and then pass the same Transfer object to the Transfer method to perform the database transfer.

If the ScriptTransfer method is not called first, the Transfer method will call ScriptTransfer with tScriptMode set to SQLOLEXfrFile_SummaryFiles and strFile set to the current directory to create the summary script files.

Visual Basic

Database.Transfer ( [TransferSpec :=] Transfer )

C++

HRESULT pDatabase->Transfer ( LPSQLOLETRANSFER pTransfer );

Elements

Element Type Description

Transfer Transfer Created Transfer object that specifies how to execute the database transfer

Remarks

The Transfer method does not remove objects or data from the source database.

The Transfer method creates three types of error log files:

  • One source error log contains errors from the source SQL Server and database and has a filename of the following form:

    source_server.source_database.LOG

    where source_server is the name of the SQL Server that contains the source database, and source_database is the name of the source database.

  • One destination error log contains errors from the destination SQL Server and database and has a filename of the following form:

    destination_server.destination_database.LOG

    where destination_server is the name of the SQL Server that contains the destination database, and destination_database is the name of the destination database.

  • Multiple bulk copy error log files contain errors from the bulk copy of data from each table, and each has a filename of the following form:

    owner.table.BCP

    where owner is the username of the object owner, and table is the name of the table.


UpdateIndexStatistics Method

Description

Updates data distribution statistics for every index in the database.

Visual Basic

Database.UpdateIndexStatistics

C++

HRESULT pDatabase->UpdateIndexStatistics ( );

Reference

UPDATE STATISTICS


Database Lists

EnumLoginMappings List


EnumLoginMappings List

Description

For every login that maps to a user in this database, lists a single-row results set describing that mapping. List is returned in a QueryResults object.

Visual Basic

QueryResults = Database.EnumLoginMappings

C++

HRESULT Database->EnumLoginMappings ( LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element Type Description

QueryResults QueryResults Returned QueryResults object

QueryResults

This method will return a results set for each login.

ColumnName ColumnType

LoginName | SQLOLE_DTypeChar
DBName | SQLOLE_DTypeChar
UserName | SQLOLE_DTypeChar
AliasName | SQLOLE_DTypeChar


Publication Methods

AddFullSubscriber Method

RemoveFullSubscriber Method


AddFullSubscriber Method

Description

Adds a server that subscribes to all articles in the publication.

Visual Basic

Publication.AddFullSubscriber (
[ServerName :=] idServer,
[[DestinationDatabase :=] idDatabase,]
[[InitialSyncType :=] tSyncType,]
[[Status :=] tStatusType] )

C++

HRESULT pPublication->AddFullSubscriber (
SQLOLE_LPCSTR idServer,
SQLOLE_LPCSTR idDatabase = NULL,
SQLOLE_SUBSYNC_TYPE tSyncType = SQLOLESubSync_Default,
SQLOLE_SUBSTATUS_TYPE tStatusType = SQLOLESubStat_Default );

Elements

Element Type Description

idServer | Identifier | Name of the subscription server.
idDatabase | Identifier | Destination database. Default is the publication database name.
tSyncType | SQLOLE_SUBSYNC_TYPE | Type of initial synchronization event used to synchronize the subscription server.
tStatusType | SQLOLE_SUBSTATUS_TYPE | Status of the subscription.


RemoveFullSubscriber Method

Description

Removes all subscriptions from a publication for the specified server.

Visual Basic

Publication.RemoveFullSubscriber ( [ServerName :=] idServer )

C++

HRESULT pPublication->RemoveFullSubscriber ( SQLOLE_LPCSTR idServer );

Elements

Element Type Description

idServer Identifier Name of subscription server


Index Methods

CheckIndex Method

Rebuild Method


CheckIndex Method

Description

Checks the internal consistency of the data and index pages of this index.

Visual Basic

strOutput = Index.CheckIndex

C++

HRESULT pIndex->CheckIndex ( SQLOLE_LPBSTR pstrOutput );

Elements

Element Type Description

strOutput String The output returned by the internal consistency check

Reference

DBCC CHECKTABLE


Rebuild Method

Remarks

If the Index.FillFactor property has been changed, Rebuild will use the new fill factor value.


Key Properties

Property Description

ExcludeReplication
Boolean
Write: Yes 		Determines if this foreign key constraint is ignored during replication. If True, this foreign key is ignored for data inserted by replication. If False, this foreign key is enforced for data inserted by replication.


Key Methods

RebuildIndex Method


RebuildIndex Method

Description

Dynamically rebuilds the index associated with this primary or unique Key. Calling this method does not require changes to the table constraints.

Visual Basic

Key.RebuildIndex

C++

HRESULT pKey->RebuildIndex ( );

Remarks

If the Key.FillFactor property has been changed, RebuildIndex will use the new fill factor value.


Table Properties

Property Description

InAlter
Boolean
Write: No 		Indicates if a group of changes has been started by BeginAlter but not yet completed. If True, BeginAlter has been called, but DoAlter, DoAlterWithNoCheck, or CancelAlter has not. If False, a group of changes has not been started by BeginAlter.


Table Methods

CheckIdentityValue Method

CheckTableDataOnly Method

ExportData Method

ImportData Method

RebuildIndexes


CheckIdentityValue Method

Description

Checks the current identity value for the table and compares it with the maximum value in the identity column. If the current identity value is invalid, it will be reset with the maximum value in the identity column.

Visual Basic

Table.CheckIdentityValue

C++

HRESULT pTable->CheckIdentityValue ( );

Reference

DBCC CHECKIDENT


CheckTableDataOnly Method

Description

Checks the internal consistency of the data pages of this table.

Visual Basic

strOutput = Table.CheckTableDataOnly

C++

HRESULT pTable->CheckTableDataOnly ( SQLOLE_LPBSTR pstrOutput );

Elements

Element Type Description

strOutput String The output returned by the internal consistency check

Reference

DBCC CHECKTABLE (..., NOINDEX)


ExportData Method

Description

Bulk copies data from the table to a data file. Set the properties of a created BulkCopy object as desired, and pass it to the ExportData method.

Visual Basic

lRowsExported = Table.ExportData ( [Bcp :=] BulkCopy )

C++

HRESULT pTable->ExportData (
LPSQLOLEBULKCOPY pBulkCopy,
LPLONG plRowsExported = NULL );

Elements

Element Type Description

lRowsExported | Long | Returned number of rows exported from the table to the data file
BulkCopy | BulkCopy | Created BulkCopy object that specifies how to execute the bulk copy


ImportData Method

Description

Bulk copies data from a data file into the table. Set the properties of a created BulkCopy object as desired, and pass it to the ImportData method.

Visual Basic

lRowsImported = Table.ImportData ( [Bcp :=] BulkCopy )

C++

HRESULT pTable->ImportData (
LPSQLOLEBULKCOPY pBulkCopy,
LPLONG plRowsImported = NULL );

Elements

Element Type Description

lRowsImported | Long | Returned number of rows imported from the data file into the table
BulkCopy | BulkCopy | Created BulkCopy object that specifies how to execute the bulk copy


RebuildIndexes Method

Description

Dynamically rebuilds all indexes on the table. Calling this method does not require changes to the table constraints.

Visual Basic

Table.RebuildIndexes (
[[SortedDataType :=] tSortedDataType,]
[[FillFactor :=] lFillFactor] )

C++

HRESULT pTable->RebuildIndexes (
SQLOLE_INDEX_TYPE tSortedDataType = SQLOLEIndex_Default,
long lFillFactor = SQLOLE_USEEXISTINGFILLFACTOR );

Elements

Element Type Description

tSortedDataType | SQLOLE_INDEX_TYPE | Sorted data option to use. Valid values are: SQLOLEIndex_Default SQLOLEIndex_SortedData SQLOLEIndex_SortedDataReorg
lFillFactor | Long | Percent of each page that SQL Server will fill with index data when rebuilding each index. Valid values are 0 through 100.

Reference

DBCC REINDEX


View Methods

ExportData Method


ExportData Method

Description

Bulk copies data from the view to a data file. Set the properties of a created BulkCopy object as desired and pass it to the ExportData method.

Visual Basic

lRowsExported = View.ExportData ( [Bcp :=] BulkCopy )

C++

HRESULT pView->ExportData (
LPSQLOLEBULKCOPY pBulkCopy,
LPLONG plRowsExported = NULL );

Elements

Element Type Description

lRowsExported | Long | Returned number of rows exported from the view to the data file
BulkCopy | BulkCopy | Created BulkCopy object that specifies how to execute the bulk copy


Alert Properties

Property Description

RaiseSNMPTrap
Boolean
Write: Yes 		Determines if an SNMP trap is raised when this Alert fires. If True, an SNMP trap is raised. If False, no SNMP trap is raised.


Executive Properties

Property Description

LimitHistoryRowsPerTaskMax
Long
Write: Yes 		The maximum number of history rows that are stored for a single task.


Task Properties

Property Description

CmdExecSuccessCode Long Write: Yes | The CmdExec return code after a task has been run.
Parameters String Write: Yes | Reserved. Do not change this property. This String stores a text column and is not limited to 255 characters.


Application Properties

Property Description

GroupRegistrationServer String Write: Yes | The computer to use for group registration information. The default is to use local group registration information. Changing this property does not automatically refresh the Application.ServerGroups collection.
GroupRegistrationVersion Long Write: No | The version number of the group registration information.
VersionBuild Long Write: No | The SQL-DMO component object layer build number.
UseCurrentUserServerGroups Boolean Write: Yes | Determines if group registration information is stored per user. If True, group registration information is stored separately for each Windows 95 or Windows NT user. If False, group registration information is stored globally for the computer. Changing this property does not automatically refresh the Application.ServerGroups collection.


Application Lists

ListAnnouncedNetworkSQLServers List

ListLocallyConfiguredSQLServers List


ListAnnouncedNetworkSQLServers List

Description

Returns a list of Name objects that contain names of SQL Servers that have been announced on the network used by the default Net-Library.

Visual Basic

ServerNameList = Application.ListAnnouncedNetworkSQLServers

C++

HRESULT pApplication->ListAnnouncedNetworkSQLServers ( LPSQLOLENAMELIST* ppServerNameList );

Elements

Element Type Description

ServerNameList NameList Returned list of Name objects

Reference

dbserverenum


ListLocallyConfiguredSQLServers List

Description

Returns a list of Name objects that contain locally configured SQL Server names. Locally configured SQL Server names are managed with the SQL Client Configuration Utility.

Visual Basic

ServerNameList = Application.ListLocallyConfiguredSQLServers

C++

HRESULT pApplication->ListLocallyConfiguredSQLServers ( LPSQLOLENAMELIST* ppServerNameList );

Elements

Element Type Description

ServerNameList NameList Returned list of Name objects

Reference

dbserverenum


Application Collections

Property Description

ServerGroups
ServerGroups
Write: No 		The collection of ServerGroup objects.


Backup Properties

Property Description

TableName Identifier Write: Yes | The table to dump or load. Applies only when used with the Database.Dump or Database.Load methods.
LoadAppendToTableData Boolean Write: Yes | Determines if loaded data is appended to the destination table. If True, loaded data is appended to the destination table. If False, and if the destination table already contains data, then the Database.Load method fails.
LoadFromSourceTableName Identifier Write: Yes | The table in the dump to load from. Applies only when used with the Database.Load method.
LoadStopDate String Write: Yes | The cutoff date and time for loading transactions. Any logged transactions that occurred after this date and time will not be loaded or rolled forward into the database. Applies only when used with the TransactionLog.Load method.
PercentCompleteNotification Long Write: Yes | The percent complete interval during a dump or load that will fire a BackupSink.PercentComplete event method. The default is 10 percent.
PipeDevices String Write: Yes | Delimited list of pipe device and volume specifiers. Each specifier consists of the named pipe name, an equal sign (=), and an optional volume name.


Backup Methods

Abort Method


Abort Method

Description

Stops a running dump or load of a database or transaction log. When one thread has used this Backup object to call the Dump or Load method of a Database or TransactionLog object (and that method has not yet returned), call Abort from another thread to stop the dump or load operation.

Visual Basic

Backup.Abort

C++

HRESULT pBackup->Abort ( );


BulkCopy Object

Description

A BulkCopy object contains complete information for a bulk copy of data out of a Table or View into a file or out of a file into a Table. For example, create a new BulkCopy object; set the properties to the appropriate values; then pass the BulkCopy object to the ImportData or ExportData method of the Table object or to the View.ExportData method.


BulkCopy Properties

Property Description

Application Application Write: No | The Application object.
ColumnDelimiter String Write: Yes | The character(s) that are used to separate columns in the data file. Set this property only if the DataFileType property has been set to SQLOLEDataFile_SpecialDelimtedChar.
DataFilePath String Write: Yes | The full path and filename of the data file. It is a destination file if it is passed to the Table.ExportData or View.ExportData method. It is a source file if it is passed to the Table.ImportData method.
DataFileType SQLOLE_DATAFILE_TYPE Write: Yes | The type of the data file.
ErrorFilePath String Write: Yes | The full path and filename of the error file. This file will contain any bulk copy errors that occur.
FirstRow Long Write: Yes | The first row to copy. It is the first row of the Table or View if it is passed to the Table.ExportData or View.ExportData method. It is the first row of the data file if it is passed to the Table.ImportData method.
FormatFilePath String Write: Yes | The full path and filename of the bulk copy format file, which is used to describe the format of the data file. Set this property only if the DataFileType property has been set to SQLOLEDataFile_UseFormatFile.
ImportRowsPerBatch Long Write: Yes | The number of rows copied during each committed batch.
IncludeIdentityValues Boolean Write: Yes | Determines if values can be inserted into the identity column of a Table. If True, the IDENTITY_INSERT option is turned on before a Table.ImportData bulk copy is started. If False, values cannot be inserted into the identity column of a Table.
LastRow Long Write: Yes | The last row of the Table or View to copy. It is the last row of the Table or View if it is passed to the Table.ExportData or View.ExportData method. It is the last row of the data file if it is passed to the Table.ImportData method.
LogFilePath String Write: Yes | The full path and filename of the log file. This file will contain bulk copy statistics and any non-bulk copy messages from SQL Server that are received.
MaximumErrorsBeforeAbort Long Write: Yes | The maximum number of bulk copy errors that can occur without stopping the bulk copy. If more errors occur, the bulk copy will be stopped.
Parent Application Write: No | The Application object.
RowDelimiter String Write: Yes | The character(s) that are used to separate rows in the data file. Set this property only if the DataFileType property has been set to SQLOLEDataFile_SpecialDelimtedChar.
SuspendIndexing Boolean Write: Yes | Determines if existing indexes (not including those that enforce primary key or unique constraints) are suspended during the Table.ImportData bulk copy. If True, these indexes are dropped before the bulk copy is started and recreated after the bulk copy is completed. If False, no changes are made to indexing.
TruncateLog Boolean Write: Yes | Determines if the transaction log is truncated. If True, the transaction log is truncated before a Table.ImportData bulk copy is started. If False, the transaction log is not truncated.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UseBulkCopyOption Boolean Write: Yes | Determines if the SELECT INTO/BULKCOPY option is turned on. If True, and if the SELECT INTO/BULKCOPY option is turned off, the option is turned on before a Table.ImportData bulk copy is started, and it is turned off after the bulk copy is complete. If False, no adjustments to the SELECT INTO/BULKCOPY option are made.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


BulkCopy Methods

Abort Method


Abort Method

Description

Stops a running bulk copy. When one thread has called the ImportData or ExportData method of the Table object or the View.ExportData method that is using this BulkCopy object, and the appropriate method has not yet returned, call Abort from another thread to stop the bulk copy operation.

Visual Basic

BulkCopy.Abort

C++

HRESULT pBulkCopy->Abort ( );


BulkCopy Collections

Property Description

Properties
Properties
Write: No 		The collection of Property objects.


QueryResults Methods

GetColumnBinary Method

GetColumnDate Method


GetColumnBinary Method

Description

Returns the data, converted to an array of bytes, in a column of a row in the current result set.

Visual Basic

abytColumnData = QueryResults.GetColumnBinary (
[Row :=] lRow,
[Column :=] lColumn )

C++

HRESULT pQueryResults->GetColumnBinary (
long lRow,
long lColumn,
LPVOID* ppvColumnData );

Elements

Element Type Description

abytColumnData | Array of Bytes | Returned column data; this array will have ColumnMaxLength elements
lRow | Long | Row number of the current results set
lColumn | Long | Column number of the specified row

Remarks

Use the QueryResults.ColumnMaxLength property to determine the number of elements in the returned array. In Microsoft Visual Basic, the returned column data is a dynamic array of Byte variables and should be converted using the Array function before use. In C++, the returned column data is an array of void (byte) variables that are allocated with the COM function CoTaskMemAlloc. The C++ application must free this memory by using the COM function CoTaskMemFree.


GetColumnDate Method

Description

Returns the data, converted to a date value, in a column of a row in the current result set.

Visual Basic

datColumnData = QueryResults.GetColumnDate (
[Row :=] lRow,
[Column :=] lColumn )

C++

HRESULT pQueryResults->GetColumnDate (
long lRow,
long lColumn,
LPSYSTEMTIME pdatColumnData );

Elements

Element Type Description

datColumnData | Date | Returned column data
lRow | Long | Row number of the current results set
lColumn | Long | Column number of the specified row

Remarks

In Visual Basic, the returned column data is a Date variable. In C++, the returned column data is a SYSTEMTIME variable that is filled with the datetime data.


RegisteredServer Object

Description

The RegisteredServer object contains the name and registration information of a SQL Server that is contained in a ServerGroup object for use with SQL Enterprise Manager. RegisteredServer objects are displayed in the Server Manager window and are stored in the Registry.


RegisteredServer Properties

Property Description

Application Application Write: No | The Application object.
Login Identifier Write: Yes | The login ID that is used to connect to SQL Server.
Name String Write: Before Add | The name of the SQL Server to connect to.
Parent Application Write: No | The Application object.
Password Identifier Write: Yes | The password that is used to connect to SQL Server.
PersistFlags Long Write: Yes | Permanent storage space contained in this object for private use by the application. SQL-DMO does not use this property.
SaLogin Boolean Write: No | Indicates if the login that was used for the connection has system administrator (SA) privilege. If True, the login is SA. If False, the login is not SA.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.
UseTrustedConnection Boolean Write: Yes | Determines if a secure connection is requested when connecting to SQL Server. If True, a secure connection is requested. If False, a normal connection is requested.
VersionMajor Long Write: No | The SQL Server version number to the left of the decimal point.
VersionMinor Long Write: No | The SQL Server version number to the right of the decimal point.


RegisteredServer Methods

Remove Method


Remove Method

Description

Removes this RegisteredServer object from the ServerGroup.RegisteredServers collection.

Visual Basic

RegisteredServer.Remove

C++

HRESULT pRegisteredServer->Remove ( );


RegisteredServer Collections

Property Description

Properties
Properties
Write: No 		The collection of Property objects.


ServerGroup Object

Description

The ServerGroup object is a named group of registered SQL Servers for use with SQL Enterprise Manager. ServerGroup objects are displayed in the Server Manager window and stored in the Registry.


ServerGroup Properties

Property Description

Application Application Write: No | The Application object.
Name String Write: Before Add | The name of this group of registered SQL Servers.
Parent Application Write: No | The Application object.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


ServerGroup Methods

Remove Method


Remove Method

Description

Removes this ServerGroup object from the Application.ServerGroups collection.

Visual Basic

ServerGroup.Remove

C++

HRESULT pServerGroup->Remove ( );


ServerGroup Collections

Property Description

Properties Properties Write: No | The collection of Property objects.
RegisteredServers RegisteredServers Write: No | The collection of RegisteredServer objects.


Transfer Object

Description

A Transfer object contains complete information for a transfer of objects and data from a source database to a destination database. Create a new Transfer object; set the properties to the appropriate values; pass that Transfer object to the ScriptTransfer method with tScriptMode set to SQLOLEXfrFile_SummaryFiles to create the script files; then pass the same Transfer object to the Transfer method to perform the database transfer. The source database is the Database object, and the destination database can be on a different SQL Server.


Transfer Properties

Property Description

Application Application Write: No | The Application object.
CopyAllDefaults Boolean Write: Yes | Determines if all defaults in the source database are copied. If True, all defaults in the source database are copied to the destination database. If False, use the AddObject or AddObjectByName method to add a default to the list of copied objects.
CopyAllObjects Boolean Write: Yes | Determines if all objects in the source database are copied. If True, all objects in the source database are copied to the destination database, and all other CopyAllObjects properties are ignored. If False, the other CopyAllObjects properties and the AddObject and AddObjectByName methods are used.
CopyAllRules Boolean Write: Yes | Determines if all rules in the source database are copied. If True, all rules in the source database are copied to the destination database. If False, use the AddObject or AddObjectByName method to add a rule to the list of copied objects.
CopyAllStoredProcedures Boolean Write: Yes | Determines if all stored procedures in the source database are copied. If True, all stored procedures in the source database are copied to the destination database. If False, use the AddObject or AddObjectByName method to add a stored procedure to the list of copied objects.
CopyAllTables Boolean Write: Yes | Determines if all tables in the source database are copied. If True, all tables in the source database are copied to the destination database. If False, use the AddObject or AddObjectByName method to add a table to the list of copied objects.
CopyAllTriggers Boolean Write: Yes | Determines if all triggers in the source database are copied. If True, all triggers in the source database are copied to the destination database. If False, use the AddObject or AddObjectByName method to add a trigger to the list of copied objects.
CopyAllUserDefinedDatatypes Boolean Write: Yes | Determines if all user-defined datatypes in the source database are copied. If True, all user-defined datatypes in the source database are copied to the destination database. If False, use the AddObject or AddObjectByName method to add a user-defined datatype to the list of copied objects.
CopyAllViews Boolean Write: Yes | Determines if all views in the source database are copied. If True, all views in the source database are copied to the destination database. If False, use the AddObject or AddObjectByName method to add a view to the list of copied objects.
CopyData SQLOLE_COPYDATA_TYPE Write: Yes | If and how data will be copied to the destination database. If set to SQLOLECopyData_False, data is not copied. If set to SQLOLECopyData_Replace, destination tables are truncated, and then data is copied to them. If set to SQLOLECopyData_Append, data is appended to destination tables.
CopySchema Boolean Write: Yes | Determines if objects that are copied from the source database are first created. If True, copied objects are created in the destination database before copying data. If False, no objects are created in the destination database, only the data is transferred from copied tables, and these tables must already exist in the destination database.
DestDatabase Identifier Write: Yes | The database on the destination SQL Server that will store the objects and data from the source database.
DestLogin Identifier Write: Yes | The login that is used to connect to the destination SQL Server.
DestPassword Identifier Write: Yes | The password that is used to connect to the destination SQL Server.
DestServer String Write: Yes | The name of the SQL Server that contains the destination database.
DestUseTrustedConnection Boolean Write: Yes | Determines if a secure connection is requested when connecting to the destination SQL Server. If True, a secure connection is requested. If False, a normal connection is requested.
DropDestObjectsFirst Boolean Write: Yes | Determines if copied objects are dropped first. If True, copied objects are first dropped from the destination database, and the CopySchema property must be set to True to recreate the copied objects. If False, copied objects are not dropped from the destination database.
IncludeDependencies Boolean Write: Yes | Determines if objects that copied objects depend upon are automatically included in the list of copied objects. If True, any objects that a copied object depends upon is automatically included in the list of copied objects. If False, no dependency checking is done, and no objects are automatically included.
IncludeGroups Boolean Write: Yes | Determines if all groups in the source database are copied. If True, all groups in the source database are created in the destination database. If False, no groups are copied.
IncludeLogins Boolean Write: Yes | Determines if all SA-created logins in the source server's master database SQL Server are copied. If True, all SA-created logins in the source server's master database are created in the destination server's master database. If False, no SA-created logins are copied.
IncludeUsers Boolean Write: Yes | Determines if all users in the source database are copied. If True, all users in the source database are created in the destination database. If False, no users are copied.
Parent Application Write: No | The Application object.
ScriptType SQLOLE_SCRIPT_TYPE Write: Yes | The type of information and operations to include in the scripts that are used to create the copied objects in the destination database.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Transfer Methods

Abort Method

AddObject Method

AddObjectByName Method


Abort Method

Description

Stops a running database transfer. When one thread has used this Transfer object to call the Database.Transfer method (and that method has not yet returned), call Abort from another thread to stop the database transfer. After calling this method, the Transfer object is invalid and cannot be used again. You must create a new Transfer object to perform a new database transfer.

Visual Basic

Transfer.Abort

C++

HRESULT pTransfer->Abort ( );


AddObject Method

Description

Adds a SQL-DMO DBObject object to the list of copied objects.

Visual Basic

Transfer.AddObject ( [DBObject :=] DBObject )

C++

HRESULT pTransfer->AddObject ( LPSQLOLEDBOBJECT pDBObject );

Elements

Element Type Description

DBObject DBObject The DBObject object


AddObjectByName Method

Description

Adds an object name to the list of copied objects.

Visual Basic

Transfer.AddObjectByName (
[ObjectName :=] idObject,
[ObjectType :=] tObjectType )

C++

HRESULT pTransfer->AddObjectByName (
SQLOLE_LPCSTR idObject,
SQLOLE_OBJECT_TYPE tObjectType );

Elements

Element Type Description

idObject | Identifier | Name of the object
tObjectType | SQLOLE_OBJECT_TYPE | Type of the object; valid values are: SQLOLEObj_UserDefinedDatatype SQLOLEObj_View SQLOLEObj_UserTable SQLOLEObj_StoredProcedure SQLOLEObj_Default SQLOLEObj_Rule SQLOLEObj_Trigger


Transfer Lists

ListObjectNames List


ListObjectNames List

Description

Returns a list of Name objects that contain the database objects that are currently included in the list of copied objects.

Visual Basic

ObjectNameList = Application.ListObjectNames (
[ObjectType :=] tObjectType )

C++

HRESULT pApplication->ListObjectNames (
SQLOLE_OBJECT_TYPE tObjectType,
LPSQLOLENAMELIST* ppObjectNameList );

Elements

Element Type Description

ObjectNameList | NameList | Returned list of Name objects
tObjectType | SQLOLE_OBJECT_TYPE | Type of the database objects; valid values are: SQLOLEObj_UserDefinedDatatype SQLOLEObj_View SQLOLEObj_UserTable SQLOLEObj_StoredProcedure SQLOLEObj_Default SQLOLEObj_Rule SQLOLEObj_Trigger


Transfer Collections

Property Description

Properties
Properties
Write: No 		The collection of Property objects


ConnectionPoint Events

ConnectionPoint events allow a COM object to receive events from SQL-DMO objects. ConnectionPoint point events are available only to C++ applications.

To implement the event methods of a SQL-DMO object named Object that supports ConnectionPoint events, a COM object (typically named Object Sink) must follow these requirements:

  • Inherit from the ISQLOLEObjectSink interface to get the correct VTBL.
  • Implement all event methods for the SQL-DMO object that is included in the ISQLOLEObjectSink interface.
  • Respond to the IID_ISQLOLEObjectSink interface ID.
To use events of a SQL-DMO object named Object that supports ConnectionPoint events
  1. Call the IUnknown::QueryInterface method of the SQL-DMO object that supports ConnectionPoint events. Pass IID_IConnectionPointContainer as the riid parameter, and pass the address of a pointer to a ConnectionPointContainer object as the ppvObj parameter.

    QueryInterface will set ppvObj to point to a ConnectionPointContainer object.

  2. Call the IConnectionPointContainer::FindConnectionPoint method of the ConnectionPointContainer object. Pass the event sink interface ID of the SQL-DMO object as the first (xxx) parameter, and pass the address of a pointer to a ConnectionPoint object as the second (yyy) parameter.

    FindConnectionPoint will set yyy to point to a ConnectionPoint object.

  3. Create an ObjectSink object.
  4. Call the ISQLOLE Object Sink::Advise method of the ConnectionPoint object. Pass a pointer to the ObjectSink object as the pAdvSink parameter, and pass the address of a token as the pdwConnection parameter.

    Advise will set pdwConnection to an advisement identifier, or "cookie," that is used when calling ISQLOLE Object Sink::Unadvise.

  5. Use the SQL-DMO object. When a SQL-DMO event for that object is fired, SQL-DMO will call the appropriate event method of the ObjectSink object.
  6. Call the ISQLOLE Object Sink::Unadvise method of the ConnectionPoint object. Pass the "cookie" advisement identifier as the dwConnection parameter.

    SQL-DMO will no longer call the ObjectSink object when SQL-DMO events are fired.

  7. Call the IUnknown::Release method of the ConnectionPoint object.
  8. Call the IUnknown::Release method of the ConnectionPointContainer object.

The following table lists the SQL-DMO objects that support ConnectionPoint events and the event sink interfaces and interface IDs for each of them.

SQL-DMO
object 		Event sink
interface 		Event sink
interface ID

SQLServer | ISQLOLEServerSink | IID_ISQLOLEServerSink
Backup | ISQLOLEBackupSink | IID_ISQLOLEBackupSink
Transfer | ISQLOLETransferSink | IID_ISQLOLETransferSink
BulkCopy | ISQLOLEBulkCopySink | IID_ISQLOLEBulkCopySink

For more information about COM events, see the Microsoft OLE Control Developer's Kit and the Microsoft Win32 SDK.


BackupSink Event Methods

DumpComplete Method

NextVolume Method

PercentComplete Method


DumpComplete Method

Description

This event method is called when a Dump method (of a Database or TransactionLog object) sends a dump complete message.

C++

HRESULT pBackupSink->DumpComplete ( SQLOLE_LPCSTR strDumpComplete );

Elements

Element Type Description

strDumpComplete String Database dump complete message


NextVolume Method

Description

This event method is called when a running Dump or Load method (of a Database or TransactionLog object) sends a mount next volume message.

C++

HRESULT pBackupSink->NextVolume ( SQLOLE_LPCSTR strNextVolume );

Elements

Element Type Description

strNextVolume String Mount next volume message


PercentComplete Method

Description

This event method is called when a running Dump or Load method (of a Database or TransactionLog object) sends a new percent complete message.

C++

HRESULT pBackupSink->PercentComplete (
SQLOLE_LPCSTR strComplete,
long lPercentComplete );

Elements

Element Type Description

strComplete | String | Percent complete message
lPercentComplete | Long | Percent complete


BulkCopySink Event Methods

BatchImported Method

RowsCopied Method


BatchImported Method

Description

This event method is called when a running Table.ImportData method sends a new batch committed message.

C++

HRESULT pBulkCopySink->BatchImported ( SQLOLE_LPCSTR strBatch );

Elements

Element Type Description

strBatch String Batch committed message


RowsCopied Method

Description

This event method is called when a running ExportData method (of a Table or View object) or Table.ImportData method sends a new 1000 rows copied message.

C++

HRESULT pBulkCopySink->RowsCopied (
SQLOLE_LPCSTR strCopied,
long lRows );

Elements

Element Type Description

strCopied | String | Rows copied message
lRows | Long | Rows copied


ServerSink Event Methods

CommandSent Method

ConnectionBroken Method

QueryTimeout Method

RemoteLoginFailed Method

ServerMessage Method


CommandSent Method

Description

This event method is called when SQL-DMO sends a Transact-SQL statement to SQL Server.

C++

HRESULT pServerSink->CommandSent ( SQLOLE_LPCSTR strSQL );

Elements

Element Type Description

strSQL String Transact-SQL statement


ConnectionBroken Method

Description

This event method is called when the connection to SQL Server is broken.

C++

HRESULT pServerSink->ConnectionBroken (
SQLOLE_LPCSTR strBroken,
LPBOOL bRetry );

Elements

Element Type Description

strBroken | String | Connection broken message.
bRetry | Boolean | Determines if SQL-DMO will attempt to reestablish the broken connection. If set to True, SQL-DMO will attempt to reestablish the broken connection. If set to False, SQL-DMO will leave the connection broken, and the current operation will fail.

Remarks

If the SQLServer.AutoReConnect property is set to True, SQL-DMO will make one attempt to automatically reestablish the broken connection. If that attempt fails, the ConnectionBroken event method is called. If the SQLServer.AutoReConnect property is set to False, the ConnectionBroken event method is called immediately.


QueryTimeout Method

Description

This event method is called when the connection to SQL Server times out during a query. The SQLServer.QueryTimeout property is the connection timeout value.

C++

HRESULT pServerSink->QueryTimeout (
SQLOLE_LPCSTR strTimeout,
LPBOOL bContinue );

Elements

Element Type Description

strTimeout | String | Timeout message.
bContinue | Boolean | Determines if SQL-DMO will wait for another timeout period. If set to True, SQL-DMO will wait for another timeout period for the query to complete. If set to False, SQL-DMO will cancel the timed-out query, and the current operation will fail.


RemoteLoginFailed Method

Description

This event method is called when a remote login to a remote SQL Server fails.

C++

HRESULT pServerSink->RemoteLoginFailed (
long lSeverity,
long lNumber,
long lState,
SQLOLE_LPCSTR strMessage );

Elements

Element Type Description

lSeverity | Long | Severity of the server message
lNumber | Long | Number of the server message
lState | Long | State of the server message
strMessage | String | Text of the server message


ServerMessage Method

Description

This event method is called when a low-severity message that does not cause a SQL-DMO error is received from SQL Server.

C++

HRESULT pServerSink->ServerMessage (
long lSeverity,
long lNumber,
long lState,
SQLOLE_LPCSTR strMessage );

Elements

Element Type Description

lSeverity | Long | Server message Severity
lNumber | Long | Server message Number
lState | Long | Server message state
strMessage | String | Server message text


TransferSink Event Methods

PercentCompleteAtStep Method

ScriptTransferPercentComplete Method

StatusMessage Method

TransferPercentComplete Method


PercentCompleteAtStep Method

Description

This event method is called when a running Database.Transfer or Database.ScriptTransfer method sends a new percent complete message for a specific step in the transfer process.

C++

HRESULT pTransferSink->PercentCompleteAtStep (
SQLOLE_LPCSTR strStep,
long lPercentComplete );

Elements

Element Type Description

strStep | String | Current step of the transfer process
lPercentComplete | Long | Percent of the step complete


ScriptTransferPercentComplete Method

Description

This event method is called when a running Database.ScriptTransfer method sends a new percent complete message.

C++

HRESULT pTransferSink->ScriptTransferPercentComplete (
SQLOLE_LPCSTR strStep,
long lPercentComplete );

Elements

Element Type Description

strStep | String | Current step of the ScriptTransfer process
lPercentComplete | Long | Percent complete for the entire ScriptTransfer process


StatusMessage Method

Description

This event method is called when a running Database.Transfer method sends a new status message.

C++

HRESULT pTransferSink->StatusMessage ( SQLOLE_LPCSTR strStatus );

Elements

Element Type Description

strStatus String Status message from Database.Transfer method


TransferPercentComplete Method

Description

This event method is called when a running Database.Transfer method sends a new percent complete message.

C++

HRESULT pTransferSink->TransferPercentComplete (
SQLOLE_LPCSTR strStep,
long lPercentComplete );

Elements

Element Type Description

strStep | String | Current step of the Transfer process
lPercentComplete | Long | Percent complete for the entire Transfer process


SQLOLE_CONFIGVALUE_TYPE

Values

SQLOLEConfig_RemoteProcTrans
SQLOLEConfig_RemoteConnTimeout
SQLOLEConfig_CursorThreshold
SQLOLEConfig_ResourceTimeout
SQLOLEConfig_UserOptions
SQLOLEConfig_ProcessorAffinityMask


SQLOLE_CONSTANTS_TYPE

Values

SQLOLE_NOENDDATE
SQLOLE_NOENDTIME
SQLOLE_USEEXISTINGFILLFACTOR


SQLOLE_COPYDATA_TYPE

Values

SQLOLECopyData_False
SQLOLECopyData_Replace
SQLOLECopyData_Append


SQLOLE_DATAFILE_TYPE

Values

SQLOLEDataFile_Default
SQLOLEDataFile_CommaDelimitedChar
SQLOLEDataFile_TabDelimitedChar
SQLOLEDataFile_SpecialDelimitedChar
SQLOLEDataFile_NativeFormat
SQLOLEDataFile_UseFormatFile


SQLOLE_DEVICE_TYPE

Values

SQLOLEDevice_PipeDump

Remarks

SQLOLEDevice_PipeDump replaces SQLOLEDevice_Reserved.


SQLOLE_ERROR_TYPE

Values

SQLOLE_ECAT_ INVALIDCONTEXT |
SQLOLE_E _CANTRENAMESERVERGROUP | Existing ServerGroups cannot be renamed.
SQLOLE_E _CANTRENAMEREGISTEREDSERVER | Existing RegisteredServers cannot be renamed.
SQLOLE_E _INDEXREBUILDKEYTYPE | Index rebuild is only available for Primary or Unique keys (Foreign keys do not have enforcing indexes).
SQLOLE_E _REBUILDINDEXOPTIONS | Only SQLOLEIndex_Default, SQLOLEIndex_SortedData, or SQLOLEIndex_SortedDataReorg are valid for index rebuilding options.
SQLOLE_ECAT_ INVALIDOBJECTDEFINITION |
SQLOLE_E _SERVERGROUPINCOMPLETE | ServerGroup definition must include the name of the group.
SQLOLE_E _REGISTEREDSERVERINCOMPLETE | RegisteredServer definition must include the name of the server.
SQLOLE_E _SERVERGROUPALREADYEXISTS | A ServerGroup with the name '%s' already exists.
SQLOLE_E _REGISTEREDSERVERALREADYEXISTS | A RegisteredServer with the name '%s' already exists in ServerGroup '%s'.
SQLOLE_ECAT_ INVALIDPLATFORM |
SQLOLE_E _BACKUPSQL65ONLY | Backup options TableName, LoadFromSourceTableName, LoadAppendToTableData, and LoadStopDate requires Microsoft SQL Server Version 6.5 or later.
SQLOLE_E _SQL65ONLY | This property or method requires Microsoft SQL Server Version 6.5 or later.
SQLOLE_E _ALERTSQL65ONLY | The RaiseSNMPTrap property requires Microsoft SQL Server Version 6.5 or later.
SQLOLE_E _REMOTESQL65ONLY | The ODBCDatasource property requires Microsoft SQL Server Version 6.5 or later.
SQLOLE_E _PIPEDEVSQL65ONLY | Named Pipe Dump devices require Microsoft SQL Server Version 6.0 or later.
SQLOLE_E _FKEYSQL65ONLY | Foreign Key option for Exclude Replication requires Microsoft SQL Server Version 6.5 or later.
SQLOLE_ECAT_ TRANSFER |
SQLOLE_E _USERABORTED | The operation was aborted by the user.
SQLOLE_E _FILEPATHREQUIRED | A file path must be specified for the Transfer files.
SQLOLE_ECAT_ BCP |
SQLOLE_E _INCOMPATIBLEPROPS | The Bulk Copy properties specified are incompatible with each other.
SQLOLE_E _BCPEXECFAILED | The Bulk Copy execution failed.
SQLOLE_E _BCPINITFAILED | The Bulk Copy initialization failed.
SQLOLE_E _BCPCONTROLFAILED | Failure in setting a Bulk Copy control parameter.
SQLOLE_E _BCPCOLFMTFAILED | Failure in setting Bulk Copy column formats.
SQLOLE_E _SUSPENDINDEX | Failure while suspending indexing.
SQLOLE_E _RESUMEINDEX | Failure while resuming indexing.


SQLOLE_OBJECT_TYPE

Values

SQLOLEObj_ServerGroup
SQLOLEObj_RegisteredServer
SQLOLEObj_BulkCopy
SQLOLEObj_Transfer


SQLOLE_SCRIPT_TYPE

Values

SQLOLEScript_SortedData
SQLOLEScript_SortedDataReorg
SQLOLEScript_TransferDefault
SQLOLEScript_DRI_NonClustered
SQLOLEScript_DRI_Clustered
SQLOLEScript_DRI_Checks
SQLOLEScript_DRI_Defaults
SQLOLEScript_DRI_UniqueKeys
SQLOLEScript_DRI_ForeignKeys
SQLOLEScript_DRI_PrimaryKey
SQLOLEScript_DRI_AllKeys
SQLOLEScript_DRI_AllConstraints
SQLOLEScript_DRI_All
SQLOLEScript_DRIWithNoCheck


SQLOLE_SRVOPTION_TYPE

Values

SQLOLESrvOpt_ODBCDatasource


SQLOLE_STATUSINFO_TYPE

Values

SQLOLEStatInfo_AutoVerifyConnection


SQLOLE_SUBSCRIBERINFO_TYPE

Values

SQLOLESubInfo_SQLServer
SQLOLESubInfo_ODBCDatasource


SQLOLE_SUBSTATUS_TYPE

Values

SQLOLESubStat_Default


SQLOLE_SUBSYNC_TYPE

Values

SQLOLESubSync_Default


SQLOLE_SRVUSERPROFILE_TYPE

Values

SQLOLESrvUserProf_CreateXP


SQLOLE_XFRSCRIPTMODE_TYPE

Values

SQLOLEXfrFile_Default
SQLOLEXfrFile_SummaryFiles
SQLOLEXfrFile_SingleFile
SQLOLEXfrFile_SingleFilePerObject


Programming SQL Distributed Management Objects Errata

The following changes should be made to Microsoft SQL Server Programming SQL Distributed Management Objects for Microsoft SQL Server 6.0.

  • On page 222, LastOccuranceDate and OccuranceCount should be LastOccurrenceDate and OccurrenceCount.


Part 5 What's New for OLE Automation Stored Procedures

What's New for OLE Automation Stored Procedures

SQL Server 6.5 includes new OLE Automation stored procedures. The following table lists the new stored procedures, which are explained in this part. Features are in alphabetical order.

Feature | New | Enhanced
sp_OACreate | · |
sp_OADestroy | · |
sp_OAGetErrorInfo | · |
sp_OAGetProperty | · |
sp_OAMethod | · |
sp_OASetProperty | · |
sp_OAStop | · |

The OLE Automation stored procedures allow you to use standard OLE Automation objects within a Transact-SQL statement batch. Because these OLE objects reside and run on the SQL Server computer, they behave as OLE extended stored procedures.

You can use existing OLE Automation objects, such as the SQL Distributed Management Objects (SQL-DMO). You can also use 32-bit Visual Basic 4.0 to create your own OLE Automation objects and install them on the SQL Server computer.

To create and use OLE Automation objects on the SQL Server computer
  1. Call sp_OACreate to create the object.
  2. Use the object.
    • Call sp_OAGetProperty to get a property value.
    • Call sp_OASetProperty to set a property to a new value.
    • Call sp_OAMethod to call a method.
    • Call sp_OAGetErrorInfo to get the most recent error information.
  3. Call sp_OADestroy to destroy the object.

Note All of the above steps must be performed within a single Transact-SQL statement batch. All created OLE objects are automatically destroyed at the end of every statement batch.


Datatype Conversions

Because SQL Server uses Transact-SQL datatypes, and OLE Automation uses Visual Basic data types, the OLE Automation stored procedures must convert the data that passes between them.

This table shows the conversion from SQL Server to Visual Basic data types.

SQL Server datatype Visual Basic data type

char, varchar, text, decimal, numeric | String
bit | Boolean
binary, varbinary, image | One-dimensional Byte() array
int | Long
smallint | Integer
tinyint | Byte
float | Double
real | Single
money, smallmoney | Currency
datetime, smalldatetime | Date
anything set to NULL | Variant set to Null

All single SQL Server values are converted to a single Visual Basic value with the exception of binary, varbinary, and image values. These values are converted to a one-dimensional Byte() array in Visual Basic. This array has a range of Byte(0 To length-1) where length is the number of bytes in the SQL Server binary, varbinary, or image values.

This table shows the conversions from Visual Basic data types to SQL Server datatypes.

Visual Basic data type SQL Server datatype

Long, Integer, Byte, Boolean, Object | int
Double, Single | float
Currency | money
Date | datetime
String with 255 characters or less | varchar
String with more than 255 characters | text
One-dimensional Byte() array with 255 bytes or less | varbinary
One-dimensional Byte() array with more than 255 bytes | image


Results Sets

When a property return value or method return value is an array, sp_OAGetProperty or sp_OAMethod returns a results set to the client. (Method output parameters cannot be arrays.) These procedures scan all the data values in the array to determine the appropriate SQL Server datatypes and data lengths to use for each column in the results set. For a particular column, these procedures use the datatype and length required to represent all data values in that column.

When all data values in a column share the same datatype, that datatype is used for the whole column. When data values in a column use different datatypes, the datatype of the whole column is chosen based on the following table.

 | int | float | money | datetime | varchar
int | int | float | money | varchar | varchar
float | float | float | money | varchar | varchar
money | money | money | money | varchar | varchar
datetime | varvhar | varchar | varchar | datetime | varchar
varchar | varchar | varchar | varchar | varchar | varchar


HRESULT Return Codes

These procedures return an int return code. The return code is 0 when successful or a non-zero HRESULT when an error occurs. An HRESULT is an OLE error code of the hexadecimal form 0x800nnnnn, but when it is returned as an int value it has the form -214nnnnnnn.

For example, passing an invalid object name (for example, 'SQLOLE.Xyzzy') to sp_OACreate will cause it to return an int HRESULT of -2147221005, which is 0x800401f3 in hexadecimal.

You can use CONVERT(binary(4), @hresult) to convert an int HRESULT to a binary value. However, using CONVERT(char(10), CONVERT(binary(4), @hresult)) will result in an unreadable string, because each byte of the HRESULT is converted to a single ASCII character. You can also use the following sample stored procedure sp_hexadecimal to convert an int HRESULT to a char value that contains a readable hexadecimal string.

CREATE PROCEDURE sp_hexadecimal
    @binvalue varbinary(255),
    @hexvalue varchar(255) OUTPUT
AS
DECLARE @charvalue varchar(255)
DECLARE @i int
DECLARE @length int
DECLARE @hexstring char(16)
SELECT @charvalue = '0x'
SELECT @i = 1
SELECT @length = DATALENGTH(@binvalue)
SELECT @hexstring = '0123456789abcdef'
WHILE (@i <= @length)
BEGIN
    DECLARE @tempint int
    DECLARE @firstint int
    DECLARE @secondint int
    SELECT @tempint = CONVERT(int, SUBSTRING(@binvalue,@i,1))
    SELECT @firstint = FLOOR(@tempint/16)
    SELECT @secondint = @tempint - (@firstint*16)
    SELECT @charvalue = @charvalue +
        SUBSTRING(@hexstring, @firstint+1, 1) +
        SUBSTRING(@hexstring, @secondint+1, 1)
    SELECT @i = @i + 1
END
SELECT @hexvalue = @charvalue

You can use the following sample stored procedure sp_displayoaerrorinfo to display OLE Automation error information when one of these procedures returns a non-zero HRESULT return code. This sample stored procedure uses the sp_hexadecimal sample stored procedure.

CREATE PROCEDURE sp_displayoaerrorinfo
    @object int,
    @hresult int
AS
DECLARE @output varchar(255)
DECLARE @hrhex char(10)
DECLARE @hr int
DECLARE @source varchar(255)
DECLARE @description varchar(255)
PRINT 'OLE Automation Error Information'
EXEC sp_hexadecimal @hresult, @hrhex OUT
SELECT @output = '  HRESULT: ' + @hrhex
PRINT @output
EXEC @hr = sp_OAGetErrorInfo @object, @source OUT, @description OUT
IF @hr = 0
BEGIN
    SELECT @output = '  Source: ' + @source
    PRINT @output
    SELECT @output = '  Description: ' + @description
    PRINT @output
END
ELSE
BEGIN
    PRINT "  sp_OAGetErrorInfo failed."
    RETURN
END


Debugging

You can debug a custom OLE Automation server created by using 32-bit Visual Basic 4.0. To do this, Visual Basic must be installed on the SQL Server computer, and SQL Server must be running under the same Windows NT user account that Visual Basic is running under. So the SQL Server must be started from the command line and independent of the Windows NT Service Control Manager (by using the sqlservr /c command), or the SQL Server service must be started under the same Windows NT user account used to log on to the system.

To debug a custom OLE Automation server
  1. Load your custom OLE Automation server project into Visual Basic.
  2. Set breakpoint(s) on the desired lines of source code.
  3. From the Run menu, choose Start With Full Compile.

    This registers and runs your custom OLE Automation server.

  4. Use the OLE Automation stored procedures to call the OLE objects exposed by your custom OLE Automation server.

    When a breakpoint is hit, the Visual Basic debugger is activated.

For more information, see your documentation for Visual Basic.

Note To use a custom OLE Automation server developed with 32-bit Visual Basic 4.0 with the OLE Automation stored procedures, Windows NT 3.51 or later Service Pack 4 must be installed on the SQL Server computer.

A custom in-process OLE server created using 32-bit Visual Basic 4.0 must have an error handler (specified with the On Error GoTo statement) for the Class_Initialize and Class_Terminate subroutines. The error handlers will prevent unhandled errors from occurring in the subroutines. Unhandled errors in the Class_Initialize and Class_Terminate subroutines can cause unpredictable SQL Server problems, such as a SQL Server access violation. Error handlers for other subroutines are also recommended.


Sample Script

This is an example of a Transact-SQL statement batch that uses the OLE Automation stored procedures to create and use a SQL-DMO SQLServer object. Portions of the code are used as examples in the stored procedure references.

DECLARE @object int
DECLARE @hr int
DECLARE @property varchar(255)
DECLARE @return varchar(255)

-- Create an object
EXEC @hr = sp_OACreate 'SQLOLE.SQLServer', @object OUT
IF @hr <> 0
BEGIN
    EXEC sp_displayoaerrorinfo @object, @hr
    RETURN
END

-- Set a property
EXEC @hr = sp_OASetProperty @object, 'HostName', 'Gizmo'
IF @hr <> 0
BEGIN
    EXEC sp_displayoaerrorinfo @object, @hr
    RETURN
END

-- Get a property using an output parameter
EXEC @hr = sp_OAGetProperty @object, 'HostName', @property OUT
IF @hr <> 0
BEGIN
    EXEC sp_displayoaerrorinfo @object, @hr
    RETURN
END
PRINT @property

-- Get a property using a results set
EXEC @hr = sp_OAGetProperty @object, 'HostName'
IF @hr <> 0
BEGIN
    EXEC sp_displayoaerrorinfo @object, @hr
    RETURN
END

-- Get a property by calling the method
EXEC @hr = sp_OAMethod @object, 'HostName', @property OUT
IF @hr <> 0
BEGIN
    EXEC sp_displayoaerrorinfo @object, @hr
    RETURN
END
PRINT @property

-- Call a method
EXEC @hr = sp_OAMethod @object, 'Connect', NULL, 'my_server', 'my_login', 'my_password'
IF @hr <> 0
BEGIN
    EXEC sp_displayoaerrorinfo @object, @hr
    RETURN
END

-- Call a method that returns a value
EXEC @hr = sp_OAMethod @object, 'VerifyConnection', @return OUT
IF @hr <> 0
BEGIN
    EXEC sp_displayoaerrorinfo @object, @hr
    RETURN
END
PRINT @return

-- Destroy the object
EXEC @hr = sp_OADestroy @object
IF @hr <> 0
BEGIN
    EXEC sp_displayoaerrorinfo @object, @hr
    RETURN
END


sp_OACreate

Creates an OLE object on the SQL Server computer.

Syntax

sp_OACreate {progid | clsid}, objecttoken OUTPUT [, context]

where

progid
Is the programmatic identifier (ProgID) of the OLE object to create. This character string describes the class of the OLE object and has the following form:

'OLEComponent.Object'

OLEComponent is the component name of the OLE Automation server, and Object is the name of the OLE object. The specified OLE object must be creatable and must support the IDispatch interface.

For example, 'SQLOLE.SQLServer' is the ProgID of the SQL-DMO SQLServer object. SQL-DMO has a component name of SQLOLE, the SQLServer object is creatable, and (like all SQL-DMO objects) the SQLServer object supports IDispatch.

clsid
Is the class identifier (CLSID) of the OLE object to create. This character string describes the class of the OLE object and has the form:

'{nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn}'

The specified OLE object must be creatable and must support the IDispatch interface.

For example, '{00026BA1-0000-0000-C000-000000000046}' is the CLSID of the SQL-DMO SQLServer object.

objecttoken OUTPUT
Is the returned object token. It must be a local variable of datatype int. This object token identifies the created OLE object and is used in calls to the other OLE Automation stored procedures.
context
Specifies the execution context that the newly created OLE object will run in. If specified, this value must be one of the following:

1In-process (.DLL) OLE server only
4Local (.EXE) OLE server only
5Both in-process and local OLE server allowed

If not specified, the default value is 5. This value is passed as the dwClsContext parameter of the call to CoCreateInstance.

If an in-process OLE server is allowed (by using a context value of 1 or 5 or by not specifying a context value), it has access to memory and other resources owned by SQL Server. An in-process OLE server that is badly behaved might damage SQL Server memory or resources and cause unpredictable results such as a SQL Server access violation.

When you specify a context value of 4, a local OLE server does not have access to any SQL Server resources, and it cannot damage SQL Server memory or resources.

Remarks

The created OLE object is automatically destroyed at the end of the Transact-SQL statement batch.

This procedure returns a 0 when successful or a non-zero HRESULT when an error occurs.

Examples

A. Use Prog ID

This example creates a SQL-DMO SQLServer object by using its Prog ID.

DECLARE @object int
DECLARE @hr int
EXEC @hr = sp_OACreate 'SQLOLE.SQLServer', @object OUT
IF @hr <> 0
BEGIN
    EXEC sp_displayoaerrorinfo @object, @hr
    RETURN
END
B. Use CLSID

This example creates a SQL-DMO SQLServer object by using its CLSID.

DECLARE @object int
DECLARE @hr int
EXEC @hr = sp_OACreate '{00026BA1-0000-0000-C000-000000000046}',
    @object OUT
IF @hr <> 0
BEGIN
    EXEC sp_displayoaerrorinfo @object, @hr
    RETURN
END


sp_OAGetProperty

Gets a property value of an OLE object.

Syntax

sp_OAGetProperty objecttoken, propertyname, [propertyvalue OUTPUT
[, index...]]

where

objecttoken
Is the object token of an OLE object previously created by sp_OACreate.
propertyname
Is the property name of the OLE object to return.
propertyvalue OUTPUT
Is the returned property value. If specified, it must be a local variable of the appropriate datatype.
index
Is an index parameter. If specified, it must be a value of the appropriate datatype.

Some properties have parameters. They are called indexed properties, and the parameters are called index parameters. A property can have multiple index parameters.

Remarks

If the property returns a single value, either:

  • Specify a local variable for propertyvalue. The property value is returned in the local variable.

    Or

  • Do not specify propertyvalue. The property value is returned to the client as a single-column, single-row results set.

If the property returns an OLE object, you must specify a local variable of datatype int for the propertyvalue parameter. An object token will be stored in the local variable, and this object token can be used with other OLE Automation stored procedures.

If the property returns an array with one or two dimensions, the array will be returned to the client as a results set as follows:

  • A one-dimensional array is returned to the client as a single-row results set with as many columns as there are elements in the array. In other words, the array is returned as (columns).
  • A two-dimensional array is returned to the client as a results set with as many columns as there are elements in the first dimension of the array and with as many rows as there are elements in the second dimension of the array. In other words, the array is returned as (columns, rows).

When the property returns an array, if propertyvalue is specified, it is set to NULL.

If propertyvalue is specified, but the property does not return a value, an error occurs. If the property returns an array with more than two dimensions, an error occurs.

You can also use sp_OAMethod to get a property value.

This procedure returns a 0 when successful or a non-zero HRESULT when an error occurs.

Examples

A. Use Local Variable

This example gets the HostName property (of the previously created SQLServer object) and stores it in a local variable.

DECLARE @property varchar(255)
EXEC @hr = sp_OAGetProperty @object, 'HostName', @property OUT
IF @hr <> 0
BEGIN
    EXEC sp_displayoaerrorinfo @object, @hr
    RETURN
END
PRINT @property
B. Use Results Set

This example gets the HostName property (of the previously created SQLServer object) and returns it to the client as a results set.

EXEC @hr = sp_OAGetProperty @object, 'HostName'
IF @hr <> 0
BEGIN
    EXEC sp_displayoaerrorinfo @object, @hr
    RETURN
END


sp_OASetProperty

Sets a property of an OLE object to a new value.

Syntax

sp_OASetProperty objecttoken, propertyname, newvalue [, index...]

where

objecttoken
Is the object token of an OLE object previously created by sp_OACreate.
propertyname
Is the property name of the OLE object to set to a new value.
newvalue
Is the new value of the property. It must be a value of the appropriate datatype.
index
Is an index parameter. If specified, it must be a value of the appropriate datatype.

Some properties have parameters. They are called indexed properties, and the parameters are called index parameters. A property can have multiple index parameters.

Remarks

This procedure returns a 0 when successful or a non-zero HRESULT when an error occurs.

Example

This example sets the HostName property (of the previously created SQLServer object) to a new value.

EXEC @hr = sp_OASetProperty @object, 'HostName', 'Gizmo'
IF @hr <> 0
BEGIN
    EXEC sp_displayoaerrorinfo @object, @hr
    RETURN
END


sp_OAMethod

Calls a method of an OLE object.

Syntax

sp_OAMethod objecttoken, methodname, [returnvalue OUTPUT
[, [@parametername =] parameter [OUTPUT]...]]

where

objecttoken
Is the object token of an OLE object previously created by sp_OACreate.
methodname
Is the method name of the OLE object to call.
returnvalue OUTPUT
Is the return value of the method of the OLE object. If specified, it must be a local variable of the appropriate datatype.
[@parametername =] parameter [OUTPUT]
Is a method parameter. If specified, parameter must be a value of the appropriate datatype.

To obtain the return value of an output parameter, parameter must be a local variable of the appropriate datatype, and OUTPUT must be specified. If a constant parameter is specified, or if OUTPUT is not specified, any return value from an output parameter is ignored.

If specified, parametername must be the name of the Visual Basic named parameter. Note that @parametername is not a Transact-SQL local variable. The at (@) is removed, and parametername is passed to the OLE object as the parameter name. All named parameters must be specified after all positional parameters are specified.

Remarks

If the method returns a single value, either:

  • Specify a local variable for returnvalue. The method return value is returned in the local variable.

    Or

  • Do not specify returnvalue. The method return value is returned to the client as a single-column, single-row results set.

If the method return value is an OLE object, you must specify a local variable of datatype int for the returnvalue parameter. An object token will be stored in the local variable, and this object token can be used with other OLE Automation stored procedures.

If the method return value is an array with one or two dimensions, the array will be returned to the client as a results set as follows:

  • A one-dimensional array is returned to the client as a single-row results set with as many columns as there are elements in the array. In other words, the array is returned as (columns).
  • A two-dimensional array is returned to the client as a results set with as many columns as there are elements in the first dimension of the array and with as many rows as there are elements in the second dimension of the array. In other words, the array is returned as (columns, rows).

When the method return value is an array, if returnvalue is specified, it is set to NULL.

An error occurs under any of the following circumstances:

  • If returnvalue is specified, but the method does not return a value
  • If the method returns an array with more than two dimensions
  • If the method returns an array as an output parameter

Note that sp_OAMethod can also be used to get a property value.

This procedure returns a 0 when successful or a non-zero HRESULT when an error occurs.

Examples

A. Call a Method

This example calls the Connect method of the previously created SQLServer object.

EXEC @hr = sp_OAMethod @object, 'Connect', NULL, 'my_server',
    'my_login', 'my_password'
IF @hr <> 0
BEGIN
    EXEC sp_displayoaerrorinfo @object, @hr
    RETURN
END
B. Get a Property

This example gets the HostName property (of the previously created SQLServer object) and stores it in a local variable.

DECLARE @property varchar(255)
EXEC @hr = sp_OAMethod @object, 'HostName', @property OUT
IF @hr <> 0
BEGIN
    EXEC sp_displayoaerrorinfo @object, @hr
    RETURN
END
PRINT @property


sp_OAGetErrorInfo

Obtains OLE Automation error information.

Syntax

sp_OAGetErrorInfo [objecttoken [, source OUTPUT [, description OUTPUT
[, helpfile OUTPUT [, helpid OUTPUT ]]]]]

where

objecttoken
Is the object token of an OLE object previously created by sp_OACreate or NULL. If an object token is specified, error information for that object will be returned. If NULL is specified, the error information for the entire batch will be returned.
source OUTPUT
Is the source of the error information. If specified, it must be a local char or varchar variable. The return value will be truncated to fit the local variable if necessary.
description OUTPUT
Is the description of the error. If specified, it must be a local char or varchar variable. The return value will be truncated to fit the local variable if necessary.
helpfile OUTPUT
Is the Help file for the OLE object. If specified, it must be a local char or varchar variable. The return value will be truncated to fit the local variable if necessary.
helpid OUTPUT
Is the Help file context ID. If specified, it must be a local int variable.

Remarks

Each call to an OLE Automation stored procedure (except sp_OAGetErrorInfo) resets the error information, so sp_OAGetErrorInfo obtains error information only for the most recent OLE Automation stored procedure call. Note that because sp_OAGetErrorInfo does not reset the error information, it can be called multiple times to get the same error information.

If no output parameters are specified, the error information is returned to the client as a results set.

This procedure returns a 0 when successful or a non-zero HRESULT when an error occurs.

This table is a list of OLE Automation errors and their common causes.

Error and HRESULT Common cause

Bad variable type (0x80020008) | The datatype of a Transact-SQL value passed as a method parameter did not match the Visual Basic data type of the method parameter, or a NULL value was passed as a method parameter. Ensure that any local variables used as method parameters are of the appropriate datatype and are set to a value other than NULL.
Unknown name (0x8002006) | The specified property or method name was not found for the specified object.
Invalid class string (0x800401f3) | The specified ProgID or CLSID is not been registered as an OLE object on the SQL Server computer.
Server execution failed (0x80080005) | The specified OLE object is registered as a local OLE server (.EXE file) but the .EXE file could not be found or started.
The specified module could not be found (0x8007007e) | The specified OLE object is registered as an in-process OLE server (.DLL file), but the .DLL file could not be found or loaded.
Type mismatch (0x80020005) | The datatype of a Transact-SQL local variable used to store a returned property value or a method return value did not match the Visual Basic data type of the property or method return value. Ensure that the local variable is of the appropriate datatype. Or, the return value of a property or a method was requested, but it does not return a value.
Parameter not found (0x80020004) | A named parameter was specified before a positional parameter. Ensure that all named parameters are specified after all positional parameters.
The parameter is incorrect (0x80070057) | The number specified as the context parameter of sp_OACreate was not valid.

Example

This example displays OLE Automation error information.

DECLARE @output varchar(255)
DECLARE @hr int
DECLARE @source varchar(255)
DECLARE @description varchar(255)
PRINT 'OLE Automation Error Information'
EXEC @hr = sp_OAGetErrorInfo @object, @source OUT, @description OUT
IF @hr = 0
BEGIN
    SELECT @output = '  Source: ' + @source
    PRINT @output
    SELECT @output = '  Description: ' + @description
    PRINT @output
END
ELSE
BEGIN
    PRINT '  sp_OAGetErrorInfo failed.'
    RETURN
END


sp_OADestroy

Destroys a created OLE object.

Syntax

sp_OADestroy objecttoken

where

objecttoken
Is the object token of an OLE object previously created by sp_OACreate.

Remarks

If sp_OADestroy is not called, the created OLE object is automatically destroyed at the end of the batch.

This procedure returns a 0 when successful or a non-zero HRESULT when an error occurs.

Example

This example destroys the previously created SQLServer object.

EXEC @hr = sp_OADestroy @object
IF @hr <> 0
BEGIN
    EXEC sp_displayoaerrorinfo @object, @hr
    RETURN
END


sp_OAStop

Stops the server-wide OLE Automation stored procedure execution environment.

Syntax

sp_OAStop

Remarks

After SQL Server is started, the shared OLE Automation stored procedure execution environment is automatically started when sp_OACreate is first called by a client. A single execution environment is shared by all clients using the OLE Automation stored procedures.

It is not necessary to call sp_OAStop. If sp_OAStop is not called, the execution environment is automatically stopped when SQL Server is shut down. After the execution environment has been stopped, any call to sp_OACreate will restart the execution environment.

Note If one client calls sp_OAStop to stop the execution environment, any client currently executing a statement batch that uses the OLE Automation stored procedures will receive an error when any OLE Automation stored procedure (except sp_OACreate) is called.

Example

This example stops the shared OLE Automation execution environment.

EXEC sp_OAStop


Object Hierarchy Syntax

The propertyname parameter of sp_OAGetProperty and sp_OASetProperty and the methodname of sp_OAMethod support object hierarchy syntax similar to Visual Basic. When this special syntax is used, these parameters have the general form:

Syntax

'TraversedObject.PropertyOrMethod'

where

TraversedObject
Is an OLE object in the hierarchy under the objecttoken specified in the stored procedure. Use Visual Basic syntax to specify a series of collections, object properties, and methods that return objects. Each object specifier in the series must be separated by a period (.).

An item in the series can be the name of a collection. Use this syntax to specify a collection:

Collection("item")

The double-quotes (") around item are required. The Visual Basic exclamation point (!) syntax for collections is not supported.

PropertyOrMethod
Is the name of a property or method of the TraversedObject.

To specify all index or method parameters by using sp_OAGetProperty, sp_OASetProperty, or sp_OAMethod parameters (including support for sp_OAMethod output parameters), use this syntax:

PropertyOrMethod

To specify all index or method parameters inside the parenthesis (causing all index or method parameters of sp_OAGetProperty, sp_OASetProperty, or sp_OAMethod to be ignored) use this syntax:

PropertyOrMethod( [ParameterName :=] "parameter" [, ...] )

The double-quotes (") around each parameter are required. All named parameters must be specified after all positional parameters are specified.

Remarks

If TraversedObject is not specified, PropertyOrMethod is required.

If PropertyOrMethod is not specified, the TraversedObject is returned as an object token output parameter from the OLE Automation stored procedure. If PropertyOrMethod is specified, the property or method of the TraversedObject is called, and the property value or method return value is returned as an output parameter from the OLE Automation stored procedure.

If any item in the TraversedObject list does not return an OLE object, an error occurs.

For more information about Visual Basic OLE object syntax, see your Visual Basic documentation.

Example

These are examples of object hierarchy syntax using a SQL-DMO SQLServer object.

-- Call the Connect method of the SQLServer object
EXEC @hr = sp_OAMethod @object,
    'Connect("my_server", "my_login", "my_password")'

-- Get the pubs..authors Table object
EXEC @hr = sp_OAGetProperty @object,
    'Databases("pubs").Tables("authors")',
    @table OUT

-- Get the Rows property of the pubs..authors table
EXEC @hr = sp_OAGetProperty @object,
    'Databases("pubs").Tables("authors").Rows',
    @rows OUT

-- Call the CheckTable method of the pubs..authors table
EXEC @hr = sp_OAMethod @object,
    'Databases("pubs").Tables("authors").CheckTable',
    @checkoutput OUT


Part 7 What's New for DB-Library for C

What's New for DB-Library for C

SQL Server 6.5 includes several new and enhanced functions for DB-Library for C. The new functions dbenlisttrans and dbenlistxatrans are designed for use with Microsoft Distributed Transaction Coordinator (MS DTC). The new DBSETLFALLBACK function is designed for fallback server support. The following table lists the new and enhanced functions, which are explained in this part. Features are in alphabetical order.

Note that the DB-Library for C Help file contains version 6.0 information. Read this section for the most up-to-date version 6.5 information.

Feature | New | Enhanced
LOGINREC structure |  | ·
Error messages |  | ·
Functions |  |
bcp_option |  | ·
dbcursoropen |  | ·
dbdatecrack |  | ·
dbenlisttrans | · |
dbenlistxatrans | · |
dbopen |  | ·
dbrpcinit |  | ·
dbrpcparam |  | ·
DBSETLFALLBACK | · |
Quoted identifiers | · |


dbenlisttrans

Enlists the current SQL Server connection in an existing MS DTC transaction.

Syntax

RETCODE dbenlisttrans (
PDBPROCESS dbproc,
LPVOID pTransaction );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
pTransaction
Is the MS DTC transaction OLE object that specifies the transaction to export to SQL Server. The client calls the MS DTC OLE ITransactionDispenser::BeginTransaction method to create the MS DTC transaction object.

Returns

SUCCEED or FAIL.

Remarks

The client application must call dbenlisttrans before performing the first update on a SQL Server that is enlisted in an MS DTC transaction.

To update two or more (N) SQL Servers using MS DTC
  1. Connect to the MS DTC by using the MS DTC OLE DtcSelectTransactionManager method to obtain a transaction manager object. For information about MS DTC, see the Guide to Microsoft Distributed Transaction Coordinator.
  2. Call dbopen N times to connect to each SQL Server.
  3. Call the MS DTC OLE ITransactionDispenser::BeginTransaction method to begin the MS DTC transaction and to obtain a transaction object.
  4. Call dbenlisttrans N times to send the MS DTC transaction to each SQL Server.
  5. Call dbsqlexec N times to perform one or more MS DTC transaction updates on each SQL Server.
  6. Call the MS DTC OLE ITransaction::Commit method to commit the MS DTC transaction. The transaction object is no longer valid after the transaction commits.
  7. Call the MS DTC OLE ITransaction::Return method to release the reference to the transaction object.
  8. Either
    • Call dbenlisttrans N times to pass a NULL transaction pointer to each SQL Server, which will disconnect each SQL Server.

    Or

    • To begin a new coordinated transaction, go to step 3.

Note You can also call dbenlisttrans and dbsqlexec in turn for each SQL Server instead of calling them as suggested in steps 4 and 5 above.

See Also

dbenlistxatrans


dbenlistxatrans

Enlists the current SQL Server connection in a transaction that is coordinated by an XA-compliant transaction processing (TP) monitor.

Syntax

RETCODE dbenlistxatrans (
PDBPROCESS dbproc,
BOOL enlisttran );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
enlisttran
Is TRUE or FALSE. TRUE specifies to enlist in the current XA transaction. False specifies to enlist in the NULL transaction, which results in the connection no longer being enlisted in any XA transaction.

When enlisttran is TRUE, the SQL Server connection is enlisted in the current XA transaction. All SQL operations performed using the SQL Server connection will be performed under the protection of the current XA transaction.

When enlisttran is FALSE, the SQL Server connection is no longer enlisted in any XA transaction. If you have used a SQL Server connection with an XA transaction, and you want to use the same SQL Server connection with a local SQL Server transaction, you must call dbenlistxatrans and pass a value of FALSE for the enlisttran parameter.

Returns

SUCCEED or FAIL.

Remarks

To use XA transactions
  1. Call dbopen once for each SQL Server connection you want to establish.
  2. Call the X/Open tx_begin function to begin an XA transaction. tx_begin calls the appropriate XA-compliant TP monitor.
  3. For each SQL Server connection you want to enlist in the XA transaction, call dbenlistxatrans with enlisttran set to TRUE. Each call associates the current XA transaction with the specified SQL Server connection.
  4. Call dbsqlexec one or more times to perform SQL Server operations.
  5. Call the X/Open tx_commit function to commit the XA transaction.

    To perform a series of XA transactions, repeat steps 2 through 5.

See the SQL_COPT_SS_ENLIST_IN_XA connection option of the SQLSetConnectOption function for information about using XA transactions through ODBC.

See Also

dbenlisttrans


DBSETLFALLBACK

Indicates that dbopen can connect to a fallback server if an attempt to connect to a primary server fails.

Syntax

RETCODE DBSETLFALLBACK (
PLOGINREC ploginrec,
LPCSTR pstatus );

where

ploginrec
Is a pointer to a LOGINREC structure, which is passed as a parameter to dbopen.
pstatus
Specifies whether fallback support is enabled or not. Set pstatus to "ON" to enable fallback support. Set pstatus to "OFF" to disable fallback support.

Returns

SUCCEED or FAIL.

Remarks

Call the DBSETLFALLBACK function to indicate that a fallback server can be used by a subsequent call to dbopen. When successfully connected to the primary server, the dbopen function automatically determines the current fallback server and verifies that the fallback information is stored in the registry. You must call the DBSETLFALLBACK function before you call the dbopen function. If the attempt to connect to the primary server fails, dbopen attempts to connect to the fallback server.

Setting pstatus to "ON" or "OFF" determines whether fallback support is available during subsequent calls to dbopen.

For DBSETLFALLBACK to function properly, the connection timeout set by calling dbsetlogintime or DBSETLTIME must be a value greater than 0.

Example

In this example, DBSETLFALLBACK specifies that fallback support is enabled prior to a call to dbopen.

DBSETLFALLBACK(loginrec, "ON");
dbproc = dbopen(loginrec, "my_server");


Using dbopen to Connect to a Fallback Server

If an attempt to connect to a primary server fails, dbopen can attempt to connect to a fallback server. You must call the DBSETLFALLBACK function to indicate that a fallback server can be used. The call to the DBSETLFALLBACK function must occur before the call to the dbopen function.

Each call to the DBSETLFALLBACK function from a machine running Windows NT or Windows 95 updates the fallback information in the local registry from the SQL Server registry. Fallback information is stored in the WIN.INI file on machines running 16-bit Windows. The dbopen function retrieves the fallback information from the local registry or from the WIN.INI file.

When dbopen attempts to connect to a fallback server, DB-Library generates warning message 10110 (SQLECONNFB):

Unable to connect: DB Server is unavailable or
does not exist -- will attempt a fallback connection.

See Also

DBSETLFALLBACK


Opening a Cursor on a Stored Procedure

In SQL Server 6.5, you can pass stored procedure parameters when you open a cursor by calling the dbrpcinit function and the dbrpcparam function.

The dbrpcinit function has an option parameter: DBRPCCURSOR. Use DBRPCCURSOR to specify the initialization of an input-parameter list for a subsequent cursor-open operation on a stored procedure. When you use DBRPCCURSOR, you must set the rpcname parameter to NULL.

No pending remote procedure calls (RPCs) can exist when you call dbrpcinit with an option of DBRPCCURSOR. The dbrpcinit function returns FAIL if pending RPCs have been initiated.

You can call the dbrpcparam function to set the value for each stored procedure parameter that was used in the process of opening a cursor. Stored procedure parameters are no longer required to be constants, and they can be passed as follows.

To open a cursor on a stored procedure that passes program variables as parameters
  1. Call the dbrpcinit function once to initialize a new stored procedure. Set the rpcname parameter to NULL, and set the option parameter to DBRPCCURSOR.
  2. Call the dbrpcparam function once per parameter to set the value of each parameter of the stored procedure.
  3. Call the dbcursoropen function to open the cursor, and in the stmt parameter, specify only the stored procedure name.
  4. Call the remaining cursor functions as you would normally. For more information, see Microsoft SQL Server Programming DB-Library for C, Chapter 5, "Cursor Functions."


Using Dynamic Cursors with dbcursoropen

When you call the dbcursoropen function with a scrollopt parameter of CUR_DYNAMIC, the tables you specify in the SELECT statement of the stmt parameter no longer require unique indexes.

In SQL Server version 6.0, the cursor automatically opens with a scrollopt parameter of CUR_INSENSITIVE and a concuropt parameter of CUR_READONLY if the SELECT statement contains a table without a unique index.

In SQL Server 6.5, the cursor automatically opens with a scrollopt parameter of CUR_INSENSITIVE and a concuropt parameter of CUR_READONLY if the SELECT statement contains any of the following:

  • ORDER BY and a table with no unique index
  • UNION
  • DISTINCT
  • GROUP BY
  • HAVING
  • Aggregate function

SQL Server will copy the results into temporary work tables. Because all fetch operations are performed on the temporary tables, you cannot make changes to the cursor by using dbcursor.


Using dbdatecrack

The dbdatecrack function accepts a NULL value for the dbproc parameter. In SQL Server 6.0, the dbdatecrack function can only be called if a DBPROCESS structure is active.


Using bcp_option

The bcp_option function has a field parameter: BCPABORT. BCPABORT stops a bulk copy operation that is already in progress. Call bcp_option with a field of BCPABORT from another thread to stop a running bulk copy operation. The value parameter is ignored.


Default Values for a LOGINREC Structure

If you do not call DBSETLAPP, the application parameter of the LOGINREC structure is set to the calling application name by default instead of to NULL, as it is in SQL Server 6.0.

If you do not call DBSETLHOST, the workstation parameter of the LOGINREC structure is set to the host workstation name by default instead of to NULL, as it is in SQL Server 6.0.


Using Quoted Identifiers

When enabled, the DBQUOTEDIDENT option specifies that DB-Library will automatically place double quotation marks (") around certain object names that are called quoted identifiers. The DBQUOTEDIDENT option is disabled by default.

Call dbsetopt with the DBQUOTEDIDENT option to enable the use of quoted identifiers. Call dbclropt with the DBQUOTEDIDENT option to disable the use of quoted identifiers. Call dbisopt to check the status of the DBQUOTEDIDENT option. When you use DBQUOTEDIDENT, you must set param to NULL.

The following table lists the functions and the parameters that are affected when DBQUOTEDIDENT is enabled.

Function | Parameter(s)
bcp_init | tblname
dbrpcinit | rpcname
dbupdatetext | dest_object src_object
dbuse | dbname
dbwritetext | objname

When you call dbrpcinit, you must explicitly place quotation marks around remote procedure names that require quotation marks in the rpcname parameter. This example demonstrates the use of quotation marks in rpcname.

"My server".."My RPC"


Error Messages

SQL Server 6.5 adds the following error messages to DB-Library for C.

Error no. | Error/ Error severity | Description
10106 | SQLEBCPS EXPROGRAM | The row length exceeds SQL Server's maximum allowable size.
10107 | SQLEDTC EXRESOURCE | Microsoft Distributed Transaction Coordinator call failed.
10108 | SQLENOTIMPL EXPROGRAM | This function is not supported on this platform at this time.
10109 | SQLENONFLOAT EXPROGRAM | Float conversion attempt failed. The source is invalid.
10110 | SQLECONNFB EXCOMM | Unable to connect: DB Server is unavailable or does not exist -- will attempt a fallback connection.


Programming DB-Library for C Errata

The following changes should be made to Microsoft SQL Server Programming DB-Library for C for Microsoft SQL Server 6.0.

  • All references to Chapter 9, "Microsoft SQL Server Cursors" should be removed.
  • On page 116, in Chapter 4, "Core Functions," the dbfreequal function should be documented in Chapter 8, "Browse Functions."
  • On page 124, the reference should indicate that you can call dbgetuserdata when dbdead returns TRUE.
  • On page 133, the if statements in the programming example for the dbmsghandle function should be changed.

    The following example correctly shows a typical message-handling function:

    #include    <sqlfront.h>
#include    <sqldb.h>

int msg_handler(dbproc, msgno, msgstate, severity, msgtext,
    srvname, procname, line)
DBPROCESS    *dbproc;
DBINT        msgno;
int            msgstate;
int            severity;
char            *msgtext;
char            *srvname;
char            *procname;
DBUSMALLINT    line;

{
    printf("SQL Server message %ld, state %d, "
        "severity %d:\n\t%s\n", msgno, msgstate, severity, msgtext);
if (strlen(srvname) != 0)
        printf ("Server '%s', ", srvname);
    if (strlen(procname) != 0)
        printf ("Procedure '%s', ", procname);
    if (line != 0)
        printf ("Line %d", line);

    return(0);
}
  • On page 173, in "dbsetmaxprocs," it should be noted that the number of platform-dependent connections for Windows NT and Windows 95 is limited by the amount of available memory.
  • On page 192, in "dbwinexit (Windows only)", it should be noted that dbwinexit does not close any connections. Use dbclose or dbexit to close connections.
  • On page 195, in "dbcursor", in the bulleted list for row, CRS_UPDATE should be deleted because a row value of 0 is invalid. An update operation cannot be performed on all rows in the fetch buffer.
  • On page 328, in Appendix A, "DB-Library Options," and on page 176, in "dbsetopt", a DBBUFFER value of 1 is invalid, and a negative DBBUFFER value will set DBBUFFER to the default of 100 rows.
  • On page 331, in Appendix A, "DB-Library Options," in the table, the possible parameter values for DBTEXTLIMIT should be 0 to 65,534 for 16-bit DB-Library and 0 to 2,147,483,647 for 32-bit DB-Library.


Part 8 What's New for DB-Library for Visual Basic

What's New for DB-Library for Visual Basic

SQL Server 6.5 includes several new and enhanced functions for DB-Library for Visual Basic. These functions include SqlCursorOpen and SqlCursorRowStatus, and they are designed for use with cursor operations. The new SqlSetLFallback function is designed for fallback server support. The following table lists the new and enhanced functions, which are explained in this part. Features are in alphabetical order.

Note that the DB-Library for Visual Basic Help file contains version 6.0 information. Read this section for the most up-to-date version 6.5 information.

Feature | New | Enhanced
LOGINREC structure |  | ·
Error messages |  | ·
Functions |  |
SqlCursorOpen |  | ·
SqlCursorRowStatus | · |
SqlDateCrack |  | ·
SqlRpcInit |  | ·
SqlRpcParam |  | ·
SqlOpen |  | ·
SqlSetLFallback | · |
SqlStrCpy |  | ·


SqlCursorOpen

The pstatus&() parameter of SqlCursorOpen has been removed. Use the new SqlCursorRowStatus function to get the row status indicator.

Syntax

SqlCursorOpen& ( sqlconn&, stmt$, scrollopt&, concuropt&, nrows& )


SqlCursorRowStatus

Returns the row fetch status value for a row in the cursor fetch buffer.

Syntax

SqlCursorRowStatus& ( sqlconn&, row&, status& )

where

sqlconn&
Is a SQL Server connection. The value of sqlconn& is returned by SqlOpen.
row&
Is the number of the row in the fetch buffer. The first row is number 1.
status&
Is the fetch status indicator for the specified row&. A row fetch status value is a bitmap of fetch status values that are ORed together.

Client cursor, transparent server cursor:

For more information about fetch status values, see SqlCursorFetch.

Explicit server cursor:

For more information about fetch status values, see SqlCursorFetchEx.

Returns

SUCCEED (1) or FAIL (0).

Remarks

This function replaces the pstatus&() parameter of SqlCursorOpen.


SqlSetLFallback

Indicates that SqlOpen can connect to a fallback server if an attempt to connect to a primary server fails.

Syntax

SqlSetLFallback& ( loginrec&, status$ );

where

loginrec&
Is a pointer to a LOGINREC structure, which is passed as a parameter to SqlOpen.
status$
Specifies whether fallback support is enabled or not. Set status$ to "ON" to enable fallback support. Set status$ to "OFF" to disable fallback support.

Returns

SUCCEED or FAIL.

Remarks

Call the SqlSetLFallback function to indicate that a fallback server can be used by a subsequent call to SqlOpen. When successfully connected to the primary server, the SqlOpen function automatically determines the current fallback server and verifies that the fallback information is stored in the registry. You must call the SqlSetLFallback function before you call the SqlOpen function. If the attempt to connect to the primary server fails, SqlOpen attempts to connect to the fallback server.

The status$ setting determines whether fallback support is available during subsequent calls to SqlOpen.

For SqlSetLFallback to function properly, the connection timeout set by calling SqlSetLoginTime must be a value greater than 0.

Example

In this example, SqlSetLFallback specifies that fallback support is enabled prior to a call to SqlOpen.

SqlSetLFallback(Loginrec, "ON")
Sqlconn = SqlOpen(Loginrec, "my_server")


Using SqlOpen to Connect to a Fallback Server

If an attempt to connect to a primary server fails, SqlOpen can attempt to connect to a fallback server. You must call the SqlSetLFallback function to indicate that a fallback server can be used. The call to the SqlSetLFallback function must occur before the call to the SqlOpen function.

Each call to the SqlSetLFallback function from a machine running Windows NT or Windows 95 updates the fallback information in the local registry from the SQL Server registry. Fallback information is stored in the WIN.INI file on machines running 16-bit Windows. The SqlOpen function retrieves the fallback information from the local registry or from the WIN.INI file.

When SqlOpen attempts to connect to a fallback server, DB-Library generates warning message 10110 (DBECONNFB):

Unable to connect: SQL Server is unavailable or does
not exist -- will attempt a fallback connection.

See Also

SqlSetLFallback


Opening a Cursor on a Stored Procedure

In SQL Server 6.5, you can pass stored procedure parameters when you open a cursor by calling the SqlRpcInit function and the SqlRpcParam function.

The SqlRpcInit function has an options& parameter: SQLRPCCURSOR. Use SQLRPCCURSOR to specify the initialization of an input-parameter list for a subsequent cursor-open operation on a stored procedure. When you use SQLRPCCURSOR, you must set the rpcname$ parameter to an empty string.

No pending remote procedure calls (RPCs) can exist when you call SqlRpcInit with an options& of SQLRPCCURSOR. The SqlRpcInit function returns FAIL if pending RPCs have been initiated.

You can call the SqlRpcParam function to set the value for each stored procedure parameter that was used in the process of opening a cursor. Stored procedure parameters are no longer required to be constants, and they can be passed as follows.

To open a cursor on a stored procedure that passes program variables as parameters
  1. Call the SqlRpcInit function once to initialize a new stored procedure. Set the rpcname$ parameter to an empty string, and set the options& parameter to SQLRPCCURSOR.
  2. Call the SqlRpcParam function once per parameter to set the value of each parameter of the stored procedure.
  3. Call the SqlCursorOpen function to open the cursor, and in the stmt$ parameter, specify only the stored procedure name.
  4. Call the remaining cursor functions as you would normally. For more information, see Microsoft SQL Server Programming DB-Library for Visual Basic, Chapter 5, "Cursor Functions."


Updating Dynamic Cursors

When you call the SqlCursorOpen function with a scrollopt& parameter of CURDYNAMIC, the tables you specify in the SELECT statement of the stmt$ parameter no longer require unique indexes.

In SQL Server version 6.0, the cursor automatically opens with a scrollopt& parameter of CURINSENSITIVE and a concuropt& parameter of CURREADONLY if the SELECT statement contains a table without a unique index.

In SQL Server 6.5, the cursor automatically opens with a scrollopt& parameter of CURINSENSITIVE and a concuropt& parameter of CURREADONLY if the SELECT statement contains any of the following:

  • ORDER BY and a table with no unique index
  • UNION
  • DISTINCT
  • GROUP BY
  • HAVING
  • Aggregate function

SQL Server will copy the results into temporary work tables. Because all fetch operations are performed on the temporary tables, you cannot make changes to the cursor by using SqlCursor.


Using SqlDateCrack

The SqlDateCrack function accepts a zero value for the sqlconn& parameter. In SQL Server 6.0, the SqlDateCrack function can only be called if a SQL Server connection is active.


Using SqlStrCpy

Visual Basic 4.0 users should preallocate buffer$ to the maximum size permitted.


Default Values for LOGINREC

If you do not call SqlSetLApp, the application$ parameter of the login record is set to the calling application name by default instead of to empty, as it is in SQL Server 6.0.

If you do not call SqlSetLHost, the workstation$ parameter of the login record is set to the host workstation name by default instead of to empty, as it is in SQL Server 6.0.


Error Messages

SQL Server 6.5 adds the following error messages to DB-Library for Visual Basic.

Number | Constant | Error message
10106 | SQLEBCPS | The row length exceeds SQL Server's maximum allowable size.
10107 | SQLEDTC | Microsoft Distributed Transaction Coordinator call failed.
10108 | SQLENOTIMPL | This function is not supported on this platform at this time.
10109 | SQLENONFLOAT | Float conversion attempt failed. The source is invalid.
10110 | SQLECONNFB | Unable to connect: DB Server is unavailable or does not exist -- will attempt a fallback connection.


OLE Custom Control

This section describes the new DB-Library for Visual Basic OLE custom control.

It discusses files as well as creating a new project and porting an old project.


DB-Library for Visual Basic Files

The following files are included with DB-Library for Visual Basic:

File | Description
VBSQL.OCX | DB-Library for Visual Basic OLE custom control
VBSQL.BAS | DB-Library for Visual Basic header file
MFC40.DLL | Current version of Microsoft Foundation Class (MFC).

The following files are required, but are not included with DB-Library for Visual Basic:

File | Description
NTWDBLIB.DLL | DB-Library for Win32® (Windows 95 and Windows NT)
DBNMPNTW.DLL (for example) | Net-Library for Win32
MFCANS32.DLL | MFC ANSI to Unicode Translation Layer
MSVCRT40.DLL | Microsoft® Visual C++® Run Time


Creating a New DB-Library for Visual Basic Project

To create a new 32-bit Visual Basic 4.0 project that uses the DB-Library for Visual Basic OLE custom control, follow these steps, which are fully outlined in the following text:

  1. Create a new Visual Basic project.
  2. Add the DB-Library for Visual Basic OLE custom control to your Toolbox.
  3. Add the DB-Library for Visual Basic header file to your project.
  4. Add the DB-Library for Visual Basic OLE custom control to a form in your project.
  5. Add code to the error handling and message handling event procedures.
To add the DB-Library for Visual Basic OLE custom control (VBSQL.OCX) to your Toolbox
  1. From the Tools menu, choose Custom Controls.

    The Custom Controls dialog box appears.

  2. Choose the Browse button.

    The Add Custom Control dialog box appears.

  3. Select the VBSQL.OCX file. By default, it is located in the C:\MSSQL\DLL directory.
  4. Choose the Open button.

    The Available Controls list now includes "Vbsql OLE Custom Control module," and it is selected.

  5. Choose the OK button.

    The DB-Library for Visual Basic OLE custom control is now included in the Toolbox. Its tooltip is "Vbsql."

To add the DB-Library for Visual Basic header file (VBSQL.BAS) to your project
  1. From the File menu, choose Add File.

    The Add File dialog box appears.

  2. Select the VBSQL.BAS file. By default, it is located in the C:\MSSQL\DBLIB\INCLUDE directory.
  3. Choose the OK button.

    The Project window now includes the VBSQL.BAS module. Visual Basic will automatically generate a unique name for this module. For a new project, the default name for this module will be "Module1."

It is recommended that you not change the VBSQL.BAS header file. If you use the Visual Basic Code window to edit the VBSQL.BAS header file, Visual Basic will add a line to the top of the file similar to the following:

Attribute VB_Name = "Module1"

The Visual Basic Code window does not display this line. After this line has been added, Visual Basic will use the specified module name, and will not automatically generate a unique name. If your project already includes a module with the same name as the modified VBSQL.BAS header file, attempting to add it will generate the following error:

Name conflicts with existing module, project, or object library

If you must change the VBSQL.BAS header file, use either Notepad (or other text editor that will not add the VB_Name line to the file), or make a copy of the VBSQL.BAS header file and include that copy in your project.

To add the DB-Library for Visual Basic OLE custom control to a form in your project
  1. From the Toolbox, select the DB-Library for Visual Basic OLE custom control.
  2. Move the pointer onto a form.

    The pointer becomes a cross hair.

  3. Drag the cross hair pointer to place the control on the form.

    The control will be called "Vbsql1" by default.

  4. You can set the Visible property of the control to False.

Add one and only one control to a single form in your project, and always keep that form loaded. Do not add the DB-Library for Visual Basic OLE custom control to more than one form, and do not unload the form that contains the control.

The DB-Library for Visual Basic OLE custom control has two custom event procedures:

Event | Occurs
Error | When a DB-Library error occurs
Message | When a SQL Server message is received

To edit the code in the error handling and message handling event procedures
  1. Double-click the DB-Library for Visual Basic OLE custom control.

    The Visual Basic Code window appears.

  2. From the Proc box, select Error to bring up the DB-Library error handler event procedure.
  3. From the Proc box, select Message to bring up the SQL Server message handler event procedure.

The Error event procedure has the following syntax:

Private Sub Vbsql1_Error (
ByVal SqlConn As Long,
ByVal Severity As Long,
ByVal ErrorNum As Long,
ByVal ErrorStr As String,
ByVal OSErrorNum As Long,
ByVal OSErrorStr As String,
RetCode As Long )

The OSErrorNum and OSErrorStr parameters are new with the DB-Library for Visual Basic OLE custom control, and they match the parameters that are available with DB-Library for C.

The Message event procedure has the following syntax:

Private Sub Vbsql1_Message (
ByVal SqlConn As Long,
ByVal Message As Long,
ByVal State As Long,
ByVal Severity As Long,
ByVal MsgStr As String,
ByVal ServerNameStr As String,
ByVal ProcNameStr As String,
ByVal Line As Long )

The ServerNameStr, ProcNameStr, and Line parameters are new with the DB-Library for Visual Basic OLE custom control, and they match the parameters that are available with DB-Library for C.

Note that Visual Basic will create a VBSQL.OCA file, usually in the same directory as VBSQL.OCX. Visual Basic stores cached-type library information (and other data that is specific to the custom control) in the VBSQL.OCA file and re-creates it as needed.

For more information about managing Visual Basic projects, see the Microsoft Visual Basic 4.0 Programmer's Guide.


Porting an Old DB-Library for Visual Basic Project

To port a Visual Basic 3.0 project that uses the old 16-bit DB-Library for Visual Basic VBSQL.VBX to a Visual Basic 4.0 project that uses the new 32-bit DB-Library for Visual Basic OLE custom control VBSQL.OCX, follow these steps:

  1. Open the 16-bit project using Visual Basic 4.0.
  2. You will receive messages similar to the following:
    Can't load (or register) custom control: 'C:\SQL60\BIN\VBSQL.VBX' --
Continue loading project?

Custom control 'VBX.VBSQL' not found

Error loading 'C:\CODE\MAIN.FRM'. A control could not be loaded due
to load error. Continue?

    In each case, choose the Yes or OK button.

  3. If you added the old DB-Library for Visual Basic header file (VBSQL.BAS or VBSQL.BI) directly to your Visual Basic 3.0 project, you might receive a message similar to the following:
    File not found: 'C:\SQL60\DBLIB\INCLUDE\VBSQL.BAS' -- Continue
loading project?

    This message indicates that Visual Basic could not find a VBSQL.BAS header file in the specified location. Add the new VBSQL.BAS header file to your project.

    If you do not receive this message, Visual Basic found a VBSQL.BAS header file at the location specified in your old project. Ensure that it is the new VBSQL.BAS header file. If it is the old VBSQL.BAS header file, remove the old one, and then add the new VBSQL.BAS header file to your project.

  4. If you pasted the contents of the old VBSQL.BAS header file into a separate .BAS file of your Visual Basic 3.0 project, remove the old header file contents from the separate .BAS file, and then add the new VBSQL.BAS header file to your project.
  5. The old VBSQL.VBX custom control will still be placed on a form in your project, probably as a red PictureBox control. Remove the old control from the form.

    Visual Basic will place your old error handling and message handling event procedures in the list of general procedures for the form. These event procedures will be named control_Error and control_Message, where control is the name of the old VBSQL.VBX custom control, for example "VBSQL1."

  6. Add the new DB-Library for Visual Basic OLE custom control (VBSQL.OCX) to a form in your project.
  7. Copy the code from the old error handling and message handling procedures (now listed as general procedures) to the Error and Message event procedures of the new DB-Library for Visual Basic OLE custom control.

    Both the Error and Message event procedures have new parameters, but the existing parameters have the same names, so the old code should work unchanged.

  8. Change all Integer values (%) used by DB-Library for Visual Basic to Long (&) values. This includes DB-Library function names (if % was used), parameters passed to DB-Library functions, and values returned by DB-Library functions.

    In all of the following examples, bold text indicates the code changes you must make. For brevity, checking of return codes is not included.

    For example, if your old Visual Basic project includes the following DB-Library code:

    Dim LoginRec As Integer
Dim SqlConn As Integer
Dim Return As Integer
Dim SqlCommand As String

LoginRec = SqlLogin
' Fill in LoginRec
SqlConn = SqlOpen(LoginRec, "gizmo")
Return = SqlUse(SqlConn, "pubs")
SqlCommand = "select au_fname from authors"
Return = SqlCmd(SqlConn, SqlCommand)
Return = SqlExec(SqlConn)

    then the new code needs only the following changes:

    Dim LoginRec As Long
Dim SqlConn As Long
Dim Return As Long
Dim SqlCommand As String

LoginRec = SqlLogin
' Fill in LoginRec
SqlConn = SqlOpen(LoginRec, "gizmo")
Return = SqlUse(SqlConn, "pubs")
SqlCommand = "select au_fname from authors"
Return = SqlCmd(SqlConn, SqlCommand)
Return = SqlExec(SqlConn)

    However, if your old Visual Basic project includes the following DB-Library code using the Integer datatype specifier (%):

    LoginRec% = SqlLogin%
' Fill in LoginRec
SqlConn% = SqlOpen%(LoginRec%, "gizmo")
Return% = SqlUse%(SqlConn%, "pubs")
SqlCommand$ = "select au_fname from authors"
Return% = SqlCmd%(SqlConn%, SqlCommand$)
Return% = SqlExec%(SqlConn%)

    then the new code can be changed to the following, using the Long datatype specifier (&) for DB-Library functions, parameters, and return values:

    LoginRec& = SqlLogin&
' Fill in LoginRec
SqlConn& = SqlOpen&(LoginRec&, "gizmo")
Return& = SqlUse&(SqlConn&, "pubs")
SqlCommand$ = "select au_fname from authors"
Return& = SqlCmd&(SqlConn&, SqlCommand$)
Return& = SqlExec&(SqlConn&)

    Because the datatype specifiers are not required for DB-Library function names, you can change the new code to the following:

    LoginRec& = SqlLogin
' Fill in LoginRec
SqlConn& = SqlOpen(LoginRec&, "gizmo")
Return& = SqlUse(SqlConn&, "pubs")
SqlCommand$ = "select au_fname from authors"
Return& = SqlCmd(SqlConn&, SqlCommand$)
Return& = SqlExec(SqlConn&)

    You can also take this opportunity to change your code to use Dim to explicitly declare your variables, thus removing the Long specifier (&) from each variable.

    If you forget to make a required change from Integer to Long, Visual Basic will generate the following error when you run the program:

    Type-declaration character does not match declared data type

    and the Visual Basic debugger will highlight the DB-Library function, parameter, or variable (for example, the SqlSetLoginTime% function or a SqlConn% variable) that is causing the error.


Programming DB-Library for Visual Basic Errata

The following changes should be made to Microsoft SQL Server Programming DB-Library for Visual Basic for Microsoft SQL Server 6.0.

  • On page 119, the Remarks text about the SqlWinExit function should be changed. The last sentence in the first Remarks paragraph currently reads:

    "Put the call to SqlWinExit before you call the End function to close an application."

    This sentence should read:

    "Put the call to SqlWinExit before you use the Unload statement to close the main form, which closes the application."

    You should also remove the End function from the sample code in the Remarks section. Instead, you should use the Unload statement to close the main form, which closes the Visual Basic application.

    Note that a number of sample code examples in Programming DB-Library for Visual Basic use the End function; they should use the Unload statement to close the main form instead.

  • On page 136, the text describing the SqlCursorFetchEx nfetchrows% parameter should be changed. Remove the following two sentences:

    "The poutlen and pvaradddr arrays specified in calls to dbcursorbind must have at least nfetchrows% elements. If these arrays are not large enough, you must break the existing bindings and then rebind with large enough arrays (at least nfetchrows% elements) before calling SqlCursorFetchEx%."

  • On page 177, the Remarks text about the SqlWriteText function should be changed. The first sentence in the third paragraph currently reads:

    "SqlWriteText% can be invoked with or without logging in, according to the value of the log% parameter."

    This sentence should read:

    "SqlWriteText can be invoked with or without logging, according to the value of the log% parameter."

  • On page 211, the text describing the SqlBCPColumnFormat ftlen& parameter should be changed. The second sentence currently reads:

    "To avoid using a terminator, set this value to -1."

    This sentence should read:

    "To avoid using a terminator, set this value to 0."

  • On page 222, in Appendix A, "DB-Library for Visual Basic Options," under SQLBUFFER, the last sentence in the first paragraph currently reads:

    "The default setting is 0 (no row buffering)."

    This sentence should be deleted.

    The following table reflects this change and replaces the table that is currently on page 222.

Parameter | Description
Less than 1 | Buffer set to 100 rows.
1 | Not allowed.
2-32,767 | The number of rows to buffer.


Part 9 What's New for Open Data Services

What's New for Open Data Services

SQL Server 6.5 includes one new and one enhanced function for Open Data Services. The following table lists the new and enhanced features, which are explained in this part. Features are in alphabetical order.

Note that the ODS Help file contains version 6.0 information. Read this section for the most up-to-date version 6.5 information.

Feature | New | Enhanced | Page
Functions |  |  |
srv_config |  | · |
srv_getbindtoken | · |  |
Loopback connections with extended stored procedures |  | · |
ODS applications |  | · |

Feature | New | Enhanced
Functions |  |
srv_config |  | ·
srv_getbindtoken | · |
Loopback connections with extended stored procedures |  | ·
ODS applications |  | ·


srv_getbindtoken

Obtains a bind token so that an extended stored procedure session can share a common transaction lock space with the client session that invoked the extended stored procedure instead of opening a separate session.

Syntax

int srv_getbindtoken (
SRV_PROC* srvproc,
char* bindtoken );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection. The srvproc parameter contains the information that the Open Data Services Library uses to manage communication and data between the application and the client.
bindtoken
Is a pointer to a buffer where the bind token will be copied. The bind token is represented as a null-terminated string. The buffer you specify should be 255 bytes in length.

Returns

SUCCEED or FAIL.

Remarks

To bind an extended stored procedure session to the client session that called the extended stored procedure so that they share the same transaction lock space
  1. The extended stored procedure calls srv_getbindtoken. This uses the existing bind token of the calling session if the calling session is already bound to a bind token. If the calling session is not already bound, srv_getbindtoken creates a new bind token and binds the calling session to the token. srv_getbindtoken then returns the bind token in the bindtoken parameter.
  2. The extended stored procedure uses the bind token with sp_bindsession to bind an extended stored procedure session to the client session. Multiple extended stored procedure sessions can be bound to a client session.
  3. A bound session is unbound when the external stored procedure returns, or when sp_bindsession is called with an empty string.

Note Only one bound session can have access to a shared connection at a time. If one session is currently executing a statement in the server or has results pending from the server, no other sessions sharing the same bound connection can gain access to the server until the current session has finished executing the current statement. If a session attempts to gain access to the connection while the server is busy, an error will be returned to the conflicting session indicating that the connection is in use and that the session should retry later.

See Also

sp_bindsession, sp_getbindtoken


srv_config

SRV_THREADAFFINITY
Is an option parameter that associates threads with available processors. Using this parameter can result in better processor cache use and performance by reducing context switching and thread migration between processors. The default is 0.

The SRV_THREADAFFINITY parameter specifies a value in an affinity mask that is a bit vector in which each bit represents processors that a thread can run on. As threads are created, they are associated with one of the processors in the affinity mask. Administrators can control processor usage by masking various processors ON or OFF for use by ODS.

Initialize SRV_THREADAFFINITY by setting the corresponding bit of the processor(s) to ON. The SRV_THREADAFFINITY processor bit value is a binary value. For example, to use processors 1 through 4, set processor bits 1 through 4 ON by using the following setting:

SRV_THREADAFFINITY = 15

To use processors 1 through 6, set processor bits 1 through 6 ON by using the following setting:

SRV_THREADAFFINITY = 63


Application Requirements

Existing ODS applications must be recompiled with Open Data Services 6.5. This is required because of changes to ODS data structures.

To avoid conflicts with RETCODE definitions in other header files (for example, ODBC), any applications that currently use RETCODE (defined in SRVDBTYP.H) should use the new SRVRETCODE instead. The sample programs now use SRVRETCODE.


Loopback Connections with Extended Stored Procedures

Extended stored procedures that make loopback connections into the same SQL Server are now supported. Call the srv_getbindtoken function to enable the loopback connection to share transaction lock space with the original client connection. Sample code in the Programmer's Toolkit demonstrates how to build an extended stored procedure that connects back into SQL Server.

See Also

srv_getbindtoken


Programming Open Data Services Errata

The following changes should be made to Microsoft SQL Server Programming Open Data Services for Microsoft SQL Server 6.0.

  • On page 42, the example comments should be changed. The comment on the fourth line reads:

    "//Number of results sets sent"

    This comment should read:

    "//If results sets have been sent"

  • On page 71, SRV_EXIT should be removed from the list of valid values for the event parameter that srv_handle can install a handler for, because the SRV_EXIT event causes an immediate shutdown of the application.
  • On page 175, the filename of the ODBC client driver for Open Data Services gateways in the text of the second bullet should be changed from ODSGAT32.DLL to ODSGT32.DLL.


Before You Begin

Microsoft® SQL Server™ 6.0 extends the performance, reliability, and scalability of earlier releases of Microsoft SQL Server to meet the needs of customers who are deploying large-scale distributed information systems. SQL Server 6.0 provides powerful tools for enterprise-wide administration, data replication, parallel DBMS performance, and scalability to very large databases. SQL Server 6.0 also provides tight integration with OLE object technology.

SQL Server 6.0 continues to adhere to industry standards, with improved ANSI SQL support and language enhancements that include declarative referential integrity (DRI), and powerful server-based cursor support which far exceeds the ANSI standard.

Note This book contains background information about Microsoft SQL Server and provides some information specific to SQL Server 6.0. For information about changes and enhancements specific to SQL Server 6.5, see the supplementary "What's New in SQL Server 6.5."


About SQL Server Setup

Before installing Microsoft SQL Server 6.0, please review the following information.

Document Conventions

Finding Further Information

Obtaining Technical Support

Microsoft SQL Server Setup provides instructions for installing the Microsoft SQL Server 6.0 and Microsoft® SQL Workstation 6.0 software. It explains installation options (such as character sets, sort orders, and network support) and how to upgrade from earlier versions of Microsoft SQL Server.

Note that this book does not provide configuration information. For details about how to configure an installed server or client, see the Microsoft SQL Server Administrator's Companion.


Document Conventions

This manual uses the following conventions to distinguish elements of text:

Convention | Purpose
UPPERCASE | Represents Transact-SQL™ syntax, paths, and filenames.
small capitals | Represent key names, such as ctrl.
bold | Represents system procedures, utility programs, commands, and user-entered text.
italic | Represents database names, table names, and variables.
monospace | Represents examples, display text, and error messages.
[brackets] | Identify optional items in syntax. Type only the information within the brackets; do not type the brackets.
{braces} | Identify required items in syntax. Type only the information within the braces; do not type the braces.
| (vertical bar) | Means "or" and signifies that you can choose only one of the items within the brackets or braces.


Finding Further Information

In addition to the introductory information in this book, additional information about setup and details about using SQL Server 6.0 is available from the following sources, as well as from the Microsoft® Development Library and Microsoft® TechNet.

The Microsoft Developer Network provides in-depth information for developers. With Level 1 of the Developer Network, you get four quarterly releases of the Development Library, packed with inside information on programming for Microsoft Windows and Windows NT, plus other program benefits. With Level 2 of the Developer Network, you'll receive all the Level 1 benefits plus quarterly releases of the Development Platform, containing the latest Windows and Windows NT Workstation operating systems and API-level SDKs and DDKs from Microsoft. For ordering information, call (800) 759-5474.

Microsoft TechNet is the front-line resource for fast complete answers to technical questions on Microsoft desktop and system products. Through two monthly CDs, you get everything from crucial data on client/server and workgroup computing, systems platforms, and database products to the latest applications support for Microsoft Windows and the Apple® Macintosh®. For ordering information, call your reseller or (800) 344-2121.

Setup Online Help

To access online Help while using the setup program, choose the Help button that is part of most setup dialog boxes, or press f1.

Online Help for SQL Server Utilities

To access online Help from most of the graphical tools provided with SQL Server, choose the Help button or press f1.

To access online Help from isql, you can execute the sp_helpsql system stored procedure. The sp_helpsql system stored procedure provides syntax for Transact-SQL statements and system procedures, and information about other SQL Server topics. For more information about sp_helpsql, see the Microsoft SQL Server Transact-SQL Reference.


SQL Server Books Online

The setup program gives you the option of installing Microsoft SQL Server Books Online. If you choose this option, setup adds the Books Online icon to the Microsoft SQL Server 6.0 program group. By choosing this icon, you can access online versions of the SQL Server documentation.

Important SQL Server Books Online contains the most up-to-date information about SQL Server 6.0, including information that changed or was unavailable when the SQL Server 6.0 books were printed.

Microsoft SQL Server System Administrator's Companion
Incorporates configuration, administration, and troubleshooting topics. Describes server and client configuration. Explains system administration tasks, such as managing devices and databases, backing up and recovering data, performing replication, scheduling tasks, managing security, and monitoring performance. Describes error conditions and gives troubleshooting procedures.
Microsoft SQL Server Database Developer's Companion
Provides an overview of Transact-SQL, which is an enhanced version of SQL (structured query language). Discusses managing data and database objects, such as tables, views, indexes, stored procedures, defaults, rules, constraints, and user-defined datatypes.
Microsoft SQL Server Transact-SQL Reference
Explains how to use Transact-SQL statements and other features to access databases, and provides syntax and descriptions for Transact-SQL statements, system procedures, utility programs, and system tables.
Microsoft SQL Server Setup
An online version of this book, which provides instructions for installing SQL Server 6.0 servers and clients.
Microsoft SQL Server Programming SQL Distributed Management Objects
Provides syntax and reference information for the SQL Distributed Management Objects, which are 32-bit OLE Automation objects for the Microsoft Windows® 95 and Windows NT™ operating systems. These objects, properties, methods, and collections are used to write scripts and programs that can administer multiple SQL Servers distributed across a network.
Microsoft SQL Server Programming DB-Library for C
Provides syntax and reference information for the DB-Library application programming interface (API), which is used to write C/C++ client programs for the Microsoft Windows®, Windows 95, Windows NT, and MS-DOS® operating systems.
Microsoft SQL Server Programming DB-Library for Visual Basic
Provides syntax and reference information for the DB-Library API, which is used to write Microsoft® Visual Basic® programming system-based client programs for the Windows operating system.
Microsoft SQL Server Programming Open Data Services
Provides syntax and reference information for the Microsoft Open Data Services API, which is used to write C/C++ server and gateway programs for the Windows NT operating system.


Obtaining Technical Support

Microsoft offers a variety of support options to help you get the most from Microsoft SQL Server 6.0. For information about these options, see the service and support card included in your SQL Server 6.0 package.

In addition, you can get technical support information from the Microsoft® Knowledge Base (KB), which can help you resolve problems. Information about the Knowledge Base (including how to get KB articles, how to get the KB on CD, and how to contribute to the KB) is available in the Help file KB_MSL.HLP, located in the \SQL60\INSTALL directory.


Chapter 1 Introduction

Introduction

Microsoft SQL Server 6.0 (pronounced "Sequel Server") provides a powerful client/server platform for delivering critical business applications efficiently across multiple environments. Microsoft SQL Server 6.0 builds on the power, scalability, and manageability of the Microsoft Windows NT operating system by providing the reliability and advanced capabilities of high-end, client/server database management.

This manual tells you how to install Microsoft SQL Server 6.0 server software and client software. It details the minimum hardware and software requirements for servers and clients, discusses the options and decisions you will encounter during an installation, takes you through installation, describes how to upgrade an existing installation, provides details about the character set and sort order choices you have during server installation, shows you how to start SQL Server, and tells you how to perform an unattended installation (an optional installation method that lets you install SQL Server 6.0 without having to respond to prompts for information).

For more information, choose one of the following topics:

SQL Server and SQL Workstation

How to Use this Manual

Installation Terminology


SQL Server and SQL Workstation

Microsoft SQL Server 6.0 software is available in two package configurations. Microsoft SQL Server 6.0 is a relational database management system that is capable¾depending on your application and hardware environment¾of supporting hundreds of simultaneous users.

The Microsoft SQL Server 6.0 software is distributed on a compact disc (CD) that contains the setup program and server software for all supported hardware platforms. The CD also contains the Microsoft client software and client setup programs.

Microsoft SQL Workstation 6.0 has the same features and functionality as Microsoft SQL Server, except that it is a single-user licensed product that supports a maximum of 15 simultaneous database connections and includes the Microsoft SQL Server 6.0 Programmer's Toolkit (PTK). SQL Workstation is intended to be primarily a development platform.


How to Use This Manual

This manual is written for those who will install and upgrade Microsoft SQL Server 6.0 servers and clients. It assumes a working familiarity with database software and concepts, operating systems, network software and protocols, and microcomputer hardware.

Chapter 1, "Introduction," provides a brief overview of the Microsoft SQL Server 6.0 product and this manual.

Chapter 2, Server Requirements, lists the minimum requirements (hardware, software, file system, and so on) necessary for a SQL Server installation.

Chapter 3, Server Options, explains the options presented by the setup program during a server installation. It is important that you understand these choices before you begin installing the server components.

Chapter 4, Server Installation, explains how to install Microsoft SQL Server 6.0 server software components on computers running the Windows NT operating system. It also describes how to upgrade existing server installations or remove existing server installations.

Chapter 5, Starting the Server, tells you how to start, pause, continue, and stop SQL Server. It also tells you how to start and stop SQL Executive.

Chapter 6, Client Installation, presents client preinstallation requirements and tells you how to install Microsoft SQL Server client components on computers running the Windows NT, Windows, and MS-DOS operating systems. It also describes how to upgrade existing client installations.

Chapter 7, Installation Troubleshooting, provides information that you will find helpful if you are unable to install SQL Server successfully. (If you are unable to correct your problem after following the instructions in this chapter, or if you are unable to connect to SQL Server after it is installed, see the Microsoft SQL Server Administrator's Companion, or contact your primary support provider.)

Appendix A, Character Sets and Sort Orders, details the character sets and sort orders you choose from during an installation. These determine the types of characters that SQL Server recognizes in your database data, the order in which SQL Server sorts data in response to queries, and the results that SQL Server returns for queries that involve character comparisons.

Appendix B, Unattended Installation, tells you how to perform an unattended installation, which allows you to install SQL Server 6.0 without having to respond to prompts for information from the setup program.


Installation Terminology

To help you understand the information presented in this manual, we begin by defining some terms you will encounter while installing SQL Server. This is a brief list of definitions and is not intended to serve as a comprehensive SQL Server glossary. Rather, it is provided as a quick reference to help you understand some of the terms that are discussed in this manual. You may find it useful to refer back to this list of definitions as you read through the other chapters of this manual.

application log
The Windows NT application log is a special file maintained by Windows NT. It can be viewed only by using the Windows NT Event Viewer. When SQL Server is configured to use the Windows NT application log, each SQL Server session writes new events to that log. Unlike the SQL Server error log, a new application log is not created each time you start SQL Server.
auto-start options
By default, the setup program installs SQL Server and SQL Executive to run as manually started Windows NT services. Optionally, each can be configured to run as an automatically started service. For each service, this choice is called the auto-start option.
backup domain controller
BDC. In a Windows NT domain, a BDC is a server that receives a copy of the domain's security database from the primary domain controller and shares the user login authentication load.
Books Online
An online version of the SQL Server documentation set, SQL Server Books Online is an installation option presented by the setup program. If you choose this option, the SQL Server Books Online icon is added to the Microsoft SQL Server 6.0 program group. By choosing that icon, you can display SQL Server user documentation on your computer screen.

A particular benefit of Books Online is the full text search capability, which allows you to very rapidly search a book or a set of books for all instances of a word or phrase.

character set
The selected character set determines the types of characters that SQL Server recognizes in the databases. A character set is a set of 256 letters, numbers, and symbols specific to a country or a language. The printable characters of the first 128 values are the same for all character sets. The last 128 characters, sometimes referred to as extended characters, are different.

During installation it is critical that you select the appropriate character set. If you need to change it later, you will need to rebuild your databases and reload your data.

client
A front-end application that uses the services provided by a server. The computer that hosts the application is often referred to as the client computer.

SQL Server client software enables computers to connect to a SQL Server over the network.

database
A collection of information, data tables, and other objects that are organized and presented to serve a specific purpose, such as facilitation of searching, sorting, and recombination of data. Databases are stored on devices.
device
A file that databases are stored in. One database can be stored on several devices. SQL Server uses two types of devices: database devices, which store databases, and dump devices, which store backups of a database.
domain
In Windows NT, a domain is a collection of computers that are grouped for viewing and administrative purposes and that share a common security database. The security database is maintained on the primary domain controller, with copies on backup domain controllers.
error log
The SQL Server error log records information from SQL Server. You can view the error log by using SQL Enterprise Manager or any text editor. When SQL Server is configured to use its error log, each SQL Server session creates a new log, and SQL Server retains the last six logs created.
FAT file system
A method for managing disk storage. A FAT (file allocation table) file system is used by an operating system (for example, by the MS-DOS® operating system) to keep track of the status of various segments of disk space used for file storage.
file system
The portion of an operating system that translates requests for file operations from an application program into low-level, sector-oriented tasks that can be understood by the drivers that control the disk drives.

SQL Server is usually installed on disk drives that are formatted for the NTFS or FAT file systems. It can be installed on a compressed NTFS volume, but at a performance penalty.

install
To set up the software to work with the computer.

An installation differs from an upgrade in that an installation provides a fresh version of the software that uses default (or user-set) configuration settings. Pre-existing user databases and data, security information, and configuration settings (if any) are not retained.

installation path
For SQL Server, the installation path is the drive and directory into which the SQL Server files will be copied. The default is C:\SQL60, although this can be set by the user who is installing.

After installation, this specific drive and directory are often referred to as the SQL Server root directory.

master database
The master database controls the user databases and the operation of SQL Server as a whole. It is automatically installed with SQL Server. It keeps track of such things as user accounts, remote user accounts, remote servers that this server can interact with, ongoing processes, the configurable environment variables, system error messages, the databases on SQL Server, the storage space allocated to each database, the tapes and disks available on the system, and the active locks.
MASTER device
The device that is automatically installed with SQL Server and is used to store the master, model, and tempdb system databases and transaction logs, and the pubs sample database and transaction log. The filename of the MASTER device is MASTER.DAT.
Net-Library
A library of functions for managing network connections and routing. Each Net-Library allows a computer to use a particular network protocol.
network adapter
An expansion card or other physical device used to connect a computer to a local area network.
NTFS
An advanced method for managing disk storage, designed for use specifically with the Windows NT operating system. It supports long file names (but maintains shorter file names for compatibility with computers running operating systems using the FAT file system). It also provides full security for access control, file system recovery, and extremely large storage media. It supports object oriented applications by treating all files as objects with user- and system-defined attributes.
primary domain controller
PDC. In a Windows NT domain, a PDC is a server that maintains the domain's security database and authenticates user logons. It also provides a copy of the domain's security database to backup domain controllers (BDCs), which share the user login authentication load.
pubs database
A sample database provided with Microsoft SQL Server. The pubs database can be helpful when you are learning to use SQL Server 6.0. All Microsoft SQL Server 6.0 documentation uses the pubs sample database as the basis for examples.
remote server
A SQL Server that can be accessed through a user's local server. The setup program can install, upgrade, or configure remote servers.
script
A collection of statements used to create database objects. Transact SQL scripts are saved as files, usually ending with the SQL filename extension.
server
A computer on a local-area network (LAN) that controls access to resources such as files, printers, and communication devices.

When you use SQL Server, you can use only servers that are designated SQL Server servers (that have the SQL Server server software installed).

setup
SETUP.EXE is the program that you run to install, upgrade, or reconfigure SQL Server servers or clients. Different setup programs are supplied for each server hardware platform and¾for Microsoft clients¾each operating system.
setup initialization file
A text file, using regular Windows .INI file format, that stores configuration information and allows SQL Server 6.0 to be installed without a user having to be present to respond to prompts for information from the setup program.
sort order
A sort order is a set of rules that determines how SQL Server collates and presents data in response to database queries. The sort order determines the order in which data is presented in response to SQL Server statements involving GROUP BY, ORDER BY, and DISTINCT. The sort order also determines how certain queries are resolved, such as queries involving WHERE and DISTINCT.

During installation it is critical that you select the appropriate sort order. If you later need to change it, you will need to rebuild your databases and reload your data.

SQL Enterprise Manager
A graphical application that allows for easy enterprise-wide configuration and management of SQL Server and SQL Server objects. SQL Enterprise Manager provides a powerful scheduling engine, administrator alert capability, drag-and-drop control operations across multiple servers, and a built-in replication management interface. You can also use SQL Enterprise Manager to manage logins, permissions, and users; create scripts; manage devices and databases; back up databases and transaction logs; and manage tables, views, stored procedures, triggers, indexes, rules, defaults, and user-defined datatypes.

SQL Enterprise Manager is installed by the setup program as part of the server software on Windows NT-based computers, and as part of the client software on Windows NT- and Microsoft® Windows 95™-based computers. Because SQL Enterprise Manager is a 32-bit application, it cannot be installed on computers running 16-bit operating systems.

SQL Executive
A component of SQL Enterprise Manager, SQL Executive provides powerful scheduling capabilities that enable replication and additionally allow you to schedule other SQL Server events, including backups, DBCC operations, and other administrative maintenance tasks. SQL Executive replaces SQL Monitor, which was included in earlier releases of SQL Server.
SQL Server
A relational database management system that is capable¾depending on your application and hardware environment¾of supporting hundreds of simultaneous users.
standalone installation
An installation of SQL Server on a computer that is not connected to a network.

A standalone installation may be used to install SQL Server on a computer that will soon be but is not yet connected to a network (if for example, it does not yet have a network adapter card installed.) Or a standalone installation might be performed on a computer that is intended as a development system that will have no need for network connections.

transaction log
A reserved area of the database in which a log of all changes to the database is recorded. It is stored in the syslogs system table and is used by SQL Server during automatic recovery.
unattended installation
Unattended installation allows you to install SQL Server 6.0 without having to respond to prompts for information from the setup program. Instead, you create an initialization file, save the initialization file on a storage device accessible to the computer that will be set up, and start setup using some required options. During setup the configuration parameters are read from the initialization file.
upgrade
To change to a newer, usually more powerful and sophisticated version of the software. An upgrade differs from an installation in that an upgrade leaves in place existing user databases and data, security information, and many (but not necessarily all) configuration settings.


Chapter 2 Server Requirements

Server Requirements

Before you install the server components, check that your system meets the minimum requirements detailed in this chapter.

For more information, choose one of the following topics:

Hardware Platforms

Hardware and Software Requirements

File Systems

Server Names

SMS Compatibility


Hardware Platforms

Microsoft SQL Server 6.0 can be installed on computers that are based on these microprocessor architectures:

  • Alpha AXP™ microprocessors
  • Intel® 32-bit x86-based microprocessors (such as the 80486 or the Pentium™)
  • MIPS® microprocessors

For more information about supported hardware, see the Windows NT Hardware Compatibility List provided with your Windows NT software.


Hardware and Software Requirements

To install the Microsoft SQL Server 6.0 server software on a Windows NT-based computer, you need the following hardware and software:

You need | Your choices
Computer Refer to the Windows NT Hardware Compatibility List for the processor architecture that corresponds to the SQL Server platform you are installing (Intel, Alpha AXP, or MIPS).

For example, if you are installing SQL Server for the Intel platform, you can choose any of the 32-bit Intel x86-based microprocessors, such as the 80486 or the Pentium.

Minimum memory 16 MB. Additional memory is recommended.

If the server will be configured to participate in data replication as either a distribution server or a combined publication/distribution server, it must have at least 32 MB of memory, with at least 16 MB assigned to SQL Server.
Disk drive space For a new installation, a minimum of 60 MB of available disk space for Intel-based computers, Alpha AXP-based computers, and MIPS-based computers. If you increase the size of the MASTER device from the default, additional space is required.

If you install SQL Server Books Online to run from the hard disk, another 15 MB of available disk space is required; if you install SQL Server Books Online to run from the CD, only 1 MB of additional space is needed.

For an upgrade from Microsoft SQL Server 4.2, approximately 50 MB of available hard disk space is required for all processor architectures.

Operating system Microsoft SQL Server 6.0 software must be installed on a computer running the Microsoft Windows NT Server operating system, version 3.5 or later. Version 3.51 is recommended.

Microsoft SQL Workstation 6.0 software can be installed on computers running the Windows NT Server or Windows NT Workstation operating systems, version 3.5 or later. Version 3.51 is recommended.

SQL Server 32-bit client software can be installed on computers running the Windows NT Server, Microsoft Windows NT Workstation, or Microsoft Windows 95 operating systems. For more information see Chapter 6, Client Installation.
Network software | SQL Server runs on the Windows NT platform using the built-in network software. Unless Banyan® VINES® or DEC™ PATHWORKS™ will be used, additional network software is not required. Full support for Novell® NetWare® clients is provided via NWLink.
Network adapter | Any of the network adapters supported by Windows NT. (If you're running a standalone SQL Server, you do not need a network adapter.) For information about supported network adapters, see your manuals for Windows NT.

Note Microsoft SQL Server 6.0 is not recommended for installation on a Primary Domain Controller (PDC) or a Backup Domain Controller (BDC), because those computers perform the resource-intensive tasks of maintaining and replicating the network accounts database and performing network login authentications.


File Systems

Server performance is not affected by the file system used (FAT or NTFS). Your choice of file system should be decided by factors other than performance.

  • The FAT file system allows dual booting with computers running MS-DOS.
  • The NTFS file system has security and recovery advantages. If you do not need to dual boot Windows NT with MS-DOS, NTFS is recommended.

    SQL Server can be installed on a compressed NTFS volume, but at a performance penalty.

For information about choosing the appropriate file system, see your manuals for Windows NT.


Server Names

The server name used by SQL Server is taken from the computer's name. Before installing Microsoft SQL Server on a server computer, make sure that the server's computer name is a valid SQL identifier.

The first character must be a letter or an underscore (_). Characters following the first character can include letters, numbers, or the symbols #, $, or _. No embedded spaces are allowed.

If other characters are used in the computer name, rename the computer before installing SQL Server. For instructions on renaming computers, see your documentation for Windows NT. Also, if the renamed computer is a member of a Windows NT Server domain, contact your network administrator to have the new computer name added to the domain.


SMS Compatibility

Microsoft SQL Server 6.0 is compatible with Microsoft® Systems Management Server (SMS) version 1.0A. However, it is not compatible with version 1.0. During an installation or an upgrade, if SMS version 1.0 is detected, the SQL Server setup program will display a warning message.


Chapter 3 Server Options

Server Options

This chapter explains the options presented by the setup program during a server installation. It is important that you understand these choices before you begin installing the server components. For more information choose one of the following topics:

Name, Company and Product ID

Remote Installation

Root Directory

MASTER Device Options

Character Set

Sort Order

Network Support

Auto-Start Options

SQL Server Books Online

SQL Executive User Account

Licensing Mode


Name, Company, and Product ID

During installation the setup program will prompt you to supply a name, company, and product ID.

Name
Is the name of a user who is responsible for using or administering this server. This is a required entry.
Company
Is the name of your company or other organization. This is an optional entry.
Product ID
Is an identifier provided on the software's CD box. Although this is an optional entry, it is strongly recommended that you enter the product ID, because it is used for product support purposes.


Remote Installation

You can use the SQL Server setup program to install the software on a remote computer. When you do so, you are prompted for the following information:

Remote Server Name
The computer name for the remote computer (for example, REMOTE).
SQL Installation Drive
The remote logical drive on which to install the SQL Server software. The default is C.

For example, to install SQL Server on the default share for the D drive (D$) on a remote computer, you would specify remote logical drive D for the SQL Installation Drive.

Windows NT Installation Drive
The remote logical drive on which the Windows NT root is already installed. This is where the setup program copies SQL Server client dynamic-link libraries (DLLs) and DLLs required only during installation. The default is the current setting for the SQL Installation Drive.

For example, if the Windows NT root for a remote computer is on the default share for its D drive (D$), you would specify remote logical drive D for the Windows NT Installation Drive.

Master Database Installation Drive
The remote logical drive on which to install the SQL Server master database. The default is the current setting for the SQL Installation Drive.

For example, to install the master database on the default share for the D drive (D$) on a remote computer, you would specify remote logical drive D for the Master Database Installation Drive.

Remote Logical Drive
The remote logical drive for the currently selected option (the SQL Server Installation Drive, the Windows NT Installation Drive, or the Master Database Installation Drive).

The default remote logical drive for the SQL Server Installation Drive is C. The default for the other two options is the current setting of the SQL Server Installation Drive.

On the local computer, the setup program assigns as many as three unused drive letters to correspond to the logical drives on the remote computer. This is not the same drive letter as the remote logical drive (which corresponds to the actual drive on the remote computer on which the files are to be installed). For example, if you're installing SQL Server on the D drive of a remote computer named \\REMOTE from a local computer named \\LOCAL, you would enter REMOTE as the Remote Server Name and D as the SQL Installation Drive.

On the local computer, the setup program assigns a unique logical drive letter (for example, X) for the drive on the remote computer (in this example, \\REMOTE\D$). You cannot change the logical drive letter assigned by the setup program. During the installation process, when prompting for a path, the setup program adds this unique logical drive letter to the default. In this example, when prompting for the SQL Server root directory, the setup program would use X:\SQL60 to correspond to \\REMOTE\D$\SQL60.

After you've installed the software on the remote computer, you can use SQL Enterprise Manager or SQL Service Manager to start and stop the remote SQL Server. For more information, see Chapter 5, Running SQL Server and Running SQL Executive.


Root Directory

The default SQL Server root directory is C:\SQL60, although during installation the setup program allows you to change this setting. SQL Server directory names must conform to the FAT 8.3 naming convention, even if the directory is installed on an NTFS volume. Do not use spaces in the directory name.

The following directories are created under the SQL Server root directory during installation:

Directory Contents
BIN
 MS-DOS - and Windows-based client executable files and Windows dynamic-link library (DLL) files
BINN
 Windows NT - based client and server executable files and online Help files
CHARSETS
 Character set and sort order files
DATA
 Database devices
DLL
 Dynamic-link library files
INSTALL
 Installation scripts and output files
LOG
 Error log files
REPLDATA
 Used by replication as the working directory for the distribution database
SAMPLE
 Sample files
SYMBOLS
 Files and libraries that can be used to generate stack dumps and traces on computers running Windows NT 3.51 or later.


MASTER Device Options

When you install SQL Server the setup program creates the MASTER database device, which is used to store the master, model, and tempdb system databases and transaction logs and, optionally, the pubs sample database and transaction log. During installation, the setup program prompts you to provide settings for these MASTER database device options:

Drive
The drive on which the MASTER database device will be installed. The default is C.
Directory
The path and filename for the MASTER database device. The default is \SQL60\DATA\MASTER.DAT.

The directory and filenames must conform to the FAT 8.3 naming convention, even if installed on an NTFS volume.

MASTER Device Size (MB)
The space to be allocated to the MASTER database device. The default (and minimum) size is 25 MB. If you have sufficient disk space, consider making the MASTER database device even larger. This will save you time later, as your need for additional space grows.

Note that if you later determine you need additional device space, you can use DISK RESIZE to increase the size of the MASTER database device. For information about DISK RESIZE, see the Microsoft SQL Server Transact-SQL Reference.


Character Set

A character set is a set of 256 uppercase and lowercase letters, numbers, and symbols. The printable characters of the first 128 values are the same for all character set choices. The last 128 characters, sometimes referred to as extended characters, differ from set to set. Because there are more than 256 characters used by the languages of the world, each character set has a somewhat different "repertoire" of extended characters.

The selected character set determines the types of characters that SQL Server recognizes in your database data. You should use the same character set for both the client and the server, or your results can be unpredictable. (You must also use corresponding character sets when bulk loading data.) However, if your databases use only the first 128 characters of a character set (if, for example, you don't use characters with diacritical marks), it makes no difference which character set you use because the first 128 characters are the same for all SQL Server character set choices.

Important It is critical that you select the correct character set when you first install SQL Server. If you need to change character sets after you've installed SQL Server, you must rebuild your databases and reload your data.

SQL Server offers three character sets:

ISO 8859-1 (Latin 1 or ANSI)
The default character set. It is compatible with the ANSI characters used by the Microsoft Windows and Windows NT operating systems.
Code page 850 (Multilingual)
Includes all characters for most languages of European, North American, and South American countries. Use this character set when you have MS-DOS-based client applications that use extended characters.
Code page 437 (U.S. English)
Although the most commonly used character set in the United States, includes many graphics characters not usually stored in databases. Unless you have an overriding reason to select this character set, choose code page 850, which provides more compatibility with languages other than United States English.

Note Additional character sets and sort orders are being developed for international users and may be included in those listed by the setup program.

For additional information about SQL Server character set choices, see Appendix A, Character Sets and Sort Orders.


Sort Order

A sort order is a set of rules that determines how SQL Server collates and presents data in response to database queries. The sort order determines the order in which data is presented in response to SQL Server statements involving GROUP BY, ORDER BY, and DISTINCT. It also determines how certain queries are resolved, such as those involving WHERE and DISTINCT.

Important It is critical that you select the correct sort order when you first install SQL Server. If you need to change sort orders after you've installed SQL Server, you must rebuild your databases and reload your data.

SQL Server offers several sort orders:

  • Dictionary order, case-insensitive (the default)
  • Binary order
  • Dictionary order, case-sensitive
  • Dictionary order, case-insensitive, uppercase preference
  • Dictionary order, case-insensitive, accent-insensitive
  • Strict compatibility with version 1.x case-insensitive databases
  • Alternate dictionary order, case-sensitive
  • Alternate dictionary order, case-insensitive
  • Alternate dictionary order, case-insensitive, uppercase preference
  • Alternate dictionary order, case-insensitive, accent-insensitive
  • Scandinavian dictionary order, case-sensitive
  • Scandinavian dictionary order, case-insensitive, uppercase preference

The version 1.x-compatible sort order applies only to code page 850.

The following table shows how the sort order affects comparisons and sorting:

Sort order | Comparison examples | Sorting example
Dictionary order,
case-insensitive 		A = a, Ä = ä, Å = å,
a ¹ à ¹ á ¹ â ¹ ä ¹ å,
A ¹ Ä ¹ Å 		A, a, à, á, â, ä, Ä, Å, å
(See Note 2)
Binary | See Note 1 | See Note 1
Dictionary order,
case-sensitive 		A ¹ a, Ä ¹ ä, Å ¹ å,
a ¹ à ¹ á ¹ â ¹ ä ¹ å,
A ¹ Ä ¹ Å 		A, a, à, á, â, Ä, ä, Å, å
Dictionary order
case-insensitive, uppercase preference 		A = a, Ä = ä, Å = å,
a ¹ à ¹ á ¹ â ¹ ä ¹ å,
A ¹ Ä ¹ Å 		A, a, à, á, â, Ä, ä, Å, å
Dictionary order
case-insensitive,
accent-insensitive 		A = a = à = á = â = Ä =
ä = Å = å 		A, a, à, á, â, Ä, ä, Å, å
Strict compatibility
with version 1.x case-
insensitive databases 		See Note 3 See Note 3
Custom | See Note 4 | See Note 4
1 Comparisons and sorting for this sort order are based on the numeric values of the characters
in the installed character set.

2 This is just one example of how the characters might be sorted. Because this sort order does
not have uppercase preference, it is faster than the corresponding sort order with uppercase
preference, but you cannot predict whether an uppercase character will come before or after its
corresponding lowercase character.

3 For the first 128 characters, comparisons and sorting for this sort order are the same as the
case-insensitive dictionary sort order. For the last 128 characters, comparisons and sorting are
the same as the Binary sort order.

4 Comparisons and sorting for a custom sort order depend on the sort order.

The four alternate sort orders and the two Scandinavian sort orders provide results similar to their counterparts. For details about how these sort orders differ from their counterparts, see Appendix A, Character Sets and Sort Orders.

When upgrading a version 4.2x SQL Server, setup installs the new program files but does not change the installed sort order.

For additional information about SQL Server sort order choices, see Appendix A, Character Sets and Sort Orders.


Network Support

Microsoft SQL Server uses network libraries, known as Net-Libraries, to pass network packets back and forth between clients and a SQL Server. The Net-Libraries, implemented as dynamic-link libraries (DLLs), perform the network operations required to communicate using specific interprocess communication (IPC) mechanism protocols.

SQL Server includes a set of server Net-Libraries that enable simultaneous connections from clients running named pipes or other interprocess communication (IPC) mechanisms. Named pipes are installed by default (and it is recommended that named pipes not be removed, even if other Net-Libraries are chosen). During installation, the setup program gives you the option of setting up one or more of these other Net-Libraries on the server:

Multi-Protocol
The Multi-Protocol Net-Library takes advantage of the powerful remote procedure call (RPC) facility of Windows NT. Unlike other Net-Libraries, Multi-Protocol Net-Library need only be selected as an option from the Select Network Protocols dialog box; it does not require the entry of any configuration parameters. Multi-Protocol Net-Library:
  • Communicates over most IPC mechanisms supported by Windows NT. (Note that for SQL Server 6.0, only TCP/IP Windows Sockets, NWLink IPX/SPX, and Named Pipes are considered tested and supported.)
  • Allows the use of integrated security over all protocols that RPC supports (including Windows-based Novell clients using SPX or IPXODI).
  • Supports encryption for both user password authentication and data.
  • Offers performance comparable to native IPC Net-Libraries for most applications.
NWLink IPX/SPX
This Net-Library allows SQL Server to communicate using the NWLink IPX/SPX protocol.

If you set up SQL Server to listen on NWLink IPX/SPX, the setup program prompts you for the Novell Bindery service name in which to register SQL Server on the Novell network. The default service name is the computer name of the server computer. The Net-Library allows Novell SPX clients to connect.

TCP/IP Sockets
This Net-Library allows SQL Server to communicate using standard Windows Sockets as the IPC method across the TCP/IP protocol.

If you set up SQL Server to listen on TCP/IP, the setup program prompts you for the TCP/IP port number SQL Server will listen on when accepting connections from TCP/IP sockets clients. The default is 1433, the official Internet Assigned Number Authority (IANA) socket number for Microsoft SQL Server.

Banyan VINES
SQL Server supports Banyan VINES Sequenced Packet Protocol (SPP) as the IPC method across Banyan VINES IP network protocol. Banyan VINES support for Windows NT-based clients and servers is available only for SQL Server on the Intel platform; it is not currently available on the MIPS or Alpha AXP platforms.

If you set up SQL Server to listen on Banyan VINES, the setup program prompts you for a StreetTalk™ PC-based service name. This has the form servicename@group@org, where servicename is the StreetTalk PC-based service name used by SQL Server, group is the group, and org is the organization. The PC-based service name used by SQL Server must first be created using the MSERVICE program included with your VINES software. Also, to start SQL Server you must be logged in with administrative privileges.

Note that before you can configure SQL Server to listen on Banyan VINES, you must install the Banyan VINES software (available from Banyan).

AppleTalk ADSP
For Intel-, MIPS-, and Alpha AXP-based computers, server-side AppleTalk® (ADSP) Net-Libraries are provided for use with Microsoft SQL Server. The server-side AppleTalk Net-Library allows Apple® Macintosh®-based clients to connect to SQL Server via native AppleTalk (as opposed to TCP/IP).

If you set up SQL Server to listen on AppleTalk, the setup program prompts you for the AppleTalk service object name. The AppleTalk service object name is assigned by your system administrator, who might want to use the machine name of the server for consistency. For example:

ACCOUNTING1

Note that it is not necessary to enter the AppleTalk zone, because the local zone will be used when registering the service.

DECnet
For Intel-, MIPS-, and Alpha AXP-based computers, server-side DECnet™ sockets Net-Libraries provide connectivity with PATHWORKS networks by allowing clients running on VMS™ to connect to Microsoft SQL Server via DECnet sockets.

If you set up SQL Server to listen on DECnet sockets, the setup program prompts you for the DECnet object ID that SQL Server will listen on when accepting connections from clients under this Net-Library.

The value of the DECnet object ID is set by your System Administrator; it should not conflict with other services on the system listening on DECnet sockets. The object ID can be either numeric or alphanumeric. To specify a numeric ID, preface it with a pound (#) sign. For example:

#150

To specify an alphanumeric value, type the ID of your choice. For example:

SQL1

For detailed information about object IDs, see your VMS documentation.

A server can listen on multiple Net-Libraries at one time. In addition to listening on the other server Net-Libraries you select, by default SQL Server always listens on named pipes as well.

By default, SQL Server listens on the standard pipe, \\.\pipe\sql\query, for named pipe connections. You can change the pipe name. You can also drop named pipe support and set SQL Server to listen only on other Net-Libraries.

You cannot change Net-Library configurations during an upgrade. The existing Net-Library configurations are carried over and can be modified after upgrade using SQL Setup from the Microsoft SQL Server 6.0 program group.


Auto-Start Options

By default, the setup program installs SQL Server and SQL Executive to run as manually started Windows NT services. However, during installation setup gives you the option to install each as an automatically started service.


SQL Server Books Online

During installation the setup program gives you the option of installing the SQL Server Books Online. This option adds the SQL Server Books Online icon to the Microsoft SQL Server 6.0 program group. By choosing this icon, you can view SQL Server documentation online.

You can install SQL Server Books Online to run from disk or the CD. You can also choose not to install SQL Server Books Online.

Installing SQL Server Books Online to run from the CD requires only about 1 MB of available disk space. Installing SQL Server Books Online to run from the disk requires about 15 MB of available disk space and provides faster performance.


SQL Executive User Account

Usually, SQL Server and SQL Executive are started and run as Windows NT services. This integration with the Windows NT Service Control Manager allows SQL Server and SQL Executive to be started and stopped as services, either locally or remotely.

Windows NT services run in the security context of a user account that they are assigned. By default, the system assigns the computer's LocalSystem account to services. However, services can have a specifically created Windows NT user account assigned to them.

Before you install SQL Server, you should create a Windows NT user account that can be assigned to the SQL Executive service. This account will enable the service to accomplish connectivity-related tasks, such as performing replication or running scheduled tasks that involve other servers.

During SQL Server installation, the setup program prompts you for the domain, username, and password of a Windows NT user account, which it then assigns to SQL Executive as its user account. (By default, the setup program always assigns SQL Server the LocalSystem account; you can change the account after installation by using the Services application in the Control Panel.) For more information, see Chapter 4, Server Installation.


Licensing Mode

Microsoft SQL Server 6.0 (a Microsoft Back Office server product) requires a Server License, plus a Client Access License for each client computer that accesses the server. You must acquire these licenses prior to using the product. A Server License is provided with the server software. Client Access Licenses are purchased separately.

Client Access Licenses can be used in one of two licensing modes. This choice of modes offers you the flexibility to choose the option that best meets your requirements:

  • Per Seat. Each computer or workstation that will be accessing or otherwise using any SQL Server¾using either Microsoft-provided client software or third-party software¾requires a Client Access License.
  • Per Server. You specify a maximum number of simultaneous user connections for the server. An equal number of Client Access Licenses are required for that server.

During installation of a server, you are asked to choose between these two licensing modes. Before the setup program can proceed, you must make your selection and then accept the terms of the license agreement.

If you are unsure which licensing mode to choose, select the Per Server option. After installation of a server, you are permitted to convert from Per Server mode to Per Seat mode at no additional cost. This is a one-time, one-way conversion option. It is not necessary to notify Microsoft if you elect to make this change. To change licensing mode to Per Seat after installation, use the Licensing application in the Control Panel. For more information, see the online Help for the Licensing application.

You are not legally permitted to change the licensing mode from Per Seat to Per Server.

To review the licensing agreement, see the Client License Access Agreement or the online Help for the Licensing application in the Control Panel.

For more information choose one of the following topics:

Per Seat Mode

Per Server Mode

Node-based Client Access

Increasing Client Access Licenses After Server Installation


Per Seat Mode

Under the Per Seat licensing mode, each client computer requires a Client Access License to connect to any Microsoft SQL Server 6.0 computer for data access purposes. Once a client computer is licensed, it may be used to access any Microsoft SQL Server computer at no additional charge.

If you select the Per Seat licensing mode, any number of licensed computers can be used to connect at the same time to any Microsoft SQL Server. You must purchase a separate Client Access License for each computer, even if you use client data access software from Microsoft, from a third-party vendor, or from any other client software supported by Windows NT Server.

The Per Seat option is often the most economical one for networks in which clients tend to connect to more than one server.

To review the Per Seat licensing agreement, see the Client License Access Agreement or the online Help for the Licensing application in the Control Panel.


Per Server Mode

With Per Server licensing, each Client Access License is assigned to a particular database server and allows one client to connect to that server for data access. You must have at least as many Client Access Licenses dedicated to that server as the maximum number of client computers that are connected to that server at one time.

If you select the Per Server option, during server installation you specify the number of Client Access Licenses (corresponding to the maximum number of concurrent client connections) that you have purchased for that server.

Note When a server reaches the maximum number of concurrent connections, Microsoft SQL Server 6.0 displays an error message and will not allow another computer to connect until at least one currently connected client disconnects.

This mode of licensing is available for Microsoft SQL Server 4.21a or later. The Per Server option is often the most economical one for networks in which clients tend to connect to only one occasional-use or special-purpose server.

To review the Per Server licensing agreement, see the Client License Access Agreement or the online Help for the Licensing application in the Control Panel.


Node-based Client Access

Node-based client access permits all data access connections originating from a single client (one unique workstation and/or computer) to be counted against a single Client Access License. Both client licensing modes provide support for node-based client access.

Beginning with version 6.0, Microsoft SQL Server client access software supports this model. This capability is available for both ODBC and DB-Library and allows Microsoft SQL Server 6.0 to automatically detect multiple data access connections originating from the same networked client. When this occurs, those connections are then counted against a single Client Access License. Application coding changes are not required to take advantage of this new node-based client access capability.

When counting Client Access Licenses, SQL Server takes advantage of this new data access client capability whenever possible. However, there are two client configurations in which clients will be counted on a per individual connection basis:

  • Previous versions of client access software

    Because these clients do not support node-based data access, SQL Server cannot detect multiple connections originating from the same node. Each connection counts as one client.

  • Non-Microsoft client access software

    Data access software from other vendors may not support node-based data access. If it does not, each connection counts as one client.


Increasing Client Access Licenses After Server Installation

Client Access Licenses may be added at any time.

If a SQL Server is licensed using the Per Server mode, after you purchase the additional licenses they must be applied to that server. Use the Licensing application in the Control Panel of the server to increase the number of users to equal the total number of Client Access Licenses purchased for that server.

For more information, see the online Help for the Licensing application in the Control Panel.


Chapter 4 Server Installation

Server Installation

This chapter explains how to install Microsoft SQL Server 6.0 server software components on computers running the Windows NT operating system. It also describes how to upgrade existing server installations.

For more information, choose one of the following topics:

Creating a User Account for SQL Executive

Installing SQL Server

Upgrading SQL Server

Installing or Upgrading SQL Workstation

Testing an Installation

Configuring SQL Server

Removing SQL Server

For information on configuring an installed server, see the Microsoft SQL Server Administrator's Companion.


Creating a User Account for SQL Executive

During SQL Server installation, the setup program asks you to provide the domain, username, and password of a Windows NT user account, which it then assigns to SQL Executive. (As an option, you can select the server's LocalSystem account, but using the LocalSystem account prevents the use of several features, such as replication and running scheduled tasks involving other servers.)

Before installing SQL Server, use the User Manager application (included as part of Windows NT Server) to create a user account that you will assign to SQL Executive. This account will usually be a domain user account (although it can also be a user account on the local server). This account should be reserved for use by SQL Executive (users should not use it to log on).

The SQL Executive user account must belong to the Administrators local group on the SQL Server computer. In addition, it is a good idea to select the Password Never Expires option, be granted the Log On As A Service right on the SQL Server computer, and have all logon hours allowed (although this is only necessary for domain accounts, since this option does not apply to accounts on the local server).

Several SQL Servers can share the same user account. In fact, when setting up replication it is a good idea for a publication server and all its subscription servers to share the same account.

During SQL Server installation, if you do not know (or have not yet created) this Windows NT user account, you can complete the installation without specifying a user account. In this case, the setup program will install SQL Executive using the computer's LocalSystem account. Later, you can use the Services application in the Control Panel (or the Services command in Server Manager) to assign an appropriate user account to SQL Executive. Note, however, that if SQL Executive is assigned the LocalSystem account, it runs in the security context of that account and can be prevented from accomplishing many connectivity-related tasks.

When upgrading from SQL Server version 4.2x to SQL Server 6.0, you will be prompted for user account information in the same manner as for a new SQL Server 6.0 installation.

For information about creating Windows NT user accounts, granting advanced user rights, setting password expiration, and managing group memberships, see your manuals for Windows NT or the User Manager online Help.

Note After you have assigned a domain user account to SQL Executive, if you start SQL Executive and the server cannot for any reason access a domain controller, the logon attempt will fail and SQL Executive will not start. You can start it by running the Services application from the Control Panel (or by using the Services command from Server Manager) and assigning the LocalSystem account to SQL Executive. However, remember that if SQL Executive is assigned the LocalSystem account, it runs in the security context of that account and can be prevented from accomplishing many connectivity-related tasks.

It is important that the password for the Windows NT user account not be changed or allowed to expire. If SQL Executive will not run after having been assigned a Windows NT user account, the password may have been changed or there may not be a domain controller available to validate the logon. If the password has changed, use User Manager to set a new password for that account. Use the Services application in the Control Panel to reenter the new password for the SQL Executive service.


Installing SQL Server

After you've reviewed the information in Chapter 3, "Server Options," and after you've created a user account for SQL Server, you're ready to install Microsoft SQL Server.

You can install the software directly from the Microsoft SQL Server 6.0 CD, or you can copy the software onto a network drive and install from there. If you plan to install from a network drive, simply copy the entire contents of the CD into a shared network directory.

For more information, choose one of the following topics:

Installing the Server Software

Installing Alongside SQL Server 4.2

Installing a Standalone Server

Using Online Help During Installation


Installing the Server Software

Before you start the setup program, you must log on to the system using a username that has administrative privileges. (This is required only when installing server components; you can install the client components using any valid username.)

The SQL Server 6.0 CD contains three separate SETUP directories, one for Intel-based computers (the \I386 directory), one for MIPS-based computers (the \MIPS directory), and one for Alpha AXP-based computers (the \ALPHA directory). You must install SQL Server from the directory containing the software compatible with your hardware platform. You cannot use a different processor architecture's setup program to install SQL Server.

To install Microsoft SQL Server 6.0
  1. From the directory containing the software compatible with your hardware platform's processor architecture, run SETUP.EXE and complete each dialog box that appears.
  2. If you are installing the software on a remote computer, when the Options dialog box appears, choose the Remote button, complete the Remote Setup dialog box, and then choose the OK button.

    If you are installing the software on the local computer, skip this step.

  3. From the Options dialog box, select the Install SQL Server and Utilities option, and then choose the Continue button.
  4. Follow the on-screen instructions. You can choose the Help button or press f1 to access the setup program's online Help.

    For information about each option presented during installation, see Chapter 3, Server Options.

Note When you perform a new installation on a remote computer, the setup program configures the remote SQL Server as if the computer has 16 MB of memory. If this default is not correct, use SQL Enterprise Manager or the sp_configure system procedure on the remote SQL Server to change the setting of the memory configuration option. For information about setting the memory configuration option, see the Microsoft SQL Server Transact-SQL Reference or the Microsoft SQL Server Administrator's Companion.

During installation, selecting the default character set and sort order results in a rapid installation (in most cases, 5 to 10 minutes or less). Choosing an alternate character set or sort order can result in a somewhat longer installation time (but still less than 30 minutes).

After the server is installed, you may need to perform several configuration tasks, such as setting server configuration parameters, setting security parameters, and registering the server and adding it to a server group. For details see Configuring SQL Server, later in this chapter.


Installing Alongside SQL Server 4.2

SQL Server 6.0 and SQL Server 4.2 can be installed alongside each other on the same server. Both can be run simultaneously. SQL Server 6.0 will be treated as a new installation and will not incorporate any configuration settings from the existing SQL Server 4.2 installation.

In a side-by-side installation, each SQL Server version must be installed in its own directory tree. In many cases, SQL Server 4.2 will have been installed under the \SQL root directory (the old default) and SQL Server 6.0 will be installed under the \SQL60 root directory (the new default).

Since both SQL Server 4.2 and SQL Server 6.0 use the same default named pipe, either SQL Server 6.0 or SQL Server 4.2 must be configured to use an alternate named pipe. For SQL Server 4.2, an alternate named pipe can be set by editing the Windows NT Registry. For SQL Server 6.0, an alternate named pipe can be set using the setup program's Change Network Support option. (It is not necessary to use the Registry Editor.) Note that if you change the named pipe a server listens on, clients that will connect to the server using named pipes must also be set up to connect to that server using the new pipe name.

If you will be installing any other Net-Libraries, make sure they are configured using names and parameters that do not duplicate those used by the SQL Server 4.2 installation.

To install SQL Server 6.0 alongside an existing SQL Server 4.2 installation
  1. From the directory containing the software compatible with your hardware platform's processor architecture, run SETUP.EXE and complete each dialog box that appears.
  2. If you are installing the software on a remote computer, when the Options dialog box appears, choose the Remote button, complete the Remote Setup dialog box, and then choose the OK button.

    If you are installing the software on the local computer, skip this step.

  3. From the Options dialog box, select the Install SQL Server and Utilities option, and then choose the Continue button.

    Do not select the Upgrade SQL Server option.

  4. Follow the on-screen instructions until the installation is complete.
  5. After SQL Server 6.0 is installed and the computer has been rebooted, change the default named pipe for one of the SQL Server installations on that computer.

    The default named pipe that a server listens on is \\.\pipe\sql\query.

    • For SQL Server 4.2, an alternate named pipe can be set by editing the Windows NT Registry. Change the ListenOn value for the key HKEY_LOCAL_MACHINE\
      SOFTWARE\
      Microsoft\
      SQLServer\
      Server
    • For SQL Server 6.0, an alternate named pipe can be set using the setup program's Change Network Support option. (It is not necessary to use the Registry Editor.)

    For example, you might change the version 4.2 server to use \\.\pipe\sql42\query, but leave the version 6.0 server with the default, \\.\pipe\sql\query.

  6. As necessary, set up clients to use the alternate pipe name.

    Because you have changed the named pipe that one of the SQL Servers listens on, clients that will connect to that server using named pipes must be configured to connect using the new pipe name. For Windows NT-, Windows 95-, and Windows-based computers, you can set the alternate pipe name by using the Advanced window of the SQL Server Client Configuration Utility. Use different server names for the different pipes that the client connects to.

    For example, you might set up clients to use terrier for \\terrier\pipe\sql\query and terrier42 for \\terrier\pipe\sql42\query.

Note Utilities such as SQL Performance Monitor will connect to the server that is using the default named pipe.


Installing a Standalone Server

The procedure for installing SQL Server software on a standalone computer (one that does not have a network adapter) is nearly the same as the standard installation procedure, except all network and remote setup options are unavailable.

Important If the setup program is unable to start the network, it assumes that you're installing on a standalone computer. If you're installing SQL Server on a computer that has a network adapter and the setup program is unable to start the network, exit the setup program, correct your network problem, and then restart the setup program.


Using Online Help During Installation

If you need instructions or more information while using the setup program, online Help is available. Simply choose the Help button that is part of most setup dialog boxes, or press f1.

The Help topic presented will usually be specific to the current dialog box. If you want other Help information, choose the Contents button in the Help window, and Help Contents will appear. The Help Contents is divided into these categories:

  • Introduction, which lists topics providing overview information
  • How To, which lists topics providing procedural information
  • More About, which lists topics providing reference information


Upgrading SQL Server

You can upgrade a Microsoft SQL Server 4.2x server on a Windows NT-based computer to SQL Server 6.0 by running the setup program and choosing the upgrade option. You can upgrade a Microsoft SQL Server 4.2 for OS/2® operating system server to Microsoft SQL Server 6.0 by first upgrading the operating system to Windows NT Server 3.5 or later (version 3.51 is recommended) and then running the SQL Server setup program to upgrade the SQL Server files. Upgrades from SQL Server 1.x are no longer supported.

Because of improvements to the system (such as new system tables and datatypes), an upgrade to SQL Server 6.0 is a one-way operation and cannot be reversed. Once a version 4.2x database has been upgraded to version 6.0, it cannot be used again with SQL Server 4.2x.

Before upgrading a Microsoft SQL Server 4.2x server, you should run the CHKUPG.EXE utility, which checks that database status is acceptable, that all necessary comments exist in the syscomments system table, and that there are no keyword conflicts.

Most applications written to work with SQL Server 4.2x should work unmodified with SQL Server 6.0. However, because new keywords have been added that may conflict with existing applications, this will not be true in all cases. For a list of new keywords, see Keywords, later in this chapter. Corrections to the behavior of subqueries may also affect applications that depended on the old behavior.

Note For information about language, statement, query, and other compatibility issues between SQL Server 6.0 and SQL Server 4.2x databases, see the compatibility information provided in the Microsoft SQL Server Transact-SQL Reference.

The setup program cannot upgrade from one processor version to another (for example, from Intel- to MIPS-based computers). Also, it is not possible to dump a database in one processor architecture and load it in another. Even if the operation appears to succeed, serious problems will subsequently result. For example, you cannot dump a database from an Alpha AXP-based computer and load it into an Intel-based computer. Nor should you copy MASTER.DAT from an Intel-based computer to a MIPS- or Alpha AXP-based computer and run setup to upgrade it. However, you can use SQL Transfer Manager to simply transfer data from one architecture to another.

Note SQL Server 6.0 detects and prevents attempts to load a dump from a different SQL Server 6.0 processor architecture, but it cannot prevent an attempt to load a dump from a different SQL Server 4.2x processor architecture, because that information is not recorded by a SQL Server 4.2x-level database dump.

For more information, choose one of the following topics:

Before Upgrading

Running the CHKUPG.EXE Utility

Upgrading from SQL Server 4.2x

Upgrading from an Earlier SQL Server 6.0 Release

Upgrading from SQL Server for OS/2


Before Upgrading

Before you begin an upgrade:

  • Back up all databases (including the master database) before upgrading the server.
  • If any databases are read only, run sp_dboption and set the read only option to FALSE. For information on sp_dboption, see the Microsoft SQL Server Transact-SQL Reference.
  • Run the CHKUPG.EXE utility, which checks that database status is acceptable, that all necessary comments exist in the syscomments system table, and that there are no keyword conflicts. CHKUPG.EXE creates a report file. Review the report and take any action the report indicates is necessary to prepare the existing installation for an upgrade.

    For more information, see Running the CHKUPG.EXE Utility later in this chapter.

  • Check that there is adequate physical disk space for the upgrade.

    At least 50 MB of free disk space is required to upgrade from SQL Server 4.2x to SQL Server 6.0.

    The master database must have at least 7 MB free, but if that much database space is not available, the setup program automatically alters the master database to increase the space allocated to it. If necessary, setup also increases the size of the MASTER device (as long as adequate disk space is available).

  • Check that no applications that could be using any of the SQL Server DLLs are running on the server you are going to upgrade. (These applications include SQL Server, SQL Monitor, and SQL Server client applications such as isql, SQL Administrator, and SQL Object Manager.) Also check that Microsoft® Word for Windows® and the Microsoft® Visual C++ development system are not running, and that no applications are using the Microsoft Visual C++ run-time library (MSVCRT20.DLL).

    In general, it is a good idea to make sure no applications are running on the server you are upgrading.

  • Log on to the system under a user account that has administrative privileges.


Running the CHKUPG.EXE Utility

Before you begin an upgrade you should run the CHKUPG.EXE utility, which checks that database status is acceptable, that all necessary comments exist in the syscomments system table, and that there are no keyword conflicts. CHKUPG.EXE writes this information to an output file. Review this report and take any action the report indicates is necessary to prepare the existing installation for an upgrade.

To check a SQL Server 4.2x installation prior to upgrading
  • From the directory containing the software compatible with your hardware platform's processor architecture (Intel, Alpha AXP, or MIPS), run the CHKUPG.EXE utility. The utility has this syntax:

    chkupg [/Usa] [/P password] [/S servername] /o filename

    where

    password
    Is the system administrator's password. If no password is provided, NULL is assumed.
    servername
    Is the name of the server being upgraded. If no servername is provided, the local server is assumed.
    filename
    Is the name of the output file. It must be a fully qualified filename, and include the drive and directory on the server where the output file will be placed.

For example:

chkupg /Usa /P /S /oc:\sql\install\myreport.out

After running CHKUPG.EXE, read its output file using any text editor.

If the CHKUPG.EXE output file indicates that the database is read only, run sp_dboption and set the read only option to FALSE. For information on sp_dboption, see the Microsoft SQL Server Transact-SQL Reference.

If the CHKUPG.EXE output file indicates that some text in the syscomments system table is missing or altered, drop and re-create the related objects, and then run CHKUPG.EXE again to verify that the necessary text exists in syscomments. (You cannot upgrade all objects from SQL Server 4.2x systems to SQL Server 6.0 if you have deleted data from the text column in the syscomments table. The setup program uses the comments in syscomments to upgrade database objects.)

CHKUPG.EXE reports both on keywords implemented in SQL Server 6.0 and on words that are reserved for future use but are not yet implemented. Reserved words are compatible with SQL Server 6.0 but can be expected to cause future conflicts. Reserved words are indicated in the output file by this notation:

[SQL-92 keyword]

For more information, see Keywords and Reserved Words, later in this chapter.

If the CHKUPG.EXE output file indicates conflicts with SQL Server 6.0 keywords, change the conflicting database or database object name and alter the applications that access those objects so that they use the new names. Keyword conflicts can be resolved either before or after the server is upgraded. Keyword conflicts will not cause an upgrade to fail.

CHKUPG.EXE only checks and reports on the current SQL Server 4.2x system. It does not correct incompatibilities, change read-only databases, add comments to syscomments, or take any other corrective action.

When you run the setup program and perform an upgrade from SQL Server 4.2x to SQL Server 6.0, one of the first things setup does is automatically run CHKUPG.EXE and inform you if a problem exists. Although setup runs CHKUPG.EXE automatically, it is still recommended that you first run CHKUPG.EXE separately.


Keywords

Following are lists of SQL Server keywords and reserved words. These are the SQL Server keywords. Keywords new for SQL Server 6.0 are shown in bold type.

ADD | ALL | ALTER
AND | ANY | AS
ASC | AVG | BEGIN
BETWEEN | BREAK | BROWSE
BULK | BY | CASE
CHECK | CHECKPOINT | CLOSE
CLUSTERED | COALESCE | COMMIT
COMMITTED | COMPUTE | CONFIRM
CONSTRAINT | CONTINUE | CONTROLROW
CONVERT | COUNT | CREATE
CURRENT | CURRENT_DATE | CURRENT_TIME
CURRENT_TIMESTAMP | CURRENT_USER | CURSOR
DATABASE | DBCC | DEALLOCATE
DECLARE | DEFAULT | DELETE
DESC | DISK | DISTINCT
DOUBLE | DROP | DUMMY
DUMP | ELSE | END
ERRLVL | ERROREXIT | EXCEPT
EXEC | EXECUTE | EXISTS
EXIT | FETCH | FILLFACTOR
FLOPPY | FOR | FOREIGN
FROM | GOTO | GRANT
GROUP | HAVING | HOLDLOCK
IDENTITY | IDENTITY_INSERT | IDENTITYCOL
IF | IN | INDEX
INSENSITIVE | INSERT | INTERSECT
INTO | IS | ISOLATION
KEY | KILL | LEVEL
LIKE | LINENO | LOAD
MAX | MIN | MIRROREXIT
NOCHECK | NONCLUSTERED | NOT
NULL | NULLIF | OF
OFF | OFFSETS | ON
ONCE | ONLY | OPEN
OPTION | OR | ORDER
OVER | PERM | PERMANENT
PIPE | PLAN | PRECISION
PREPARE | PRIMARY | PRINT
PROC | PROCEDURE | PROCESSEXIT
PUBLIC | RAISERROR | READ
RECONFIGURE | REFERENCES | REPEATABLE
REPLICATION | RETURN | REVOKE
ROLLBACK | ROWCOUNT | RULE
SAVE | SCROLL | SELECT
SERIALIZABLE | SESSION_USER | SET
SETUSER | SHUTDOWN | SOME
STATISTICS | SUM | SYSTEM_USER
TABLE | TAPE | TEMP
TEMPORARY | TEXTSIZE | THEN
TO | TRAN | TRANSACTION
TRIGGER | TRUNCATE | TSEQUAL
UNCOMMITTED | UNION | UNIQUE
UPDATE | UPDATETEXT | USE
USER | VALUES | VARYING
VIEW | WAITFOR | WHEN
WHERE | WHILE | WITH
WRITETEXT |  |


Reserved Words

These are SQL Server reserved words. Reserved words are compatible with SQL Server 6.0 but can be expected to cause conflicts in the future.

ABSOLUTE | ACTION | ALLOCATE
ARE | ASSERTION | AT
AUTHORIZATION | BOTH | CASCADE
CASCADED | CAST | CATALOG
CHAR_LENGTH | CHARACTER | CHARACTER_LENGTH
COLLATE | COLLATION | COLUMN
CONNECT | CONNECTION | CONSTRAINTS
CORRESPONDING | DATE | DAY
DEFERRABLE | DEFERRED | DESCRIBE
DESCRIPTOR | DIAGNOSTICS | DISCONNECT
DOMAIN | END_EXEC | ESCAPE
EXCEPTION | EXPIREDATE | EXTERNAL
EXTRACT | FALSE | FILE
FIRST | FULL | GET
GLOBAL | HOUR | IMMEDIATE
INITIALLY | INNER | INPUT
INTERVAL | JOIN | LAST
LEADING | LEFT | LOCAL
MATCH | MINUTE | MONTH
NAMES | NATIONAL | NATURAL
NCHAR | NEXT | NO
OCTET_LENGTH | OUTER | OUTPUT
OVERLAPS | PAD | PARTIAL
POSITION | PRESERVE | PRIOR
PRIVILEGES | RELATIVE | RESTRICT
RETAINDAYS | RIGHT | ROWS
SCHEMA | SECOND | SESSION
SIZE | SPACE | SQLSTATE
TIME | TIMESTAMP | TIMEZONE_HOUR
TIMEZONE_MINUTE | TRAILING | TRANSLATE
TRANSLATION | TRUE | UNKNOWN
USAGE | USING | VALUE
VOLUME | WORK | WRITE
YEAR | ZONE |

For more information about keywords and reserved words, see the Microsoft SQL Server Transact-SQL Reference.


Upgrading from SQL Server 4.2x

You can upgrade Microsoft SQL Server 4.2x on a Windows NT-based computer to SQL Server 6.0 by using the following instructions.

For information on upgrading from SQL Server 4.2 for OS/2, see Upgrading from SQL Server for OS/2, later in this chapter.

To upgrade Microsoft SQL Server 4.2x to SQL Server 6.0
  1. Complete the upgrade prerequisites described earlier in "Before Upgrading" and Running the CHKUPG.EXE Utility.
  2. From the directory containing the software compatible with your hardware platform's processor architecture (Intel, Alpha AXP, or MIPS), run SETUP.EXE and follow the on-screen instructions.
  3. If you are installing the software on a remote computer, when the Options dialog box appears, choose the Remote button, complete the Remote Setup dialog box, and then choose the OK button.

    If you are installing the software on the local computer, skip this step.

  4. From the Options dialog box, select the Upgrade SQL Server option, and then choose the Continue button.
  5. Follow the on-screen instructions. You can choose the Help button or press f1 to access the setup program's online Help.

    For information about each option presented during installation, see Chapter 3, Server Options.

Regardless of which networks you've configured SQL Server to listen on, the setup program always uses named pipes when connecting to the server during an upgrade. (Named pipes work between Windows NT - based computers no matter which network transport they are running.)

Important If the DB-Library software on the computer from which the setup program was started is configured to use an IPC mechanism other than named pipes, the setup program temporarily changes the default network to named pipes. If in the rare case that setup terminates unexpectedly without restoring the original default network value, you might need to reset this value yourself by using the SQL Server Client Configuration Utility. In addition, if you've been starting SQL Server on an alternate pipe or have disabled named pipes altogether, you must temporarily reconfigure SQL Server to listen on the standard pipe (\\.\pipe\sql\query) before beginning the upgrade.

After completing the upgrade and rebooting the server computer, check your Windows NT search path (path) to be sure that the \SQL\BINN directory precedes any \SQL\BIN or \SQL\BINP directories used for earlier versions of SQL Server. If the server computer has multiple versions of SQL Server components, checking that \SQL\BINN appears first in the path ensures that the current Windows NT - based version is the one that will run.

To check your Windows NT search path
  • From an operating-system prompt, type:

    path

After the server is upgraded, you may need to perform several configuration tasks, such as setting server configuration parameters, setting security parameters, and registering the server and adding it to a server group. For details, see Configuring SQL Server, later in this chapter.


Upgrading from an Earlier SQL Server 6.0 Release

If you are upgrading from an earlier SQL Server 6.0 installation, follow this procedure. From the directory containing the software compatible with your hardware platform's processor architecture, simply run the setup program and choose the Upgrade SQL Server and Utilities option. It is not necessary to run the CHKUPG.EXE utility, although it is advisable to do so.


Upgrading from SQL Server for OS/2

You can upgrade a Microsoft SQL Server 4.2 for OS/2 server to Microsoft SQL Server 6.0 by first upgrading the operating system to Windows NT Server and then running the SQL Server setup program to upgrade the SQL Server files.

To upgrade a Microsoft SQL Server for OS/2 system to SQL Server 6.0
  1. Back up all your databases (including the master database).
  2. Upgrade the operating system.

    If you will be installing SQL Server 6.0, upgrade from OS/2 to Windows NT Server version 3.5 or later. Version 3.51 is recommended. If you will be installing SQL Workstation 6.0, upgrade to Windows NT Workstation version 3.5 or later. Version 3.51 is recommended.

    For operating-system upgrade information, see your manuals for Windows NT.

  3. From the i386 directory containing the software compatible with the Intel processor architecture, run the SQL Server 6.0 setup program and follow the on-screen instructions.
  4. When the Options dialog box appears, select the Upgrade SQL Server option, and then choose the Continue button.
  5. Follow the on-screen instructions. You can choose the Help button or press f1 to access the setup program's online Help.


Installing or Upgrading SQL Workstation

Microsoft SQL Workstation 6.0 has the same features and functionality as Microsoft SQL Server 6.0, except that it is a single-user licensed product that supports a maximum of 15 simultaneous database connections. SQL Workstation is primarily intended to be used as a development platform.

To install, upgrade, test, configure, or remove SQL Workstation, follow the same instructions provided in this chapter for SQL Server.


Testing an Installation

When a server installation or upgrade is complete, you can test the installation by connecting to it locally by running the isql utility from the server computer.

To test the installation
  1. Reboot the server computer, and then start SQL Server by typing the following from an operating-system prompt:

    net start mssqlserver

  2. Connect to SQL Server by typing:

    isql /Usa /P

    If isql connects, you'll see the following isql prompt:

    1>

    If isql cannot connect, you'll get a DB-Library error. (For help in identifying and correcting the problem, see Chapter 7, Installation Troubleshooting.)

  3. Enter a simple query by typing:

    select @@servername
    go

    The isql utility returns the server name, as shown in this example:

    1> select @@servername
2> go
-------------------------------
WOLFHOUND
(1 row affected)
1>
  4. Verify that you have checked a version 6.0 server by typing:

    select @@version
    go

    The isql utility returns the version information.

  5. Quit the isql utility by typing:

    exit


Configuring SQL Server

After the server is upgraded, you may need to perform several configuration tasks, such as setting server configuration parameters, setting security parameters, and registering the server and adding it to a server group. For some post-upgrade configuration tasks you use SQL Enterprise Manager; for other tasks, you use SQL Setup. These applications can be started from the Microsoft SQL Server 6.0 program group, shown here:

You can use SQL Enterprise Manager to configure many server options. For a newly installed server, you would typically use SQL Enterprise Manager to:

  • Register the server and add it to a server group
  • Set security options
  • Set server options
  • Set configuration options

Of course, SQL Enterprise Manager has additional substantial capabilities. For information on using SQL Enterprise Manager, see the SQL Enterprise Manager online Help or the Microsoft SQL Server Administrator's Companion.

You can use SQL Setup not only to install new software and upgrade existing software, but also to configure the server after installation and install specific components. After a server is installed, you can use SQL Setup to:

  • Change network support
  • Add a language
  • Rebuild the master database and, optionally, change the character set and sort order
  • Set security options
  • Set server options
  • Remove SQL Server

Important SQL Setup updates the Windows NT Registry with all the information required to run SQL Server. If you need to update any of the information written to the Registry, reconfigure the installation options by running SQL Setup again or by running SQL Enterprise Manager, rather than using the Windows NT Registry editor (regedt32). Using SQL Enterprise Manager or SQL Setup protects you from inadvertently changing entries that should not be changed and ensures that the integrity of the Registry is maintained.

For more information on configuring a server after installation or upgrade, see the Microsoft SQL Server Administrator's Companion.


Removing SQL Server

When you remove a SQL Server installation, the setup program deletes all SQL Server entries from the Windows NT Registry. It also gives you the option to automatically delete the SQL Server directory tree from the root down. (If you choose this option, after setup has removed SQL Server, you must manually delete the SQL Server root directory and a few remaining files. This procedure is necessary because setup cannot delete itself.)

To remove a SQL Server installation
  1. From the Microsoft SQL Server 6.0 program group, choose the SQL Setup icon.
  2. Follow the on-screen instructions until the Options dialog box appears.
  3. If you're removing the software from a remote computer, choose the Remote button, complete the Remote Setup dialog box, and then choose the OK button.
  4. From the Options dialog box, select the Remove SQL Server option.
  5. Choose the Continue button.

    The Remove SQL Server dialog box appears.

  6. To remove SQL Server files, select the Remove Files From check box.
  7. Choose the Resume button.


Chapter 5 Starting the Server

Starting the Server

For information, choose one of the following topics:

Running SQL Server

Running SQL Executive


Running SQL Server

For information about Running SQL Server, choose one of the following topics:

Running SQL Server as a Service

Configuring SQL Server for Automatic Startup

Starting SQL Server Manually

Pausing SQL Server

Continuing SQL Server

Stopping SQL Server

Running SQL Server on a Network

Running SQL Server Without a Network


Running SQL Server as a Service

Because Microsoft SQL Server is integrated with the Windows NT Service Control Manager, it can be started and stopped as a service, either locally or remotely. It can be manually started, stopped, paused, and continued using SQL Enterprise Manager, SQL Service Manager, the Services application in the Control Panel, or the NET START command.

Optionally, SQL Server can be started automatically as a service when Windows NT starts. You can specify this option during installation by using the setup program. After installation, you can specify this option by using SQL Enterprise Manager.

When you start SQL Server as a Windows NT service, you can log off from the Windows NT network without shutting down SQL Server.

Note that SQL Server can also be started as an application, from a command prompt. For more information, see Other Startup Procedures.


Configuring SQL Server for Automatic Startup

After installation, to configure SQL Server as an automatically started service
  1. From the Microsoft SQL Server 6.0 program group, start SQL Enterprise Manager.
  2. From SQL Enterprise Manager's Server Manager window, open a server group and select a server.
  3. From the Server menu, choose Configurations.

    The Server Configuration dialog box appears.

  4. From the Server Configuration dialog box, choose the Server Options tab.
  5. Select the Auto Start Server At Boot Time Check box.
  6. Choose the OK button.

To cancel automatic startup of SQL Server, perform the same procedure but clear the Auto Start Server At Boot Time Check box.

You can also use the Services application in the Windows NT Control Panel to configure SQL Server as an automatically started service. For information, see your manuals for Windows NT.


Starting SQL Server Manually

You can start SQL Server 6.0 using SQL Service Manager, SQL Enterprise Manager, or the Services application in the Control Panel. From an operating-system prompt you can start it as a service or as an executable file. You can also start it in a minimal configuration (useful if the setting of a configuration value¾for example, over-committing memory¾has prevented the server from starting). For more information, choose one of the following topics:

Starting SQL Server Using SQL Service Manager

Starting SQL Server Using SQL Enterprise Manager

Other Startup Procedures

Startup Options

Starting SQL Server with Minimal Configuration


Starting SQL Server Using SQL Service Manager

To start SQL Server using SQL Service Manager
  1. From the Microsoft SQL Server 6.0 program group, start SQL Service Manager.

    The SQL Service manager window appears:

  2. If the service is a remote service, select or enter the remote server name in the Server box, and then choose the Connect button.

    This connects you to the remote server and fills the Services box with the names of the SQL Server services that are registered on the remote computer. Note that the Server box appears only if the Remote Control option on the System menu (opened by choosing the "-" box in the upper left-hand corner of the window) is turned on.

  3. In the Services box, select MSSQLServer.

    The current state of the service is indicated by the light on the traffic signal and by the message in the status bar.

  4. Choose the green Start/Continue light.
  5. If a confirmation box appears, choose the Yes button.

    SQL Server starts as a service under the Windows NT Service Control Manager using the default startup options written to the Windows NT Registry by the setup program.

You can also stop, pause and continue SQL Server by using the same procedure used to start the service. To stop the service, select the red light, to pause the service, select the yellow light, to continue a paused service, select the green light.

The SQL Service Manager System menu (opened by choosing the "-" box in the upper left-hand corner of the window) includes these options:

Action Verify
Indicates whether you want the SQL Service Manager to present a confirmation box before stopping, pausing, starting, or continuing a service, including dependent services such as SQL Executive. (For details about the dependencies between SQL Server and SQL Executive, see Running SQL Executive.)
Remote Control
Indicates whether you want the SQL Service Manager window to include the Server box for controlling services on remote servers.
Polling Interval
Displays the Polling Interval dialog box, which is used to set how often the state of the service (SQL Server or SQL Executive) is checked.

The Polling Interval dialog box contains two options:

The Foreground Polling Interval (secs.)
Sets the polling interval, in seconds, for the SQL Service Manager when it is running in the foreground (not minimized). The default is 2.
Background Polling Interval (secs.)
Sets the polling interval, in seconds, for the SQL Service Manager when it is running in the background (minimized). The default is 5.


Starting SQL Server Using SQL Enterprise Manager

To start SQL Server using SQL Enterprise Manager
  1. From the Microsoft SQL Server 6.0 program group, start SQL Enterprise Manager.
  2. From SQL Enterprise Manager's Server Manager window, open a server group and select a server.
  3. From the toolbar, choose the Services button (the stoplight).

    The SQL Service Manager window appears.

  4. From the Services window of SQL Server Manager, choose the green Start/Continue light.

    Status text in the SQL Server Manager dialog box informs you when SQL Server has started.

You can also stop, pause and continue SQL Server by using the same procedure used to start the service. To stop the service, select the red light, to pause the service, select the yellow light, to continue a paused service, select the green light.

You can also start the server using a drop-down menu available from the Server Manager window.

To start SQL Server using Server Manager's drop-down menu
  1. From the Microsoft SQL Server 6.0 program group, start SQL Enterprise Manager.
  2. From SQL Enterprise Manager's Server Manager window, open a server group and select a server.
  3. Using the right mouse button, click the server name. Then, from the drop-down menu that appears, choose Start.

    The server starts.

You can also stop, pause, and continue SQL Server by using the drop-down menu.


Other Startup Procedures

You can also start SQL Server by:

  • Using the Services application in the Control Panel. For information, see your documentation for Windows NT.
  • Typing the following from an operating-system prompt:

    net start mssqlserver

  • Running the SQL Server application, SQLSERVR.EXE, from an operating-system command prompt using the options described under "Startup Options," later in this chapter.

Note that the first three methods start SQL Server as a service under the Windows NT Service Control Manager, but the third method does not. When SQL Server is started independent of the Service Control Manager, all system messages print in the window used to start SQL Server, and you cannot pause, stop, or continue SQL Server as a service using SQL Enterprise Manager, SQL Service Manager, the Control Panel Services application, or the net commands.

When you start SQL Server from the command line, any command-line options that you enter take precedence over the default command-line options written to the Windows NT Registry by the setup program. In addition, you must shut down SQL Server before logging off from the Windows NT network.

The following example shows how to start SQL Server from the command line using C:\SQL60\DATA\MASTER.DAT as the MASTER database device path and C:\SQL60\LOG\ERRORLOG as the error log path:

sqlservr -c -dc:\sql60\data\master.dat -ec:\sql60\log\errorlog

For more information on the options used in this example, see Startup Options later in this chapter.


Startup Options

Default SQL Server startup options are stored in the Windows NT Registry. These startup options are used as defaults whenever SQL Server is started, whether it is started as a service or from the command line. Use SQL Enterprise Manager to change the default startup options. (For details, see the Microsoft SQL Server Administrator's Companion.)

You can start SQL Server using the following options (which will not affect the default settings in the Registry):

-c
Shortens startup time by starting SQL Server independent of the Windows NT Service Control Manager.
-d master_device_ path
Indicates the fully qualified path for the MASTER database device (typically, C:\SQL60\DATA\MASTER.DAT). If you do not provide this option, the existing Registry parameters are used.
-e error_log_ path
Indicates the fully qualified path for the error log file (typically, C:\SQL60\LOG\ERRORLOG). If you do not provide this option, the existing Registry parameters are used.
-f
Starts SQL Server in minimal configuration. Useful if the setting of a configuration value (for example, over-committing memory) has prevented the server from starting. For more information, see Starting SQL Server with Minimal Configuration.

Under some conditions it may be necessary to stop the SQL Executive service (if it is running) in order to connect to SQL Server after it has been started with the -f option.

-m
Starts SQL Server in single-user mode. When you start SQL Server in single-user mode, only a single user can connect, and the CHECKPOINT mechanism, which guarantees that completed transactions are regularly written from the disk cache to the database device, is not started. (Typically, this option is used if you experience problems with system databases that need to be repaired.)

Under some conditions it may be necessary to stop the SQL Executive service (if it is running) in order to connect to SQL Server after it has been started with the -m option.

-n
Does not use the Windows NT event log to log SQL Server events. If you start SQL Server with the -n option, it is advisable to also use the -e option, or SQL Server events will not be logged.
-p precision_level
Specifies the maximum level of precision to be supported by decimal and numeric datatypes. By default, SQL Server has a maximum precision of 28. The acceptable values for precision_level are from 1 to 38; however, if no precision_level is supplied with the -p parameter, a maximum precision of 38 will be allowed for decimal and numeric datatypes.
-r master_mirror
Indicates the fully qualified path for the device used to mirror the MASTER database device. Use this option when starting SQL Server if the MASTER database device is damaged. (SQL Server always attempts to use the primary device specified by the -d option before it uses the mirror device specified by the -r option.)
-s registry_key
Starts SQL Server using an alternate set of startup parameters stored in the Registry under the key registry_key. This option, which can be run only from the command line, lets you select from multiple previously defined startup configurations. You could, for example, create an alternate Registry key to start SQL Server in single-user mode. (This applies only to the SERVER subkey.)
/T trace#
Indicates that SQL Server should be started with a specified trace flag (trace#) in effect. Trace flags are used to start the server with non-standard behavior. For a list of available trace flags (trace#), see the Microsoft SQL Server Transact-SQL Reference.

Important When specifying a trace flag, use /T to pass the trace flag number. A lowercase t (/t) is accepted by SQL Server, but it sets other internal trace flags that are needed only by SQL Server support engineers.

-x
Disables the keeping of CPU time and cache-hit ratio statistics. Allows maximum performance.


Starting SQL Server with Minimal Configuration

The -f startup option enables you to start the server with minimal configuration. The -f option is useful if the setting of a configuration value (for example, over-committing memory) has prevented the server from starting.

Note Use the minimal configuration option only for correcting configuration problems (when the server will not start because a configuration value is set to an unacceptable value). It should not be used as the standard way of starting the server.

When you start SQL Server using the minimal configuration option:

  • Temporary changes in memory usage are affected. User connections, open databases, locks, open objects, language information in cache, and asynchronous I/O are all set to the minimum values shown by sp_configure. The procedure cache is set to 50 percent, with minimal total procedure and buffer cache.
  • SQL Server starts in single-user mode (the equivalent of the -m option). Only a single user can connect, and the CHECKPOINT mechanism (which guarantees that completed transactions are regularly written from the disk cache to the database device) is not started.
  • Remote access is disabled.
  • Read-ahead is disabled.
  • Tempdb_in_ram (an sp_configure parameter) is set to 2 MB.
  • Autoexec procedures are not run.

Once the server has been started with the minimal configuration option, you will likely want to do one or more of the following:

  • Change sp_configure values and reconfigure
  • Create a new disk device with DISK INIT
  • Make a device a default device using sp_diskdefault
To start SQL Server with minimal configuration from a command prompt
  • Type:

    sqlservr -f

To start SQL Server with minimal configuration and independent of the Windows NT Service Control Manager
  • From a command prompt, type:

    sqlservr -c -f

To start the server with minimal configuration, using the Services application in the Control Panel
  1. Open the Control Panel and start the Services application.
  2. From the list of services, select SQL Server.
  3. In the Startup Parameters box, type -f.
  4. Choose the Start button.

Under some conditions it may be necessary to stop the SQL Executive service (if it is running) in order to connect to SQL Server when it has been started with the -f option.


Pausing SQL Server

When you pause SQL Server, users who have connections to SQL Server can finish their tasks, but new connections are not allowed. You can pause the SQL Server service only if you started it as a service. For example, you might pause SQL Server a few minutes before shutting it down.

You can also pause the SQL Server service by using SQL Enterprise Manager, SQL Service Manager, the Services application in the Windows NT Control Panel, or by typing the following from an operating-system prompt:

net pause mssqlserver


Continuing SQL Server

You can continue the SQL Server service (resume accepting connections after pausing) by using SQL Enterprise Manager, SQL Service Manager, the Services application in the Windows NT Control Panel, or by typing the following from an operating-system prompt:

net continue mssqlserver


Stopping SQL Server

You can stop SQL Server locally from the server or remotely from a client or another server. If you've started SQL Server as a service, you can stop it by using SQL Enterprise Manager, SQL Service Manager, the Services application in the Control Panel, or the net stop mssqlserver command. If you've started SQL Server from the command line, you can stop SQL Server from a client (either locally or remotely) by using the SHUTDOWN command. You can stop SQL Server from a command prompt window by pressing ctrl c.

When you use any of these procedures to stop SQL Server, SQL Server shuts down in an orderly fashion by performing the following steps:

  • Disabling logins (except for system administrators)
  • Performing a CHECKPOINT in every database

In addition, if you stop SQL Server from a client, SQL Server waits for any currently executing Transact-SQL statements or stored procedures to finish. To bring the system to an immediate halt, you must issue the statement SHUTDOWN WITH NOWAIT from a client.

When you plan to shut down SQL Server, it's a good idea to first pause the SQL Server service and then broadcast a message that SQL Server will be stopped. Give users enough time to finish their current tasks, and then shut down SQL Server as described in the preceding section.

To stop SQL Server using SQL Service Manager
  1. From the Microsoft SQL Server 6.0 program group, start SQL Service Manager.

    The SQL Service manager Window appears.

  2. To stop a remote SQL Server, in the Server box, select or enter the name of the remote server, and then choose the Connect button.
  3. From the Service box, select MSSQLServer.
  4. Choose the yellow Pause light to pause the service.
  5. Send a message informing connected users that the server will soon be shutting down. After an appropriate interval, proceed to step 6.
  6. Choose the red Stop light.
To stop SQL Server using SQL Enterprise Manager
  1. From the Microsoft SQL Server 6.0 program group, start SQL Enterprise Manager.

    The SQL Enterprise Manager Window appears.

  2. From SQL Enterprise Manager's Server Manager window, open a server group and select a server.
  3. From the toolbar, select the Services icon (the stoplight).
  4. Choose the yellow Pause light to pause the service.
  5. Send a message informing connected users that the server will soon be shutting down. After an appropriate interval, proceed to step 6.
  6. Choose the red Stop light.
  7. Choose the Done button.
To stop SQL Server from operating-system prompt
  • Type:

    net stop mssqlserver

To stop SQL Server from an isql client
  • Type:

    SHUTDOWN [WITH NOWAIT]

    Issuing SHUTDOWN waits for currently executing Transact-SQL statements or stored procedures to finish before shutting down. Issuing SHUTDOWN WITH NOWAIT brings the system to an immediate halt.

To broadcast a shutdown message
  • From an operating-system prompt, type:

    net send /users "message"

    For example:

    net send /users "SQL Server is going down in 20 minutes.
Please disconnect."

    The /users option causes the specified message to be sent to all users connected to the server. For descriptions of other net send options, see your manuals for Windows NT.

You can also stop SQL Server locally from the server by using the Services application in the Control Panel. For more information, see your manuals for Windows NT.


Running SQL Server on a Network

For SQL Server to communicate over the network, the Server (network) service must be running. By default, Windows NT starts its built-in Server service automatically whenever the Windows NT starts. If necessary, you can find out whether the Server service has started by typing the following command at an operating-system prompt:

net start

If the Server service has been started, it will be listed in the net start output along with the other running services, as shown here:

C:\> net start
These Windows NT services are started:

   ClipBook Server
   Computer Browser
   EventLog
   Messenger
   Network DDE
   Network DDE DSDM
   Server
   Workstation

The command completed successfully.
C:\>

If the Server service has not been started, start it by typing the following command at an operating-system prompt:

net start server

You'll receive the following message to indicate that the service has been started:

The Server service was started successfully.

You can also use the Services application in the Control Panel to check service status and to start and stop services. For details, see your manuals for Windows NT.


Running SQL Server Without a Network

When running SQL Server without a network, you follow the same procedures as if SQL Server were running with a network, except that you don't need to start the built-in Server service. Because SQL Enterprise Manager, SQL Service Manager, and the net start and net stop commands are always functional (even without a network), the procedures for starting and stopping SQL Server are identical for network or standalone operation.

When connecting to a standalone SQL Server from a local client such as isql, you bypass the network and connect directly to the SQL Server using a local pipe. The only difference between a local pipe and a network pipe is whether or not the network is involved ¾ both establish a connection with SQL Server using the standard pipe (\pipe\sql\query) unless otherwise directed.

When you connect to a local SQL Server without specifying a server name, you're using a local pipe. When you connect to a local SQL Server and explicitly specify a server name, you're using either a network pipe or another network IPC mechanism such as IPX/SPX (if you have configured SQL Server to use multiple networks). Because a standalone SQL Server does not support network pipes, you must omit the unnecessary server_name argument when connecting to the SQL Server from a client. For example, to connect to a standalone SQL Server from isql, type:

isql /Usa /P


Running SQL Executive

SQL Executive is a Windows NT service that resides on the server computer. SQL Executive provides the SQL Server 6.0 scheduling engine, offers robust and varied task scheduling and alerting abilities, and is capable of handling large client/server environments. SQL Executive administration is integrated within SQL Enterprise Manager. Scheduling information is maintained in the msdb database (which is created automatically by setup). For information on using and administering SQL Executive, see the Microsoft SQL Server Administrator's Companion.

SQL Executive can be manually started and stopped in the same manner as SQL Server, by using SQL Service Manager or the Services application in the Control Panel. Use the same procedures provided earlier in this chapter for SQL Server, except those that specify the SQL Executive service rather than the SQL Server (MSSQLServer) service. SQL Executive cannot be paused or continued.

Optionally, SQL Executive can be started automatically when Windows NT starts. You can specify this option during installation using the setup program, or after installation using SQL Enterprise Manager or the Services option in the Control Panel. For SQL Enterprise Manager, use the same procedures described earlier in "Configuring SQL Server for Automatic Startup," but select the Auto Start Executive At Boot Time option.

During installation, SQL Executive should be configured to log on as a service using a special Windows NT user account created for that purpose. For information about this user account, see Chapter 4, Server Installation.

If SQL Executive detects that the MSSQLServer service has stopped unexpectedly, it will automatically attempt up to three times to restart MSSQLServer. This automated restart behavior can be adjusted by modifying values in the Windows NT Registry.

RestartSQLServer specifies whether SQL Executive will attempt to restart the MSSQLServer service once it has been detected as having stopped unexpectedly. Setting this value to 0 prevents automated restart attempts.

MSSQLServer\
SQLExecutive\
RestartSQLServer
Type: REG_DWORD
Value: 0 (false) or 1 (true). The default is 1.

RestartSQLServerInterval specifies, in minutes, the delay between attempts to restart the MSSQLServer service. Changing this value changes the interval between restart attempts.

MSSQLServer\
SQLExecutive\
RestartSQLServerInterval
Type: REG_DWORD
Value: Between 1 and 60 (inclusive). The default is 5.

EventLogPollingPeriod specifies, in seconds, the interval between alert engine polls of the Windows NT applications log (as the alert engine checks for logged SQL Server events).

MSSQLServer\
SQLExecutive\
EventLogPollingPeriod
Type: REG_DWORD
Value: Between 10 and 3600 (inclusive). The default is 20.


Chapter 6 Client Installation

Client Installation

This chapter discusses preinstallation requirements and provides installation instructions for Microsoft SQL Server client components on computers running the Windows NT, Windows 95, Windows, Windows for Workgroups, or MS-DOS operating systems. It also describes how to upgrade existing client installations.

For information on configuring an installed client, see the Microsoft SQL Server Administrator's Companion.

For more information, choose one of the following topics:

Client Platforms

Client Hardware and Software Requirements

Client Installation Options

Installing Client Software

Installing ODBC Drivers

Configuring an Installed Client


Client Platforms

The SQL Server setup program can install 32-bit client software (including SQL Enterprise Manager) on computers running these operating systems:

  • Microsoft Windows NT Server version 3.5 or later. (Version 3.51 is recommended.)
  • Microsoft Windows NT Workstation version 3.5 or later. (Version 3.51 is recommended.)
  • Microsoft Windows 95.

Client software is also provided for computers running these 16-bit operating systems:

  • Microsoft Windows (throughout this book, Windows refers to Windows- and Windows for Workgroups-based clients).
  • MS-DOS


Client Hardware and Software Requirements

To install the 32-bit SQL Server client utilities and libraries, the computer must be equipped with the following hardware and software:

You need | Your choices
Computer | Refer to the Windows NT Hardware Compatibility List for the processor architecture that corresponds to the SQL Server platform you are installing (that is, Intel, Alpha AXP, or MIPS). For example, if you are installing SQL Server for the Intel platform, your choices are any of the 32-bit Intel x86-based microprocessors, such as the 80486 or the Pentium.
Minimum memory | 16 MB.
Disk drive space | A minimum of 7 MB of free disk space. If you install SQL Server Books Online to run from the hard disk, another 15 MB of available disk space is required; if you install SQL Server Books Online to run from the CD, only 1 MB of additional space is needed.
Operating system | Microsoft Windows NT Server version 3.5 or later, Microsoft Windows NT Workstation version 3.5 or later, or Microsoft Windows 95. (For Windows NT Server and Windows NT Workstation, version 3.51 is recommended.)
Network software | SQL Server client software runs on the Windows NT platform using the built-in network software. Unless Banyan VINES or DEC PATHWORKS will be used, additional network software is not required.
Network adapter | Any of the network adapters supported by Windows NT. If you're not using network operations (if, for example, you're connecting locally to a standalone SQL Server), a network adapter is not required. For information about supported network adapters, see your manuals for Windows NT.

The 16-bit SQL Server client utilities and libraries can be installed on computers running the Windows or MS-DOS operating systems.

Note The CD provided with Windows NT Server provides the latest version of Microsoft Windows for Workgroups. Use this version on computers that will run the Windows for Workgroups operating system and will have the SQL Server client software installed.

The 16-bit SQL Server client utilities can also be installed on computers running the Windows NT operating system (although for Windows NT-based computers, the 32-bit client software is recommended):

  • 16-bit Windows-based SQL Server client software runs on Windows NT under Windows on Windows (WOW).
  • MS-DOS - based SQL Server client software runs on Windows NT under the virtual DOS machine (VDM).


Client Installation Options

Choose one of the following topics for information on the choices and options you will encounter during client installation.

Client Options for 32-bit Computers

Client Options for 16-bit Computers


Client Options for 32-bit Computers

Choose one of the following topics for information about the choices and option you will be presented with during installation of client utilities on a Windows NT-based client.

The Installation Path

Client Utilities

SQL Server Books Online


Installation Path

For Windows NT- and Windows 95-based clients, the default SQL Server client installation root directory is C:\SQL60, although you can specify another directory. These are the directories created under the root directory:

Directory Contents
C:\SQL60\BINN
 Windows NT - based client executable files
C:\SQL60\DLL
 Dynamic-link library files
C:\SQL60\INSTALL
 SQL Server Books Online files

The SQL Server setup program places copies of the DB-Library and Net-Library DLLs in the \WINDOWS\SYSTEM32 directory.


Client Utilities

Microsoft SQL Server includes several client utilities, which are used for specific database and network tasks. Although the client utilities are always installed on the server during a new installation, they can also be installed on a 32-bit workstation independent of the server software. When you install the client software independent of the server software, the setup program always installs the client support libraries, such as DB-Library. Some of the utilities, however, are optional.

These are the client utility installation choices:

BCP
Installs the bulk copy utility (bcp), used to copy data to or from an operating-system file.
ISQL/w
Installs both versions of the isql utility (ISQL/w and isql), used to enter Transact-SQL commands and procedures.
SQL Enterprise Manager
Installs SQL Enterprise Manager, used to perform server and enterprise administration tasks.
SQL Security Manager
Installs SQL Security Manager, used to manage user accounts for SQL Servers that have security integration with Windows NT.
Configuration Diagnostics
Installs the following configuration utilities:
SQL Client Configuration Utility
Used to determine which version of DB-Library is installed on a client and to set up SQL Server connection information on a client.
makepipe/readpipe
Used to test if network named pipes are working.

For more information about using these client utilities, see the Microsoft SQL Server Administrator's Companion and the Microsoft SQL Server Transact-SQL Reference.


SQL Server Books Online

During 32-bit client software installation, the setup program gives you the option of installing SQL Server Books Online. This option adds the SQL Server Books Online icon to the Microsoft SQL Server 6.0 program group. By choosing this icon, you can view SQL Server documentation online.

You can install SQL Server Books Online to run from disk (which uses more disk space but increases performance) or to run from CD (which reduces disk space used). You can also choose not to install SQL Server Books Online.


Client Options for 16-bit Computers

Client software is provided for Windows- and MS-DOS - based computers.

Options for Windows-based Clients

Options for MS-DOS - based Clients


Options for Windows-based Clients

For Windows- and Windows for Workgroups-based clients, the default SQL Server root directory is C:\SQL60, although during installation you can specify a different directory. The only directory created under the root is C:\SQL60\BIN, which contains Windows-based client executable files and Windows dynamic-link library (DLL) files. A named pipe Net-Library is placed in the \WINDOWS\SYSTEM directory.

During installation, this setup program creates the SQL Server Tools program group and installs ISQL/w and the SQL Client Configuration Utility.

During installation, choose one of the following as the default Net-Library:

  • Named Pipes
  • Novell SPX
  • Banyan VINES
  • TCP/IP Sockets
  • Multi-Protocol

After installation, you can use the SQL Client Configuration Utility to configure the client to use other Net-Libraries. For information on these Net-Libraries, see the Microsoft SQL Server Administrator's Companion.

During 16-bit client software installation on Windows-based clients, the setup program gives you the option of installing SQL Server Books Online on the client's hard disk. This option adds the SQL Server Books Online icon to the Microsoft SQL Server Tools program group. By choosing this icon, you can view SQL Server documentation online.


Options for MS-DOS - based Clients

You create the root directories for MS-DOS - based clients. The preferred SQL Server root directory is C:\SQL60, although you can specify a different directory. Under the SQL Server root directory, create the \BIN subdirectory. In this directory, place the MS-DOS - based client executable files.

The MS-DOS - based client software provides these client utilities:

  • bcp
  • isql

Three TSRs can be used to communicate with the underlying network layer:

  • Named Pipes (DBNMPIPE.EXE)
  • Novell SPX (DBMSSPX.EXE)
  • Banyan VINES (DBMSVINE.EXE)

For information on these Net-Libraries, see the Microsoft SQL Server Administrator's Companion.


Installing Client Software

You can install the SQL Server client software directly from the Microsoft SQL Server 6.0 CD, or you can copy the software onto a network drive and install from there. If you plan to install from a network drive, simply copy the entire contents of the CD into a shared network directory.

To install the Client software
  • For 32-bit client computers, run the same setup program used to install the SQL Server server components. The setup program is included on the SQL Server CD in the directory (\ALPHA, \I386, or \MIPS) containing the software compatible with your hardware platform's processor architecture.
  • For Windows- and Windows for Workgroups -based clients, run the setup program located in the \CLIENTS\WIN16 directory.
  • For MS-DOS -based clients, copy the files from the \CLIENTS\MSDOS directory into the \SQL60\BIN directory on the client.

For more information, choose one of the following topics:

Installing Client Software on 32-bit Computers

Installing Client Software on 16-bit Computers


Installing Client Software on 32-bit Computers

The following procedure explains how to install Microsoft SQL Server client software on computers running the Windows NT or Windows 95 operating systems. You can run the setup program from a local drive or from a network drive. Remember that while running setup, you can choose the Help button or press f1 to access the setup program's online Help.

Note You do not need to install SQL Server client utilities on a computer that already has the SQL Server server components installed on it, since the client utilities are automatically installed with the server components.

To install client software on a Windows NT-based computer
  1. From the directory containing the software compatible with your hardware platform's processor architecture, run SETUP.EXE and complete each dialog box that appears.
  2. If you are installing the software on a remote computer, when the Options dialog box appears, choose the Remote button, complete the Remote Setup dialog box, and then choose the OK button.

    If you are installing the software on the local computer, skip this step.

  3. From the Options dialog box, select the Install Utilities Only option, and then choose the Continue button.

    The Install Client Utilities dialog box appears.

  4. Complete the Install Utilities dialog box.
    • In the Drive box, select the drive on which to install the client utilities.
    • In the Directory box, type the name of the root directory in which to install the client utilities. The default is \SQL60.
    • The Utilities To Be Installed list displays all the available utilities, with a check box for each. By default, all utilities are selected for installation. For each utility that you do not want to install, clear the check box.
  5. When you have completed the Install Utilities dialog box, choose the Continue button.

    The SQL Server Books Online dialog box appears.

  6. Complete the SQL Server Books Online dialog box, and choose the Continue button.
  7. When the installation is complete, the Completed dialog box appears. Choose the Reboot button.

    After rebooting the computer, you can access the SQL Server graphical client utilities from the Microsoft SQL Server 6.0 program group.

When you install client utilities on a Windows 95-based computer, the AUTOEXEC.BAT file is updated with the path of the SQL Server root directory. The old AUTOEXEC.BAT file is saved as AUTOEXEC.nnn, where nnn is a number from 001 to 099.

To install client software on a Windows 95-based computer
  1. From the i386 directory, run SETUP.EXE and complete each dialog box that appears.
  2. When the Install or Remove Client Utilities dialog box appears, select the Install Utilities Only option and then choose the Continue button.

    The Install Client Utilities dialog box appears.

  3. Complete the Install Utilities dialog box and choose the Continue button.

    The SQL Server Books Online dialog box appears.

  4. Complete the SQL Server Books Online dialog box and choose the Continue button.

When the installation is complete, the Completed dialog box appears.

To upgrade an existing client installation on a 32-bit computer
  • Make sure that no SQL Server client components are running on the computer; then perform the same steps as for a new installation.
To remove the 32-bit client utilities from a Windows 95-based computer
  • Run the setup program and choose the Remove Client Utilities option.

You can also install the MS-DOS - or 16-bit Windows-based client software on computers running the Windows NT or Windows 95 operating systems:

  • To install the MS-DOS - based client software on a computer running Windows NT or Windows 95, run SETUP.EXE from the \CLIENTS\MSDOS directory of the drive containing the SQL Server 6.0 installation software. For information, see Installing MS-DOS - based Clients.
  • To install 16-bit Windows-based client software on a computer running Windows NT or Windows 95, run SETUP.EXE from the \CLIENTS\WIN16 directory of the drive containing the SQL Server 6.0 installation software. For information, see Installing Windows-based Clients.

You can also use the setup program to remove the client utilities from a Windows 95-based computer.


Installing Client Software on 16-bit Computers

Client software can be installed on Windows- and MS-DOS - based computers.

Installing Windows-based Clients

Installing MS-DOS - based Clients


Installing Windows-based Clients

You can run the setup program for Windows-based clients from a local drive or from a network drive. Remember that while running setup, you can choose the Help button or press f1 to access the setup program's online Help.

To install client software on a Windows-based computer
  1. From the \CLIENTS\WIN16 directory of the drive containing the SQL Server 6.0 installation software, run SETUP.EXE.
  2. Follow the on-screen instructions. You will be asked to:
    • Specify the drive and directory where the software will be installed. The default is C:\SQL60.
    • Choose whether to install the optional tools (ISQL/w and the SQL Client Configuration Utility). The default is to install all optional tools.
    • Specify the default Net-Library. This can be Named Pipes, Novell SPX, Banyan VINES, TCP/IP Sockets, or Multi-Protocol.
  3. When the installation is finished, a completion dialog box appears. Choose the OK button to exit the setup program.

To upgrade an existing client installation on a Windows- or Windows for Workgroups-based computer, first make sure that no SQL Server client components are running on the computer and then perform the same steps as for a new installation.


Installing MS-DOS - based Clients

No setup program is provided for MS-DOS -based clients. To install the software, copy the files from the \CLIENTS\MSDOS directory on the SQL Server CD into a \SQL60\BIN directory you create on the client.

It is recommended that you add the \SQL60\BIN directory you create to the computer's path. You can also add an entry to the AUTOEXEC.BAT file to start the SQL Server client software each time the client starts.

To upgrade an existing client installation on a MS-DOS - based computer, first make sure that no SQL Server client components are running on the computer, and then perform the same steps as for a new installation. To be sure a TSR is not loaded, type the following from an operating-system prompt:

enddblib


Installing ODBC Drivers

If you will use the Microsoft® Access® database management system, the Microsoft® Visual Basic® programming system, or another ODBC application to connect to SQL Server from a client, you should install the latest ODBC drivers on that client. ODBC drivers can be installed on client workstations running the Windows NT, Windows 95, Windows for Workgroups, and Windows operating systems.

For computers running Windows NT, the ODBC driver is installed automatically when the SQL Server setup program installs the server or client software.

For computers running Windows or Windows for Workgroups, you must install the ODBC drivers after the SQL Server client software is installed. An ODBC setup program is provided on the SQL Server CD in the \CLIENTS\WIN16\ODBC directory. This setup program installs the latest ODBC SQL Server driver, the ODBC Driver Manager application (ODBC) in the Control Panel, and the associated ODBC Help file.

To install the ODBC driver on a Windows- or Windows for Workgroups-based computer
  1. From the \CLIENTS\WIN16\ODBC directory on the SQL Server 6.0 CD, run SETUP.EXE.
  2. Follow the on-screen instructions. For more information during the installation, choose the Help button.

If you are upgrading an existing installation, the new ODBC driver will replace the existing driver. If you want to keep the existing driver, make a backup copy of SQLSRVR.DLL and DRVSSRVR.HLP, found in the \WINDOWS\SYSTEM directory.

For more information about installing, configuring, and using the ODBC driver, see the online Help for the ODBC setup program and the online Help for the ODBC application in the Control Panel.


Configuring an Installed Client

Once the SQL Server client software is installed, optional client configuration parameters can be set by the SQL Server Client Configuration Utility on client computers running the Windows NT, Windows 95, Windows, and Windows for Workgroups operating systems.

No client configuration utility is provided for MS-DOS - based clients, because MS-DOS - based clients use a terminate-and-stay-resident (TSR) program, and only one Net-Library TSR can be loaded at a time.

For information on setting optional client configuration parameters, see the Microsoft SQL Server Administrator's Companion.


Chapter 7 Installation Troubleshooting

Installation Troubleshooting

This chapter provides information that you will find helpful if you are unable to install SQL Server for Windows NT successfully.

For more information, choose one of the following topics:

Installation Failures

Database Upgrade Failures

Viewing Logs

If you are unable to correct your problem after following the instructions in this chapter, or if you are unable to connect to SQL Server after it is installed, refer to the Microsoft SQL Server Administrator's Companion, or contact your primary support provider.


Installation Failures

The most common cause of SQL Server for Windows NT installation failures is insufficient disk space. If your SQL Server installation has failed, the first thing you should do is check your available disk space.

If you don't seem to have a disk space problem, check the SQL Server error log or the Windows NT event log, or check the installation output files for any information that might help you isolate the problem. For information, see Viewing Logs.

In some cases, disk space problems are caused by the Windows NT virtual memory page file (PAGEFILE.SYS) growing during installation. In these cases, the message written to the log will indicate that there is a memory allocation error. For SQL Server, the PAGEFILE.SYS file must be at least 12 MB greater than the amount of memory installed on the computer. For example, for a 16-MB system, the minimum PAGEFILE.SYS size is 28 MB. The more memory that is installed on the computer, the less space you need for your PAGEFILE.SYS file.

If you are running into installation problems caused by PAGEFILE.SYS growing during the installation, you can correct the problem by:

  • Freeing some space by deleting unnecessary files from your hard disk.
  • Using the System application in the Windows NT Control Panel to ensure that the settings for your PAGEFILE.SYS allow it to grow to the recommended size.

For more information about checking and configuring the size of PAGEFILE.SYS, see your manuals for Windows NT.

For more information, choose the following topic:

Installation Output Files


Installation Output Files

During the installation process, the setup program creates a number of output files in the \SQL60\INSTALL directory that can be useful for troubleshooting installation problems. The output files have the filename extension .OUT. If the setup program fails to complete, examine the .OUT files for information about what caused the failure. You can examine the .OUT file by using any text editor.

Each .OUT file represents an installation script. You can search for .OUT files by typing this command from the \SQL60\INSTALL directory:

dir *.out /od

The last file returned by this command will often be the .OUT file for the script that failed. In that .OUT file, the last line will often reference the error that caused the installation to fail.


Database Upgrade Failures

When a SQL Server is upgraded to version 6.0, all of its databases are automatically upgraded by the setup program. However, under some conditions it may not be possible to upgrade a particular database to version 6.0. This can occur, for example:

  • When the database name is a SQL Server 6.0 reserved word or keyword
  • When the database is set to read-only or offline

Note You should always run the chkupg utility prior to upgrading. This utility detects these conditions, allowing you to correct them prior to upgrading. For information on using chkupg, see Chapter 4, Server Installation.

When one of these conditions is encountered during a server upgrade a message is displayed. After the server upgrade completes you can determine the affected database by reviewing all the report files (files ending in the .OUT filename extension), correct the condition that prevented the database upgrade, and then use the sp_db_upgrade system procedure to upgrade the database to version 6.0.

To upgrade a database
  1. Determine the affected database by reviewing the .OUT files.

    Report files ending in the .OUT filename extension are stored in the \SQL60\INSTALL directory. Review all .OUT files, especially CHKUPG.OUT and UPGRADE.OUT.

  2. Correct the condition that prevented the database upgrade.
  3. From a query interface (for example, from ISQL/w), type:

    sp_db_upgrade dbname

    where

    dbname
    Is the name of the database to be upgraded.

For example:

sp_db_upgrade pubs


Viewing Logs

Microsoft SQL Server logs events in two locations:

  • The SQL Server error log, which can be viewed by using SQL Enterprise Manager or any text editor. When SQL Server is configured to use its error log, each SQL Server session creates a new log, and SQL Server retains the last six logs created. For more information, see Viewing the SQL Server Error Log.
  • The Windows NT application log, which is a special file that can be viewed only by using the Windows NT Event Viewer. When SQL Server is configured to use the Windows NT application log, each SQL Server session writes new events to that log. (Unlike the SQL Server error log, a new application log is not created each time you start SQL Server.) For more information, see Viewing the Windows NT Application Log.

Both logs record similar information; however, the SQL Server error log contains only SQL Server messages, and the Windows NT event log contains messages for all activities on the computer. Both logs automatically time-stamp all events recorded.

By default, setup configures the server to use both logs. You can use SQL Enterprise manager to control whether SQL Server uses either or both of the logs. For more information, see the SQL Enterprise Manager online Help or the Microsoft SQL Server Administrator's Companion.

Note SQL Executive also writes events to the Windows NT application log and to a Task History that can be displayed using SQL Enterprise Manager. For more information on viewing the task history, see the SQL Enterprise Manager online Help or the Microsoft SQL Server Administrator's Companion.

For more information, choose one of the following topics:

Viewing the SQL Server Error Log

Viewing the Windows NT Application Log


Viewing the SQL Server Error Log

You can also view the SQL Server error log by using any text editor. By default, the error log is \SQL60\LOG\ERRORLOG.

When SQL Server is configured to use its error log, each SQL Server session creates a new log, and SQL Server retains the last six logs created. The current log has no filename extension. The old logs are distinguished by their filename extension (.1, .2, .3, and so on), with the lowest number being the most recent log.

If the server was successfully installed, you can also view the error log by using SQL Enterprise Manager.

To view the SQL Server error log using SQL Enterprise Manager
  1. From the Microsoft SQL Server 6.0 program group, start SQL Enterprise Manager.

    The SQL Enterprise Manager window appears.

  2. From SQL Enterprise Manager's Server Manager window, open a server group and select a server.
  3. From the Server menu, choose Error Log.

    The SQL Server error log appears.

When SQL Server is configured to use its error log, each SQL Server session creates a new log, and SQL Server retains the last six logs created. The current log has no filename extension. SQL Server maintains the last 6 error logs created. The old logs are distinguished by their filename extension (.1, .2, .3, and so on), with the lowest number being the most recent log.


Viewing the Windows NT Application Log

When SQL Server is configured to use the Windows NT application log, each SQL Server session writes new events to that log. The Windows NT application log is a special file that can be viewed and managed only by using Windows NT Event Viewer. Unlike the SQL Server error log, a new application log is not created each time you start SQL Server.

To view the Windows NT application log
  1. From the Administrative Tools program group, start the Event Viewer application.

    The Event Viewer window appears.

    SQL Server events are identified by the entry MSSQLServer in the Source column. SQL Executive events are identified by the entry SQLExecutive

  2. To view the log of a remote computer, from the Log menu choose Select Computer, and then complete the dialog box that appears.

    If you will be viewing the log of the local computer, skip this step.

  3. If the Application log is not displayed, from the Log menu choose Application.

    Three Windows NT logs¾Application, System, and Security¾can be displayed by Event Viewer. The name of the displayed log is shown in the title bar of the dialog box. SQL Server and SQL Executive events are written to the Application log.

  4. Optionally, to display only SQL Server events, choose Filter Events from the View menu, select MSSQLServer from the Source box, and then choose the OK button.

    To view only SQL Executive events, select SQLExecutive instead.

  5. To view more information about an event, double-click the event.

    The Event Detail dialog box appears.

For more information about using Event Viewer, managing the application log, and understanding the information it presents, see the online Help for Event Viewer or your manuals for Windows NT.


Appendix A Character Sets and Sort Orders

Character Sets and Sort Orders

The character set and sort order choices you make during installation determine the types of characters that SQL Server recognizes in your database data, the order in which SQL Server sorts data in response to queries, and the results that SQL Server returns for queries that involve character comparisons.

Carefully consider the options before installing character sets and sort orders. Changing these options after installation requires you to rebuild your databases and reload your data.

For information on character sets and sort orders, choose one of the following topics:

  • Character Sets
  • Sort Orders
  • Custom
  • The Effect on Passwords of Changing Sort Orders

Note Additional character sets and sort orders are being developed for international users and may be included in those listed by the setup program.


Character Sets

The character set and sort order choices you make during installation determine the types of characters that SQL Server recognizes in your database data. For information about character sets, choose one of the following topics:

About Character Sets

ISO 8859-1

Code Page 850

Code Page 437

Setting Alternate Code Pages

Note During an installation, selecting the default character set and sort order results in a rapid installation (in most cases, 5 to 10 minutes or less). Choosing an alternate character set or sort order can result in a somewhat longer installation time (but still less than 30 minutes).


About Character Sets

Following are the SQL Server character set choices. The default is ISO 8859-1 (Latin 1 or ANSI).

ISO 8859-1 (Latin 1 or ANSI)

Code Page 850 (Multilingual)

Code Page 437 (U.S. English)

You must use the same character set on both the client and the server, or your results can be unpredictable. However, if your databases use only the first 128 characters of a character set (for example, if you don't use characters with diacritical marks), it makes no difference which character set you use because the first 128 characters are the same for all the character set choices.

The SQL Server character set choices are illustrated in the following figures and are described in the following sections. For additional information about character sets, refer to your manuals for Windows NT.

Code page 850 (Multilingual)

Code page 437 (U.S. English)

ISO 8859-1 (Latin 1 or ANSI)


ISO 8859-1

This is the default character set. ISO 8859-1 is also known as the Latin 1 or ANSI character set. It is compatible with the ANSI characters used by the Windows NT and Windows operating systems.

The ISO 8859-1 character set might be appropriate if you intend to use Windows NT - and Windows-based clients exclusively, or if you need to maintain exact compatibility with a SQL Server environment for UNIX or VMS.


Code Page 850

Code page 850 is a multilingual character set that includes all the characters used by most of the languages of European, North American, and South American countries.


Code Page 437

Code page 437 is the most commonly used character set in the United States. If you have character-based applications that depend on extended characters for graphics, use this character set. Otherwise, use code page ISO 8859-1, which provides more compatibility with languages other than United States English.

You can find out if you need to use code page 437 for specific applications by changing your Windows NT configuration to use ISO 8859-1 and then running your application. If the application looks the way you expect it to, use ISO 8859-1. If the application looks unusual, use code page 437. For information about setting the code page in your Windows NT configuration, see your manuals for Windows NT.


Setting Alternate Code Pages

The code page or pages a client uses are determined by system settings. The procedure for changing these system settings depends on the client operating system.

To set alternate code pages under the Windows NT operating system
  • Use the International application in the Windows NT Control Panel as described in your manuals for Windows NT.
To set alternate code pages under the Windows or MS-DOS operating systems
  1. Add or change entries in the CONFIG.SYS file, as indicated in the following example:
    COUNTRY=001,850,C:\DOS\COUNTRY.SYS
DEVICE=C:\DOS\DISPLAY.SYS CON=(EGA,850,2)

    (These entries prepare the console device for code page 850.)

  2. Add or change entries in the AUTOEXEC.BAT file, as indicated in the following example:
    NLSFUNC
MODE CON CP PREP=((850,437)C:\DOS\EGA.CPI)
CHCP 850

    (These entries set code pages 850 and 437 as alternate code pages, and set code page 850 as the default.)


Sort Orders

The sort order chosen for a server determines the order in which SQL Server sorts data in response to queries, as well as the results that SQL Server returns for queries that involve character comparisons.

For information, choose one of these topics:

About Sort Orders

Dictionary Order, Case-insensitive

Binary Order

Dictionary Order, Case-sensitive

Dictionary Order, Case-insensitive, Uppercase Preference

Dictionary Order, Case-insensitive, Accent-insensitive

Additional Sort Orders for Code Page 850

Sort Order IDs

Performance Comparisons


About Sort Orders

SQL Server has these sort orders. The default is Dictionary order, case-insensitive.

Dictionary Order, Case-insensitive

Binary Order

Dictionary Order, Case-sensitive

Dictionary Order, Case-insensitive, Uppercase Preference

Dictionary Order, Case-insensitive, Accent-insensitive

Additional Sort Orders for Code Page 850

Version 1.x - compatible Sort Order

Alternate Sort Orders

Scandinavian Sort Orders

Sort Order IDS

Performance Comparisons

Custom

The 1.x-compatible sort order applies only to code page 850.

Binary order is the fastest sort order, but strings sorted using Binary order are not necessarily listed in dictionary order. The dictionary sort orders are generally listed in the same order as in a standard dictionary, but each dictionary sort order has a different set of rules for sorting uppercase characters, lowercase characters, and characters with diacritical marks.

The following sections describe each of the sort order choices and give examples of how similar characters compare and sort for each. For performance comparisons, see Performance Comparisons.


Dictionary Order, Case-insensitive

This is the default sort order. With this sort order, characters are compared according to the following rules:

  • Uppercase and lowercase characters are treated as equivalent.
  • Characters with diacritical marks are treated as different from all other characters (except their corresponding uppercase or lowercase characters).

For example:

A = a
Ä = ä
Å = å
a ¹ à ¹ á ¹ â ¹ ä ¹ å
A ¹ Ä ¹ Å
Jose = jose
Jose ¹ Josè

With this sort order, characters are compared according to the following rules:

  • Uppercase characters are not given sorting preference over their corresponding lowercase characters (they can appear before or after them).
  • Uppercase characters with diacritical marks are not given sorting preference over their corresponding lowercase characters (they can appear before or after them).
  • Characters with diacritical marks are sorted after characters without diacritical marks.
  • Characters with diacritical marks are sorted in the order they appear in the character set.

For example:

A, a, à, á, â, Ä, ä, Å, å
a, A, à, á, â, Ä, ä, Å, å
A, a, à, á, â, ä, Ä, Å, å


Binary Order

Binary order is the simplest and fastest sort order. The collating sequence for this sort order is based on the numeric value (0 through 255) of the characters in the installed character set. Using the binary sort order, ZYXWV sorts before abcde because the character Z precedes the character a in all character sets. Sorting for extended characters (such as characters with diacritical marks) depends on the installed character set.

If you want your data to sort in a more conventional order, choose one of the dictionary sort orders. Remember, however, that dictionary sort orders come with a tradeoff in performance.


Dictionary Order, Case-sensitive

With this sort order, characters are compared according to the following rules:

  • Uppercase and lowercase characters are treated as not equivalent.
  • Characters with diacritical marks are treated as different from all other characters (including their corresponding uppercase or lowercase characters).

For example:

A ¹ a
Ä ¹ ä
Å ¹ å
a ¹ à ¹ á ¹ â ¹ ä ¹ å
A ¹ Ä ¹ Å
Jose ¹ jose
Jose ¹ José

With this sort order, characters are compared according to the following rules:

  • Uppercase characters are sorted before their corresponding lowercase characters.
  • Uppercase characters with diacritical marks are sorted before their corresponding lowercase characters.
  • Characters with diacritical marks are sorted after characters without diacritical marks.
  • Characters with diacritical marks are sorted in the order they appear in the character set.

For example:

A, a, à, á, â, Ä, ä, Å, å


Dictionary Order, Case-insensitive, Uppercase Preference

With this sort order, characters with diacritical marks are treated as different from all other characters (except their corresponding uppercase or lowercase characters). For example:

A = a
Ä = ä
Å = å
a ¹ à ¹ á ¹ â ¹ ä ¹ å
A ¹ Ä ¹ Å
Jose = jose
Jose ¹ José

With this sort order, characters are compared according to the following rules:

  • Uppercase characters are sorted before their corresponding lowercase characters.
  • Uppercase characters with diacritical marks are sorted before their corresponding lowercase characters.
  • Characters with diacritical marks are sorted after characters without diacritical marks.
  • Characters with diacritical marks are sorted in the order they appear in the character set

For example:

A, a, à, á, â, Ä, ä, Å, å


Dictionary Order, Case-insensitive, Accent-insensitive

With this sort order, characters are compared according to the following rules:

  • Uppercase and lowercase characters are treated as equivalent.
  • Characters with diacritical marks are treated as equal to their counterparts without diacritical marks.

For example:

A = a = à = á = â = Ä = ä = Å = å
Jose = jose = José = josé

With this sort order, lowercase characters are paired with their corresponding uppercase characters (for example, a and A) and are sorted before any corresponding uppercase character with a diacritical mark (for example, Ä).

For example:

A, a, à, á, â, Ä, ä, Å, å


Additional Sort Orders for Code Page 850

In addition to the sort orders described in the preceding sections, SQL Server includes additional sort orders for code page 850:

  • Strict compatibility with version 1.x case-insensitive databases
  • Alternate dictionary order, case-sensitive
  • Alternate dictionary order, case-insensitive
  • Alternate dictionary order, case-insensitive, uppercase preference
  • Alternate dictionary order, case-insensitive, accent-insensitive
  • Scandinavian dictionary order, case-sensitive
  • Scandinavian dictionary order, case-insensitive, uppercase preference

For more information, choose one of the following topics:

Version 1.x - compatible Sort Order

Alternate Sort Orders

Scandinavian Sort Orders


Version 1.x-compatible Sort Order

This sort order is provided for strict compatibility with SQL Server version 1.x case-insensitive databases. It uses the dictionary sort order with case insensitivity and no uppercase preference for the first 128 characters of the character set and the Binary sort order for the remaining 128 characters. Using this sort order choice, A and a are sorted and grouped together, but à and Ä are sorted as unique characters according to their binary values in the installed character set.

This option offers no advantage over other sort orders other than strict compatibility with earlier versions of SQL Server. Unless you have case-insensitive databases set up for earlier versions of SQL Server that use extended characters, and you require the upgraded version to have exactly the same, less functional sort order semantics, you should choose another sort order.


Alternate Sort Orders

The Alternate sort orders are similar to their counterparts, but they differ as follows:

  • For the case-sensitive option, all uppercase variants of a character are sorted before any equivalent lowercase variants. For example:
    A, À, Á, Ä, a, à, á, ä

    This is in contrast to the standard case-sensitive option in which the uppercase and lowercase pairings are maintained for each distinct character. For example, the characters in the previous example are sorted as follows using the standard dictionary order with case sensitivity:

    A, a, À, à, Á, á, Ä, ä
  • Ø and ø sort at the end of the character set.
  • Ñ is sorted distinctly from N.


Scandinavian Sort Orders

The Scandinavian sort orders differ from the other sort orders because the extended characters (Ø, Å, Ä, and Ö) are sorted after Z.


Sort Order IDs

The following table shows the sort order ID for each SQL Server sort order. The filename is the name of the corresponding sort order file installed in one of three character set directories under \SQL60\CHARSETS, and the filename extension indicates the corresponding character set.

ID | Name | Filename
30 | Binary order | CP437BIN.437
31 | Dictionary order, case-sensitive | DICTION.437
32 | Dictionary order, case-insensitive | NOCASE.437
33 | Dictionary order, case-insensitive, uppercase preference | NOCASEPR.437
34 | Dictionary order, case-insensitive, accent-insensitive | NOACCENT.437
40 | Binary order | CP850BIN.850
41 | Dictionary order, case-sensitive | DICTION.859
42 | Dictionary order, case-insensitive | NOCASE.850
43 | Dictionary order, case-insensitive, uppercase preference | NOCASEPR.850
44 | Dictionary order, case-insensitive, accent-insensitive | NOACCENT.850
49 | Strict compatibility with Version 1.x case-insensitive databases | NOCASE34.850
50 | Binary order | ISO_1BIN.ISO
51 | Dictionary order, case-sensitive | DICTION.ISO
52 | Dictionary order, case-insensitive | NOCASE.ISO
53 | Dictionary order, case-insensitive, uppercase preference | NOCASEPR.ISO
54 | Dictionary order, case-insensitive, accent-insensitive | NOACCENT.ISO
55 | Alternate dictionary order, case-sensitive | ALTDICT.850
56 | Alternate dictionary order, case-insensitive, uppercase preference | ALTNOCSP.850
57 | Alternate dictionary order, case-insensitive, accent-insensitive | ALTNOACC.850
58 | Scandinavian dictionary order, case-insensitive, uppercase preference | SCANNOCP.850
59 | Scandinavian dictionary order, case-sensitive | SCANDICT.850
61 | Alternate dictionary order, case-insensitive | ALTNOCS.850

Note Additional character sets and sort orders are being developed for international users and may be included in those listed by the setup program.


Performance Comparisons

Binary order is the fastest sort order option.

The following table shows the approximate decrease in sort order performance, relative to Binary order, for each sort order. The operation evaluated involved string comparisons on character fields.

Sort order | Percent slower
Dictionary order, case-sensitive | 20%
Dictionary order, case-insensitive | 20%
Dictionary order, case-insensitive, uppercase preference | 20%
Dictionary order, case-insensitive, accent-insensitive | 35%

The percentages in the table are approximate. The overall performance difference between sort orders varies significantly depending on the types of operations and the type of data used. Sorting operations that depend on string comparisons on character fields (for example GROUP BY and LIKE statements) take more time to process than other sorting operations and have the greatest effect on sorting speed.

With certain queries, if there is a nonunique clustered index on a character value, sort order options that define uppercase preference require the optimizer to perform a sort. Using a sort order with no uppercase preference, such as Dictionary order, case-insensitive (no uppercase preference), greatly improves performance because no sorting is necessary. Choosing Dictionary order, case-insensitive (no uppercase preference), causes an uppercase A and a lowercase a to be treated the same in an ORDER BY statement.


Custom

SQL Server can install custom sort orders from definition files as they become available. A sort order definition file can have any legal filename, but the convention is to use the filename extension .SRT.

To install a custom definition file
  1. If SQL Server is not yet installed, start the setup program and install SQL Server. Or after the server is installed, from the Microsoft SQL Server 6.0 program group start the setup program and choose the option to rebuild the MASTER database.
  2. Follow the on-screen instructions until the Installation Options dialog box (for a new installation) or the Rebuild Options dialog box (for a MASTER database rebuild) appears.
  3. Select the Order button.
  4. From the list in the Sort Orders dialog box, scroll to the bottom and select Custom; then choose OK.
  5. Continue with setup, following the on-screen instructions until the SQL Server Path dialog box appears.
  6. If necessary, insert the disk containing the definition file into the disk drive.
  7. In the Sort Filename box, enter the full path to the definition file. Include the drive letter, directory, and filename.
  8. In the Sort Order Number box, enter the sort order ID.

    If a sort order ID is specified in documentation provided with the definition file, use that number. If no sort order ID is specified, use any number not currently used for a sort order. For a list of sort order IDs for the sort orders provided with SQL Server, see Sort Order IDs.

  9. Choose the Continue button and continue with setup, following the on-screen instructions until the installation or rebuild is complete.


The Effect on Passwords of Changing Sort Orders

Because of the introduction of one-way encrypted passwords with SQL Server 6.0, changing the sort order has an impact on the use of passwords.

When a login ID is added or a password is changed, the password encryption algorithm takes the supplied password and generates a numeric representation of it, which is stored in the syslogins table. (If you look in master..syslogins.password, what looks like garbled text is actually a textual representation of the binary encrypted password).

  • If the password is generated on a case-sensitive server, the original password text, as typed, is supplied to the password algorithm. When the password is subsequently checked, the user must supply the same characters in the appropriate case for authentication.
  • If the password is generated on a case-insensitive server, the password is converted to uppercase before generating and checking the encrypted form. When the password is subsequently checked, the user can supply the characters in upper- or lowercase.

When changing sort orders, if a user transfers syslogins out of the server with one sort order and into a new server with another sort order, the encrypted passwords will be moved as generated. This has the following effects:

  • If moving from case-insensitive to case-sensitive servers, users will need to type passwords in uppercase to be authenticated.
  • If moving from case-sensitive to case-insensitive servers, users will not be able to log in unless the password generated in the case-sensitive server was entirely in uppercase.

When changing sort orders, take the appropriate steps to ensure that users will be able to log in to the server when the sort order conversion is complete. If the system administrator (SA) is not able to log in because of the effects described, you will need to restore the original sort order to correct the problem.

For information about changing character sets and sort orders and for information about login IDs and passwords, see the Microsoft SQL Server Administrator's Companion.


Appendix B Unattended Installation

Unattended Installation

In most cases you will run install SQL Server interactively, starting SETUP.EXE (as described in Chapter 4, "Server Installation") and determining the settings for each installation option by responding to the setup program's on-screen instructions. This can be referred to as an attended installation.

The setup program also allows you to install SQL Server without having to respond to prompts from the setup program. Instead, you create an initialization file that contains the settings for each installation option, and you save the initialization file on a storage device accessible to the computer(s) that will be set up. You can create as many initialization files as needed to support the servers to be installed. When appropriate, you start SETUP.EXE with command-line options that cause it to run in unattended mode, specifying the initialization file to be used to configure the new installation. This is referred to as unattended installation.

Unattended installation is convenient if you will be installing several SQL Servers with identical configurations. It is also convenient if you would like to use SQL Executive to schedule an installation.

Unattended setup supports installation for the local server only. It does not permit remote server installation.

For more information, choose one of the following topics:

Creating a Setup Initialization File

Performing an Unattended Installation

Format of the Setup Initialization File

A Sample Setup Initialization File


Creating a Setup Initialization File

The setup initialization file contains the information that will be used to set configuration parameters when SQL Server is installed. Instead of responding to prompts for information from the setup program during installation, you enter configuration parameters ahead of time, in the configuration file, and during installation setup obtains the necessary settings from there.

To create a setup initialization file
  1. Using any text editor, create a new text file.
  2. Enter configuration information following the format described in Format of the Setup Initialization File and A Sample Setup Initialization File later in this appendix.
  3. Save the initialization file on a storage device accessible to the computers that will be set up. Save as a text file, using any filename ending in the .INI filename extension.

Optionally, you can create custom scripts that will run during installation. All custom scripts must be placed in one directory on the server being installed (or in one directory accessible to the server). The path to the scripts and the name of the scripts must be entered in the setup initialization file. For more information, see [Scripts], later in this appendix.

All the entries in the initialization file are strings and can also be created using the Windows function WritePrivateProfileString. For example:

// Assume lpszKeyValue is user's name string from user interface
LSTR lpszKeyValue
// Needs to be written to [License]FullName in SETUP.INI
WritePrivateProfileString("License","FullName",
   lpszKeyValue,"SETUP.INI")

For information about using WritePrivateProfileString, see your Windows programming documentation.

Important The setup program does not perform error checking of the values entered in the initialization file. It is up to the user to ensure that the .INI file contains valid values.


Performing an Unattended Installation

To perform an unattended installation, run SETUP.EXE from the command line using the following syntax:

setup /t IniFilePath = filename

where filename is a fully qualified filename, including the path. The path can be a local path or a redirected path to a network drive, but it cannot be a UNC path. Note that IniFilePath is case-sensitive and must be typed with the capitalization exactly as shown. There must be a space on each side of the equal sign ( = ).

For example, if you have created an initialization file named MYPC.INI and have saved it on drive E: in the \SETINI directory, from the directory containing the setup program for the server's processor architecture (that is, Intel, MIPS, or Alpha AXP), you would type:

setup /t IniFilePath = e:\setini\mypc.ini

After installation delete the setup initialization file, since it contains the password for the SQL Executive service logon account.


Format of the Setup Initialization File

The initialization file used by setup is a text file using regular Windows .INI file format. Following are tables listing the sections, entries, descriptions, and (where appropriate) values that can be included in the file. For examples, see A Sample Setup Initialization File.

For more information, choose one of the following topics:

[License]

[SQLPath]

[MasterPath]

[NewOptions]

[Charset]

[SortOrder]

[Network]

[LogonAccount]

[Scripts]


[License]

These values correspond to those user types in the Enter Name and Organization dialog box and the licensing dialog boxes of the setup program.

FullName and Mode are required. If Mode is set to 0 (Per Server), PerServerUsers is required. Orgname and ProductID are optional, although an entry for ProductID is strongly recommended.

Entry | Description | Value
FullName | User or owner | A name
Orgname | Organization | A name
ProductID | Product identification number (supplied on the SQL Server CD box) | An ID
Mode | Licensing mode | 0 Per Server 1 Per Seat
PerServerUsers | Number of users in Per Server mode | A number


[SQLPath]

These values correspond to those user types in the SQL Server Installation Path dialog box of the setup program. An entry is required for each value.

Entry | Description | Value
SQLPath | The directory where SQL Server will be installed | The SQL Server root directory. For example: \SQL60
LogicalSQLDrive | The drive where SQL Server will be installed | The drive. For example: E:


[MasterPath]

These values correspond to those user types in the MASTER Device Creation dialog box of the setup program. An entry is required for each value.

Entry | Description | Value
MasterSize | MASTER device size, in MB * | 20 minimum. More is recommended. For example: 25
MasterDBFileName | MASTER device file name | A file name ending in the .DAT file name extension. For example: MASTER.DAT
MasterDBPath | The directory where the MASTER device will be placed | The path. For example: \SQL60\DATA
LogicalDBDrive | The drive where the MASTER device will be created | A drive letter. For example: C:
* MasterSize plus 9 MB must be less than the available disk space on the server being installed.


[NewOptions]

These values correspond to the check boxes at the bottom of the Installation Options dialog box of the setup program. An entry is required for each value.

Entry | Description | Value
AutoServerService | Indicates whether SQL Server will be automatically started with the system | CHECKED | NOTCHECKED
AutoExecutiveService | Indicates whether SQL Executive will be automatically started with the system | CHECKED | NOTCHECKED
BooksOnline | Installation selection for SQL Server Books Online | 1 Copy to hard disk 2 Run from CD 3 Do not install


[Charset]

This value correspond to the one selected in the Select Character Set dialog box of the setup program. A CharSet entry is required.

Entry | Description | Value
CharSet | The characters set installed for the server | cpISO = ANSI (ISO 8859-1) cp 850 = 850 Multilingual cp437 = 437 U.S. English

For more information about character sets, see Appendix A, Character Sets and Sort Orders.


[SortOrder]

These values correspond to those selected in the Select Sort Order dialog box of the setup program. An entry is required for each value.

The valid SortFileName entries are dependent on the CharSet value entered.

Entry | Description | Value
SortFileName | Sort file name | See the following table of sort file values.
SortConfigValue | Sort order value in sysconfig | See the following table of sort configuration values.

These are the valid sort orders for each character set.

CharSet entry | Valid SortFileName | Sort order
cpISO | iso_1bin.iso | Binary
 | diction.iso | Dictionary order, case-sensitive
 | nocase.iso | Dictionary order, case-insensitive
 | nocasepr.iso | Dictionary order, case-insensitive, uppercase preference
 | noaccent.iso | Dictionary order, case-insensitive, accent-insensitive
cp850 | cp850bin.850 | Binary
 | diction.850 | Dictionary order, case-sensitive
 | nocase.850 | Dictionary order, case-insensitive
 | nocasepr.850 | Dictionary order, case-insensitive, uppercase preference
 | noaccent.850 | Dictionary order, case-insensitive, accent-insensitive
 | nocase34.850 | Strict compatibility with Version 1.x case-sensitive databases
 | altdic.850 | Alternate dictionary order, case-sensitive
 | altnocs850 | Alternate dictionary order, case-insensitive
 | altnoacc.850 | Alternate dictionary order, case-insensitive, accent-insensitive
 | altnocsp.850 | Alternate dictionary order, case-insensitive, uppercase preference
 | scannocp.850 | Scandinavian dictionary order, case-insensitive, uppercase preference
 | scandict.850 | Scandinavian dictionary order, case-sensitive
cp437 | cp437bin.437 | Binary
 | diction.437 | Dictionary order, case-sensitive
 | noaccent.437 | Dictionary order, case-insensitive, accent-insensitive
 | nocase.437 | Dictionary order, case-insensitive
 | nocasepr.437 | Dictionary order, case-insensitive, uppercase preference

These are the valid entries for SortConfigValue.

For this SortFileName | Use this SortConfigValue entry
iso_1bin.iso | 50
diction.iso | 51
nocase.iso | 52
nocasepr.iso | 53
noaccent.iso | 54
cp850bin.850 | 40
diction.850 | 41
nocase.850 | 42
nocasepr.850 | 43
noaccent.850 | 44
nocase34.850 | 49
altdic.850 | 55
altnoacc.850 | 57
altnocsp.850 | 56
scannocp.850 | 58
scandict.850 | 59
altnocs.850 | 61
cp437bin.437 | 30
diction.437 | 31
noaccent.437 | 34
nocase.437 | 32
nocasepr.437 | 33

For more information about sort orders, see Appendix A, Character Sets and Sort Orders.


[Network]

These values correspond to the Net-Libraries that a user selects in the Select Network Protocols dialog box of the setup program and to the values a user types in the individual dialog boxes that subsequently appear for each selected Net Library.

A Net-Library is specified by entering the Net-Library name in the NetLibList. The NetLibList is entered in the format: {"NetLib1","NetLib2", ...}. Each Net-Library name is enclosed in double quotation marks and separated by commas. No spaces are allowed after a comma. For example:

NetLibList={"SSNMPN60","SSMSRP60","SSMSSP60","SSMSSO60"}

The named pipes Net-Library must always be entered, because during installation it is used by setup. If needed, named pipe support can be removed after installation. One or more other Net-Libraries can also be entered. For each Net-Library entered, the corresponding parameter value must be provided. For example, if you enter SSMSRP60 in the NetLibList, you must also provide a MultiProtEncrypt entry.

Entry | Description | Value
NetLibList | List of Net-Libraries to load (1) | One or more Net-Library names (1) Entered as: {"NetLib1","NetLib2", ...}
ServerNMPipe | The named pipe name (2,3) |
MultiProtEncrypt | Sets server-enforced encryption (2,4) | CHECKED | NOTCHECKED
SPXServiceName | SPX service name (2,5) |
TCPIPSocketNumber | TCP/IP socket number (2,6) |
ADSPObjectName | ADSP object name (2,7) |
VinesStreetName | Banyan VINES street name (2,) |
DecNetObjectID | DECnet object ID (2,8) |
1. See the table that follows for Net-Library values. 2. For information about valid parameters to enter for each Net-Library, see the Microsoft SQL Server Administrator's Companion. 3. The default named pipe name is \\.\pipe\sql\query. 4. The default Multi-Protocol encryption setting is NOTCHECKED. 5. The default SPX service name is the computer name. 6. The default TCP/IP socket number is 1433. 7. The default ADSP object name is the computer name. 8. The default DECnet object ID is 150.

These are the valid NetLibList entries:

NetLibList Entry | Is Net-Library for | Associated Value
SSNMPN60 | Named Pipes | ServerNMPipe
SSMSRP60 | Multi-Protocol | MultiProtEncrypt
SSMSSP60 | NWLink IPX/SPX | ServiceName
SSMSS060 | TCP/IP Sockets | TCPIPSocketNumber
SSMSAD60 | AppleTalk ADSP | ADSPObjectName
SSMSVI60 | Banyan VINES | StreetName
SSMSDE60 | DECnet Sockets | DecNetObjectID


[LogonAccount]

These values correspond to those displayed in the SQL Executive Log On Account dialog box.

If LocalSystem is set to CHECKED, entries for UserName and UserPassword are not necessary. If LocalSystem is set to NOTCHECKED, entries for UserName and UserPassword are required.

Entry | Description | Value
LocalSystem | Indicates whether SQLExecutive runs under a Windows NT user account or the server's LocalSystem account. | CHECKED | NOTCHECKED
UserName | The username for the Windows NT user account. | The username. For example: user80
UserPassword | The password for the user account. | The password. For example: XYZ45MNO


[Scripts]

These entries specify a path to and the name of custom scripts that will be executed when the setup program runs. The path must be a directory on the local server being installed or a directory accessible to that server. These are optional entries, but if a CustomScriptList is entered, a CustScPath entry is required.

Entry | Description | Value
CustScPath | A path to a directory where customization scripts can be found. | A drive letter and path. For example: C:\TMP
CustomScriptList | A list of custom scripts to execute. The scripts must exist in the directory specified by CustScPath. | One or more script names, entered as: {"customscript1", "customscript2", ...} Each script name is enclosed in double quotation marks and separated by commas. No spaces are allowed after a comma.


A Sample Setup Initialization File

[License]
FullName=Royce Aydel
OrgName=CLXD5 Corporation
ProductID=AB1234567
Mode=0
PerServerUsers=50

[SQLPath]
SQLPath=\SQL60
LogicalSQLDrive=D:

[MasterPath]
MasterSize=30
LogicalDBDrive=D:
MasterDBPath=\SQL60\DATA
MasterDBFileName=MASTER.DAT

[NewOptions]
AutoServerService=CHECKED
AutoExecutiveService=CHECKED
BooksOnline=1

[CharSet]
CharSet=cpISO

[SortOrder]
SortFileName=nocase.iso
SortConfigValue=52

[Network]
NetLibList={"SSNMPN60","SSMSRP60","SSMSSP60","SSMSSO60"}
ServerNMPipe=\\.\pipe\sql\query
MultiProtEncrypt=NOTCHECKED
SPXServiceName=ROYCEA3
TCPIPSocketNumber=1433

[LogonAccount]
LocalSystem=NOTCHECKED
Username=ExecService
Password=ABC1234

[Scripts]
CustomScPath=C:\TEMP
CustScriptList={"script1.sql","script2.sql","script3.sql"}


Before You Begin

Microsoft® SQL Server™ 6.0 extends the performance, reliability, and scalability of earlier releases of Microsoft SQL Server to meet the needs of customers who are deploying large-scale distributed information systems. SQL Server 6.0 provides powerful tools for enterprise-wide administration, data replication, parallel DBMS performance, and scalability to very large databases. SQL Server 6.0 also provides tight integration with OLE object technology.

SQL Server 6.0 continues to adhere to industry standards, with improved ANSI SQL support and language enhancements that include declarative referential integrity (DRI), and powerful server-based cursor support that far exceeds the ANSI standard.

Note This book contains background information about Microsoft SQL Server and provides some information specific to SQL Server 6.0. For information about changes and enhancements specific to SQL Server 6.5, see the supplementary "What's New in SQL Server 6.5."


About the Administrator's Companion

The Microsoft SQL Server Administrator's Companion provides background information about SQL Server administration, and provides instructions for administering SQL Server. It is written for system administrators who are responsible for overseeing and maintaining systems that run SQL Server. It contains information about creating and managing servers, devices, and databases. It explains SQL Server replication, backing up and recovering data, scheduling tasks, managing security, and monitoring performance. It also describes server and client configuration, details error conditions, and provides troubleshooting information.

This book assumes that you are familiar with Transact-SQL®, the enhanced version of SQL (structured query language). (For information about Transact-SQL, see the Microsoft SQL Server Transact-SQL Reference.) This book also assumes that you are familiar with the Microsoft® Windows NT™, Microsoft® Windows® 95, Microsoft Windows, and MS-DOS® operating systems.


Document Conventions

This manual uses the following conventions to distinguish elements of text:

Convention | Purpose
UPPERCASE | Represents Transact-SQL syntax, paths, and filenames.
MIXEDcase | Shows syntax abbreviations. The uppercase portion is required; the lowercase portion is optional.
small capitals | Represent key names, such as ctrl.
bold | Represents system procedures, utility programs, commands, and user-entered text.
italic | Represents database names, table names, column names, index names, and variables.
monospace | Represents examples, display text, and error messages.
[brackets] | Identify optional items in syntax. Type only the information within the brackets; do not type the brackets.
{braces} | Identify required items in syntax. Type only the information within the braces; do not type the braces.
| (vertical bar) | Means "or" and signifies that you can choose only one of the items within the brackets or braces.
... (ellipsis) | Indicates that you can repeat the previous syntax item.


Finding Further Information

In addition to the administration information in this book, additional information about using SQL Server 6.0 is available from the following sources, as well as from the Microsoft® Development Library and Microsoft® TechNet.

The Microsoft Developer Network provides in-depth information for developers. With Level 1 of the Developer Network, you get four quarterly releases of the Development Library, packed with inside information on programming for Microsoft Windows and Windows NT, plus other program benefits. With Level 2 of the Developer Network, you'll receive all the Level 1 benefits plus quarterly releases of the Development Platform, containing the latest Windows and Windows NT Workstation operating systems and API-level SDKs and DDKs from Microsoft. For ordering information, call (800) 759-5474.

Microsoft TechNet is the front-line resource for fast complete answers to technical questions on Microsoft desktop and system products. Through two monthly CDs, you get everything from crucial data on client/server and workgroup computing, systems platforms, and database products to the latest applications support for Microsoft Windows and the Apple® Macintosh®. For ordering information, call your reseller or (800) 344-2121.

Online Help

To access online Help while using SQL Server, choose the Help button or press f1 from within SQL Enterprise Manager or ISQL/w. To access context-sensitive Transact-SQL Help from SQL Enterprise Manager or ISQL/w, press shift f1. From within isql, execute the sp_helpsql system stored procedure.

SQL Server Books Online

The setup program gives you the option of installing Microsoft SQL Server Books Online. If you choose this option, setup adds the Books Online icon to the Microsoft SQL Server 6.0 program group. By choosing this icon, you can access online versions of the SQL Server documentation.

Important SQL Server Books Online contains the most up-to-date information about SQL Server 6.0, including information that changed or was unavailable when the SQL Server 6.0 books were printed.

Microsoft SQL Server System Administrator's Companion
The online version of this book incorporates configuration, administration, and troubleshooting topics. Describes server and client configuration. Explains system administration tasks, such as managing devices and databases, backing up and recovering data, performing replication, scheduling tasks, managing security, and monitoring performance. Describes error conditions and gives troubleshooting procedures.
Microsoft SQL Server Database Developer's Companion
Provides an overview of Transact-SQL, which is an enhanced version of SQL (structured query language). Discusses managing data and database objects, such as tables, views, indexes, stored procedures, defaults, rules, constraints, and user-defined datatypes.
Microsoft SQL Server Transact-SQL Reference
Explains how to use Transact-SQL statements and other features to access databases, and provides syntax and descriptions for Transact-SQL statements, system procedures, utility programs, and system tables.
Microsoft SQL Server Setup
Provides instructions for installing SQL Server 6.0 servers and clients.
Microsoft SQL Server Programming SQL Distributed Management Objects
Provides syntax and reference information for the SQL Distributed Management Objects, which are 32-bit OLE Automation objects for the Microsoft Windows 95 and Windows NT operating systems. These objects, properties, methods, and collections are used to write scripts and programs that can administer multiple SQL Servers distributed across a network.
Microsoft SQL Server Programming DB-Library for C
Provides syntax and reference information for the DB-Library application programming interface (API), which is used to write C/C++ client programs for the Microsoft Windows, Windows 95, Windows NT, and MS-DOS operating systems.
Microsoft SQL Server Programming DB-Library for Visual Basic
Provides syntax and reference information for the DB-Library API, which is used to write Microsoft® Visual Basic® programming system-based client programs for the Windows operating system.
Microsoft SQL Server Programming Open Data Services
Provides syntax and reference information for the Microsoft Open Data Services API, which is used to write C/C++ server and gateway programs for the Windows NT operating system.


Part 1 Introduction

Introduction

Microsoft SQL Server 6.0, Microsoft's relational database management system for distributed client/server computing, is designed to support large-scale distributed computing environments. Microsoft SQL Enterprise Manager, included with SQL Server 6.0, is a graphical tool that provides powerful, enterprise-wide system administration capabilities for SQL Server 6.0 servers. The following chapters introduce Microsoft SQL Server 6.0 and SQL Enterprise Manager.

Chapter 1, Overview, provides a summary of features new for SQL Server 6.0, discusses what the setup program installs, explains how to use this documentation to learn how to administer SQL Server, provides "quick start" instructions on how to start and log on to SQL Server, and lists SQL Server 6.0 capacities.

Chapter 2, Introducing the SQL Distributed Management Framework, introduces the Distributed Management Framework (DMF), an integrated framework of the objects, services, and components used to manage Microsoft SQL Server. The primary management tool is Microsoft SQL Enterprise Manager, which provides an intuitive, graphical user interface for managing Microsoft SQL Servers across an enterprise.


Chapter 1 Overview

Overview

Microsoft SQL Server 6.0 is a multiuser relational database management system that provides a powerful client/server platform for delivering critical business applications efficiently across multiple environments. It combines the power, scalability, and manageability of the Microsoft Windows NT operating system with the reliability and advanced capabilities of high-end, client/server database management.

This chapter discusses what the setup program installs, provides "quick start" instructions on how to start and log in to SQL Server, explains how to use this documentation to learn how to administer SQL Server, and lists SQL Server 6.0 capacities.

For information, choose one of the following topics:

How to Use the Administrator's Companion

What Setup Installs

Special Users of SQL Server

Getting Started with SQL Server

SQL Server Capacities


How to Use the Administrator's Companion

This documentation provides information you will need to administer Microsoft SQL Server 6.0. It is written for system administrators (SAs) who are responsible for overseeing and maintaining systems that run SQL Server. It presents configuration, administration, and troubleshooting topics. It describes server and client configuration and explains system administration tasks, such as managing devices and databases; managing security; backing up, recovering and transferring data; performing replication; scheduling tasks and setting up alerts; and monitoring performance. It also describes error conditions and gives troubleshooting procedures.

This documentation assumes that you are familiar with operating systems, networks, databases, and Transact-SQL, an enhanced version of SQL (Structured Query Language). It also assumes that the SQL Server software is already installed on the server computer. For information about installing SQL Server 6.0, see Microsoft SQL Server Setup. For information about Transact-SQL, see the Microsoft SQL Server Transact-SQL Reference.

For information about managing data and database objects¾such as tables, views, indexes, stored procedures, defaults, rules, constraints, and user-defined datatypes¾see the Microsoft SQL Server Transact-SQL Reference and the Microsoft SQL Server Database Developer's Companion.

This documentation assumes that you will be using SQL Enterprise Manager for most administrative tasks. For information on SQL Enterprise Manager, see Chapter 2, Introducing the SQL Distributed Management Framework. For information about system stored procedures that can also be used to administer SQL Server, see the Microsoft SQL Server Transact-SQL Reference.

The following summarizes the organization of information in the Microsoft SQL Server Administrator's Companion.

Part 1, Introduction
The chapters in Part 1 introduce this documentation, Microsoft SQL Server 6.0, the Distributed Management Framework (SQL-DMF), and SQL Enterprise Manager.
Part 2, Configuration
The chapters in Part 2 explains how to configure servers and clients. SQL Server provides setup programs that largely automate the installation of server software and client software. In most cases, you will be able to use the software immediately after installing it. However, there are a number of configuration tasks that can be performed after installation to optimize a server or client for your particular network, database, and business environment.
Part 3, Devices, Databases, and Drives
The chapters in Part 3 explain how to manage devices, databases, transaction logs, and drives.
Part 4, Security
The chapters in Part 4 explain how to manage SQL Server 6.0 security. They show how SQL Server security interacts with security for Windows NT-based domains and computers, what the three types of SQL Server security are, what SQL Server 6.0 logins and database users are, and what SQL Server 6.0 object and statement permissions are. You will also learn about the tools that are used to perform each security management task, and how to perform these tasks.
Part 5, Data Management
The chapters in Part 5 explain how to export, import, back up, and recover data.
Part 6, Replication
Replication, which is provided as an integral element of Microsoft SQL Server 6.0, allows you to automatically distribute read-only copies of transactional data from a source server to one or more destination servers at one or more remote locations. The chapters in Part 6 present the information you need to establish and maintain data replication between the servers of your enterprise.
Part 7, Other Operations
Using SQL Server's scheduling engine, you can schedule and automate a number of tasks, including command executions, Transact-SQL Statements, and replication events. Using the alerts engine, you can set up SQL Enterprise Manager to automatically respond to SQL Server events by executing a predefined task or sending an alert or a page to selected users. Using SQLMail, you can send messages through the built-in mail application programming interface (MAPI) client interface in Windows NT. Using SQL Performance Monitor, SQL Enterprise Manager, and the sp_monitor system stored procedure, you can monitor server activity and performance. The chapters in Part 7 explain how.
Part 8, Troubleshooting
The chapters in Part 8 list error messages, describe error conditions, and suggest troubleshooting procedures and techniques.


What Setup Installs

Although this documentation does not discuss installation, it is important to know how SQL Server is installed and what is installed with it. The setup program installs system devices and databases, system tables, system stored procedures, a character set and sort order, some default users, administrative tools and utilities, and, optionally, SQL Server Books Online.

For information, choose one of the following topics:

System Devices and Databases

System Tables

System Stored Procedures

Character Sets and Sort Orders

Administrative Tools And Utilities

SQL Server Books Online

For in-depth information about SQL Server 6.0 installation, see Microsoft SQL Server Setup.


System Devices and Databases

A database is a collection of data, data tables, and other objects that are organized and presented to serve a specific purpose, such as facilitation of searching, sorting, and recombination of data. Databases are stored on devices.

A device is an operating-system file in which databases are stored. One database can be stored on several devices. SQL Server has two types of devices: database devices, which store databases, and dump devices, which store backups of a database.

When SQL Server is installed, the setup program creates the MASTER, MSDBDATA, and MSDBLOG database devices. It creates the master, model, tempdb, and pubs databases and places them on the MASTER database device. It creates the msdb database and places it on the MSDBDATA database device, and places the msdb transaction log on the MSDBLOG device.

In most cases, it is best if the devices created by setup are not being used for other databases. Before users create databases, they should create one or more other devices for the use of those databases.

For information about the system databases installed by the setup program, choose one of the following topics:

master Database

model Database

msdb Database

tempdb Database

pubs Database


master Database

When SQL Server is installed the setup program creates the MASTER database device, then creates the master database and places it on that device. The master database controls user databases and the operation of SQL Server as a whole. It keeps track of user accounts, remote user accounts, remote servers that this server can interact with, ongoing processes, configurable environment variables, system error messages, the databases on SQL Server, the storage space allocated to each database, the tapes and disks available on the system, and the active locks.

It is possible to add user objects to the master database, but it is not recommended. Any objects created in the master database should be used for the administration of the system as a whole. Set permissions in master so that most users cannot create objects there. You can discourage users from creating objects in master by changing each user's default database (the database to which a user is connected after logging in). However, the system administrator's default database should remain master.

Important You should back up the master database each time you change it ¾ each time you create, alter, or drop any device or database; each time you create, alter, or drop a database object from master; and each time you execute a stored procedure that changes master.


model Database

When SQL Server is installed the setup program creates the MASTER database device. One of the databases it creates and places on that device is model. This database provides the template or prototype on which new user databases are based. Each time a database is created, SQL Server makes a copy of the model database and then extends it to the creation size requested.

Important A new database can never be smaller than the model database.

The model database contains the system tables required for each user database. It can be modified to customize the structure of newly created databases so that every change you make to model is reflected in each new database. These are some of the changes commonly made to model:

  • User datatypes, constraints, rules, or defaults are added.
  • Users who are to be given access to all databases on a SQL Server are added.
  • Default privileges, particularly for guest accounts, are established in model.
  • Database configuration options (such as select into/bulkcopy) are set in the model database. The setting is reflected in all new databases.

Typically, most users are not granted permission to modify the model database. There is no need to grant read permission either, since the entire contents of model are copied into each new user database.


msdb Database

The msdb database supports SQL Executive and provides a storage area for scheduling information. During server software installation, the setup program automatically creates two devices (2 MB and 1 MB) on the same disk drive as the master database and then places the msdb database on the 2-MB device (MSDBDATA) and its transaction log on the 1-MB device (MSDBLOG).


tempdb Database

When SQL Server is installed the setup program creates the MASTER database device. One of the databases it creates and places on that device is tempdb. This database provides a storage area for temporary tables and other temporary working storage needs. No special permissions are required to use tempdb (that is, to create temporary tables or to execute commands that might require storage space in the tempdb database).

All temporary tables are stored in tempdb, no matter which database the user who creates them is using. You can query a temporary table from inside the database in which it was created or from tempdb. If you query tempdb..sysobjects, you will notice that a suffix is attached to the names of temporary tables. System stored procedures (for example, sp_help) work on temporary tables, but only if you use the procedures from tempdb.

The tempdb database is a shared work space used by the databases on SQL Server. A user's temporary tables are dropped from tempdb when the current user leaves SQL Server or during recovery from a system failure. A stored procedure's temporary tables are dropped when the procedure exits. Temporary tables can also be dropped explicitly before a session ends.

The default size of tempdb is 2 MB. Certain activities, such as the following, can make it necessary to increase the size of tempdb:

  • Large temporary tables
  • Significant activity on temporary tables (which will fill up the tempdb log)
  • Large sorts, or many simultaneous sorts
  • Subqueries and aggregates with GROUP BY
  • A large number of open cursors

The system administrator can increase the size of tempdb. Note that tempdb is created on the MASTER device by default. Additional space can be added on MASTER or on any other initialized device. The system administrator can also create tempdb in RAM.


pubs Database

The pubs database is a sample database provided as a learning tool. The pubs database is the basis of most of the examples in the Microsoft SQL Server documentation. This sample database is described in the Microsoft SQL Server Transact-SQL Reference.

After pubs has been used as a learning tool, you may need to reinstall it to restore its original tables, schema, and content. For instructions about how to reinstall pubs, see the Microsoft SQL Server Transact-SQL Reference.

If the pubs database is not required for learning purposes, you can drop it.


System Tables

A table is a collection of rows (records) that have associated columns (fields). The master database and each user database contain system tables of information about SQL Server as a whole and about each user database.

All of the SQL Server - supplied tables in the master database (the controlling database) are considered system tables. Each user database is created with a subset of those system tables.

The master database and its tables are created when you install SQL Server. The system tables in a user database are automatically created when the database is created. The names of most system tables begin with sys. For in-depth information about the system tables, see the Microsoft SQL Server Transact-SQL Reference.

For more information, choose one of the following topics:

Permissions for System Tables

Querying the System Tables


Permissions for System Tables

A permission is the security authorization that allows a user to perform certain actions on certain database objects or to use certain statements. Permissions for using the system tables are controlled by the database owner (just like permissions on user tables).

The SQL Server setup program sets up permissions so that all users can read the system tables, except for a few fields.


Querying the System Tables

The system tables can be queried just as any other tables can. For example, this statement returns the names of all system tables in the database:

select name
from sysobjects
where type = 'S'

SQL Server has system stored procedures, many of which provide shortcuts for querying the system tables. For more information, see System Stored Procedures.

Caution System tables should not be directly altered by any user under any circumstance. For example, do not attempt to modify syslogs with a DELETE, UPDATE, or INSERT statement. Doing so makes it impossible for SQL Server to recover correctly in case of a system failure. In addition, attempting to delete all rows from syslogs will cause SQL Server to get into an infinite loop that eventually fill up the entire database.


System Stored Procedures

A system stored procedure is a precompiled collection of Transact-SQL statements. Many system stored procedures are available for managing SQL Server and for displaying information about databases and users.

The names of most system stored procedures begin with sp_. System stored procedures are located in the master database and are owned by the system administrator, but many of them can be run from any database. If a system stored procedure is executed in a database other than master, it operates on the system tables in the database from which it is executed.

You can also write your own precompiled collection of Transact-SQL statements, called stored procedures, that can be executed from any database.

In addition to system stored procedures, extended stored procedures are installed with SQL Server. Extended stored procedures provide additional functionality for SQL Server by providing a way to dynamically load and execute a function within a dynamic-link library (DLL) in a manner similar to that of a stored procedure, seamlessly extending SQL Server functionality. Actions outside of SQL Server can be easily triggered and external information returned to SQL Server. Return status codes and output parameters (identical to their counterparts in regular stored procedures) are also supported.

SQL Server includes system stored procedures that add and drop extended stored procedures and that provide information about extended stored procedures. In addition, SQL Server provides a number of extended stored procedures. Other extended stored procedures can be created by programmers using Microsoft Open Data Services. For information about creating extended stored procedures, see Microsoft SQL Server Programming Open Data Services.

For information about system stored procedures, stored procedures, and extended stored procedures, see the Microsoft SQL Server Transact-SQL Reference.


Character Sets and Sort Orders

The character set determines the types of characters that SQL Server recognizes in databases. A character set is a set of 256 letters, numbers, and symbols specific to a country or a language. The printable characters of the first 128 values are the same for all character sets. The last 128 characters, sometimes referred to as extended characters, are different.

You should use the same character set for both the client and the server, or your results can be unpredictable. However, if your databases use only the first 128 characters of a character set (for example, if you do not use characters with diacritical marks), it makes no difference which character set you use, because the first 128 characters are the same for all character sets.

A sort order is a set of rules that determines how SQL Server collates and presents data in response to database queries. The sort order determines the order in which data is presented in response to SQL Server statements involving GROUP BY, ORDER BY, and DISTINCT. The sort order also determines how certain queries are resolved, such as queries involving WHERE and DISTINCT.

During installation, SQL Server allows you to select a character set and a sort order to be used by the server. Several sort orders and character sets are available. The default character set is ANSI (ISO 8859-1), and the default sort order is dictionary order, case-insensitive. For in-depth information about character sets and sort orders, see Microsoft SQL Server Setup.

The character set and sort order applies to the entire server. You cannot have different databases with different character sets or sort orders on a server.

You cannot dump and load databases between servers that are configured for different character sets or sort orders.

Caution Care should be taken to select the correct character set and sort order during SQL Server installation. If the character set or sort order needs to be changed after SQL Server is installed, you must completely rebuild the master database, which renders all other databases useless. Reinstalling SQL Server with a new character set or sort order can profoundly affect the results of queries to previously created databases.


Administrative Tools and Utilities

A number of administrative tools are provided with SQL Server 6.0. The particular tools that are provided depend on whether the server software or the client software is installed and on the computer's operating system.

For more information, choose one of the following topics:

Server Tools and Utilities

Client Tools and Utilities


Server Tools and Utilities

When the server software is installed, administrative tools and utilities are available from the Microsoft SQL Server 6.0 program group, from the Windows NT Control Panel, and from the command line.

The Microsoft SQL Server 6.0 program group is created when the server software is installed:

These are the graphical tools installed with the server software:

Graphical tool | Description
SQL Setup | Used to reconfigure the server. You can use the setup program to change network support options, add a language, rebuild the master database, change the character set or sort order, set server options, set security options, and remove SQL Server.
SQL Service Manager | Used to start, pause, continue, and stop SQL Server and SQL Executive.
ISQL/w | Allows you to enter Transact-SQL statements and system stored procedures in a graphical query interface. ISQL/w also provides the capability for graphically analyzing queries.
SQL Security Manager | Allows you to manage user accounts for SQL Servers that are using security integration with Windows NT.
SQL Enterprise Manager | Provides easy, enterprise-wide management from a server or a workstation. It allows you to perform system administration tasks using a graphical interface. You can configure servers, manage databases and database objects, schedule events, configure and manage replication, and do much more. For information about SQL Enterprise Manager, see Chapter 2, Introducing the SQL Distributed Management Framework.
SQL Transfer Manager | Provides an easy, graphical way to transfer objects and data from one SQL Server to another. You can transfer from a Microsoft-based SQL Server or a non-Microsoft-based SQL Server to a Windows NT-based Microsoft SQL Server (for example, transferring data from a Microsoft SQL Server running on an Intel-based SQL Server to a different processor architecture).
SQL Performance Monitor | Integrates Windows NT Performance Monitor with SQL Server, providing up-to-the-minute activity and performance statistics.
SQL Server Books Online | Provides online access to the Microsoft SQL Server documentation set. Includes a powerful and easy-to-use full-text search capability.
Microsoft ODBC SQL Server Driver | Is an online Help file providing information about the Microsoft ODBC SQL Server Driver.
SQL Distributed Management Objects | Is an online Help file displaying the Microsoft SQL Server Distributed Management Object Model.
SQL Client Configuration Utility | Sets the default Net-Library and server connection information on clients. It also displays the DB-Library version number and searches for multiple copies of DB-Library and Net-Library in your path.

These are the command-line utilities installed with the server software:

Utility program | Description
bcp | Copies data to or from an operating-system file.
isql | Provides a query interface and allows you to perform system administration tasks from a server or a workstation. Also executes batch files that contain one or more SQL statements. (For details about isql and creating batch files, see the Microsoft SQL Server Transact-SQL Reference.)
makepipe and readpipe | Test the integrity of the network named-pipe services.

In addition to the command-line utilities, you can also administer SQL Server using any tool that issues Transact-SQL statements. For information about the command-line utilities and about Transact-SQL statements, see the Microsoft SQL Server Transact-SQL Reference.


Client Tools and Utilities

Which administrative and utilities tools that are installed on a client depend on the computer's operating system.


SQL Server Books Online

During installation of server software¾or of client software on 32-bit or 16-bit Windows-based computers¾the setup program gives you the option of installing SQL Server Books Online. Selecting this option installs the SQL Server Books Online software and adds the SQL Server Books Online icon to the Microsoft SQL Server 6.0 program group.

SQL Server Books Online provides on-screen access to the entire SQL Server 6.0 documentation set. A notable and powerful feature is its full-text search capability, which allows you to quickly search for a word or a phrase. You can search through the entire documentation set or through only selected books or topics. For more information on full-text search, see the online Help for SQL Server Books Online.

You can install SQL Server Books Online to run from the disk (which provides the best performance) or to run from the CD (which uses less disk storage space). You can also choose to not install SQL Server Books Online.


Special Users of SQL Server

Three types of special users administer and control SQL Server: system administrators (SAs), database owners (DBOs), and database object owners.

  • The system administrator (SA) is the person responsible for the administrative and operational functions that are independent of any particular application and is likely to have a comprehensive overview of SQL Server and all of its applications.

    The duties of an SA typically include installing SQL Server; configuring servers and clients; managing and monitoring the use of disk space, memory, and connections; creating devices and databases; authorizing SQL Server users and granting them permissions; transferring data in and out of SQL Server databases; backing up and restoring databases; implementing and maintaining replication; scheduling unattended operations; monitoring and tuning SQL Server performance; and diagnosing system problems. The system administrator may also advise application designers about the data that already exists on SQL Server, make recommendations about standardizing data definitions across applications, and so on.

    The SA operates outside the protection system; SQL Server does no permission checking for the SA. The SA is also treated as the owner of whatever database he or she is using. Anyone who knows the SA password can log in and act as SA.

  • A database owner (DBO) is the user who creates a database. Each database has only one owner. The DBO has full privileges inside the database and determines the access and capabilities provided to other users. In the owned database, the user is recognized as DBO; in other databases, the database owner is known by his or her database username. DBO status can be reassigned to a different user. Only one login ID can be DBO, although other login IDs can be aliased to DBO. (An alias is a database username that is shared by several login IDs. An alias allows you to treat more than one person as the same user inside a database, giving all of them the same permissions.)

    The SA can be the DBO of some or all databases.

  • A database object owner is the user who creates a database object (tables, indexes, views, defaults, triggers, rules and procedures). Each database object has only one owner. The database object owner is automatically granted all permissions on the database object. The database object owner can grant permission to other users to use that object. Database object ownership cannot be transferred.

Many of the commands and procedures discussed in this documentation require the user to be logged on as system administrator. (For information about logging on as SA, see Logging in and Logging Off.) Other topics discussed in this documentation are relevant to database owners and database object owners. No special login identification is needed for database or database object owners.

There are also three special login IDs¾probe, repl_publisher, and repl_subscriber¾that, depending on the server configuration, can exist by default on a server.

  • When SQL Server is installed, the probe login ID is automatically created. This is a special login ID that is installed by the setup program and is used as the security context within which some administrative applications (for example, SQL Performance Monitor) connect to a SQL Server that is configured for standard security. Note that if a SQL Server is set up for integrated security, sa is used for this purpose, instead of probe.
  • When a server is configured to participate in replication as a subscription server, the repl_publisher login ID is automatically created. It allows replication processes on the distributor (which may be a separate distribution server, or a combined publication/distribution server) to connect to the subscription server and replicate table schema and data to destination databases.
  • When a server is configured to participate in replication as a publication server, the repl_subscriber login ID is automatically created. It allows replication processes on a subscription server to connect to the publication server and execute stored procedures.

The probe, repl_publisher and repl_subscriber login IDs should not be modified, nor should users use them to log in.

For in-depth information about system administrators, database owners, and database object owners, and the probe, repl_publisher and repl_subscriber login IDs, see Part 4, Security.


Getting Started with SQL Server

To administer SQL Server, you must start it and¾if required by the server security mode selected¾provide a login ID and password to log in. The following topics will help you get started quickly. For more in-depth information, see Microsoft SQL Server Setup.

For information, choose one of the following topics.

Running SQL Server

Logging In and Logging Off

Shutting Down SQL Server


Running SQL Server

There are several ways to start SQL Server and SQL Executive. One easy way is to use SQL Service Manager.

To start SQL Server using SQL Service Manager
  1. From the Microsoft SQL Server 6.0 program group, start SQL Service Manager.

  2. If the service is a remote service, select or enter the remote server name in the Server box, and then choose the Connect button.

    This connects you to the remote server and fills the Service box with the names of the SQL Server services that are registered on the remote computer. Note that the Server box appears only if the Remote Control option on the System menu (in the upper left-hand corner of the window) is turned on.

  3. In the Services box, select MSSQLServer or SQLExecutive.

    MSSQLServer is the service for SQL Server. SQLExecutive is the service for SQL Executive. The current state of the service is indicated by the light on the traffic signal and by a status message in the status bar.

  4. Double-click the green Start/Continue light.

    The selection¾ MSSQLServer or SQLExecutive¾starts as a service under the Windows NT Service Control Manager using the default startup options written to the Windows NT Registry by the setup program.

SQL Server (MSSQLServer) can also be paused, continued, and stopped using the same procedure used to start the service, but instead selecting the yellow light to pause the service, the green light to continue a paused service, or the red light to stop the service. SQL Executive can be started and stopped this way, but not paused or continued.

For information about other ways to start SQL Server and SQL Executive, see Microsoft SQL Server Setup.


Logging In and Logging Off

If the server is set up to use integrated security (as described in Chapter 3, Configuring Servers), you will not need to supply a login ID or password (and if you do supply them, they will be ignored by SQL Server).

If the server is not set up to use integrated security, after you start the server computer, you must log in to SQL Server to administer it. When using the graphical management tools provided with SQL Server, if a login is required the application will prompt you to supply the server name, a login ID, and a password. When using the isql utility, log in as described in the following procedure.

To log in to a SQL Server using isql

From the command line, type: isql /U login_id /P password /S servername

where

login_id
Is the login identification. Use sa the first time you log in. Depending on how you set up the sort order when you installed SQL Server, the login ID might be case-sensitive. For more information, see Microsoft SQL Server Setup.
password
Is the login password. The first time you log in as sa there is no password.
servername
Specifies which server you want to log in to.

For the full syntax of the isql utility, see the Microsoft SQL Server Transact-SQL Reference. For information about logging on using the graphical administrative tools provided with SQL Server, see the online Help for each application.

The first time you log in to a newly installed SQL Server, use sa as your login identification and no password. After you log in, change the SA password to prevent other users from using the system administrator's privileges. You can change your own password, and the SA can change any user's password, by using SQL Enterprise Manager or sp_password. For information on changing the SA password, see Chapter 3, Configuring Servers. or the Microsoft SQL Server Transact-SQL Reference.

You log off from SQL Server by exiting the application you are using to administer it.


Shutting Down SQL Server

There are several ways to stop SQL Server and SQL Executive. One easy method is to use SQL Service Manager.

Before you shut down SQL Server, it's a good idea to first pause the SQL Server service and then broadcast a message that SQL Server will be stopped. Pausing prevents additional user connections from being established. Give users enough time to exit their current tasks, and then shut down SQL Server. For information about broadcasting a shutdown message, see Microsoft SQL Server Setup.

You should shut down SQL Executive before shutting down SQL Server.

To shut down SQL Server or SQL Executive using SQL Service Manager
  1. From the Microsoft SQL Server 6.0 program group, start SQL Service Manager.
  2. To stop services on a remote SQL Server, in the Server box, select or enter the name of the remote server and then choose the Connect button.
  3. From the Service box, select MSSQLServer or SQLExecutive.
  4. If you are stopping SQL Server, double-click the yellow Pause light to pause the service, and then send a message informing connected users that the server will soon be shutting down. After an appropriate interval, proceed to step 5.

    If you are stopping SQL Executive, skip this step and proceed to step 5.

  5. Double-click the red Stop light.

    The service stops.

For information about other ways to start, pause, continue, and stop SQL Server and SQL Executive, see Microsoft SQL Server Setup.


SQL Server Capacities

The following table lists the system limits for various SQL Server objects. These are the set limits for SQL Server. Practical limits may often be less and will vary by application.

Object | Limits
Devices | 256 devices per SQL Server. Maximum size for each logical device is 32 gigabytes (GB). (1)
Databases | 32,767 databases. The minimum database size is 1 MB. The maximum database size is 1 terabyte (TB). (2)
Tables | 2 billion tables per database. The maximum number of bytes per row is 1962 (excluding text and image columns). The maximum table size is about 1 TB.
Columns | 250 columns per table.
Indexes | 1 clustered index per table. 249 nonclustered indexes per table. A composite index can have up to 16 columns.
Triggers | Maximum of three triggers per table ¾ one each for INSERT, UPDATE, and DELETE. Triggers can have 16 levels of nesting.
Stored procedures | A stored procedure can contain as many as 255 parameters and have up to 16 levels of nesting.
User connections | 32,767 (3)
Open databases | 32,767
Locks | 2 billion (2,147,483,647)
Open objects | 2 billion (2,147,483,647)
(1) The maximum total addressable storage is 8 TB (256 devices * 32 GB maximum per device).

(2) Each logical device can be a maximum of 32 GB, and each database can have a maximum of 32 device fragments (32 GB * 32 = 1 TB).

(3) For Microsoft SQL Server 6.0. Microsoft SQL Workstation 6.0 has the same capabilities as Microsoft SQL Server, except that it is a single-user licensed product that supports a maximum of 15 simultaneous database connections.


Chapter 2 Introducing the SQL Distributed Management Framework

Introducing the SQL Distributed Management Framework

The SQL Distributed Management Framework (SQL-DMF) is an integrated framework of objects, services, and components used to manage Microsoft SQL Server. SQL-DMF provides a flexible and scaleable management framework that is adaptable to your specific needs. SQL-DMF lessens the need for user-attended maintenance tasks¾such as database backup and alert notification¾by providing services that interact directly with SQL Server.

All the key components of SQL-DMF are core elements of SQL Server. SQL-DMF allows you to proactively manage the SQL Servers in your enterprise by allowing you to define scenarios and corrective actions and trigger either alerts to notify someone of the problem or tasks to correct the problem.

At its most basic level, SQL-DMF provides direct access to the SQL Server engine and services from the command line through Transact-SQL. The second tier of the framework is a set of distributed management objects (DMOs) that provides an object interface to the SQL Server engine and services. The top level of the framework is a graphical administration tool, SQL Enterprise Manager, which provides you with an easy way to manage a multiple-server environment. The framework also provides services for replication, scheduling, and alerting.

Command-line access to the SQL Server engine and services is through Transact-SQL, an enhanced version of SQL (structured query language). Using Transact-SQL, you can perform administrative tasks such as creating devices and databases. You can also insert, update, and delete data stored in SQL Server. For an overview of using Transact-SQL, see Microsoft SQL Server Database Developer's Companion. The Transact-SQL language is fully documented in Microsoft SQL Server Transact-SQL Reference.

The distributed management objects (DMOs) are 32-bit OLE objects and expose interfaces for all SQL Server management functions. DMO provides over 60 objects and over 1000 properties and methods. SQL Server functions exposed through DMO include system stored procedures, system catalogs, Transact-SQL statements, extended stored procedures, and scheduling, alert, and replication commands. DMO is fully documented in Microsoft SQL Server Programming SQL OLE Objects. The DMO objects support OLE automation, which allows their use with Visual Basic 4.0 or the Visual Basic for Applications environment (available with products such as the 32-bit version of Microsoft Excel).

Microsoft SQL Enterprise Manager provides an intuitive, graphical user interface that enables you to easily manage Microsoft SQL Servers across an enterprise. Using SQL Enterprise Manager you can perform SQL Server management tasks, such as creating devices and databases; backing up and restoring databases; performing queries; managing replication, alerting, and scheduling tasks; and much more.

The rest of this chapter provides an overview of SQL Enterprise Manager. For detailed information about how to use SQL Enterprise Manager features, see online Help.

For more information, see Microsoft SQL Enterprise Manager.


Microsoft SQL Enterprise Manager

Microsoft SQL Enterprise Manager is a graphical tool¾included as part of Microsoft SQL Server 6.0¾that provides an intuitive way to administer SQL Servers enterprise-wide.

SQL Enterprise Manager provides powerful administration tools for managing multiple servers. A new scheduling engine enables you to schedule tasks to run automatically at a specified time, completely unattended. A new alert engine enables you to set alerts for various SQL Server events and either notify someone, through email or paging, or automatically execute a task. Additionally, a replication service enables you to set up and administer replication for SQL Servers across your network.

SQL Enterprise Manager is installed by the setup program as part of the server software on Windows NT-based computers, and as part of the client software on Windows NT- and Windows 95-based computers. (Because SQL Enterprise Manager is a 32-bit application, it cannot be installed on computers running 16-bit operating systems.) You start SQL Enterprise Manager by choosing its icon from the Microsoft SQL Server 6.0 program group.

When you start SQL Enterprise Manager, it looks like this:

Anyone who can access SQL Server can use SQL Enterprise Manager; no explicit permission is needed. Access to the objects and tasks within SQL Enterprise Manager is controlled by the permissions of the login identification. If the user logs in as system administrator (SA), then that user can access all tasks and objects. If a user is the database owner (DBO), then that user can access those tasks and objects the DBO has permission for. Any user can access all objects he or she has created and perform whatever other tasks he or she has permission for.

With SQL Enterprise Manager you can:

  • Configure SQL Server
  • Start, pause, resume, and stop servers
  • Create and manage devices and databases
  • Manage database objects (everything from tables and views to user-defined datatypes)
  • Set up alerts
  • Create and schedule tasks
  • Set up and manage replication
  • Execute and analyze queries
  • Back up and restore databases
  • Generate SQL scripts
  • Manage object and statement permissions
  • Manage server login IDs and database users
  • View object dependencies
  • Monitor current server activity
  • View the SQL Server error log

You can administer these SQL Server tasks using the menus in SQL Enterprise Manager or the toolbar buttons. When you point to a button and pause for a moment, the name of the button appears in a ToolTip, as shown here for the Replication - Publishing button.

For more information, see The Server Manager Window.


The Server Manager Window

The Server Manager window in SQL Enterprise Manager makes it easy to navigate through your servers and the objects on those servers. At the top level, servers are arranged into groups. If you:

  • Click the plus (+) sign beside a group name, a list of servers appears.
  • Click the plus (+) sign beside a server name, a list of the objects and services on that server appears.
  • Click the plus (+) sign beside a folder, a list of the objects and services in that folder appears.

By clicking the plus (+) or minus ( - ) sign, you can expand and collapse lists. Certain menu items are available only if the corresponding object is selected in the Server Manager. For example, you cannot manage a server until it is selected in the Server Manager window. You cannot manage any database objects until you have selected a database in the Server Manager window.

In addition to using the menus or toolbar buttons, you can also proceed directly to the tasks to perform for a given object by clicking the object with the right mouse button. A menu appears adjacent to the object, as illustrated here.

By using the Server Manager window, you can see the status of the servers at a glance. The lights in the stoplight icon for each server indicate whether that SQL Server is started, paused, or stopped. (However, status is only displayed when SQL Enterprise Manager is installed on a Windows NT-based computer. It is not displayed for a Windows 95-based computer.) A red zigzag next to the stoplight indicates a server that you are currently connected to. At the database level, various database icons indicate that the database is suspect or in single-user or read-only mode.

Choosing the Display Legend button in the Server Manager window displays a legend that defines what each Server Manager icon indicates.

For more information, see Getting Started with SQL Enterprise Manager.


Getting Started with SQL Enterprise Manager

The first time you start SQL Enterprise Manager, the Register Server dialog box appears.

You must provide the name of one or more SQL Servers that you will be managing using SQL Enterprise Manager. Each time you enter a new server name, you must complete the login information.

  • After you enter a server name, select either Use Standard Security or Use Trusted Connection. This choice determines the type of security that will be used for the connection when SQL Enterprise Manager connects¾as a client¾to that server. The preferred option for security is to use a trusted connection, where Window NT security validates the user and a password does not need to be stored at the client.
  • If you selected Use Standard Security, in the Login ID box type the login ID of a valid administrative account (such as SA) for that server; and in the Password box type the password for that login ID. If you selected Use Trusted Connection, the login ID and password are unnecessary.

Note The Use Trusted Security option is recommended, since it allows SQL Enterprise Manager to connect without storing a password.

When you register a server, you can also create a group for that server to be a member of, or you can assign that server to a group that already exists. Server groups help you organize the servers of your enterprise. Typical server groups might include development, production, marketing, and so on.

Once you have registered a server, it appears in the Server Manager window each time you start SQL Enterprise Manager. You can immediately begin to perform tasks for that server using SQL Enterprise Manager. Initial administration tasks that you might want to perform include:

  • Verifying that all SQL Server configuration options are set appropriately
  • Creating devices and databases
  • Creating login IDs
  • Configuring the SQL Server for replication

For more information, see the online Help for SQL Enterprise Manager.


Part 2 Configuration

Configuration

SQL Server provides setup programs that largely automate the installation of server software and client software. In most cases, you will be able to use the server or client software immediately after installing it. However, there are a number of configuration tasks that can be performed after installation to optimize a server or client for your particular network, database, and business environments. The following chapters discuss these configuration tasks.

Chapter 3, Configuring Servers, explains how to fine-tune SQL Server for your particular environment. This chapter shows you how to do such things as set the system administrator's password, set server options and configuration options, configure network support, add a language, set relevant operating system options, assign a user account to SQL Executive, view server attributes, and rebuild the master database.

Chapter 4, Configuring Clients, explains how to configure client software after it has been installed. This chapter shows you how to display the DB-Library version currently installed on the client, set the client's default Net-Library, and set up server connection information on the client. It also provides information about each of the available Net-Libraries.


Chapter 3 Configuring Servers

Configuring Servers

Because the SQL Server setup program provides intelligent defaults for SQL Server, you are able to run SQL Server immediately after installing it. However, there are a number of configuration tasks that can be performed after installation to fine-tune SQL Server for your particular environment. You can register the server with SQL Enterprise Manager, change the SA password, set the configuration options, set the server options, add support for additional network protocols, add support for a language, set the Windows NT options for the server, add Registry keys, and more.

In particular, after installing a server you will usually¾at a minimum¾perform these tasks:

  • Register the server with SQL Enterprise Manager (as described in Registering a Server with SQL Enterprise Manager, later in this chapter.)
  • Configure the SQL Server memory option (usually, the most important configuration option you will set, described in Setting the Memory Option, later in this chapter.)

Depending on the requirements of your installation, there are a number of other configuration tasks you can perform for a new server. You may also find it necessary to alter configuration settings for an existing server. This chapter explains how.

For more information about configuring servers, choose one of the following topics:

Registering a Server with SQL Enterprise Manager

Assigning an SA Password

Setting Configuration Options

Setting Server Options

Changing Network Support

Viewing Server Attributes

Adding a Language

Setting Windows NT Options on the Server

Rebuilding the Master Database

Adding Registry Keys

Assigning a Service Account to SQL Server or SQL Executive

Note that other parts of this documentation cover additional configuration tasks you could perform for a newly installed server. For example:

  • Setting up login security and adding users are documented in Part 4, Security.
  • Scheduling the automatic initiation of tasks, managing alerts, and using SQLMail (including information about setting up a SQLMail post office) are documented in Part 7, Other Operations.
  • Setting up and managing replication is documented in Part 6, Replication.


Registering a Server with SQL Enterprise Manager

To be administered by SQL Enterprise Manager, a server must first be registered with SQL Enterprise Manager. Registering a server provides SQL Enterprise Manager with the server name and tells SQL Enterprise Manager which server group the server belongs to. Once it is registered, a server is listed in SQL Enterprise Manager's Server Manager window.

When a new installation of SQL Enterprise Manager, is run for the first time, SQL Enterprise Manager automatically prompts you to register servers. All subsequent times you run SQL Enterprise Manager, to register servers you must follow the instructions provided in the following topics.

For more information, choose one of the following topics:

Creating Server Groups

Registering Servers


Creating Server Groups

When you register a server with SQL Enterprise Manager, you must place it in one of SQL Enterprise Manager's server groups. Server groups provide a convenient grouping of servers for administrative purposes. For example, if your duties include database backup responsibilities, you might create a server group and then to that group add all the servers you have backup responsibility for.

By default, SQL Enterprise Manager is installed with a server group named SQL 6.0, but you can create other server groups. It is a good idea to create server groups before you register servers.

To create server groups
  1. From the Microsoft SQL Server 6.0 program group, start SQL Enterprise Manager.

    Note If this is a new installation, the first time you run SQL Enterprise Manager it automatically opens the Register Server dialog box and prompts you to register servers. If so, from that dialog box choose the Server Groups button, and skip step 2.

  2. From the Server menu choose Server Groups.

    The Manage Server Groups dialog box appears.

  3. In the Name box, type a unique name for the new group.
  4. Select either Top-Level Group or Sub-Group of.

    This specifies whether the group will appear at the top level of the tree in the Server Manager window, or as a sub-group of another server group. If appropriate, you can create many sub-group levels.

  5. If you selected Sub-Group of, then from the list of groups select the parent group (the group this group will be a sub-group of).

    If you selected Top Level Group, skip this step.

  6. Choose Add Group.
  7. Repeat steps 3-6 for each server group you need to create.

For security reasons, SQL Enterprise Manager server groups are private and are created only at the local computer (the computer that is running SQL Enterprise Manager). If you have several computers that have SQL Enterprise Manager installed, and if you would like those computers to display identical server groups, then you must go to each computer that has SQL Enterprise Manager installed and create those groups by performing the preceding procedure. (Or, to duplicate a SQL Enterprise Manager server registration configuration, you could copy the \SQL60\BINN\SERVERS.BIN file from one computer to another.)

For more information about creating, managing, and using server groups, see the SQL Enterprise Manager online Help.


Registering Servers

When registering a server with SQL Enterprise Manager, you register it at the computer that has SQL Enterprise Manager installed. This is done because login information must be stored locally on each computer that will use SQL Enterprise Manager. You cannot do this remotely.

This means, for example, that if six computers have SQL Enterprise Manager installed, and if you want all six installations of SQL Enterprise Manager to be able to administer a newly installed server, at each of those six computers you must start SQL Enterprise Manager and use the following procedure to register the new server.

The server name used by SQL Server is taken from the computer's name. Before registering a server, make sure that the server's computer name is a valid SQL identifier. The first character can be alphabetic or an underscore (_). Characters following the first character can include letters, numbers, or the symbols #, $, or _. No embedded spaces are allowed.

If other characters are used in the computer name, rename the computer. (It is best to do this before installing SQL Server.). For instructions on renaming computers, see your documentation for Windows NT. Also, if the computer is a member of a Windows NT domain, contact your network administrator to have the new computer name added to the domain.

To register a server with SQL Enterprise Manager
  1. From the Microsoft SQL Server 6.0 program group, start SQL Enterprise Manager.

    If this is a new installation, the first time you run SQL Enterprise Manager it automatically opens the Register Server dialog box and prompts you register servers. If so, skip step 2 and proceed directly to step 3.

  2. From the toolbar choose the Register Server button. Or from the Server menu choose Register Server. Or click the right mouse button on the server name, and from the drop-down menu that appears choose Register Server.

    The Register Server dialog box appears.

  3. In the Server box, type the server name of the SQL Server to be registered. Or choose the List Servers button and select the server from the Select Server dialog box that appears.
  4. Select either Use Standard Security or Use Trusted Connection. This choice determines the type of security that will be used for the connection when SQL Enterprise Manager connects¾as a client¾to the SQL Server that is being registered.

    The preferred option for security is to use a trusted connection, where Windows NT security validates the user. (This requires integrated or mixed security. For information, see Chapter 8, Security Concepts.

  5. If you selected Use Standard Security, in the Login ID box type the login ID of a valid administrative account for that server, and in the Password box type the password for that login ID. The SA account and password can be used.

    If you selected Use Trusted Connection, skip this step.

  6. Select or clear the Display Server Status In Server Manager option, which allows server status (started, paused, or stopped) to be displayed in the Server Manager window.

    This turns service polling on and off (using the Windows NT Service Control Manager). By default, this option is selected.

  7. Select a Server Group.

    The server will become a member of this group. The default group is SQL 6.0, although you have the option of creating additional groups. You can change a server's group at any time.

    If the group you need does not yet exist, create it by choosing the Server Groups button, and complete the Manage Server Groups dialog box that appears. For more information, see Creating Server Groups, earlier in this chapter.

  8. Choose Register.
  9. Repeat steps 3-8 for each server to be registered with this copy of SQL Enterprise Manager.

For more information about registering servers, see the SQL Enterprise Manager online Help.


Assigning an SA Password

Initially, there is no password for the system administrator. After a server is installed, you should assign a password to SA immediately. Do not forget it. If you forget the SA password, you must reinstall SQL Server.

It is not necessary to assign an SA password if the server is set for integrated security only. However, it is recommended that you assign an SA password if the server is set for standard or mixed security. For a discussion of each type of security, see Chapter 8, Security Concepts.

The first time you log in to a newly installed SQL Server, use sa as your login identification and no password. After you log in, use SQL Enterprise Manager or sp_password to change the SA password to prevent other users from using the system administrator's privileges.

If the server is already registered with SQL Enterprise Manager, you can use that tool to change the SA password.

To use SQL Enterprise Manager to change the SA password on a newly installed server
  1. Start SQL Enterprise Manager, and from the Server Manager window, select the server for which you will modify the SA password.
  2. From the Server Manager window, open the Logins folder for that server.

    The logins for that server are listed.

  3. Double-click the SA login ID.

    The Manage Logins dialog box appears, displaying information about the SA login ID.

  4. In the Password box, type the new password, and then choose Modify.

    The Confirm Password dialog box appears.

  5. In the Confirm New Password box, type the new password.
  6. Choose OK.

    The SA password is changed.

You can also use sp_password to change the SA password. Type:

sp_password old_password, new_password [, login_id]

For example, to change the SA password to "rover" on a newly installed server, type:

sp_password null, rover, sa

For more information about sp_password, see the Microsoft SQL Server Transact-SQL Reference.

For more information about the settings you can modify for a login ID, see Part 4, Security.


Setting Configuration Options

SQL Server configuration options control various aspects of SQL Server performance and memory allocation. If you find that you need to adjust the SQL Server configuration, you can reset some of the configuration options to fine-tune performance and refine storage allocation. For example, for a new installation you will usually want to adjust the SQL Server memory option.

For more information choose one of the following topics:

Setting the Configuration Options

Configuration Options and Values


Setting the Configuration Options

Configuration options are displayed and managed by using either SQL Enterprise Manager or the sp_configure system procedure. For information about using sp_configure, see the Microsoft SQL Server Transact-SQL Reference. For information about using SQL Enterprise Manager, see the instructions that follow.

Note There are two types of configuration options: standard and advanced. Advanced options should be changed only under very special and usually rare circumstances. Advanced options are displayed and can be managed only when show advanced option has been set to 1.

To display or set the configuration options
  1. From the Microsoft SQL Server 6.0 program group, start SQL Enterprise Manager.
  2. From the Server Manager window, open a server group and select a server.
  3. From the Server menu, choose Configurations.
  4. From the Server Configuration dialog box, choose the Configuration tab.

    The Configuration window displays a list of the configuration options.

  5. To display information about a listed option, select the option.

    The current setting of the option appears in the Running column. An explanation of the option appears in the Description box.

  6. To change an option, select the Current box for that option, and then type the new value. Repeat as necessary for each option to be changed.

    For a list of the available configuration options, their minimum and maximum acceptable values, and their default settings, see Configuration Options and Values, later in this chapter. For detailed information describing each configuration option and discussing the effects of changing its value, see the sp_configure System Stored Procedure in the Microsoft SQL Server Transact-SQL Reference.

  7. To apply a change immediately, choose the Apply Now button.
  8. When you finish setting the options, choose the OK button.

    Note that some options take effect immediately, whereas others require the server to be restarted. For more information, see the Microsoft SQL Server Transact-SQL Reference.

For more information about each of the standard and advanced configuration options, see sp_configure System Stored Procedure in the Microsoft SQL Server Transact-SQL Reference.

For more information about setting the memory and tempdb in RAM options, see Setting the Memory Option and When to Use Tempdb in RAM, later in this chapter.


Configuration Options and Values

The following table lists each configuration option, its minimum and maximum acceptable value, and its default setting.

Many configuration options are considered advanced and should be changed only under very special and usually rare circumstances. Advanced options are displayed or managed only when show advanced option is set to 1. Standard options are shown in bold type and advanced options are shown in plain type.

Dynamic options are noted with an asterisk (*). A new setting for a dynamic option takes effect immediately. A new setting for a non dynamic option takes effect after the server is restarted.

Option Name | Minimum Value | Maximum Value | Default Value

allow updates* | 0 | 1 | 0
backup buffer size* | 1 | 10 | 1
backup threads | 0 | 32 | 5
cursor threshold* | -1 | 2147483647 | -1
database size | 1 | 10000 | 2
default language | 0 | 9999 | 0
default sortorder id | 0 | 255 | 52
fill factor | 0 | 100 | 0
free buffers* | 20 | 524288 | 204
hash buckets | 4999 | 26500 | 7993
language in cache | 3 | 100 | 3
LE threshold maximum* | 2 | 500000 | 200
LE threshold minimum* | 2 | 500000 | 20
LE threshold percent* | 1 | 100 | 0
locks | 5000 | 2147483647 | 5000
logwrite sleep (ms)* | -1 | 500 | 0
max async IO | 1 | 255 | 8
max lazywrite IO* | 1 | 255 | 8
max worker threads* | 10 | 1024 | 255
media retention | 0 | 365 | 0
memory | 1000 | 1048576 | 4096
nested triggers* | 0 | 1 | 1
network packet size* | 512 | 32767 | 4096
open databases | 5 | 32767 | 20
open objects | 100 | 2147483647 | 500
priority boost | 0 | 1 | 0
procedure cache | 1 | 99 | 30
RA cache hit limit* | 1 | 255 | 4
RA cache miss limit* | 1 | 255 | 3
RA delay* | 0 | 500 | 15
RA pre-fetches* | 1 | 1000 | 3
RA slots per thread | 1 | 255 | 5
RA worker threads | 0 | 255 | 3
recovery flags | 0 | 1 | 0
recovery interval* | 1 | 32767 | 5
remote access | 0 | 1 | 1
remote login timeout* | 0 | 2147483647 | 5
remote query timeout* | 0 | 2147483647 | 0
resource timeout | -1 | 2147483647 | 10
set working set size | 0 | 1 | 0
show advanced option* | 0 | 1 | 0
SMP concurrency | -1 | 64 | 0
sort pages* | 50 | 511 | 64
spin counter* | 1 | 2147483647 | 10000
tempdb in ram (MB) | 0 | 2044 | 0
user connections | 5 | 32767 | 20
* Dynamic option.

For detailed information describing the configuration options and discussing the effects of changing the values, and for information about using sp_configure, see sp_configure System Stored Procedure in the Microsoft SQL Server Transact-SQL Reference.

For more information about setting the memory and tempdb in RAM options, see Setting the Memory Option, and When to Use Tempdb in RAM, later in this chapter.


Setting the Memory Option

When you install SQL Server, the setup program assigns 8 MB of memory to SQL Server if the computer has less than 32 MB of RAM, and 16 MB of memory if the computer has 32 MB or more of RAM. After installation, you can and often should manually configure memory to a greater amount.

In particular, you must set the SQL Server memory option appropriately for servers that will be participating in replication. If a server will act as either a remote distribution server or a combined publication/distribution server, it must have at least 32 MB of memory installed, with at least 16 MB assigned to SQL Server. If a remote distribution server will be set up to perform distribution for more than one publication server, the remote distribution server will require additional memory (and additional available disk space). There are no special memory or other hardware requirements for subscription servers or for publication servers that are configured to use a remote distribution server. For more information on replication, see Part 6, Replication.

Note As you increase the SQL Server memory configuration, you need to ensure that there is sufficient disk space to grow the virtual memory support file (PAGEFILE.SYS) to accommodate the additional memory. For information on the virtual memory support file, see your documentation for Windows NT.

The memory option is set in the same manner as any other configuration option, by using SQL Enterprise Manager.

To set the memory option
  1. From the Microsoft SQL Server 6.0 program group, start SQL Enterprise Manager.
  2. From the Server Manager window, open a server group and select a server.
  3. From the Server menu, choose Configurations.
  4. From the Server Configuration dialog box, choose the Configuration tab.

    The Configuration window displays a list of the configuration options.

  5. Select the memory option, and then type the new setting in the Current box.

    The current setting of the option appears in the Running column. The displayed number represents the size of available memory in 2K units. (For example, 8 MB is entered as 4096.) For more information, see the discussion following this procedure.

  6. Review and change other options as appropriate.
  7. Choose the OK button.

    The setting is changed, but it does not take effect until the server is restarted.

  8. From the toolbar, select the Stop/Pause/Start Server button.
  9. If there are users connected to this server, double-click the yellow lamp to pause the server, and then send a message to connected users that the server will soon be shutting down. After an appropriate interval, proceed to the next step.

    If there are no connected users, skip this step.

  10. Double-click the red lamp to stop the server, and then after the status text indicates the server has stopped, double-click the green lamp to restart the server.

To determine the optimal memory for your system, subtract the memory required for Windows NT (and other system uses, if the machine is not wholly dedicated to SQL Server) from the total physical memory. Ideally, you want to allocate as much memory as possible to SQL Server without causing the system to page. You can use SQL Performance Monitor to help determine what the threshold is for your system: the Page Faults/sec counter of the Memory Object indicates whether you are generating any page faults. If so, SQL Server is running with too much memory. The threshold varies depending on your system. For example, on a 32-MB system, 16 MB might be appropriate for SQL Server; on a 64-MB system, 40 MB might be appropriate.

The amount of memory specified must be sufficient for the SQL Server static memory needs (kernel overhead, user stack space, and so on), as well as for the procedure cache and the data cache (also called buffer cache). The memory left over after the SQL Server memory needs are met is divided between the procedure cache and the data cache. The percentage allocated to the procedure cache is set with the procedure cache configuration option. You can use DBCC MEMUSAGE and statistics from SQL Performance Monitor to help you adjust this value. Change this value only when you add or remove memory or when you change how you use your system.

When the memory option is reconfigured, this will automatically cause a possible change to the configured free buffers configuration option. The free buffers configuration value will be set to 5% of the new memory size.

The maximum value for the memory option is 2 GB. Note, however, that the memory option does not include memory needs for tempdb if you have placed tempdb in RAM using the tempdb in ram (MB) option.

For information about using SQL Performance Monitor, see Chapter 19, Monitoring Server Activity and Performance. For more information about allocating memory to SQL Server, see More About Memory, next in this chapter.

You can also display and change the memory option by using sp_configure. For information about using sp_configure to set the configuration options, see sp_configure System Stored Procedure in the Microsoft SQL Server Transact-SQL Reference.


More About Memory

This topic discusses the amount of memory that should be allocated to SQL Server in various machine memory configurations.

Microsoft Windows NT provides each Win32 application a 4-GB virtual address space, the lower 2 GB of which is private per process and available for application use. The upper 2 GB is reserved for system use.

The 4-GB address space is mapped to the available physical memory by the Windows NT Virtual Memory Manager (VMM). The available physical memory can be up to 4 GB, depending on hardware platform support.

A Win32 application such as SQL Server only perceives virtual or logical addresses, not physical addresses. How much physical memory an application uses at a given time (the working set) is determined by available physical memory and the VMM. The application cannot directly control memory residency.

Virtual address systems such as Windows NT allow the over committing of virtual memory, such that the ratio of virtual to physical memory exceeds 1:1. As a result, larger programs can run on machines with a variety of physical memory configurations. However, in most cases, using significantly more virtual memory than the combined average working sets of all the processes will result in poor performance.

For better performance, SQL Server "locks" memory and tempdb (if using tempdb in ram) as a working set. Because of this, it is possible for you to receive "out of memory" errors when running other applications. The set working set size parameter (set with sp_configure or SQL Enterprise Manager) can disable the "locking" of memory as a working set. If "out of memory" errors occur, you may have too much memory assigned to SQL Server.

Configuring SQL Server for more virtual memory than there is physical memory can result in poor performance. Also, the Windows NT operating system memory requirement must be considered (about 12 MB with some variation depending on application-induced overhead). This system overhead requirement can grow as SQL Server parameters are configured upward and Windows NT needs more resident memory to support such things as additional threads, page tables, and so on.

This results in a varying amount of memory that can be given to SQL Server, depending on the machine memory configuration. The following table presents a rough figure of this and assumes a dedicated database server. If the machine is shared between multiple uses, such as a file server, a database server, and a client workstation, less memory should be given to SQL Server and more left for the operating system and other uses.

Machine memory (MB) | Approximate SQL Server memory allocation (MB)
16 | 4
24 | 8
32 | 16
48 | 28
64 | 40
128 | 100
256 | 216
512 | 464

Note These are only rough figures and are presented to give an approximate idea of SQL Server memory allocation over different memory states. For more information, you can use the many monitoring features of SQL Performance Monitor to determine your system memory behavior. Another good source of information is Optimizing Windows NT, from the Windows NT Resource Kit, which devotes nearly 600 pages to various aspects of monitoring and optimizing Windows NT and Win32 applications.

16 MB is the minimum available memory for SQL Server on Intel-based computers. SQL Server on Alpha AXP- and MIPS-based computers will require more memory because of the average lower density of RISC machine instructions. However, considering the overall software, hardware, application, and personnel investment in typical client/server systems, adding more memory is usually a wise (and by comparison inexpensive) investment. Many sites report that 32 MB is a good starting point, and it is not uncommon for servers to be configured for 128 MB or more memory, which they put to beneficial use.

The point at which additional memory fails to provide worthwhile benefits is entirely situation-dependent and is determined primarily by the locality of reference of the database accesses. The important point to remember is that memory increases that are small as a percentage of total memory rarely afford any significant benefit. Two things control this point:

  • SQL Server uses extra memory primarily as buffer cache
  • Most cache hit ratio studies indicate a fairly flat curve beyond several megabytes

For this reason, whether 14 MB, 16 MB, or 18 MB is given to SQL Server on a 32 MB computer will rarely make a significant difference in SQL performance. Conversely, attempting to crowd Windows NT by giving excessive memory to SQL Server can result in poor performance because of excessive paging.

The implication is that you should add physical memory to the machine in significant amounts before allocating this to SQL Server. Whether adding memory will be beneficial should be studied beforehand. The easiest way to determine this is by using SQL Performance Monitor to check the SQL Server cache hit ratio while the system is under a typical load. If the hit ratio is relatively high (over 90%), adding more memory will usually not be beneficial. This is because additional memory can mainly be used for additional SQL Server data cache, thereby increasing the hit ratio. In this case, the hit ratio is already high, and the maximum available improvement quite small.

If the hit ratio is consistently lower than this, adding more memory may improve the hit ratio (and thereby performance) if the locality of reference is such that it can be bracketed by economically or technically feasible amounts of memory.

For more information about SQL Performance Monitor, see Chapter 19, Monitoring Server Activity and Performance.


When to Use Tempdb in RAM

The temporary tempdb database is used for work space in sorting and for creating temporary tables in some join operations. Microsoft SQL Server provides a powerful option, tempdb in RAM, which allows the tempdb to be made entirely memory resident. In some specific situations, this can provide a performance advantage. However if tempdb in RAM is used inappropriately, it can consume memory that would otherwise be used for the SQL Server cache buffer system, and this can hurt performance.

In most cases, the available RAM is best used as a data cache, rather than as the location of tempdb. Data in tempdb will itself be cached using the SQL cache buffer system's LRU algorithm.

This is analogous to the decision of using a RAM disk versus using the smartdrive cache program on a Microsoft Windows workstation. In this case, the RAM consumed for the RAM disk is unavailable for smartdrive and can only be used for objects specifically placed on the RAM disk. In a few cases where your knowledge of the application environment is such that you know that most access is to a few files, and if they are small enough to fit on the RAM disk, and if your remaining disk accesses have such poor reference locality that no feasible amount of cache will provide a good hit ratio, then a RAM disk might be superior to smartdrive. However, in most cases smartdrive will be superior, since it caches all accesses (not just those placed on the RAM disk).

Similarly, use of tempdb in RAM can accelerate tempdb operations but will deplete memory available for the SQL cache buffer, which can lower the cache hit ratio. Memory used for tempdb in RAM is allocated separately from the pool set by the memory option, and the server must be configured appropriately.

For example, if you use 10MB for tempdb in RAM, the memory setting must be reduced by 10MB to free up memory for this. By contrast, giving all available memory to SQL Server (as opposed to setting some aside for tempdb in RAM) can increase the cache hit ratio. The SQL cache buffer system will cache all disk I/O operations, including tempdb.

Because of the limited amount of RAM available on many machines, this will constrain the available size of tempdb when used in RAM. If unforeseen growth requirements for tempdb materialize, this could be a problem. If this is a concern, it is better to leave tempdb as part of the regular data cache, which will have the effect of keeping the most active pages in RAM.

Using available RAM for the SQL cache buffer system is usually better than using a large chunk of it for tempdb in RAM. However, using tempdb in RAM might be beneficial if all of the following conditions are true:

  • You have a significant amount of available system RAM. This normally would equate to more than 64 MB, with amounts of 128 MB and above more typical.
  • Your applications have a locality of reference such that the SQL Server cache hit ratio is poor, even with a lot of available buffer cache. This hit ratio can be viewed by using SQL Performance Monitor to monitor the Cache Hit Ratio counter in the SQLServer object. For information about using SQL Performance Monitor, see Chapter 19, Monitoring Server Activity and Performance.
  • Your applications do a lot of tempdb operations. Rather than guess whether this is the case, this can be monitored by using sp_lock to observe the lock activity in tempdb while queries are running.

    Or you can monitor tempdb space consumption by issuing this (or a similar) query either interactively or from a looping batch file:

    SELECT SUM(DPAGES) FROM TEMPDB..SYSINDEXES
  • The tempdb operations are sized so that they will fit on the tempdb made possible by your RAM configuration.

If the decision is made to use tempdb in RAM, it is best to objectively verify the performance benefit obtained from this. To do this:

  1. Select a query or small set of queries that typify your most frequently performed tempdb-intensive operations.
  2. Run these several times, noting the execution time.
  3. Reconfigure for tempdb in RAM, run the identical queries, and note the difference.

If the amount of improvement is not worthwhile, it is probably best to give the RAM back to the SQL cache system. Using tempdb in RAM is safe and will not harm database integrity or recoverability. This is because tempdb is only used for intermediate operations and is re-created from scratch upon each server restart.

The tempdb in RAM option is an important performance tool that is available for cases where analysis shows it to be beneficial. In some cases it can provide a significant performance improvement, but it should not be used indiscriminately.


Setting Server Options

The server options include a number of SQL Server options, such as the paths to the SQL Server root directory, master database, and error log; the auto-start settings for SQL Server, SQL Executive, and SQL Mail; support for tape devices; the logging of SQL Server events to the Windows NT log; the mode used by SQL Performance Monitor; and SQL Server startup parameters.

You can set Server options by choosing SQL Setup from the SQL Server program group and following the on-screen instructions. You can also set server options using SQL Enterprise Manager, but in that program a few options (the auto-start option for SQLMail, Windows NT logging, and SQL Performance Monitor integration) are read only and cannot be modified.

For information on using SQL Enterprise Manager to set the server options, see its online Help. For information on using SQL Setup, see the following instructions.

To set server options using SQL Setup
  1. From the Microsoft SQL Server 6.0 program group, start SQL Setup.
  2. Follow the on-screen instructions until the Microsoft SQL Server 6.0 Options dialog box appears.

  3. Select Set Server Options and choose Continue.

    The Select Server Options dialog box appears.

  4. Review and change the options as necessary.

    For information on each option, see the information that follows this procedure.

  5. When you finish configuring the server options, choose the Change Options button.

These are the server options:

Root Directory
Displays the path for the root directory containing SQL Server files.
Master Database Path
Displays the path and filename for the MASTER database device.
Errorlog Path
Displays the path and filename of the SQL Server error log file. By default, setup installs the server to use this log. To prevent this error log from being created, delete this entry. If this entry is blank, a SQL Server error log is not written.

The SQL Server error log contains only SQL Server messages. The SQL Server error log can be viewed by using SQL Enterprise Manager or any text editor. When SQL Server is configured to use its error log, each SQL Server session creates a new log. SQL Server retains the last six logs created.

Auto Start Server at Boot Time
Select this option if you want SQL Server to start automatically whenever the computer starts.
Auto Start Executive at Boot Time
Select this option if you want SQL Executive to start automatically whenever the computer starts.
Auto Start Mail Client
Select this option to automatically start a mail client session when SQL Server is started.
Windows NT Event Logging
Select this option if you want to log SQL Server and SQL Executive events in the Windows NT application log.

The Windows NT application log is a special file that can be viewed only by using the Windows NT Event Viewer. When SQL Server is configured to use the Windows NT application log, each SQL Server session writes new events to that log. (Unlike the SQL Server error log, a new application log is not created each time you start SQL Server.) Note that the Windows NT event log contains messages from all activities on the computer (not just from SQL Server).

Note that if you will be setting up SQL Server alert generation, you must select this option. For information on SQL Server alerts, see Chapter 17, Managing Alerts.

SQL Performance Monitor Integration
This option has two modes, each of which make SQL Server performance statistics available to the Windows NT Performance Monitor. When using either mode, set the Performance Monitor Refresh Interval long enough not to overload SQL Server with requests.
Direct Response Mode
Select this option if you want SQL Server statistics gathering to be performed separately from SQL Server Statistics display. With this option, data is available immediately to the Performance Monitor, and response time is optimized; however, the statistics display is one period behind the statistics retrieved.
On Demand Mode
Select this option if you want the Performance Monitor to request and wait for the latest data from SQL Server during each refresh period. With this option, you get the latest data, but response time for Performance Monitor is not as good as with Direct Response Mode.
xp_cmdshell - Impersonates Client
Select this option to restrict use of xp_cmdshell to users who have administrator privileges on the Windows NT-based computer where SQL Server is running. When this option is selected, only users who have connected to SQL Server via a trusted connection and are members of the local Administrators group on that computer are allowed to use xp_cmdshell.

By default, xp_cmdshell runs in the security context of the server. When this option is selected, the commands run by xp_cmdshell continue to execute in the server's security context.

Parameters
Choose this button to display a dialog box you can use to set SQL Server startup options.
Tape Support
Choose this button to display a dialog box you can use to set the amount of time to wait when trying to read a tape that has not been loaded in the drive.
Mail Login
Choose this button to display a dialog box you can use to provide a mail login name and mail login password. This will allow the system to auto-start the mail client.


Changing Network Support

Microsoft SQL Server uses network libraries, known as Net-Libraries, to pass network packets back and forth between clients and a SQL Server. The Net-Libraries, implemented as dynamic-link libraries (DLLs), perform the network operations required to communicate using a specific protocol. SQL Server includes a set of server Net-Libraries that enable simultaneous connections from clients running named pipes or other interprocess communication (IPC) mechanisms.

By default, SQL Server is installed to use the named pipes Net Library plus any other Net-Libraries you specify during installation. By default, SQL Server listens on the standard pipe, \\.\pipe\sql\query, for named pipes connections. However, if you configure SQL Server to listen on a non-standard named pipe, SQL Executive will not be able to connect to SQL Server locally (which it does by default). You must configure SQL Executive to connect using a specific server name, as described below.

Network support options can be changed after installation by choosing SQL Setup from the SQL Server program group and following the on-screen instructions. You can add Net-Libraries, remove Net-Libraries, and change Net-Library configuration settings.

To change a server's Net-Library support
  1. From the Microsoft SQL Server 6.0 program group, start SQL Setup.
  2. Follow the on-screen instructions until the Microsoft SQL Server 6.0 Options dialog box appears.

  3. Select Change Network Support and choose Continue.

    The Select Network Protocols dialog box appears.

  4. Select or clear the check boxes to determine which network protocols to support on the server.

    When you open this dialog box, the setup program preselects any networks for which server Net-Libraries have already been installed.

    If you deselect a network, the setup program removes the Net-Library from your configuration. All installed Net-Libraries-including named pipes-can be removed. However, if you deselect named pipes, SQL Executive will not be able to connect to SQL Server locally (which it does by default). You must configure SQL Executive to connect using a specific server name, as described below.

  5. Choose the OK button.
  6. A configuration dialog box appears for each selected Net-Library. Follow the on-screen instructions to complete the configuration dialog(s).

    For instructions on completing each Net-Library configuration dialog box, see the setup program's online Help.

To configure SQL Executive to connect to SQL Server using a specific server name, first create a specific server connection entry using the Advanced tab of the SQL Client Configuration Utility. Configure this server entry to connect to the local server using the appropriate Net-Library and connection string. Then set the ServerHost value in the SQL Executive section of the Windows NT Registry to the server entry as follows:

HKEY_LOCAL_MACHINE\
SOFTWARE\
Microsoft\
MSSQLServer\
SQLExecutive\
ServerHost
Type: REG_SZ
Value: server

The Multi-Protocol Net-Library supports optional encryption for both data exchange and user password authentication when communicating over trusted connections. Encryption can be either set at each client or enforced for all clients by the server. Server-enforced encryption automatically encrypts all communication between clients using the client-side Multi-Protocol Net-Library and the server listening on the server-side Multi-Protocol Net-Library.

To configure a server to enforce encryption
  1. From the Select Network Protocols dialog box, select the Multi-Protocol option, and then choose the OK button.

    Configuration dialog boxes appear for each selected network protocol. Complete each until the Multi-Protocol Encryption dialog box appears.

  2. Select the Enable Multi-Protocol Encryption option.
  3. Choose the Continue button.

Server-enforced encryption is supported only by the Multi-Protocol Net-Library. Note that if Net-Libraries for other protocols are also loaded by the server, incoming connections over those Net-Libraries will not use encryption.

When configuring SQL Server to listen on the Multi-Protocol Net-Library, and when using SPX/IPX via NWLink, you also need to install the Windows NT NetWare Gateway services along with the Windows NT SAP Agent.


Viewing Server Attributes

SQL Enterprise Manager can display attribute names and matching values for SQL Server, the database gateway, and the underlying data source.

To use SQL Enterprise Manager to display server attributes
  1. From the Microsoft SQL Server 6.0 program group, start SQL Enterprise Manager.
  2. From the Server Manager window, open a server group and select a server.
  3. From the Server menu, choose Configurations.

    The Server Configuration/Options dialog appears.

  4. Choose the Attributes tab.

    The Attributes window appears, listing SQL Server version information, various environmental variables, and their values.

    The displayed values cannot be modified.

Server attributes can also be viewed using xp_msver. For information, see the Microsoft SQL Server Transact-SQL Reference.


Adding a Language

Microsoft SQL Server is available in both United States English and localized versions. All versions include system messages in United States English. Localized versions also include system messages that have been translated into another language (such as German or French).

When you install a localized version of SQL Server, the setup program automatically installs the localized messages and date/time formats for you. If you have more than one alternate language, you can use the setup program to install the localized messages and date/time formats for each language. The setup program lets you determine the default language. DB-Library™ - based applications use the country settings established using the International application in the Windows NT Control Panel. For additional information, see the descriptions of dbconvert and dbinit in Microsoft SQL Server Programming DB-Library for C.

ODBC-based applications use code page translation, This is defined from the ODBC Control Panel application, while setting up the options for the ODBC SQL Server driver.

You can add additional languages at any time simply by running setup¾it is not necessary to perform a full installation to add a language. You can find out which languages have been installed by using the sp_helplanguage System Stored Procedure (described in the Microsoft SQL Server Transact-SQL Reference.

You change the default language for SQL Server by using the setup program or the SET LANGUAGE statement. You set the default language for a specific user using SQL Enterprise Manager or by using the sp_defaultlanguage System Stored Procedure (described in the Microsoft SQL Server Transact-SQL Reference).

To use setup to install an additional language on the server
  1. From the Microsoft SQL Server 6.0 program group, double-click the SQL Setup icon.
  2. Follow the on-screen instructions until the Microsoft SQL Server 6.0 Options dialog box appears.

  3. Select Add Language and then choose the Continue button.

    The Select Language dialog box appears.

  4. In the Language Name box, type the name of the language.
  5. In the SA Password box type the password to use when installing the language file.
  6. To set this alternate language as the default language for SQL Server, choose the check box for Default Language.
  7. Choose Continue.

    The SQL Server Path dialog box appears.

  8. In Path box, type the full path (drive letter, path, and filename).
  9. Choose Continue.

For more information on adding a language, see the setup program's online Help.


Setting Windows NT Options on the Server

In addition to setting the SQL Server options described in this chapter, there are several Windows NT options you might want or need to set on the server computer to tune your system to best suit your needs. For more information choose one of the following topics:

Maximizing Throughput

Configuring Server Tasking

Hiding the Server on the Network


Maximizing Throughput

When you run the SQL Server setup program, your Windows NT system is automatically configured to maximize throughput for network applications. This enables the server to accommodate more connections. Although this configuration is recommended for SQL Server, you can change the setting back to the Windows NT default by using the following procedure.

To change throughput back to the default
  1. Open the Main program group, and double-click the Control Panel icon.

    The Control Panel window appears.

  2. Double-click the Network icon.

    The Network Settings dialog box appears.

  3. From the list in the Installed Network Software box, select Server.
  4. Choose the Configure button.

    The Server dialog box appears.

  5. Select Maximize Throughput for File Sharing.
  6. Choose the OK button.

    The Network Settings dialog box returns.

  7. Choose the OK button again.

Throughput can be set for computers running the Windows NT Server operating system. This configuration setting does not apply to computers running the Windows NT Workstation operating system. For additional information about maximizing throughput, see your documentation for Windows NT.


Configuring Server Tasking

If you plan on connecting to SQL Server from local clients, it's a good idea to set up the server so that foreground and background applications run with equal priority. This allows SQL Server¾which runs as a background application¾to run at equal priority with other applications (such as client applications) that might be running in the foreground.

When you run the setup program, server tasking is set appropriately for SQL Server. To change it back to the Windows NT default, use the following procedure.

To change server tasking back to the default
  1. Open the Main program group, and double-click the Control Panel icon.

    The Control Panel window appears.

  2. Double-click the System icon.

    The System dialog box appears.

  3. Choose the Tasking button.

    The Tasking dialog box appears.

  4. Select a Foreground/Background Responsiveness option.

    The Windows NT default is Best Foreground Application Response Time. SQL Server setup changes this to Foreground and Background Applications Equally Responsive.

  5. Choose the OK button.

    The System dialog box returns.

  6. Choose the OK button again.


Hiding the Server on the Network

When you install SQL Server, setup makes an entry in the Windows NT Registry so that named pipe clients can see the SQL Server in a server enumeration box, such as those that appear in ISQL/w. If you want to hide the server on the network, you must set a switch using the Network application in the Windows NT Control Panel.

When a server is hidden, named pipe clients can still connect to it, but they cannot see it when viewing servers.

To hide a server from named pipe clients
  1. Open the Main program group and double-click the Control Panel icon.

    The Control Panel window appears.

  2. Double-click the Network icon.

    The Network Settings dialog box appears.

  3. From the list in the Installed Network Software box, select Server.
  4. Choose the Configure button.

    The Server dialog box appears.

  5. Clear the Make Browser Broadcasts to LAN Manager 2.x Clients check box.
  6. Choose the OK button.

    The Network Settings dialog box returns.

  7. Choose the OK button again.

    For named pipe clients, the server is hidden.

You can reveal the server later by running the Network application and selecting the Make Browser Broadcasts to LAN Manager 2.x Clients check box.


Rebuilding the master Database

The master database is the system database that keeps track of user accounts, remote user accounts, remote servers, environment variables, system error messages, system databases, database storage allocation, devices, and active locks.

The setup program can be used to rebuild the master database. This rewrites the master database and resets the configuration values on its existing device. This process can also be used to change the server's character set or sort order.

Caution Rebuild the master database only when it is absolutely essential. Rebuilding the master database completely rewrites the master database, destroys all information added since SQL Server was first installed, and renders all other databases unusable. If you rebuild the master database, you must recreate the user databases, reload each database from the most recent dump, and then reapply any changes not included in the dump.

When rebuilding the master database, you have the option of changing the character set or sort order. Because the sort order is used to construct all indexes, including system indexes, all databases must be rebuilt if you change the sort order. The setup program rebuilds the master database for you, but you must rebuild user databases yourself.

If you must rebuild the master database or change the character set or sort order, follow this procedure.

To use setup to rebuild the master database
  1. If you are changing the character set or the sort order, back up all databases. If not, go to step 4.
  2. Put all data definition language (DDL) commands in batch files. You will use the batch files to recreate the structure of your databases after changing the sort order. (SQL Enterprise Manager can help with this step.)
  3. Use the bcp (bulk copy) utility to copy data out of your tables.

    Include all database objects. Also copy out lists of users.

  4. Back up the entire SQL Server directory tree and any disk devices that you have created in other directories.
  5. From the Microsoft SQL Server 6.0 program group, double-click the SQL Setup icon and follow the on-screen instructions until the Microsoft SQL Server 6.0 Options dialog box appears.

  6. Select the Rebuild Master Database option, and then choose Continue.

    A confirmation dialog box appears.

  7. Choose Resume.

    The Rebuild Options dialog box appears.

  8. To change the character set during the rebuild, choose the Sets button, and complete the Select Character Set dialog box that appears.

    For information about the character sets provided with SQL Server, see Microsoft SQL Server Setup.

  9. To change the sort order during the rebuild, choose the Orders button, and complete the Select Sort Order dialog box that appears.

    Important The sort order is used to construct all indexes, including system indexes. If you change the sort order, all databases must be rebuilt. The setup program rebuilds the master database for you, but you must rebuild user databases yourself.

    For information about the sort orders provided with SQL Server, see Microsoft SQL Server Setup.

  10. In the Rebuild Options dialog box, choose Continue.

    The SQL Server Installation Path dialog box appears.

  11. If it is not correctly displayed in the dialog box, enter the location of the existing SQL Server installation, and then choose Continue.

    The Rebuild Master Device dialog box appears.

  12. If it is not correctly displayed in the dialog box, enter the location and name of the existing MASTER device. Also enter a MASTER device size, and then choose Continue.

    The setup program rebuilds the master database.

  13. When the rebuild completes and the completion dialog box appears, choose the Exit button.
  14. If you changed the character set or sort order, recreate all databases using the batch files created in step 2, and then use bcp to copy the data back into your databases.

For information about bcp, see Chapter 11, Exporting and Importing Data.

The files MASTER.DA@ and MASTER.AL@ are stored in the \SQL60\INSTALL directory. When installing SQL Server or rebuilding the master database, one of these two files is used. When the default sort order and character set are selected during an installation or a master database rebuild, MASTER.DA@ is expanded and copied onto the server, replacing MASTER.DAT. When an alternate character set and/or sort order is selected, MASTER.AL@ is expanded and copied onto the server, and several SQL scripts are run. Because of this, selecting the default character set and sort order results in a rapid master database rebuild. Choosing an alternate character set or sort order can result in a somewhat longer rebuild time.

Because of the introduction of one-way encrypted passwords with SQL Server 6.0, changing the sort order has an impact on the use of passwords. For information, see Microsoft SQL Server Setup.


Adding Registry Keys

When you install SQL Server, the setup program writes a set of default startup options in the Windows NT Registry under the key:

HKEY_LOCAL_MACHINE
\SOFTWARE
\Microsoft
\MSSQLServer
\MSSQLServer

If you want to create and store alternate sets of startup options in the Registry ¾ for example, to start SQL Server in single-user mode ¾ copy the MSSQLServer key (under MSSQLServer) to a new key, and then edit the options in the new key to suit your needs. Each startup option is stored as a separate parameter in the Parameters entry of the MSSQLServer key, starting with SQLArg0, then SQLArg1, and so on. The order of the parameters is not important.

Only experienced users should use REGEDT32 to edit the Windows NT registry. Editing of the Registry is not generally recommended, and inappropriate or incorrect changes can cause serious configuration problems for your system.

To copy the Server key to a new key
  1. Start the Registry editor (run the REGEDT32.EXE program).
  2. Switch to the HKEY_LOCAL_MACHINE window.
  3. Double-click the SOFTWARE entry.
  4. Double-click the Microsoft entry.
  5. Select the MSSQLServer entry.
  6. From the Edit menu, choose Add Key.
  7. In the Key Name box, enter a name for the new key.
  8. Choose the OK button.
  9. Select the MSSQLServer entry (under MSSQLServer).
  10. From the Registry menu, choose Save Key.
  11. In the File Name box, enter a filename for the saved key.
  12. Choose the OK button.
  13. Select the new key.
  14. From the Registry menu, choose Restore.
  15. In the File Name box, enter the filename for the saved key.
  16. Choose the OK button.
  17. Choose the Yes button.

For example, you could create a new key called SingleUser and then edit this Registry entry to include the additional -m startup option.

HKEY_LOCAL_MACHINE
\SOFTWARE
\Microsoft
\MSSQLServer
\SingleUser
\Parameters

Using this procedure, you could create a new key called SingleUser, and then edit this entry

HKEY_LOCAL_MACHINE
\SOFTWARE
\Microsoft
\MSSQLServer
\SingleUser
\Parameters

to include the additional -m startup option.

The entire Parameters entry for the SingleUser key would look like this:

HKEY_LOCAL_MACHINE
    \Software
        \Microsoft
            \MSSQLServer
                \SingleUser
                    \Parameters
SQLArg0 : REG_SZ : -dC:\SQL\DAT\MASTER.DAT
SQLArg1 : REG_SZ : -eC:\SQL\LOG\ERRORLOG
SQLArg2 : REG_SZ : -m

To start SQL Server using this alternate key, you would start SQL Server from the command line using the -s startup option, as shown in the following example:

sqlservr -c -sSingleUser


Assigning a Service Account to SQL Server or SQL Executive

SQL Server is installed by the setup program to run as a Windows NT service under the computer's LocalSystem account. In most situations, this is appropriate and suitable. However, LocalSystem is a special account that has no user account information associated with it and cannot be granted any privileges on another computer. In some cases, services running under the LocalSystem account will be unable to access certain network resources.

For example, Microsoft LAN Manager user-level security servers and Novell NetWare Servers will not allow a Windows NT service running under the LocalSystem account to access their file shares. Therefore, in some situations¾primarily when SQL Server will be accomplishing connectivity-related tasks¾it may be necessary to create and assign a Windows NT user account to SQL Server. This allows SQL Server to run in the security context of the user account and not in the context of the computer's LocalSystem account.

The account you create will usually be a domain account (although it could be an account on the local server). To create the user account, use the User Manager application¾provided with Windows NT¾to create a user account that belongs to the Administrators local group on the local SQL Server computer. It is also a good idea to have the Password Never Expires option selected. For information on how to do this, see your docmentation for Windows NT or the online Help for User Manager. If you do not have privileges that allow you to use User Manager for Domains, have a network administrator create the user account for you.

In most cases, as part of SQL Server installation, you will have already created an account with these characteristics and assigned it to SQL Executive. If this has been done, then you can usually assign the same account to SQL Server, and you will not need to create a new user account.

However, if during SQL Server installation you did not assign a user account to SQL Executive, then you will need to create the account. You can use the following procedure to assign a user account to both SQL Executive and SQL Server.

The SQL Server service is named MSSQLServer. The SQL Executive service is named SQLExecutive.

To assign a user account to SQL Server or SQL Executive
  1. Open the Main program group and double-click the Control Panel icon.

    The Control Panel window appears.

  2. Double-click the Services icon.

    The Services dialog box appears.

  3. From the list of services, select MSSQLServer or SQLExecutive, and then choose the Startup button.

    The Service startup dialog box appears.

  4. Choose the This Account option, and then type the user account in the This Account box.

    Or to select from a list of available user accounts, choose the browse (...) button and complete the Add User dialog box that appears.

  5. Enter the password for that user account in the Password and Confirm Password boxes.

    Make certain you type the correct password. The service will not start if the password is incorrect.

  6. Choose OK.
  7. Choose Close.

    The new account assignment takes effect the next time the service is started.

If you have difficulty starting SQL Server or SQL Executive under a particular user account, you can:

  • Use User Manager to verify that the account has the log on as a service right on the computer and is a member of the Administrators group on the computer. (Both of these must be assigned within the security context of the local computer, not the domain.)
  • Use the Services application in the Control Panel to re-enter the user account password. If the password is incorrect or has changed (for example, if it expired and was changed by a user), the service cannot be started until the correct password is entered.

    If necessary, change the account's password using User Manager, and then enter that password for the service, using the Services application in the Control Panel.

If you still have difficulty starting SQL Server or SQL Executive under a particular user account, one way to troubleshoot is to assign that account to another service¾for example, the Spooler service¾and verify that the service can be successfully started. If not, it is probable that the account is not properly configured or cannot be validated by the domain controller (for example, if no domain controller is available).

For more information about assigning a user account to SQL Executive, see Microsoft SQL Server Setup.


Chapter 4 Configuring Clients

Configuring Clients

After client software has been installed, you can perform configuration tasks such as checking library version numbers, changing the default Net-Library, setting DB-Library preferences, or setting up server connections. This chapter explains how and also presents a general discussion of network client connections.

For information on installing client software, see Microsoft SQL Server Setup.

For more information, choose one of the following topics:

Configuring the Client Software

Network Client Connections


Configuring the Client Software

For Windows NT-, Windows 95, and Windows-based clients, the SQL Server client software includes the SQL Client Configuration Utility. This utility displays the DB-Library version currently installed on the system, sets the default Net-Library, and sets up server connection information on the client.

A client configuration utility is not provided for MS-DOS - based clients because MS-DOS - based clients use a terminate-and-stay-resident (TSR) program, and only one Net-Library TSR can be loaded at a time.

For Windows NT- or Windows-based clients, ODBC client applications use the standard ODBC configuration application in the Control Panel to configure SQL Server data sources. ODBC client applications use the same default Net-Library and Advanced client options as does DB-Library, unless these settings are overridden during data source setup.

For more information, choose one of the following topics:

Starting the Client Configuration Utility

Checking Library Version Numbers

Setting the Default Net-Library

Setting DB-Library Preferences

Setting Up Server Connections


Starting the Client Configuration Utility

Depending on the operating system, the SQL Client Configuration Utility is started in slightly different ways.

To start the SQL Client Configuration Utility from a Windows NT-based client
  1. Open the Microsoft SQL Server 6.0 program group.
  2. Double-click the SQL Client Configuration Utility icon.

To start the SQL Client Configuration Utility from a Windows 95-based client
  1. Click the Start button, and then point to Programs.
  2. Point to the Microsoft SQL Server 6.0 folder.

    Note If the 16-bit client software is installed, point to the SQL Server Tools folder.

  3. Click the SQL Client Configuration Utility program.
To start the SQL Client Configuration Utility from a Windows- or Windows for Workgroups-based client
  1. Open the SQL Server Tools program group.
  2. Double-click the SQL Client Configuration Utility icon.

For clients running the Windows or Windows for Workgroups operating systems, the utility can also be started by running W3DBVER.EXE from the \SQL60 directory.


Checking Library Version Numbers

When running SQL Server client utilities, it is important that the client run the most current versions of DB-Library and the Net-Libraries. Check the version numbers with the SQL Client Configuration Utility.

The following illustration shows the SQL Client Configuration Utility that is provided for Windows NT- and Windows 95-based clients, with the DB-Library tab selected.

The following illustration shows the same utility with the Net-Library tab selected.

Note If the SQL Client Configuration Utility window does not display a Net-Library version number and you are using a Net-Library provided by Microsoft, then you are using a version that is no longer supported, the SQL Client Configuration Utility cannot find the Net-Library in the path, or a component required by the selected default network cannot be found. All currently supported Microsoft client Net-Libraries are included in your SQL Server package.

To check for multiple copies of the client libraries (with different version levels) on your system, choose the Locate button in the SQL Client Configuration Utility window. If the results of using the Locate button indicate that there are multiple copies on your system, be sure that only the appropriate version is in your path.

The ODBC SQL Server driver version can be checked using the ODBC application in the Control Panel.

To check the ODBC SQL Server driver version
  1. From the Control Panel, double-click the ODBC application.
  2. Choose the Drivers button.
  3. Select the SQL Server driver from the list of installed ODBC drivers.
  4. Choose the About button.

    The About dialog appears. The version number is displayed.


Setting the Default Net-Library

When you install SQL Server client utilities on a workstation you can specify the client's default Net-Library, which supports communication between the client and SQL Server. (The setup program's default is to set the Named Pipes Net-Library as the default.) However, if after installation you determine that the client will be regularly connecting to a server that is not configured to support the client's default interprocess communication (IPC) mechanism (for example, NWLink IPX/SPX), after installation you can change the client's default Net-Library.

  • For Windows NT-, Windows 95-, and Windows-based clients, change the default Net-Library by using the SQL Client Configuration Utility.
  • For MS-DOS - based clients, change the default Net-Library by loading a different Net-Library TSR program.

The following table lists the SQL Server client Net-Libraries for the Windows NT, Windows 95, Windows, and MS-DOS operating systems:

Net-Library | Windows NT or Windows 95 | Windows (1) | MS-DOS
Named Pipes | DBNMPNTW.DLL | DBNMP3.DLL | DBNMPIPE.EXE
NWLink IPX/SPX | DBMSSPXN.DLL | DBMSSPX3.DLL | DBMSSPX.EXE
Banyan VINES | DBMSVINN.DLL | DBMSVIN3.DLL | DBMSVINE.EXE
TCP/IP Sockets | DBMSSOCN.DLL | DBMSSOC3.DLL | Not available
Multi-Protocol | DBMSRPCN.DLL | DBMSRPC3.DLL (2) | Not available
(1) 16-bit Windows: Microsoft Windows 3.11 and Microsoft Windows for Workgroups. (2) The Multi-Protocol Net-Library used by Windows-based clients (DBMSRPC3.DLL) also uses the following runtime DLLs: RPCNS1.DLL, RPCRT1.DLL, RPC16C3.DLL, RPC16C1.DLL, RPC16DG3.DLL, RPC16C4.DLL, RPC16C5.DLL, RPC16C6.DLL, RPC16DG6.DLL and SECURITY.DLL. These are provided with SQL Server and installed by the setup program as Net-Libraries.

Connection limits for each of these Net-Libraries are shown in the following table:

Net-Library 		Windows NT
or Windows 95
Windows
MS-DOS
Named Pipes | No limit (1) | 34 (2) | 15 (3)
NWLink IPX/SPX | No limit (1) | 25 (2,4) | 15 (5)
Banyan VINES | No limit (1) | 15 | 15
TCP/IP Sockets | No limit (1) | 6 | N/A
Multi-Protocol | No limit (1) | No limit (6) | N/A
(1) Limited only by operating-system memory resources.

(2) Might vary with different versions of DB-Library and the Net-Library (due to
possible differences in the sizes of some internal data structures).

(3) Limited by the number of available MS-DOS file handles.

(4) The Windows-based client Net-Libraries use one IPX socket per connection and one
to three SPX sessions per connection. To achieve the maximum number of connections,
set the IPX Sockets parameter to 32 and the SPX Connections parameter to 96 in the
SHELL.CFG file. You may also need to change the Novell NET.CFG file.

(5) The MS-DOS - based client Net-Libraries use one IPX socket per connection and one to
three SPX sessions per connection. To achieve the maximum number of connections,
set the IPX Sockets parameter to 22 and the SPX Connections parameter to 66 in the
SHELL.CFG file.

(6) Limit is determined by the underlying protocol that is being used.

To set the default Net-Library for Windows NT- or Windows 95-based clients
  1. Start the SQL Client Configuration Utility as described in Starting the Client Configuration Utility, earlier in this chapter.

    The SQL Client Configuration Utility window appears.

  2. Choose the Net-Library tab.

  3. From the list in the Default Network box, select a Net-Library.
  4. Choose the Done button.
To set the default Net-Library for Windows-based clients
  1. From the SQL Server Tools program group, double-click the SQL Client Configuration Utility icon.

    The SQL Client Configuration Utility window appears.

  2. From the list in the Default Network box, select a Net-Library.
  3. Choose the Change button.
  4. Choose the Done button.
To set the default Net-Library for MS-DOS - based clients
  • Using a text editor, edit the computer's AUTOEXEC.BAT file so that it loads the appropriate Net-Library TSR at system startup.

MS-DOS - based clients use terminate-and-stay-resident (TSR) programs to communicate with the underlying network layer. Only one Net-Library TSR can be loaded at a time. These TSR programs are included with the client software for MS-DOS - based clients: :

  • Named Pipes (DBNMPIPE.EXE)
  • Novell SPX (DBMSSPX.EXE)
  • Banyan VINES (DBMSVINE.EXE)

Note that MS-DOS-based clients do not support TCP/IP sockets and Multi-Protocol.

During installation, the setup program gives you the option of selecting one of the TSR programs for automatic loading every time the operating system starts, and of adding the \SQL\BIN directory to the system path. If you do not select this setup option, you will need to load the TSR manually. You may also need to make sure the \SQL\BIN directory is in the path.

A TSR can be manually loaded by typing its executable name from a command prompt (for example, type dbnmpipe).

Since only one TSR can loaded at once, a loaded TSR must be unloaded before a different TSR can be loaded. To stop a loaded TSR, run the ENDDBLIB.EXE utility (from a command prompt, type enddblib).

You can also set the default MS-DOS Net-Library by editing the AUTOEXEC.BAT file.


Setting DB-Library Preferences

For Windows-NT- and Windows 95-based clients, the SQL Client Configuration Utility includes two options for setting DB-Library preferences:

  • The Automatic ANSI to OEM option enables DB-Library to convert characters from OEM to ANSI when communicating with SQL Server, and from ANSI to OEM when communicating from SQL Server to the client. By default, this is set on.
  • The Use International Settings option enables DB-Library to get date, time, and currency formats from the system rather than using hard-coded parameters or parameters specified in SQLCOMMN.LOC. By default, this is set on.

For Windows-based clients, the SQL Client Configuration Utility includes the Automatic ANSI to OEM option but not the Use International Settings option. By default, the setting for the Automatic ANSI to OEM option is set off.

To set DB-Library conversion preferences on a Windows NT- or Windows 95-based client
  1. Start the SQL Client Configuration Utility as described in Starting the Client Configuration Utility, earlier in this chapter.

    The SQL Client Configuration Utility appears.

  2. Select or clear the check box for the Automatic ANSI to OEM option.
  3. Select or clear the check box for the Use International Settings option.
  4. Choose the Done button.
To set DB-Library conversion preferences on a Windows-based client
  1. From the SQL Server Tools program group, double-click the SQL Client Configuration Utility icon.

    The SQL Client Configuration Utility window appears.

  2. Select or clear the check box for the Automatic ANSI to OEM option.
  3. Choose the Done button.

For information on setting DB-Library conversion preferences on an MS-DOS-based client, see Microsoft SQL Server Programming
DB-Library for C.


Setting Up Server Connections

By default, SQL Server client/server connections are established over named pipes using dynamic server names that require no special configuration on the clients. (You can connect using named pipes over any Microsoft-supplied transport, including NWLink IPX/SPX, TCP/IP, and NetBEUI.)

If you need to connect to a SQL Server using another network transport that is not the default, or if you need to connect to a SQL Server that is listening on an alternate named pipe, you must first add the connection information to the appropriate configuration file on the client.

  • For Windows NT - and Windows 95-based clients, connection information is stored in the Registry.
  • For Windows-based clients, connection information is stored in the WIN.INI file.
  • For MS-DOS - based clients, connection information can be set using environment variables, depending on the Net-Library in use.

For Windows NT-, Windows 95, and Windows-based clients, you set up server connections by using the SQL Client Configuration Utility, which updates the appropriate information on the client.

Note Advanced connection information can be shared by both DB-Library and ODBC applications. If the server name specified in the ODBC SQL Server dialog box matches a server name configured using the Advanced tab of the SQL Client Configuration Utility, and if the ODBC network address and network library remain set to default, then the connection information shown in the Advanced tab of the SQL Client Configuration Utility is used by ODBC.

To set up server connections on a Windows NT- or Windows 95-based client
  1. Start the SQL Client Configuration Utility as described in Starting the Client Configuration Utility, earlier in this chapter.

    The SQL Client Configuration Utility window appears.

  2. Choose the Advanced tab.

  3. In the Server box, enter the name of the server. This is the name of the server you are using in DB-Library applications such as isql. The name does not need to match a network server name.
  4. In the DLL Name box, select the name of the Net-Library (for example, Named Pipes) from the list.

    Or you can type the name of a Net-Library DLL to use for the connection. (Do not type the ".DLL" filename extension.) Net-Library DLL choices are listed in "Setting the Default Net-Library," earlier in this chapter.

  5. In the Connection String box, you can enter additional connection information as required. If no connection string is entered, the server name is used.

    For information on the type of connection information that can be entered in this box for each Net-Library, see Network Client Connections.

  6. Choose the Add/Modify button.
  7. Choose the Done button.
To set up server connections on a Windows-based client

  1. From the SQL Server Tools program group, double-click the SQL Client Configuration Utility icon.

    The SQL Client Configuration Utility window appears.

  2. Choose the Advanced button.

    The Advanced Client Options dialog box appears.

  3. In the Server box, enter the name of the server. This is the name of the server you are using in DB-Library applications such as isql. The name does not need to match a network server name.
  4. In the DLL Name box, type the name of a Net-Library DLL to use for the connection.

    Net-Library DLL choices are listed in "Setting the Default Net-Library," earlier in this chapter.

  5. In the Connection String box, enter additional connection information as required. For example, to establish TCP/IP sockets connections without using DNS or WINS, enter the TCP/IP address and port, such as:
    11.1.4.68,1433

    For information on the type of connection information that can be entered in this box for each Net-Library, see Network Client Connections.

  6. Choose the Add/Change button.
  7. Choose the OK button.
  8. Choose the Done button.

For MS-DOS - based clients, you set up server connections by setting an environment variable. Typically, this involves changing the client's AUTOEXEC.BAT file.

For MS-DOS - based clients using the named pipes Net-Library (DBNMPIPE.EXE), you can set up a connection to use alternate pipe names by assigning an environment variable equal to the fully qualified pipe name. For example:

set servername = \\myserver\pipe\altpipe\query

You must set this variable before you load the Net-Library TSR. Other Net-Libraries for MS-DOS supplied by Microsoft do not support server aliases using environment variables. For Net-Libraries supplied by companies other than Microsoft, see your package documentation.


Network Client Connections

For additional information about configuring network client connections, choose one of the following topics.

Named Pipes Clients

Multi-Protocol Clients

NetWare Clients

TCP/IP Sockets Clients

Banyan VINES Clients

AppleTalk ADSP Clients

DECnet Sockets Clients


Named Pipes Clients

Normally, clients connect to a server using the server's machine name. However, if a server is set up to listen on an alternate pipe name, the client must also be set up to communicate to that pipe name. Use the Advanced option of the SQL Client Configuration Utility to set up an server name aliased to that alternate pipe. Provide the server machine name, the DLL name for the Named Pipes Net-Library, and the alternate pipe name. For example:

\\myserver\pipe\altpipe

For more information, see Setting Up Server Connections.

Note The client side Win32 named pipe Net-Library (DBNMPNTW.DLL) does not support server enumeration on Windows 95-based computers. This means that applications such as ISQL/w and SQL Enterprise Manager will not list SQL Servers of the network if the server list is selected from a connection dialog box. Server enumeration over named pipes on all other platforms continues to be supported.


Multi-Protocol Clients

SQL Server 6.0 includes the new Multi-Protocol Net-Library, which takes advantage of the powerful remote procedure call (RPC) facility of Windows NT to provide new functionality and ease of use. Multi-Protocol Net-Library provides the ability to communicate simultaneously over one or more IPC mechanisms supported by Windows NT.

Note Only TCP/IP Windows Sockets, NWLink IPX/SPX, and Named Pipes are considered to be tested and supported.

For Multi-Protocol, the server's machine name is used by clients for name resolution.

To configure a Windows NT-based client to use the Multi-Protocol Net-Library
  1. On the client, make sure you have support for at least one IPC protocol supported under Multi-Protocol on the server (Named Pipes, IPX/SPX, TCP/IP, or Windows sockets).

    When using SPX/IPX via NWLink, you also need to install the Windows NT NetWare Client services.

  2. From the Microsoft SQL Server 6.0 program group, choose the SQL Client Configuration icon, and then set Multi-Protocol as the default Net-Library.

Note The Win32 Multi-Protocol network library is supported on Windows NT versions 3.5 and 3.51. However, connections are not supported from Windows NT version 3.5 clients to Windows NT version 3.51 servers. Clients running Windows NT version 3.5 should upgrade to version 3.51 in order to connect via the Multi-Protocol Net-Library to servers running Windows NT version 3.51.

To configure a Windows-based client to use the Multi-Protocol Net-Library
  1. On the client, make sure you have support for a protocol supported under Multi-Protocol on the server (Named Pipes, IPX/SPX or TCP/IP sockets).
  2. Choose the SQL Client Configuration Utility from the SQL Server Tools program group, and then select Multi-Protocol as the default Net-Library.

Both Windows- and Windows NT-based clients can also create aliases for specific server names to use the Multi-Protocol Net-Library, by using the Advanced option in the SQL Client Configuration Utility.

To create an alias for a specific server name to use the Multi-Protocol Net-Library
  1. From the SQL Client Configuration Utility, select the Advanced option.
  2. In the Server box, enter the machine name of the system running SQL Server and listening on the Multi-Protocol Net-Library.
  3. In the DLL Name box, select Multi-Protocol (for Windows NT-based clients) or enter DBMSRPC3 (for Windows-based clients).
  4. The Connection String box may be left blank, since the server's machine name is used for name resolution. However, if the alias name being used is different, the machine name must be supplied as the connection string.
SECURITY.DLL and the Path on 16-bit Clients

When using the 16-bit Window Multi-Protocol Net-Library, the SECURITY.DLL is necessary for integrated security and encryption. The 16-bit Windows setup program copies this DLL to the SQL Server client directory. Note that since the 16-bit Windows setup program does not modify the path, this directory must be placed in the computer's path if you will be running SQL Server applications that do not reside in this directory.

Integrated Security and 16-bit Clients

The 16-bit Windows Multi-Protocol Net-Library (by default) assumes integrated security on connection attempts. Thus, to allow standard connections to SQL Server (non-integrated security when the server is started in mixed or standard mode), make the following change to the WIN.INI file to bypass the authentication dialog box:

[RPCnetlib]
Security=none

On Windows 3.1-based workstations using the 16-bit Windows Multi-Protocol Net-Library with SQL Server Integrated Security, the authentication dialog box allowing login to a Windows NT domain generally appears on the first connection attempt to the server from an application. However, some applications (such as ISQL\w) use "make/break" logic designed to minimize idle connections to the server, creating situations in which the authentication dialog box appears each time a connection is closed and then reopened.

Client-side Encryption for 16-bit Clients

To enforce encryption over the Multi-Protocol Net-Library on a per-client basis for a 16-bit Windows-based client, set the following value in the client's WIN.INI file:

[RPCnetlib]
Security=Encrypt

This will cause all communication over the Multi-Protocol Net-Library between this client and the server to be encrypted. (Only this client's communications will be encrypted. Other clients using the Multi-Protocol Net-Library, which do not have this parameter set, will not use encryption.)

Client-side Encryption for 32-bit Clients

For Windows NT- or Windows 95-based clients, to enforce encryption over the Multi-Protocol Net-Library on a per-client basis, you must create the RPCNetlib Registry key and the following Registry value:

HKEY_LOCAL_MACHINE
\SOFTWARE
\Microsoft
\MSSQLServer
\Client
\RPCNetlib

Value Name: Security
Data Type: REG_SZ
String: Encrypt

This will cause all communication over the Multi-Protocol Net-Library between this client and the server to be encrypted. (Only this client's communications will be encrypted. Other clients using the Multi-Protocol Net-Library, which do not have this parameter set, will not use encryption.)

Server Enumeration

There is no support for server enumeration with the Multi-Protocol Net-Library. From applications that have options to list servers by calling dbserverenum, you will not be able to identify SQL Servers listening on the Multi-Protocol Net-Library.

Name Resolution

Due to the nature of the Multi-Protocol Net-Library architecture, no server-side listen-on service name needs to be provided when SQL Server is loading SSMSRPCN.DLL. By default, clients connect by simply using the machine name. When establishing a connection, the Net-Library passes the machine name to the RPC run time, which determines which IPC/protocols are available and attempts to use each one until a connection is established. (Only NWLink IPX/SPX, TCP/IP sockets, and Named Pipes are considered tested and supported.)

To accomplish the machine name to node connection, the RPC run time uses a naming service compatible with the transport used (WINS for TCP/IP, SAP for NWLink IPX/SPX and Net BIOS broadcasts for Named Pipes). No ports or sockets need to be specified in the connection string, since a local RPC database is used to resolve the names over the supported protocols. This all happens behind the scenes, so by default, only the machine name needs to be passed to establish a connection. This is the desired configuration and makes the general configuration of the client and server very easy.

However, for troubleshooting and testing, it is possible for specific connection strings to be used. A client can establish a connection using the Multi-Protocol Net-Library over a specific protocol only, and also (if desired) specify the hard-coded connection string. Based on this, the Net-Library will allow direct connection if a defined RPC name is passed on the connection attempt. For example, to establish a connection in which the client-side Multi-Protocol Net-Library will only attempt to use TCP/IP sockets, you could use either of the following formats for the connection string:

ncacn_ip_tcp:machine_name
ncacn_ip_tcp:11.125.9.53[3848]

In the first example, the connection will be established over TCP/IP sockets and the machine name will be used for the appropriate name resolution method. In the second example, the actual IP address and socket is used to identify SQL Server. Similarly, for NWLink IPX/SPX connections, you could use either of the following formats for the connection string:

ncacn_spx:machine_name
ncacn_spx:~00000023AF737F208AB[24584]

For Named Pipes connections, you could use the following format for the connection string:

ncacn_np:machine_name
ncacn_np:\\\\SERVER[\\pipe\\0000008D.001]

For all of these cases (TCP/IP sockets, NWLink IPX/SPX, or Named Pipes), you can determine what actual address the server-side Multi-Protocol Net-Library started listening on for each protocol by examining the Windows NT Application log messages which are written when SQL Server starts and the Net-Libraries are loaded.

Note When stopping and starting a SQL Server listening on this Net-Library, the actual address may vary, depending on available socket addresses for Named Pipes. Therefore, it is always preferable to use the machine name when establishing connections.


NetWare Clients

The Microsoft IPX/SPX Net-Libraries for SQL Server normally query the NetWare Bindery to translate a server name into the network address of a SQL Server. However, it is possible to make direct connections to SQL Server over IPX/SPX without accessing the NetWare Bindery. For Windows NT- and Windows-based clients, you make direct connections by using the SQL Client Configuration Utility to set the network address of the SQL Server. For MS-DOS - based clients, you make direct connections by using the network address instead of the server name when starting the client.

Note The instructions that follow require you to know the network number (the segment/net that the server is on) and the NIC number of the server you want to connect to. To determine the network number, see your network administrator. The default network number is 0 (which indicates the local network). You can determine the NIC number under Windows NT by typing net config server from an operating-system prompt. (The NIC number appears after Streams\NwlnkNb.) The default port is 33854 unless a specific value is specified in the ListenOn entry of the Windows NT Registry.

For additional information about configuring NetWare clients, choose one of the following topics.

Windows- and Windows NT-based Clients

Windows for Workgroups-based Clients on NetWare Networks

MS-DOS - based Clients


Windows- and Windows NT-based Clients

To set up a server connection entry that includes a server name, the correct DLL name for the client operating system (DBMSSPXN for Windows NT - based clients and DBMSSPX3 for Windows-based clients), and a connection string, use the Advanced button of the SQL Client Configuration Utility. The format of the connection string is as follows:

NIC_address,port,network_number

For example:

08012B327C21,33854,1

You can make a direct connection from a client by using the server name that you entered in the Server box when setting up the connection string using the SQL Client Configuration Utility. For example, if you set up the connection using the server name SQLNOVELL, you could make a direct connection by using the ISQL/w application. In the Connect Server dialog box specify the server SSQLNOVELL, enter a valid username and password, and choose the Connect button.


Windows for Workgroups-based Clients on NetWare Networks

Windows for Workgroups version 3.11 enhances the network integration available with Novell NetWare by offering peer network functionality, as well as connectivity to Windows NT-based computers. SQL Server clients running Windows for Workgroups can be configured in several ways by using the Network Setup application.

If only Windows support for Novell NetWare is installed (and Microsoft Windows Network is not installed), then you are using the Novell NetWare IPX protocol (IPXODI). This protocol supports SPX as the interprocess communication (IPC) method for connecting to SQL Server. Use the SQL Client Configuration Utility to set the default network to Novell IPX/SPX. This configuration will allow Windows for Workgroups to use the IPX/SPX Net-Library to connect to SQL Server 6.0 running NWLink.

If only the Microsoft Windows Network is installed (and Windows support for Novell NetWare is not installed), then you can still use IPX to connect to SQL Server 6.0. Use the Drivers button to ensure that the IPX/SPX Compatible Transport With NetBIOS network protocol is installed. This IPX protocol is included with Windows for Workgroups 3.11 and is similar to the NWLink IPX/SPX protocol. This protocol supports named pipes as the interprocess communication (IPC) method for connecting to SQL Server. Use the SQL Client Configuration Utility to set the default network to Named Pipes. This configuration will allow Windows for Workgroups to use the Named Pipes Net-Library to connect to SQL Server running NWLink.

If both the Microsoft Windows Network and Windows support for Novell NetWare are installed, you can use either the Named Pipes or IPX/SPX Net-Library to connect to SQL Server running NWLink. Using IPX/SPX is only allowed in this configuration if IPX/ODI drivers are loaded and WFW is in dual net mode.

If integrated security is required, the Named Pipes or Multi-Protocol Net-Libraries are necessary. If data encryption is required, the Multi-Protocol Net-Library is necessary.


MS-DOS - based Clients

With MS-DOS - based clients, you cannot set up the connection information in advance, so you must enter the appropriate connection information each time you connect. Simply load the DBMSSPX.EXE TSR, and then connect to the server using the connection string instead of the server name. To make a direct connection using isql, type the following:

isql -U username -P password -S NIC_address,port,network_number

For example:

isql -U sa -P mysecret -S08012B327C21,33854,1


TCP/IP Sockets Clients

For Windows- or Windows NT-based clients, SQL Server supports client communication using standard Windows Sockets as the IPC method across the TCP/IP protocol.

Important The Windows Sockets Net-Libraries have been extensively tested on the supported platforms for connecting to Microsoft SQL Server. Using these Net-Libraries with other TCP/IP protocols should work if those protocols properly support Windows Sockets. However, their use on these platforms is not guaranteed. The protocol provider should test and state their support policy.

Third party 16-bit TCP/IP products (other than those provided with Windows for Workgroups) which properly support the Windows Sockets specifications should work properly with the Win16 TCP/IP Sockets Net-Library (DBMSSOC3.DLL). While not officially tested and supported, products that properly implement the specification should work with the Net-Library.

Note MS-DOS-based applications running with the Microsoft Windows TCP/IP protocol stack must use the Named Pipes Net-Library, DBNMPIPE.EXE. There is no TCP/IP sockets support in MS-DOS.

For additional information about configuring TCP/IP Windows Sockets clients, choose one of the following topics.

Windows Sockets Support for Windows- and Windows for Workgroups-based Clients

Simplified System Administration Using DHCP and WINS

Client Configuration


Windows Sockets Support for Windows- and Windows for Workgroups-based Clients

Microsoft TCP/IP-32 for Windows for Workgroups 3.11 is tested and supported for use with the Win16 TCP/IP Sockets Net-Library and is distributed with Windows NT Server version 3.5 or later. It allows Windows for Workgroups clients to use a 32-bit protected-mode stack and take advantage of TCP/IP services provided by Windows NT Server version 3.5 or later (such as the DHCP and WINS services).

While not officially tested and supported, third party TCP/IP products that properly implement the Windows Sockets specification may be used.


Simplified System Administration Using DHCP and WINS

Windows NT version 3.5 or later provides for easy administration of large TCP/IP networks by offering the Dynamic Host Configuration Protocol (DHCP) service for automatic TCP/IP configuration, and the Windows Internet Name Service (WINS) for dynamic mapping of network names and addresses. This enables users to operate in large-scale TCP/IP networking environments with little administrative support.


Client Configuration

To configure a Windows- or Windows NT-based client to use the Windows Sockets Net-Library, follow the steps under "Setting Up Server Connections," earlier in this chapter. In the DLL Name box, enter the appropriate Windows Socket Net-Library name. For Windows NT-based clients, select TCP/IP Sockets from the list. For Windows-based clients, type dbmssoc3 in the box.

The Connection String uses the format:

ip_address,[socket_number]

where ip_address is the IP address of the computer running SQL Server and socket_number is the optional socket number that SQL Server is listening on.

It is also possible to configure a Windows- or Windows NT-based client to use the Windows Sockets Net-Library by default. From the SQL Client Configuration Utility, in the Default Network box select TCP/IP Sockets. Using this method, connections can be established by using the ip_address,[socket_number] directly as the SQL Server name, or by using a server name with the format:

host_name,[socket_number]

where host_name is a TCP/IP host name that has been defined in the client HOSTS file or on a Domain Name Service (DNS), or is the machine name of a Windows NT Server running SQL Server if WINS is enabled, and socket_number is the optional socket number that SQL Server is listening on. For a client running Windows for Workgroups, the HOSTS file is located in the \WINDOWS directory by default. For a client running Windows NT, the HOSTS file is located in the \WINDOWS\SYSTEM32\DRIVERS\ETC directory by default. For other TCP/IP protocols that support Windows Sockets, see your TCP/IP documentation.

In all cases, if the socket_number is not specified, the Net-Library uses 1433, the official Internet Assigned Number Authority (IANA) socket number for Microsoft SQL Server.


Banyan VINES Clients

SQL Server supports Banyan VINES Sequenced Packet Protocol (SPP) as the IPC method across Banyan VINES IP network protocol. Banyan VINES support for Windows NT-based clients is available only on the Intel platform; it is not currently available on the MIPS or Alpha AXP platforms.

MS-DOS- and Windows-based clients require Banyan VINES client software version 4.11(5) or later. Windows NT version 3.5-based clients require Banyan VINES client software version 5.56(2) or later. Contact your Banyan support provider for information about the latest supported client software for each client platform.

A StreetTalk™ language PC-based service name has the form servicename@group@org, where servicename is the StreetTalk PC-based service name used by the SQL Server, group is the group, and org is the organization. (Note that the service name used by a SQL Server must first be created using the MSERVICE program included with your VINES software.)

For Windows- or Windows NT-based clients, you can use the SQL Client Configuration Utility, as described earlier in this chapter, to set up Banyan VINES connections.

If a client application gives a partial StreetTalk name (a name that doesn't include the group and organization) as the server name, the VINES SPP Net-Library will use standard VINES services to complete the rest of the StreetTalk name with your login defaults. If no PC-based service or nickname matching the server name is found within the user's own group and organization, the VINES SPP Net-Library looks for a special group named MSSQL within your organization. This allows network administrators to define a group of SQL Servers that are accessible with one-part names from all groups in the same organization.

You can override the default name MSSQL by setting a group@org variable on each client to a newgroup@org value. Both the group and organization are required.

For an MS-DOS-based client, this is an environment variable that must be set before the DBMSVINE.EXE Net-Library TSR is loaded. For example:

SET group@org=SQLServers@xyzcorp

For a Windows-based client, set group@org by adding a [DBMSVINE] section to your WIN.INI file. For example:

[DBMSVINE]
group@org=SQLServers@xyzcorp

For a Windows NT-based client, add a DBMSVINE key to the Windows NT Registry. Add the following key

\HKEY_LOCAL_MACHINE
\SOFTWARE
\Microsoft
\ MSSQLServer
\Client
\DBMSVINE

with a REG_SZ value group@org set to newgroup@org.

All of these examples change the default collection of SQL Servers to SQLServers@xyzcorp. Then, when any client application attempts to connect to a server named GIZMO, the VINES SPP Net-Library first looks for a PC-based service or nickname in your login group and then looks for one named GIZMO@SQLServers@xyzcorp.

The VINES SPP Net-Library files do not support the use of StreetTalk names that contain embedded spaces, and they use one VINES IP socket per server and one SPP connection per database connection.


AppleTalk ADSP Clients

If you experience difficulties establishing connections from Apple Macintosh clients via AppleTalk, check the Windows NT application log or the SQL Server error log, and verify that the AppleTalk Net-Library is loaded correctly. If it is not, the log will contain an error message.

If the AppleTalk Net-Library is loaded properly on the server, you should see a message similar to the following in the Windows NT application log or the SQL Server error log:

Using 'SSMSADSN.DLL' version '6.00.0.0' to listen on 'servicename'
To verify that a Macintosh client can connect to the server
  1. On the SQL Server computer that is running Windows NT with the Macintosh services installed, establish a Macintosh file share.
  2. From the Macintosh client, verify that the server's file share can be accessed.
To verify that SQL Server is listening on AppleTalk and can accept a client connection
  1. Copy the client-side AppleTalk Net-Library (DBMSADSN.DLL) from the \SQL60\DLL directory of the server to the same directory of a remote Windows NT-based computer running the Windows NT Services for Macintosh.
  2. On the remote workstation, use the SQL Server Client Configuration Utility to change the default Net-Library to DBMSADSN.DLL.
  3. Attempt an ISQL connection with the AppleTalk service object name. For example:
    isql -Usa -P -Sservicename

    If you can connect with ISQL and execute queries, the server is properly configured to listen on AppleTalk and is accepting connections.

    Note The Win32 AppleTalk (ADSP) client side Net-Library (DBMSADSN.DLL) is included for testing ADSP connections and troubleshooting AppleTalk connections between Macintosh clients and SQL Server. This Net-Library is only intended to used when testing connections from a remote client to SQL Server. If local connections are attempted via the ADSP Net-Library to a SQL Server listening on AppleTalk, a network error can be generated (Net-Library error 11: getsockopt()).


DECnet Sockets Clients

To support VMS clients to NT SQL Server via DECNet sockets, the NT Server system should be running Digital's NT Pathworks for Windows NT version 4.1b. This version is supported on both NT 3.5 and NT 3.51.

Note Because of networking incompatibilities for out-of-band data, you may notice a delay in sending attention events to cancel queries (such as using CRTL+C to cancel a query sent by ISQL). The length if the delay is proportional to the size of the result set.

If you experience difficulties establishing connections from VMS clients via DECNet sockets, check the Windows NT application log or the SQL Server error log, and verify that the DECNet sockets Net-Library is loaded correctly. If not, you will see an error message.

If the DECnet sockets Net-Library is loaded properly on the server, you should see a message similar to the following in the Windows NT application log or the SQL Server error log:

Using 'SSMSDECN.DLL' version '6.00.0.0' to listen on '#150'
To check a DECnet socket connection from a client to the server
  • Start the NCP utility on the VMS client and type:

    LOOP NODE node_address

    where

    node_address
    Is the DECnet node address of the Windows NT-based server.

For example, to check the connection between the client and SQL Server at DECnet node address 1.996, start NCP and type:

LOOP NODE 1.996

If the connection is open, the output should look similar to this:

LOOP NODE test started at 22-Jul-1994 9:59:12
   Connect completed to node NTSQL
   Remote node maximum buffer size for loopback: 4096
   Successfully send and receive, message 1.
LOOP NODE test finished successfully at 22-Jul-1994 9:59:13
To verify that SQL Server is listening on DECnet sockets and can accept a client connection
  1. If necessary, copy the client-side DECnet Net-Library from the \SQL60\DLL directory to the same directory on a Windows NT-based computer with Pathworks for Windows NT installed.
  2. On this system, use the SQL Server Client Configuration Utility to change the default Net-Library to DBMSDECN.DLL.
  3. Attempt an ISQL connection with the node address and the DECnet object ID. For example:
    isql -Usa -P -S1.909,#150

    If you can connect with ISQL and execute queries, the server is properly configured to listen on DECnet sockets and is accepting connections.


Part 3 Devices, Databases, and Drives

Devices, Databases, and Drives

The chapters in this part tell you how to manage devices, databases, transaction logs, and drives.

Chapter 5, Managing Devices, describes devices, the operating system files used to store databases, transaction logs, and their backups. Before you can create a new database you must create the device(s) the database will be stored on. This chapter tells you how to create and manage devices.

Chapter 6, Managing Databases, tells you how to create and manage databases and their transaction logs. (A transaction log is a storage area reserved by SQL Server to keep track of transactions made to the database)..

Chapter 7, Managing Drives, helps you improve SQL Server performance by showing you how to efficiently manage the placement of data on storage devices.


Chapter 5 Managing Devices

Managing Devices

Devices are operating system files used to store databases, transaction logs, and their backups. Before you can create a new database, you must create the device(s) the database will be stored on. One device can store many databases, and a database can be stored across more than one device. This chapter tells you how to create and manage devices.

There are two types of devices: database devices and dump devices. Database devices store databases and transaction logs; dump devices store database and transaction log backups. Database devices are stored on disk files. Dump devices can be stored on disks, diskettes, or tapes (or for integration with other applications, named pipes). Only the system administrator (SA) can create devices.

When you install SQL Server, these devices are created:

  • The MASTER database device

    This device is used by the master, model, tempdb, and pubs databases.

  • The MSDBDATA and MSDBLOG database devices

    The MSDBDATA device is used by the msdb (scheduling) database, and the MSDBLOG device is used by its transaction log.

  • Three dump devices

    DISKDUMP, DISKETTEDUMPA, and DISKETTEDUMPB.

    Note Diskette dump devices are supported in order to provide compatibility with earlier releases.

As administrator, you will need to create database devices to support databases and transaction logs, and dump devices to support backup of those databases and transaction logs.

Because creating and dropping devices makes changes to the master database, you should always dump the master database after you add or modify devices.

For more information, choose one of the following topics:

Managing Database Devices

Managing Dump Devices


Managing Database Devices

As an administrator, you will allocate space for, create, modify, expand, drop, mirror, set as a default, and view information about database devices.

For information about database devices, choose one of the following topics:

About Database Devices

Accessing the Device Management Windows

Adding a Database Device

Setting Up Default Database Devices

Displaying Information About Database Devices

Expanding a Database Device

Mirroring a Database Device

Dropping a Database Device

Stored Procedures Used to Manage Database Devices


About Database Devices

After you install a SQL Server, you will need to create the database devices necessary to support the databases that will be created. When you create a database device, you provide both a logical and a physical name.

  • A logical name is a name used by SQL Server to identify the database device. The logical name follows the SQL Server rules for identifiers. For information about these rules, see the Microsoft SQL Server Transact-SQL Reference.

    When using SQL Enterprise Manager (and Transact-SQL statements), you most often refer to the database device by its logical name.

  • A physical name is an operating-system filename that includes a full path and follows the rules for operating-system filenames.

These are examples of physical and logical names for database devices:

Type of file | Example logical name | Example physical name
Database device | CUSTOMER_LIST | C:\SQL60\DATA\CUST.DAT
Database device | RESERVATIONS | D:\DATA\RES_DATA.DAT
Database device | RES_TLOG | D:\TRANLOG\RES_TLOG.DAT

In most cases, at the time you create a database device for a database, you should also create a separate database device for its transaction log. It is important to store a database and its transaction log on separate devices so that you can dump the transaction log separately from the database and so that (if appropriate) you can mirror it. Putting the transaction log on a separate device also increases performance.

The minimum size for a device is 1 MB. Depending on the size of the database to be placed on a device, and depending on whether you plan to put more than one database on a device, you will probably want to make a new device bigger than 1 MB. For information on estimating the size of a database that you will place on a device, see Appendix B, Estimating Database Size.

A database device can be created only on a local disk drive. SQL Server does not support the use of database devices accessed over the network.


Accessing the Device Management Windows

In most cases, database devices are administered by using the Manage Database Devices, New Database Device, and Edit Database Devices windows of SQL Enterprise Manager. These windows can be accessed in several ways.

To access the Manage Database Devices window
  1. From the Microsoft SQL Server 6.0 program group, double-click the SQL Enterprise Manager icon.
  2. From the Server Manager window, select a server.
  3. Open the Manage Database Devices window by using one of these techniques:
    • From the toolbar, choose the Manage Devices button.

    • From the Manage menu, choose Devices.
    • In the Server Manager window, open the tree for the selected server (choose its "" button), click the right mouse button on the Database Devices folder, and then from the drop-down menu that appears, choose Edit.

    After you perform one of those techniques, the Manage Database Devices window appears.

To access the New Database Device window
  1. From the Server Manager window, select a server.
  2. Open the New Database Device window using one of these techniques:
    • Open the Manage Database Devices window, and then choose the New Device button.

    • In the Server Manager window, click the right mouse button on the Database Devices folder, and then from the drop-down menu that appears, choose New Device.

    After you perform one of those techniques, the New Database Device window appears.

Note You can also open the New Database Device window while creating or modifying a database. This allows you to create a new device at the time you create the database or transaction log the new device will support. For more information, see Chapter 6, Managing Databases.

To access the Edit Database Devices window
  1. From the Server Manager window, select a server.
  2. Open the Edit Database Devices window by using one of these techniques:
    • Open the Manage Database Devices window, select a device name, and then choose the Edit Device button.

    • Open the Manage Database Devices window, and then double-click a device name.
    • In the Server Manager window, under the Database Devices folder, double-click the device you want to edit.
    • In the Server Manager window, under the Database Devices folder click the right mouse button on a device, and then from the drop-down menu that appears, choose Edit.

    After you perform one of those techniques, the Edit Database Devices window appears.

For simplicity, each procedure in this chapter will reference only one of these techniques. However, you can substitute the other techniques for opening each window.


Adding a Database Device

You add a database device by using SQL Enterprise Manager or the DISK INIT statement. The following procedure assumes that you are using SQL Enterprise Manager. For information about using the DISK INIT statement, see the Microsoft SQL Server Transact-SQL Reference.

Note If you are planning to use hardware- or operating system-based striping to hold large databases, set up the stripe sets prior to defining devices. For information see Chapter 7, Managing Drives.

To add a database device
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Manage Devices button.

    The Manage Database Devices window appears.

  2. Choose the New Device button.

    The New Database Device window appears.

  3. In the Name box, type a name for the device.
  4. In the Drive box, select a drive on which to place the device.
  5. In the Path box, specify the path of the system file for this device.

    The Path box is filled in automatically using a combination of the name you entered in the Name box and the location of this SQL Server's MASTER device. To change the location, type a different path in the box, or choose the Locate button and select a different directory from the displayed directory tree.

  6. In the Size box, type a size for the device.

    Choose a size that is adequate for the intended use of this device. The Available Storage Space graph displays space available on the local drives. The size is represented in megabytes.

  7. To make the device a default device (a device on which databases are created if no device is specified), select the Default Device checkbox.
  8. To mirror the device, choose Mirroring, and complete the Database Device Mirroring dialog box that appears.

    SQL Server mirroring is used to ensure full recovery and continued operation in the event of media failure. For more information on mirroring, see Chapter 7, Managing Drives.

  9. In the New Database Device window, choose OK.

    The device is created.

When a database device is created, its logical and physical names are entered in the sysdevices table in the master database.

You can also create a new database device while creating or modifying a database. This allows you to create a new device at the time you create the database or transaction log the new device will support. For more information, see Chapter 6, Managing Databases.


Setting Up Default Database Devices

SQL Server maintains a pool of one or more devices that are set as default devices. If you don't specify a database device when you create a database, that database is placed on a default database device selected by SQL Server. Default database devices are used in alphabetical order, and one is filled before another one is used. Only database devices can be default devices. (Dump devices cannot be set as default devices.)

When SQL Server is installed, the MASTER device is the only default database device. You should remove MASTER as a default database device and set up a number of default database devices for users to create databases on.

When creating a device, you have the option of making the new device a default device. When editing an existing device, you have the option of changing its default status.

For example, to use SQL Enterprise Manager to remove the MASTER device from the pool of default devices, you would perform the following procedure.

To remove the MASTER device from the pool of default database devices
  1. In the Server Manager window, select a server, open the server's Database Devices folder, and then double-click the MASTER device.

    The Edit Database Devices window appears.

  2. Clear the Default Device checkbox.
  3. Choose the OK button.
To add a device to the pool of default database devices
  1. Open the Edit Database Devices window for the database device.
  2. Select the Default Device checkbox.
  3. Choose OK.

Note You should dump the master database after setting or clearing default status for any device.

You can also add a database device to or remove it from the pool of default devices by using the sp_diskdefault system procedure. For more information, see the Microsoft SQL Server Transact-SQL Reference.

Setting a default database device marks the device in the sysdevices table as a default database device.


Displaying Information About Database Devices

SQL Enterprise Manager provides several ways to view information about database devices. You can view a list of the database devices on a server, view a graphical representation of the database devices on a server, and view information about an individual database device.

To view a list of the database devices on a server
  1. From the Server Manager window, select a server.
  2. Open the tree for that server (click the server's "" button), and then open the Database Devices folder for that server (click the folder's "" button).

    The database devices for the server are listed.

To view a graphical representation of the database devices on a server
  • From the Server Manager window, select a server, and then from the toolbar, choose the Manage Devices button.

    The Manage Database Devices window appears.

    The Manage Database Devices window lists the logical names of all of the database devices for that server. A graph shows the size of each device, and the space used on each device. Dump devices and mirror devices are not shown.

To view information about an individual database device
  • Open the Manage Databases Devices window for a server, and double-click on a device name.

    The Edit Database Devices window for that device appears.

    The Edit Database Devices window displays the logical name (the Name), the physical name (the Location), the size in MB, and whether or not this is a default device. It also provides a graphical representation of space used.

You can also query the sysdevices system table or run the sp_helpdevice system procedure to view more information about database devices. For more information, see the Microsoft SQL Server Transact-SQL Reference.


Mirroring a Database Device

SQL Server mirroring is used to ensure full recovery and continued operation in the event of media failure. Mirroring a device continuously duplicates the information from one SQL Server device to another. All transactions completed on a mirrored device are copied to its duplicate device. In the event that one device fails, the other contains an up-to-date copy of all transactions.

SQL Server mirroring can be set up at the same time a device is created or edited. Once mirroring has been set up, you can edit the device and mirror, unmirror, or remirror an existing device, or switch to a mirror device.

Note SQL Server mirroring is one way you can mirror a disk for recoverability, but disk mirroring can also be accomplished with the Windows NT Advanced Server software. You can also take advantage of hardware disk arrays that support various RAID levels. In most cases, the use of hardware-based RAID or Windows NT software-based RAID is recommended over SQL Server mirroring.

For information on setting up mirroring, and about using hardware- or software-based RAID, see Chapter 7, Managing Drives.


Expanding a Database Device

If you find you need additional space for a database device¾and if there is adequate space on the storage media¾you can expand the space allocated to that device.

To expand a database device
  1. Open the Edit Database Devices window for the device.

    The Size (MB) box displays the current size of that device.

  2. In the Size (MB) box, type a larger number.

    A database device can be enlarged using this technique, but it cannot be shrunk.

  3. Choose OK.

You can also use the DISK RESIZE statement to increase the size of a database device. For information about the DISK RESIZE statement, see the Microsoft SQL Server Transact-SQL Reference.


Dropping a Database Device

Dropping a device frees up storage space on the server. When you use SQL Enterprise Manager to drop a device, all databases on it are also dropped. Only the SA has permission to drop devices.

Dropping a database device frees the file handle and the device number. This means that you can delete the physical file from the hard disk without shutting down SQL Server. You can also immediately create a new device with that same device number and logical name. (You can use the same physical name as well, as long as you've deleted the physical file.)

There are two ways to drop a device using SQL Enterprise Manager: from the Manage Database Devices window and from the Server Manager window.

To drop a database device using the Manage Database Devices window
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Manage Devices button.

    The Manage Database Devices window appears.

  2. Select a device, and then choose the Delete Device button.

    A confirmation box displays a list of any databases on that device.

  3. To confirm deletion, choose Drop.

    The SQL Server database device is dropped, but the physical file still remains.

  4. Delete the device's operating system file.

    You must delete the device's filename from the directory where it is located. Use File Manager or the operating-system del command. It is not necessary to shut down and restart SQL Server.

To drop a database device using the Server Manager window
  1. In the Server Manager window, select a server, and then open its Database Devices folder.
  2. Click the right mouse button on a device, and then from the drop-down menu that appears, choose Delete.

    A confirmation box displays a list of any databases on that device.

  3. To confirm deletion, choose Drop.
  4. Delete the device's operating system file.

You can also drop a device by using the sp_dropdevice stored procedure. However, when you use sp_dropdevice to drop a device, you must drop all databases on that device before you can drop the device. For information about sp_dropdevice, see the Microsoft SQL Server Transact-SQL Reference.

Dropping a device removes the device from the sysdevices table.


Stored Procedures Used to Manage Database Devices

In addition to using SQL Enterprise Manager, you can also administer database devices using the DISK INIT statement and several system stored procedures. The DISK INIT statement is used to reserve and format physical storage for database devices. A summary of the stored procedures follows. For more information on each, see the Microsoft SQL Server Transact-SQL Reference.

Note that you are not required to use the DISK INIT statement or stored procedures to manage database devices. In most cases, SQL Enterprise Manager is the recommended tool.

Stored procedure | Description
sp_diskdefault | Sets a database device's status to indicate whether the device can be used for database storage when the user does not specify a database device or specifies DEFAULT with the CREATE DATABASE or ALTER DATABASE statement.
sp_dropdevice | Removes a SQL Server database device or dump device.
sp_helpdevice | Reports information about SQL Server database devices and dump devices.
sp_logdevice | Puts the syslogs system table, which contains the transaction log, on a separate database device.


Managing Dump Devices

Dump devices store backup copies of databases and transaction logs. It is important to create dump devices and then perform regular backups to those dump devices, so that you can recover your databases in the case of media failure. Dump devices can be disk files, tapes, or diskettes; or for integration with other applications, named pipes. (Diskette dump devices are supported in order to provide compatibility with earlier releases.)

Because the use of dump devices is associated with backup and restoration activities, the information that follows should be reviewed before you perform the procedures described in Chapter 12, Backing Up and Restoring.

For more information, select one of the following topics:

About Dump Devices

Adding a Dump Device

Displaying Information About Dump Devices

Dropping a Dump Device

Stored Procedures Used to Manage Dump Devices


About Dump Devices

After you install a SQL Server, you will need to create the dump devices necessary to back up the system. When you create a dump device, you provide both a logical and a physical name. The logical name must follow the SQL Server rules for identifiers and can be up to 30 characters. The physical name is an operating-system filename that includes the full path and follows the rules for operating-system filenames, or the universal naming convention (UNC) for network devices.

Following are examples of logical and physical names for dump devices.

Type of dump device | Example of a logical name | Example of a physical name
Disk | TLOGDUMP | C:\SQL60\DATA\TLOG01.DAT
Disk (network) | DATADUMP | \\TERRIER\BACK\DUMP11.DAT
Tape | TAPEDUMP | \\.\TAPE0
Diskette | DISKETTEDUMPA | A:\SQLTABLE.DAT
Named pipe | PIPEDUMP | \\.\PIPE\SQL\DUMP
Null | DISKDUMP | NUL

Following is information about each type of dump device.

About Disk Dump Devices

SQL Server supports both local and network disk dump devices. A local disk dump device is created on a disk drive attached to the local computer. A network disk dump device is created on a shared network directory.

When creating a network disk dump device, you can specify the physical name by using a UNC name (for example, \\TERRIER\PUBLIC\DATABACK.DAT).

Important When creating a dump device on a remote network location, be sure that the account under which SQL Server runs has appropriate write capabilities on the remote machine. Ownership and permission problems can interfere with the use of disk dump devices on network shares. Make certain that appropriate file, directory, and share permissions are given to the account under which SQL Server runs.

If SQL Server is running under the LocalSystem account (which is the default configuration), you need to add the share of the remote dump device to the NullSessionShares Registry key.

\\HKEY_LOCAL_MACHINE
\System
\CurrentControlSet
\Services
\LanmanServer
\Parameters

Name: NullSessionShares
Type: REG_MULTI_SZ
Data: COMCFG

In order to access some network resources, you can assign a user account to the SQL Server service (MSSQLServer). You can still run SQLMail in this case. For more information see Chapter 3, Configuring Servers, and Chapter 18, Setting Up Mail.

About Tape Dump Devices

SQL Server supports local tape dump devices (on tape drives attached to the local computer). Network tape dump devices are not supported.

To create a tape dump device, you must first install a tape drive using Windows NT. For information about Windows NT - supported tape drives, refer to the hardware compatibility list for Windows NT. For information about installing a tape drive, see the drive manufacturer's documentation and the documentation for the Windows NT Setup program.

When creating a tape dump device for SQL Server, you must use the physical name that has been assigned to the tape drive by Windows NT. For example, Windows NT will give this physical name to the first tape drive installed on a computer:

\\.\TAPE0

Additional tape devices on a computer will have a similar name, with the number incrementing for each (\\.\TAPE1, \\.\TAPE2, and so on). If more than one tape drive is installed on a computer, you can determine the number of a particular tape drive by using the Windows NT Backup utility from the Administrative Tools program group.

When dumping to a tape dump device, use only the recommended tapes for the specific tape drive, as documented by the drive manufacturer. If you are using DAT drives, use computer-grade (Digital Data Storage-DDS) DAT tapes. If you do not use a computer grade tape, SQL Server backups will be restricted to a single tape; a database dump that spans multiple tapes will not be allowed.

About Diskette Dump Devices

Two diskette (floppy disk) dump devices are created when SQL Server is installed: DISKETTEDUMPA and DISKETTEDUMPB.

Diskette dump devices are supported in order to provide compatibility with earlier releases. SQL Enterprise Manager cannot be used to initiate a diskette dump, because the console command-line utility must be used to prompt the user and then wait for responses. For information about creating and using diskette disk dump devices, see the Microsoft SQL Server Transact-SQL Reference.

About Named Pipe Dump Devices

Named pipe dump devices allow third-party vendors a flexible and powerful way to connect their own software and provide specialized backup and restoration capabilities.

Named pipe dump devices are not created or administered by using SQL Enterprise Manager or the sp_addumpdevice stored procedure. To use a named pipe dump device, you provide¾as part of a DUMP or LOAD statement¾the name of the named pipe that will be used by a client application.

For more information about using named pipe dump devices, see the information about the LOAD and DUMP statements provided in the Microsoft SQL Server Transact-SQL Reference.

About the Null Device

A special device, named DISKDUMP, is created when SQL Server is installed. Backing up to DISKDUMP sends the data to the NULL device. This dumps data without saving it. You can use the DISKDUMP device name as a bit bucket in conjunction with database or transaction log backups.

Important You cannot retrieve dumps sent to the NULL (DISKDUMP) device.


Adding a Dump Device

You can create a dump device while managing backup and restoration, from the Database Backup/Restore dialog box of SQL Enterprise Manager. Or you can create a dump device directly from the Server Manager window.

To create a dump device
  1. From the Server Manager window, select a server; from the Tools menu, choose Backup/Restore; and then from the Database Backup/Restore dialog box that appears, choose the New button.

    Or from the Server Manager window, select a server, click the right mouse button on the Dump Devices folder, and from the drop-down menu that appears, choose New Dump Device.

    The Create Dump Device window appears.

  2. In the Device Name box, type the logical name for the dump device.

    This name will be used when you back up to or restore from the dump device. The name must follow the rules for identifiers and can be up to 30 characters. If you specify a name longer than 30 characters, the name is truncated.

  3. In the Device Path box, type the physical name for the dump device.

    The physical name is an operating-system filename that includes the full path. Physical names must follow the rules for operating-system filenames or (for network disk devices only) universal naming convention names. Names containing nonalphanumeric characters must be enclosed in quotation marks.

    If you do not remember the path you want to use, you can choose the Locate button and select a path from the directory tree that is displayed.

    For more information about physical names, see About Dump Devices, earlier in this chapter.

  4. Select a device type.
    • Disk creates a dump device file on a hard disk (or other disk media).
    • Tape creates a dump device for a tape drive.
  5. If you selected Tape in step 5, also select or clear the Skip Headers checkbox.

    This option indicates whether ANSI tape labels are read or ignored. Clearing this option tells SQL Server to recognize any existing ANSI tape labels on the tape you are writing to.

    For example, if the ANSI label of a tape warns that it has not expired or that you don't have permission to write to it, selecting this option causes SQL Server to ignore the warning. Or if the tape you are writing to is new (and therefore has no ANSI label), SQL Server writes a new label on the first try. Selecting this option prevents unnecessary retries as SQL Server tries to find a label.

    This allows you to choose between the security of paying attention to ANSI labels and the convenience of ignoring them. In either case, SQL Server still writes the labels.

  6. Choose the Add button.

    The dump device is added. Backups to that device can now be performed.

    Note From File Manager or the MS-DOS command line, a disk dump device will not appear as a file in the specified directory until a backup has been performed to that device.

Another way to add a disk or tape dump device is to use the sp_addumpdevice system procedure. In addition, you can use sp_addumpdevice to add a diskette dump device. For more information, see the Microsoft SQL Server Transact-SQL Reference.

When a dump device is added, its logical and physical names are entered in the sysdevices table in the master database.


Displaying Information About Dump Devices

SQL Enterprise Manager provides several ways to view information about dump devices. You can view a list of dump devices, view information about the backups stored on a device, or view the physical name (path and filename) of a device.

To view a list of dump devices on a server
  1. From the Server Manager window, select a server, and then open the Dump Devices folder.

    The dump devices for this server are listed.

  2. To view information about the backups that have been stored on a dump device, choose the device's "" button.
    • Full database dumps are indicated by a database icon.

    • Transaction log dumps are indicated by a page icon.

Information about dump devices can also be viewed from the Database Backup/Restore dialog box while managing backup and restoration.

To view dump device information while managing backup and restoration
  1. From the Server Manager window, select a server, and then from the Tools menu choose Backup/Restore.

    The Database Backup/Restore window appears. The dump devices for this server are listed.

  2. To view information about the backups that have been stored on a dump device, choose the device's "" button.
    • Full database dumps are indicated by a database icon.

    • Transaction log dumps are indicated by a page icon.

  3. To view header information about the backups that have been stored on a dump device, select the device, and then choose the Info button.

    The Header Information dialog box appears.

    For a description of the information presented in this dialog box, see Chapter 12, Backing Up and Restoring.

To view the physical name of a dump device
  • From the Database Backup/Restore dialog box, select a dump device, and then choose the Edit button.

    The Database Backup/Restore dialog box appears.

    The Device Path box displays the physical name of the dump device.

The sp_helpdevice system procedure can also display information about dump devices. And you can query the sysdevices system table to view information about dump devices. For more information, see the Microsoft SQL Server Transact-SQL Reference.


Dropping a Dump Device

There are two ways to drop a dump device using SQL Enterprise Manager: from the Database Backup/Restore dialog box while you manage backup and restoration, or directly from the Server Manager window.

When you drop a dump device, all data that has been backed up to that device is also dropped.

To drop a dump device from the Server Manager window
  1. In the Server Manager window, select a server, and then open its Dump Devices folder.
  2. Click the right mouse button on a dump device, and then from the drop-down menu that appears, choose Delete.

    A confirmation box appears.

  3. To confirm deletion, choose Yes.

    The dump device is dropped.

  4. Delete the device's operating system file.

    You must delete the device's filename from the directory where it is located. Use File Manager or the operating-system del command. It is not necessary to shut down and restart SQL Server.

To drop a dump device from the Database Backup/Restore dialog box
  1. From the Server Manager window, select a server, and then from the Tools menu, choose Backup/Restore.

    The Database Backup/Restore dialog box appears.

  2. From the Dump Devices list, select a device, and then choose the Edit button.

    The Edit Dump Device dialog box appears.

  3. Choose the Delete button.

    A confirmation box appears.

  4. To confirm deletion, choose Yes.
  5. Delete the device's operating system file.

You can also drop a dump device by using the sp_dropdevice stored procedure. For information, see the Microsoft SQL Server Transact-SQL Reference.

Dropping a device removes the device from the sysdevices table.


Stored Procedures Used to Manage Dump Devices

In addition to using SQL Enterprise Manager, you can also administer dump devices by using system stored procedures. A summary of these stored procedures follows. For more information, see the Microsoft SQL Server Transact-SQL Reference.

Note that you are not required to use these stored procedures to manage dump devices. In most cases, SQL Enterprise Manager is the recommended tool.

Stored procedure | Description
sp_addumpdevice | Adds a dump device to SQL Server.
sp_dropdevice | Removes a SQL Server dump device or database device.
sp_helpdevice | Reports information about SQL Server dump devices and database devices.


Chapter 6 Managing Databases

Managing Databases

Databases reside on database devices. A database can reside on one or more database devices, and each database device can hold a portion of one or more databases. Each database has an associated transaction log, a storage area reserved by SQL Server to keep track of transactions made to the database.

The transaction logs for SQL Server are write ahead, which means that the commands sent to SQL Server are recorded in the log before any of the data in the database is changed. The transaction log is actually another system table, syslogs, but you should not directly query or modify it. The transaction log competes with data for space on a database device; to improve performance, put the transaction log on a separate database device from the database.

Important Devices must be created before their databases are created. Once you have created database devices, you can store databases and their transaction logs on them.

Using SQL Enterprise Manager, you can easily manage databases across the servers of your enterprise. Providing an intuitive and simple-to-use graphical interface, SQL Enterprise Manager allows you to add, list, monitor, modify, expand, and drop databases, and perform management actions for the associated transaction logs. SQL Enterprise Manager can show you charts depicting database size and available space.

Databases can also be managed using Transact-SQL statements and system procedures. For information, see the Microsoft SQL Server Transact-SQL Reference.

For more information about managing databases and transaction logs, choose one of the following topics:

Before Creating Databases

Accessing the Database Management Windows

Creating Databases

Expanding or Shrinking Databases

Expanding or Moving Transaction Logs

Setting Database Options

Displaying Information About Databases

Dropping Databases

Using Databases on Removable Media

For information on improving database performance using options such as striping, RAID, or segments, and for information on protecting data using mirroring¾including use of the disk mirroring available with Windows NT Server¾see Chapter 7, Managing Drives.

For information on dumping and restoring databases and transaction logs, see Chapter 12, Backing Up and Restoring. For information about managing database objects (tables, views, indexes, stored procedures, triggers, defaults, rules, and user-defined datatypes), and for information on improving and optimizing database performance, see the Microsoft SQL Server Database Developer's Companion.


Before Creating Databases

When you create a database, it is important to accurately specify the amount of space to allocate for it. If you allocate too much space, you waste device space that could be used by other databases. If you allocate too little space, the database may run out of storage space. (However, note that if you don't allocate enough storage space for the database, or if the database later grows to use most or all of its allocated space, you will be able to easily expand the room allocated to the database, as long as there is space available on one or more devices.)

Following are some basic concepts to review before you begin to create databases and their associated transaction logs.

SQL Server uses three units of data storage:

  • The page (2KB in size)
  • The extent (8 continuous pages)
  • The allocation unit (32 extents, or 256 pages)

Each fragment of storage for a database must be at least 1 allocation unit ¾ 0.5 MB, or 256 contiguous 2KB pages. The first of the 256 pages is the allocation page. It contains an array that shows how the other 255 pages are used; unlike all other pages, it does not contain database rows.

SQL Server allocates storage space for a database on one or more database devices. SQL Server can theoretically manage as many as 32,767 databases. You can specify which database device, or database devices, to put the database on, and the amount of space to allocate for the database. In addition, you can place the database's transaction log on a separate database device. The following illustration shows the relationship between databases and devices.

If you do not specify a database device, SQL Server places the database on one or more of the database devices specified as default devices in the sysdevices table of the master database. For more information about assigning a database device as default, see Chapter 5, Managing Devices. If you do not specify a size for the database, SQL Server allocates the size of the model database or the size specified by the Database Size configuration option, whichever is larger.

Unless you are creating very small, non-critical databases, you should always place the transaction log on a separate device from its database. This improves performance and allows you to keep backups of the log.

In general, you should allocate from 10 to 25 percent of your database size for the transaction log. This is a rough guideline, and the size will vary considerably according to database usage. If you frequently modify a database, the transaction log can grow quite large, so it's a good idea to monitor the size of your log to determine how much space you will need.

To check the space used by a database's transaction log
  • From the database, type:

    dbcc checktable (syslogs)

You can also use another DBCC command, DBCC SQLPERF (LOGSPACE), to check the space used by a database's transaction log. For information on using DBCC CHECKTABLE (SYSLOGS) and DBCC SQLPERF (LOGSPACE), see the Microsoft SQL Server Database Developer's Companion.

Initially, only the system administrator has permission to create databases. However, the SA can grant permission to create databases to other SQL Server users, and the SA can change database ownership. For more information about permissions, see Chapter 8, Security Concepts.

The minimum size allowed for a new database is determined by the size of the model database. When SQL Server is installed, the model database is allocated 1 MB of storage space (unless you have upgraded from a previous version of SQL Server, in which case model will still be allocated 2 MB). For information on changing the size of the model database, see Expanding or Shrinking Databases, later in this chapter.

For more information about estimating database size, see Appendix B, Estimating Database Size. For information on reducing allocated storage space, see Expanding or Shrinking Databases, later in this chapter.


Accessing the Database Management Windows

In most cases, databases are administered using the Manage Databases, New Database, and Edit Database windows of SQL Enterprise Manager. These windows can be accessed several ways.

To access the Manage Databases window
  1. From the Microsoft SQL Server 6.0 program group, double-click the SQL Enterprise Manager icon.
  2. From the Server Manager window, select a server.
  3. Open the Manage Databases window using one of these techniques:
    • From the toolbar, choose the Manage Databases button.

    • From the Manage menu, choose Databases.
    • In the Server Manager window, open the tree for the selected server (choose the "" button), click the right mouse button on the Databases folder, and then from the drop-down menu that appears, choose Edit.

    After you perform one of those techniques, the Manage Databases window appears.

    Choose the Legend button (under the toolbar) to view a legend explaining the graph.

To access the New Database window
  1. From the Server Manager window, select a server.
  2. Open the New Database window using one of these techniques:
    • From the Manage Databases window, choose the New Database button.

    • In the Server Manager window, open the tree for the selected server (choose the "" button), click the right mouse button on the Databases folder, and then from the drop-down menu that appears, choose New Database.
    • In the Server Manager window, under the Databases folder, click the right mouse button on a database, and then from the drop-down menu that appears, choose New Database.

    After you perform one of those techniques, the New Database window appears.

    Choose the Legend button (under the Devices on Server title) to view a legend explaining the graph.

To access the Edit Database window
  1. From the Server Manager window, select a server.
  2. Open the Edit Database window by using one of these techniques:
    • In the Manage Databases window, select a database name, and then choose the Edit Database button.

    • In the Manage Database window, double-click on a database name.
    • In the Server Manager window, under the Databases folder, double-click on the database you want to edit.
    • In the Server Manager window, under the Databases folder, click the right mouse button on a database, and then from the drop-down menu that appears, choose Edit.

    After you perform one of those techniques, the Edit Database window appears.

For simplicity, each procedure in this chapter will reference only one of these techniques. However, you can substitute the other techniques for opening each window.


Creating Databases

You add a database using SQL Enterprise Manager or the CREATE DATABASE statement. This chapter describes the use of SQL Enterprise Manager. For information about using CREATE DATABASE and other statements, see the Microsoft SQL Server Transact-SQL Reference.

Creating a database allocates storage space for the database on a device. When you create a database, a transaction log is also created to record all transactions performed on that database. You should store the transaction log on a different device from the database to simplify recovery and to improve performance. If you do not specify a different device, the log is created as part of the database.

To create a database
  1. From the Server Manager window, select a server; then from the toolbar, choose the Manage Databases button.

    The Manage Databases window appears.

  2. Choose the New Database button.

    The New Database window appears. A default device is automatically listed in the Data Device box. A graph lists the devices for that server and shows the size and available space for each.

  3. In the Name box, type a name for the database.

    The name must comply with the SQL Server rules for identifiers. For information about these rules, see the Microsoft SQL Server Transact-SQL Reference.

  4. From the list in the Data Device box, select a database device on which to place the data. Or to create a new device for this database, select <new> and complete the New Database Device dialog box that appears.

    When you open the New Database window, the Data Device box is automatically filled with the name of the first (sorted alphabetically) device. If you do not change the entry, that device is used.

    Refer to the graph at the bottom of the dialog box for a display of the devices on the server and the available space on each.

  5. In the Data Device Size box, type the amount of space, in megabytes, to allocate on that device for the database.

    By default, the maximum space available on the selected device is entered in this box. The legal values for Data Device Size range from 1 MB through 2 (23) MB. If the size you request is unavailable, SQL Enterprise Manager displays a message showing how much space is available.

  6. From the list in the Log Device box, select a device on which to place the transaction log. Or to create a new device for this transaction log, select <new> and complete the New Database Device dialog box that appears.

    When you open the New Database window, the Log Device box shows (none) selected. Unless you are creating very small, noncritical databases, you should always place the transaction log on a separate device from its database. This improves performance and allows you to keep backups of the log.

    Refer to the graph at the bottom of the dialog box for a display of the devices on the server and the available space on each.

  7. In the Log Device Size box, type the amount of space, in megabytes, to allocate on that device for the transaction log.

    By default, the maximum space available on the selected device is entered in this box. In general, you should allocate from 10 to 25 percent of your database size for the transaction log. If the size you request is unavailable, SQL Enterprise Manager displays a message telling you how much space is available.

  8. Optionally, if you will be loading a backup into this database before using it, choose the Create for Load option.

    This results in more rapid database creation. With this option the pages are not zero-initialized when the database is created. However, users other than DBO cannot access the database until a backup is loaded into the database using SQL Enterprise Manager or the LOAD statement, and the database option DBO Use Only is cleared (off). For more information about this option, see the discussion of CREATE DATABASE FOR LOAD in the Microsoft SQL Server Transact-SQL Reference.

  9. Choose OK.

    The database is added.

Note Each time you create a database, you should back up the master database. This makes recovery easier and safer in case master is later damaged. For information, see Chapter 12, Backing Up and Restoring.

When a database is created and the space allocation is specified for the database devices, SQL Server initializes every bit in the database devices to 0 (except for the allocation page for each 256-page block). However, if a device has not previously contained data, then the device will not be reinitialized, and database creation time is significantly reduced.

A database can occupy different amounts of space in each of several database devices. For information about extending the database across other devices, see Expanding or Shrinking Databases, later in this chapter.

Databases can also be created by using the CREATE DATABASE statement. The sp_helpdevice system procedure can be used to display a list of available devices that a new database can be placed on. For information, see the Microsoft SQL Server Transact-SQL Reference.

The creation of a new database is recorded in the sysdatabases table. Entries are also made in sysusages, which keeps track of the space allocated to databases.


Expanding or Shrinking Databases

To expand a database is to allocate additional device space to the database. If a database grows so that it uses most or all of the space allocated for it, you can expand it.

You expand a database using SQL Enterprise Manager or the ALTER DATABASE statement. This chapter describes the use of SQL Enterprise Manager. For information about using ALTER DATABASE and other statements, see the Microsoft SQL Server Transact-SQL Reference.

You can expand a database by allocating more space on its existing device or by allocating space on another device. A database can occupy more than one database device with different amounts of space on each. When expanding a database, you must increase the size of the database by at least 1 MB. Permission for expanding a database defaults to the database owner and is automatically transferred with database ownership. For information on permissions and database ownership, see Chapter 8, Security Concepts.

You cannot expand the master database on any device other than MASTER. If the master database requires more space, you can use SQL Enterprise Manager or the DISK RESIZE statement to increase the size of the MASTER device, and then expand the master database on the MASTER device. For information on expanding a device, see Chapter 5, Managing Devices.

To expand a database
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Manage Databases button.

    The Manage Databases window appears.

  2. Select a database name, and then choose the Edit Database button.

    The Edit Database window appears.

    Under Information, the Size field shows the amount of space allocated to the database, and the Space Available field shows the amount of unused allocated space.

  3. Choose the Expand button.

    The Expand Database dialog box appears.

  4. From the list in the Data Device box, select a database device on which to expand the database. Or to create a new device for the database expansion, select <new> and complete the New Database Device dialog box that appears.

    Refer to the graph at the bottom of the dialog box for a display of the devices on the server, and the available space on each.

  5. In the Data Device Size box, type a size, in megabytes, to allocate to the database.

    If this is a device the database already has space on, enter the amount of additional space to allocate (not the total space). The default is the maximum space available on the selected device.

  6. Choose OK.

    The Edit Database window returns.

  7. Choose OK.

Note While the database is expanded, the transaction log can also be expanded. For information about expanding transaction logs, see Expanding or Moving Transaction Logs, next in this chapter.

You can also expand the tempdb database, including tempdb in ram. However, when tempdb resides in RAM, it can only be altered 10 times without requiring the server to be shut down and restarted. Altering tempdb while it is in RAM causes each alteration of the database to allocate a new "chunk" of contiguous memory to tempdb. This memory, although it is contiguous, is not necessarily located next to the existing portion(s) of tempdb in RAM. To obtain maximum performance, the server should be stopped and restarted after tempdb is altered. For information about tempdb and tempdb in ram, see the Microsoft SQL Server Transact-SQL Reference.

If a database has been allocated unused space that you would like to recapture, you can shrink the database. In order to shrink a database, the database must be in single-user mode, but SQL Enterprise Manager sets this option automatically for you while it is shrinking the database.

To shrink a database
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Manage Databases button.

    The Manage Databases window appears.

  2. Select a database name, and then choose the Edit Database button.

    The Edit Database window appears.

    Under Information, the Size field shows the amount of space allocated to the database, and the Space Available field shows the amount of unused allocated space.

  3. Choose the Shrink button.

    A message appears, informing you that the database will be set to single-user mode during the shrink operation, and asking whether or not to continue.

  4. Choose Yes.

    The Shrink Database dialog box appears.

    There may be a delay before the minimum size is shown.

  5. Enter a smaller size in the Database Size (MB) box, and then choose the OK button.

    The database is set to single-user mode, the database is shrunk, and then the single-user setting is cleared. The Edit Database window returns.

  6. Choose OK.

You can also reduce the allocated space using DBCC SHRINKDB. To shrink the master or tempdb databases you must start the server in single-user mode (use the sqlservr command-line executable with the -m parameter) and use the DBCC SHRINKDB command. For information, see the Microsoft SQL Server Transact-SQL Reference.

Note After you expand or shrink a database, back up the master database.


Expanding or Moving Transaction Logs

A transaction log is a storage area reserved by SQL Server to keep track of transactions made to a database. The transaction log is actually another system table, syslogs, but you should not directly query or modify it.

To expand a transaction log is to allocate additional device space to the log. If a log becomes larger than the space you have allocated for it, you can expand it.

You expand a transaction log using SQL Enterprise Manager or the ALTER DATABASE statement. This chapter describes the use of SQL Enterprise Manager. For information about using ALTER DATABASE and other statements, see the Microsoft SQL Server Transact-SQL Reference.

If you need to expand the transaction log, you must expand it on a device separate from the one on which the database resides. If the transaction log has already been placed on a separate database device from the database, you can expand the amount of space allocated to the log on that device, or you can expand it on another device. The LOGSEGMENT, which stores the logs, is automatically mapped to the new fragment of space on the database device. All database devices available within SQL Server can be used to increase log space.

If the log is not on a separate database device, you can increase the amount of space allocated to it by adding a new database device and then moving the transaction log to that database device (as described later in this topic).

To expand a transaction log
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Manage Databases button.

    The Manage Databases window appears.

  2. Select a database from the names adjacent to the graph, and then choose the Edit Database button.

    The Edit Database window appears.

  3. Choose the Expand button.

    The Expand Database dialog box appears.

  4. From the list in the Log Device box, select a device on which to place the transaction log. Or to create a new device for this transaction log, select <new> and complete the New Database Device dialog box that appears.

    Refer to the graph at the bottom of the dialog box for a display of the devices on the server and the available space on each.

  5. In the Log Device Size box, type a size, in megabytes, to allocate to the log.

    If this is a device the log already has space on, enter the amount of additional space to allocate (not the total space). The default is the maximum space available on the selected device.

  6. Choose OK.

    The Edit Database window returns.

  7. Choose OK.

Note After you expand a transaction log, back up the master database.

To move a transaction log is to place it on a different device. If a transaction log was created on the same device as its database, then it must compete with data for space on the database device, and you can improve performance by moving it to another device.

Use sp_logdevice to move a transaction log to another device. Because sp_logdevice affects only future allocations of space for the transaction log, the first pages of the log remain on the same device as the data, leaving them temporarily vulnerable. The transaction log remains on the original database device until the currently allocated extent (8 2KB pages) has been filled and the transaction log has been dumped. Only the database owner can move the log. You cannot move the master database's transaction log.

The following steps show how to use sp_logdevice to move a transaction log.

To move the transaction log
  • Type

    sp_logdevice dbname, database_device

    where

    dbname
    Is the name of the database whose transaction log you want to move to a different device.
    database_device
    Is the logical name of the database device you want to put the transaction log on. The transaction log must have been expanded onto this device using SQL Enterprise Manager or the ALTER DATABASE statement.

The following steps illustrate moving the entire transaction log to a new device that will contain only the transaction log.

To move a transaction log
  1. Use SQL Enterprise Manager to expand the transaction log to a new device.
  2. Use sp_logdevice to move the transaction log to a new device.

    Note that sp_logdevice affects only future allocations of space for the log. The remaining steps in this procedure must be accomplished before the log moves.

  3. Complete enough transactions to fill the extent of eight pages that the log is currently using. You can run DBCC CHECKTABLE on the syslogs table to determine when a new page is used. When the total of the pages has increased by eight, the log is on the new device.
  4. Ensure that enough time passes that all active transactions on the old database device have completed.
  5. Dump the transaction log (using either SQL Enterprise Manager or DUMP TRANSACTION), which removes from the log all pages written to disk. As long as there are no active transactions in the portion of the log on the old database device, all of the log pages on the old database device are removed.
  6. Run the sp_helplog system procedure to verify that the complete log is on the new log device.

Note After you move a transaction log, back up the master database.

For more information on sp_logdevice, DBCC CHECKTABLE, DUMP TRANSACTION, and sp_helplog, see the Microsoft SQL Server Transact-SQL Reference.

When you expand a database, a new row is added to the sysusages table for each new portion of space allocated to the database. When a transaction log is expanded or moved, the sysdatabases and sysusages tables are updated to reflect the new location of the log.


Setting Database Options

You can set a number of options for most databases. For the master database, you can only set one option, Truncate Log on Checkpoint.

To set database options
  1. From the Server Manager window, select a server, and then open that server's Databases folder and double-click a database name.

    The Edit Database window for that database appears.

  2. Choose the Options tab.

    The Options window appears.

  3. Select or clear the check boxes for each of the options.
    Select Into / Bulk Copy
    When this option is selected, nonlogged operations can be performed.

    When this option is on, you can perform the following nonlogged operations: use the nonlogged WRITETEXT and UPDATETEXT statements, use the SELECT INTO statement, or use fast bcp to do nonlogged loads.

    If this option is set, tables with no indexes are loaded using bcp without logging the data changes in the transaction log. This results in faster loads. If this option is not set, or if the table has indexes, bcp in operations are logged.

    You do not have to turn this option on to use SELECT INTO on a temporary table, because tempdb is never recoverable.

    When the Select Into / Bulk Copy option is set, you are allowed to dump the transaction log only if you have not performed any nonlogged operations (select into, fast bulkcopy, or nonlogged WRITETEXT or UPDATETEXT statements) since the last database dump. If nonlogged operations have occurred since the last database dump, executing the DUMP TRANSACTION statement produces an error message instructing you to use DUMP DATABASE instead.

    By default, the Select Into / Bulk Copy option is set to off in newly created databases. To change the default, set this option in the model database.

    DBO Use Only
    When this option is selected, only the database owner can access the database. (This status is indicated by the database icon in the Server Manager window. Choose Server Manager's Display Legend button for more information.)
    No Checkpoint on Recovery
    Defines whether or not a checkpoint record is added to the database after it is recovered during a SQL Server startup. If this option is off (cleared)¾the default condition¾a checkpoint record is added.

    The No Checkpoint on Recovery option is useful when an up-to-date copy of a database is kept. In these situations, there are a "primary" and a "secondary" database. Initially, the primary database is dumped and loaded into the secondary database. Then, at intervals, the transaction log of the primary database is dumped and loaded into the secondary database. If this option is on (selected) in the secondary database, no checkpoint record is added to a database after it is recovered, so that subsequent transaction log dumps from the primary database can be loaded into it.

    Read Only
    When this option is selected, users can view the contents of a database but cannot modify data. (This status is indicated by the database icon in the Server Manager window. Choose Server Manager's Display Legend button for more information.)
    Single User
    When this option is selected, only one user at a time can access the database. When this option is selected, the Truncate Log on Checkpoint option is not supported. Truncate the log after single user operations are completed. (This status is indicated by the database icon in the Server Manager window. Choose Server Manager's Display Legend button for more information.)
    Columns Null by Default
    Selecting this option is the equivalent of setting sp_dboption ANSI null default option to TRUE, which changes the database default Nullability to NULL. For more information¾including a discussion of nullability¾see the Microsoft SQL Server Transact-SQL Reference.
    Truncate Log on Checkpoint
    When this option is selected, the transaction log is truncated (committed transactions are removed) every time the CHECKPOINT process occurs (usually about once per minute).

    It can be useful to set this option to on while doing development work during which backups of the transaction log are not needed. If this option is off (the default condition) and the transaction log is never dumped, the transaction log continues to grow, and you can run out of space in your database.

    While the Truncate Log on Checkpoint option is on, you cannot dump the transaction log because the log is being truncated, and changes therefore are not recoverable from transaction log dumps. In this situation, executing the DUMP TRANSACTION statement produces an error message instructing you to use DUMP DATABASE instead.

    By default, the Truncate Log on Checkpoint option is set to off in newly created databases. To change the default, set this option in the model database. The Truncate Log on Checkpoint option is set to on by default for the master database. It is advised that you leave this value set to on to avoid filling up the transaction log for the master database. Since you cannot dump only the transaction log for the master database, there is no benefit in changing this value.

  4. Choose OK.


Displaying Information About Databases

You have several ways to view information about databases and their transaction logs.

To view a list of the databases on a server
  • In the Server Manager window, select a server and open the Databases folder.

    The databases for this server are listed.

To view a graphical representation of all the databases on a server
  • From the Server Manager window, select a server, and then from the toolbar, choose the Manage Databases button.

    The Manage Databases window appears. A graph shows the total size of each database, and for a selected database displays the space used and the space available.

    Choose the Legend button (under the toolbar) to view a legend explaining the graph.

You can also view information about an individual database.

To view information about an individual database
  1. From the Server Manager window, select a server, open its Databases folder, and then double-click on a database.

    The Edit Databases dialog box appears, displaying information about the database.

  2. To view the option settings for this database, select the Options tab.

    The Options window appears, displaying the setting of the database options.

    For information about database options, see Setting Database Options, earlier in this chapter.

  3. To view the permissions set for this database, select the Permissions tab.

    The Permissions windows appears, displaying the statement permissions set for this database.

    For information about database permissions, see Chapter 8, Security Concepts.

Although the Current Activity window of SQL Enterprise Manager primarily displays information about server-wide activity, the SA can open it to review database-related activity information.

To view current activity
  • From the Server Manager window, select a server, and then from the toolbar, choose the current Activity button.

    The Current Activity window appears.

    For an explanation of the Current Activity window and the information it provides, see Chapter 19, Monitoring Server Activity and Performance.

These system procedures can also be used to display database-related information.

System procedure | Description
sp_helpdb | Reports information for all the databases on SQL Server, or if you supply a database name, about that database only. Provides database name, database size, owner, database ID, creation date, and options set. For an individual database, also lists device fragments, fragment size, fragment usage (data or log), device used, and device segments.
sp_helplog | Reports the name of the device that contains the first page of the transaction log.
sp_spaceused | Provides a summary of the storage space that a database, transaction log, or database object is using. Allows you to monitor the amount of space available.

You can monitor a database's transaction log by running sp_spaceused against syslogs. It is a good idea to do this regularly. The transaction log can grow rapidly if there are frequent database modifications. If the transaction log is not on a separate database device, then space can become a problem because the log competes with the rest of the database for space.

For information on using the sp_helpdb, sp_helplog, and sp_spaceused system procedures, see the Microsoft SQL Server Transact-SQL Reference.

Another way to see how much space is used by the transaction log is to use the DBCC CHECKTABLE (SYSLOGS) or DBCC SQLPERF (LOGSPACE) commands. You can also continuously monitor log space using SQL Performance Monitor. For information, see Chapter 19, Monitoring Server Activity and Performance, and the Microsoft SQL Server Transact-SQL Reference.

You can write your own queries to get information about the amount of physical storage space available on a SQL Server. To do this, use the master database and query the sysdevices table. For example, to determine the total number of 2K blocks of storage space that exist on a SQL Server, you could issue this query against sysdevices:

select sum(high - low)
from sysdevices
where status in (2, 3)

----------------------
7168

(1 row affected)

You can also query the sysdatabases system table to view information about databases, and the sysusages system table to view information about the space allocated to databases.

For information about syslogs, sysdevices, sysdatabases, and sysusages, see the Microsoft SQL Server Transact-SQL Reference.

Note You should not update the system tables directly.


Dropping Databases

Dropping a database removes all its objects and frees the storage space allocated to it. All references to the dropped database in the master database system tables are also removed. After you drop a database, all the login IDs that used that database as their default database will use master as their default database instead.

You cannot drop the master, model, or tempdb databases. You cannot drop a database that is open for reading or writing by any user. You cannot drop a published database (a database that is participating in replication by publishing some or all of its tables). However, you can drop databases marked suspect or offline. For information on suspect and unrecovered databases, see Part 8, Troubleshooting.

Only the database owner and the SA have permission to drop databases. This permission cannot be transferred.

Databases can be dropped by using the Manage Databases and Server Manager windows.

To drop a database from the Manage Databases window
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Manage Databases button.

    The Manage Databases window appears.

  2. Select a database name, and then choose the Delete Database button.

    A confirmation dialog box appears.

  3. Choose Yes.

    The database is dropped.

Another way to drop a database is to delete it from the Server Manager window.

To delete a database using the Server Manager window
  1. From the Server Manager window, select a server, and then open the Databases folder for that server.

  2. Click the right mouse button on the database, and then from the drop-down menu that appears, choose Delete. Or select the database and press the Del key.

    A confirmation dialog box appears.

  3. Choose Yes.

    The database is dropped.

Note After you drop a database, you should back up the master database.

You can also use the DROP DATABASE statement to drop a database. For information, see the Microsoft SQL Server Transact-SQL Reference.

Dropping a database removes references to that database from the sysdatabases and the sysusages tables.


Using Databases on Removable Media

With Microsoft SQL Server 6.0, you can create databases for distribution on removable media. You can distribute these databases on read-only removable media, such as CD-ROM, or you can distribute on writable removable media, such as floppy drives, WORM drives, or optical drives.

The removable media installation process copies a database device containing the system catalog tables and the transaction log onto the server's disk. This allows you to create or administer users, permissions, views, and stored procedures for the database, while keeping your data on read-only removable media.

Note After installing a database on removable media, do not attempt to modify (write to) the read-only data on the removable media.

Although the procedures presented in this section primarily describe the administration of databases and devices on removable media, some of the procedures that follow can also be used to administer normal databases and devices residing on fixed storage media.

To support databases on floppy disks, the minimum user database size can now be made as low as 1 MB. This allows a complete database to be created and used from most types of floppy disks. Note that the new default database size of 1 MB applies only to a new installation. Upgrading does not change the size of model. System tables reserve about 512K in a new user database, so with a newly created 1 MB database, only about 0.5 MB is available for data tables. Note that if you add objects to your model database, you may need to increase the default database size.

For more information, choose one of the following topics:

Creating a Removable Media Database

Certifying a Removable Media Database

Installing a Removable Media Database

Placing a Database Online or Offline

Uninstalling a Database

Stored Procedures Used for Removable Media Databases


Creating a Removable Media Database

A database that will later be distributed on removable media must conform to these guidelines:

  • The database must be created on new devices.
  • The database must be created on devices that are not and will not be used by any other databases. This ensures that the first fragment begins at the start of the device and that any additional fragments that may be created by altering the database will be contiguous and in the proper sequence.
  • The database should use three or more devices. Place the system catalog tables on one device, the transaction log on one device, and the data tables on one or more devices.

To make certain that the database you create conforms to these requirements, create the database using the sp_create_removable stored procedure. This stored procedure creates three or more devices and places the database on those devices. One device holds the system catalog tables, a second holds the transaction log, and the third and subsequent devices hold data tables. You must be the SA to use sp_create_removable.

To create a database that can later be distributed on removable media
  • Type

    sp_create_removable dbname, syslogical, 'sysphysical', syssize,
    loglogical, 'logphysical', logsize, datalogical1, 'dataphysical1', datasize1
    [... , datalogical16, 'dataphysical16', datasize16]

    where

    dbname
    Is the name of the database that will be created for use on removable media.
    syslogical
    Is the logical name of the device that will contain the system catalog tables.
    sysphysical
    Is the physical name, including a fully qualified path, of the device that will hold the system catalog tables.
    syssize
    Is the size, in megabytes, of the device that will hold the system catalog tables. The minimum syssize is 1.
    loglogical
    Is the logical name of the device that will contain the transaction log.
    logphysical
    Is the physical name, including a fully qualified path, of the device that will contain the transaction log.
    logsize
    Is the size, in megabytes, of the device that will contain the transaction log. The minimum logsize is 1.
    datalogical
    Is the logical name of a device that will contain the data tables.

    There must be at least one data device. The maximum is 16 data devices. In general, you will create more than one data device when the database is expected to be large and will need to be distributed on multiple disks.

    dataphysical
    Is the physical name, including a fully qualified path, of a device that will contain data tables.
    datasize
    Is the size, in megabytes, of a device that will contain data tables. The minimum datasize is 1.

For example:

sp_create_removable inventory,invsys,'c:\sql60\data\invsys.dat',2,
   invlog,'c:\sql60\data\invlog.dat',4,
   invdata,'c:\sql60\data\invdata.dat',10

For more information about using sp_create_removable, see the sp_create_removable System Stored Procedure topic in the Microsoft SQL Server Transact-SQL Reference.

After the database has been created, perform database development in the normal manner but following these rules:

  • Keep the devices exclusive. Do not add any other databases or logs to the devices used by the database.
  • Keep the SA as DBO of the database.
  • Do not add users to the database, and do not change user permissions. (However, groups can be added and permissions granted to groups.)
  • Do not reference objects outside the database (for example, do not create views, stored procedures, or triggers referencing objects outside the database), since those objects will not be available when the database is distributed.

The device created for the transaction log is used only during database development. (When database development is complete you will run sp_certify_removable, which will truncate the transaction log, move it to the system device, and drop the log device, among other actions.)

As an alternate development method, you can create and develop a database normally, run sp_create_removable to create the new database that will be distributed on removable media, and then use SQL Transfer Manager to copy the data tables from the original database to the new database. After that, you can certify the database by using sp_certify_removable.

Optionally, you can also create one or more that can be used to add login IDs and database users and to grant permissions after the database is distributed and installed.


Certifying a Removable Media Database

When database development is complete, use the sp_certify_removable stored procedure to prepare the database for distribution on removable media. This stored procedure checks that there are no user-created objects in the database, no permissions granted to users, that the SA is the DBO and the owner of all database objects, and that all fragments are contiguous and in sequence. It also truncates the transaction log, moves it to the system device, drops the log device, and sets the database to offline.

The SA must be owner of the database and all database objects because SA is a known user who exists on all SQL Servers and can be counted on to exist when the database is later distributed and installed.

To certify that a database is configured properly for distribution on removable media
  • Type:

    sp_certify_removable dbname[, AUTO]

    where

    dbname
    Is the name of the database to be verified.
    AUTO
    As necessary, gives ownership of the database and all database objects to the SA, and drops any user-created database users and any permissions they may have.

For example:

sp_certify_removable inventory

If the preceding indicates, for example, that user-created users exist in the database, you could then issue the stored procedure by using the AUTO option:

sp_certify_removable inventory,AUTO

If the database is configured properly, this stored procedure sets the database offline and returns information that will be required when the database is later installed using sp_dbinstall. It returns the physical and logical names and the size in megabytes of the system and data devices. Make a note of this information, and provide it¾along with the distribution disk¾to users who will be installing the removable media database.

If you run this stored procedure without the AUTO option and it returns information indicating that the SA is not the DBO, that user-created objects exist, that the SA does not own all objects in the database, or that non-default permissions have been granted, then you have two choices. You can correct those conditions normally, using SQL Server tools and procedures, and then run sp_certify_removable again, or you can simply run sp_certify_removable by using the AUTO option.

Note that this stored procedure only checks for users and user permissions. It is permissible to add groups to the database and to grant permissions to those groups.

For more information about using sp_certify_removable, see the sp_certify_removable System Stored Procedure topic in the Microsoft SQL Server Transact-SQL Reference.

Once the database has been certified, it can be copied, and then that master copy can be reproduced for distribution. Before reproducing the master copy onto distribution disks, you can compare files to ensure that the master copy is identical to the original. For example, to use the fc utility in Windows NT to compare the device files in two directories, you could type:

fc  c:\sql60\data\remove\*.dat  e:\manu\*.dat

For more information about the fc utility, see your documenatation for Windows NT.

When the database is distributed, be sure to include the information returned by sp_certify_removable (the physical and logical names and the size, in megabytes, of the system and data devices).


Installing a Removable Media Database

Use sp_dbinstall to install a removable media database. sp_dbinstall must be run once for each device of the database. It copies the system device to the hard disk (which places the system catalog tables and the transaction log on read-write media). It can leave the data device on the distribution media (usually, a CD), or copy it to the hard disk, but it always remains read-only.

The information required by the sp_dbinstall parameters was provided when the database was verified using sp_certify_removable. This information should have accompanied the distribution disk.

Databases are installed as offline (unavailable). Place the newly installed database online (ready to be used) using sp_dboption.

To install a database and place it online
  1. Place the removable media into the drive.
  2. Run sp_dbinstall to install the system device. Type:

    sp_dbinstall database,logical_dev_name,'physical_dev_name',size,
    'devtype'[,'location']

    where

    database
    Is the name of the removable media database being installed.

    Any valid database name conforming to the SQL Server rules for identifiers can be used. You are not required to enter the database name originally used for this database during development.

    logical_dev_name
    Is the logical name of the device being installed.
    physical_dev_name
    Is the physical name, including the fully qualified path, of the device being installed. The path entered here is the path to the device on the distribution media.
    size
    Is the size, in 1 MB blocks, of the device being installed.
    devtype
    Indicates the type of device that is being installed.

    SYSTEM indicates that the device being installed contains the system catalog tables and the transaction log. The system device must be installed before the data device.

    DATA indicates that the device being installed contains data tables. Data devices must be installed after the system device. Note that even if a data device will be left on the distribution media, it must be installed by using this stored procedure.

    If the database contains more than one data device, this stored procedure must be run once for each device.

    location
    Indicates the destination location to which the device will be copied from the distribution media. This is usually a destination on the computer's local hard disk. The location is a fully qualified filename, including the drive, directory, and filename of the device. The referenced directories must already exist (sp_dbinstall will not create them).

    A location is required for the system device. It is optional for the data device (since the data device can be left on the distribution media).

    Before the database can be used (that is, can be set online using sp_dboption), all its devices must be available. This means that if a database¾because of size¾has been distributed on several CDs with a different data device on each CD, and if the computer is equipped with only one CD drive, then as each device is installed, sp_dbinstall must be provided a location parameter for all but one of the devices, so that all but one of the data devices are copied off the distribution CDs onto the computer's local hard disk. If this is done, only one CD will need to be in the CD drive when the database is used. To eliminate all need for a CD disk when using the database, all the data devices can be copied.

    For example:

    sp_dbinstall inventory,invsys,'e:\invsys.dat',2,'SYSTEM',
   'c:\sql60\data\invsys.dat'
  3. Run sp_dbinstall again to install the data device.

    For example:

    sp_dbinstall inventory,invdata,'e:\invdata.dat',10,'DATA'
  4. Run sp_dboption to place the database online. Type:

    sp_dboption dbname,offline,FALSE

    where

    database
    Is the name of the database being placed online.
    offline
    Is the sp_dboption option being set.
    FALSE
    Is the setting for offline.

    When offline is TRUE, the database is offline. When FALSE, the database is online and can be used.

    For example:

    sp_dboption inventory, OFFLINE, FALSE

    When a database is placed online, any needed removable disk must be in the disk drive. A disk is needed if it contains a data device that was not moved to the local hard disk during installation.

  5. Now that the database is online, administer the database in the normal manner to add database users, set permissions, and add views and stored procedures.

Note After you install a database, you should back up the master database.

For more information about using sp_dbinstall and sp_dboption, see the sp_dbinstall System Stored Procedure and sp_dboption System Stored Procedure topics in the Microsoft SQL Server Transact-SQL Reference.


Placing a Database Online or Offline

Placing a database online makes it ready to be used. All devices belonging to the specified database are opened (if they are not already open) and marked nondeferred, and the database is recovered and becomes available for use. Recovery is skipped if the database is set as read only.

Placing a database offline sets the database as unavailable and allows the storage media (CD or other) to be removed from the drive. All devices belonging to that database are closed and marked as deferred, except those that contain space belonging to other online databases. Databases placed offline are not recovered automatically at server startup.

Before a removable media disk is removed from a drive, all databases on that disk must be placed offline.

Note If you remove the storage media from the drive without first placing the database offline, you can later receive operating system error messages.

Use the sp_dboption stored procedure to place a database online or offline.

To place an installed database online
  1. If necessary, place the removable media into the drive.

    When a database is placed online, any needed removable disk must be in the disk drive. A disk is needed if it contains a data device that was not moved to the local hard disk during installation.

  2. Run sp_dboption using the offline, false option.

    For example, to place the database inventory online, from the Query Analyzer in SQL Enterprise Manager, use:

    sp_dboption inventory,offline,FALSE
To place a database offline
  1. Make sure the database has no active users.

    View active users by opening the Current Activity window of SQL Enterprise Manager.

  2. Run sp_dboption using the offline, true option.

    For example, to place the database inventory offline, from the Query Analyzer in SQL Enterprise Manager, use:

    sp_dboption inventory,offline,true
To remove media that contains an installed database
  1. Place the database offline using sp_dboption
  2. If the removable media contains more than one database, repeat step 1 for each.
  3. Remove the storage media from the drive.

For more information about using sp_dboption, see the sp_dboption System Stored Procedure topic in the Microsoft SQL Server Transact-SQL Reference.


Uninstalling a Database

If you will no longer be using a removable media database, it can be uninstalled using the sp_dbremove stored procedure. The removable media does not need to be in the drive for you to uninstall the database.

The sp_dbremove stored procedure removes the entries in sysdatabases and sysusages for the specified database. If the dropdev keyword is included, it also removes from sysdevices all devices of which that database has exclusive use. It does not delete the physical operating system files for the devices.

To uninstall a database
  • Run sp_dbremove to remove the database. Type:

    sp_dbremove database[,dropdev]

    where

    database
    Is the name of the database to be removed.
    dropdev
    Removes from sysdevices all devices of which that database has exclusive use. It does not delete the physical operating system files for the devices.

    For example, to remove the sales database and drop all its devices, type:

    sp_dbremove sales,dropdev

The sp_dbremove stored procedure can be used to remove all databases, not only those on removable media.

Note After you remove a database you should back up the master database.

For more information about using sp_dbremove, see the sp_dbremove System Stored Procedure topic in the Microsoft SQL Server Transact-SQL Reference.


Stored Procedures Used for Removable Media Databases

The following stored procedures are used to administer removable media. The following information provides summary descriptions. For more information, see the Microsoft SQL Server Transact-SQL Reference.

Stored procedure | Role in removable media administration
sp_certify_removable | Verifies that a database is configured properly for distribution on removable media. If the database passes, it is set to offline, and some information required for installation is returned.
sp_create_removable | Creates a removable media database. Creates three or more devices and places the database on those devices. One device holds the system catalog tables, one the transaction log, and one or more the data tables. Use this stored procedure to create the database prior to performing database development.
sp_dbinstall | Installs a database and its devices. Must be run once for each device of the database being installed. Copies the system device to the hard disk (which places the system catalog tables and the transaction log on read-write media). Can leave data devices on the distribution media (usually, a CD) or can copy data devices to the hard disk.
sp_dboption | Used to place a database online (database is ready to be used) or offline (database is unavailable). Place a database offline before removing a disk containing the data device from a drive.
sp_dbremove | Used to remove an installed database (and, optionally, any devices it has exclusive use of). This procedure can be used for all databases, not just those on removable media.

Note Some of these stored procedures have other uses and other options not documented here. This chapter discusses only the functionality of these stored procedures related to removable media. For more information, see the Microsoft SQL Server Transact-SQL Reference.

Also, although this section focuses on administering databases on removable media, note that you can also set databases and devices to online or offline using sp_dboption, and you can use sp_dbremove to drop databases, whether the databases are on removable media or not.


Chapter 7 Managing Drives

Managing Drives

By managing the placement of data on drives, you can improve performance, implement fault tolerance, or do both. In the context of managing drive storage for a SQL Server computer, performance refers in part to the speed of read and write operations, and fault tolerance refers to the ability of the system to continue functioning¾without data loss¾when part of the system fails.

There are a number of methods you can use to manage the placement of data on drives:

  • Hardware-based RAID, which can protect against data loss in the event of media failure and also improve performance.
  • Windows NT-based disk striping and striping with parity, both of which improve performance. In addition, disk striping with parity protects against data loss in the event of media failure.
  • Windows NT-based disk mirroring and duplexing, both of which are fault-tolerance mechanisms that protect against data loss in the event of media failure. They can also improve read performance.
  • SQL Server device mirroring, a fault-tolerance mechanism that protects against data loss in the event of media failure.
  • SQL Server segments, which can improve SQL Server performance by giving you more control over where you place data on database devices.

This chapter provides an overview of the drive management methods. It also provides instructions for setting up the SQL Server-based drive management methods (SQL Server mirroring and SQL Server segments).

For information choose one of the following topics:

Overview of Drive Management Methods

Using SQL Server Mirroring

Using SQL Server Segments

File Systems


Overview of Drive Management Methods

This section provides an overview of some methods you can use to manage the placement of data on drives to improve performance, implement fault tolerance, or do both. For more information choose one of the following topics:

About RAID

About Hardware-based Solutions

About Windows NT-based Disk Striping and Striping with Parity

About Windows NT-based Disk Mirroring and Duplexing

About SQL Server Device Mirroring

About SQL Server Segments

Important The fault-tolerance methods discussed in this chapter are not a replacement for proper backup strategies. You still must perform periodic backups to protect your databases and data against catastrophic loss. For information about backing up your databases, see Chapter 12, Backing Up and Restoring.


About RAID

RAID stands for redundant array of inexpensive disks. Fault-tolerant disk systems are categorized in six RAID levels, 0 through 5. Each level offers various mixes of performance, reliability, and cost. Each level uses a different algorithm to implement fault tolerance. Following is a brief description of each RAID level.

Level 0
RAID level 0 is commonly referred to as disk striping and uses a disk file system called a stripe set. Data is divided into blocks and is spread in a fixed order among all the disks in the array. RAID level 0 improves read and write performance by spreading operations across multiple disks, so that operations can be performed independently.

RAID level 0 is similar to level 5, but level 5 also provides fault tolerance.

Level 1
RAID level 1 is commonly referred to as disk mirroring and uses a disk file system called a mirror set. Disk mirroring provides a redundant, identical copy of a selected disk. All data written to the primary disk is written to the mirror disk. RAID level 1 provides fault tolerance. It also generally improves read performance (but may degrade write performance).
Level 2
RAID level 2 adds redundancy by using error correcting code, while employing a disk-striping strategy that breaks a file into bytes and spreads it across multiple disks. The error-correction method requires several disks. This strategy offers only a marginal improvement in disk utilization and read-write performance over mirroring (RAID level 1). RAID level 2 is not as efficient as other RAID levels and is not generally used.
Level 3
RAID level 3 uses the same striping method as level 2, but the level 3 error-correction method requires only one disk for parity data. The disk space utilization varies with the number of data disks and may be as high as 86 percent. RAID level 3 provides some read and write performance improvement.
Level 4
RAID level 4 employs striped data in much larger blocks or segments than levels 2 and 3. Like that of level 3, the level of error-correction method requires only one disk for parity data. It keeps user data separate from error-correction data. RAID level 4 is not as efficient as other RAID levels and is not generally used.
Level 5
RAID level 5 is commonly referred to as striping with parity. This is the most popular strategy for new designs. It is similar to level 4 in that it stripes the data in large blocks across all the disks in the array. It differs in that it writes the parity across all the disks. The data redundancy is provided by the parity information. The data and parity information are arranged on the disk array so that the two are always on different disks.

Striping with parity (RAID level 5) has better performance than mirroring (RAID level 1). However, when a stripe member is missing¾for example, when a disk fails¾read performance degrades.

RAID levels 0, 1, and 5 are the RAID implementations typically used with SQL Server.

Using RAID technology to spread a database over multiple disks can yield performance improvements. A hardware disk array typically delivers the best I/O performance, because I/O functions like striping and mirroring are efficiently handled in firmware. Compare this to operating system-based RAID, where processor cycles are consumed (reducing the cycles available to SQL Server). Operating-system software-based RAID provides a cost advantage, however. Where cost is a consideration and redundancy and good performance are required, Windows NT-based stripe sets with parity are a good solution.

Data striping (RAID level 0) is the highest-performance RAID configuration, but if one disk fails, all the data on the stripe set are inaccessible. A typical technique for relational database management systems is to configure the database on a RAID level 0 drive and then place the transaction log on a device that is mirrored. This technique enables you to get the best disk I/O performance for the database while maintaining data recoverability (assuming you perform regular database backups) through a mirrored transaction log.

If data must be quickly recoverable, you should consider mirroring the transaction log and placing the database on a RAID 5 disk device.

Because it provides better performance than any other RAID implementation, hardware-based RAID level 0 (striping) is a good solution when you do not require redundancy and fault tolerance. The following table provides a summary of advantages and disadvantages of hardware- and software-based striping.

 | Advantages | Disadvantages
Windows NT-based striping | Low cost | Uses system processing resources.
Hardware-based striping | Does not compete for processor cycles. Fastest performance of all RAID implementations. | Cost

The next table provides a summary of the advantages and disadvantages of the RAID solutions that provide redundancy and fault tolerance and are typically used with SQL Server.

 | Advantages | Disadvantages
Hardware-based RAID level 3 or 5 | Has excellent performance. Does not compete for processor cycles. | Cost
Hardware-based RAID level 1 | Has best redundancy. Does not compete for processor cycles. | Cost
Windows NT-based RAID level 1 | Has good redundancy. Low cost. | Uses system processing resources.
Windows NT-based RAID level 5 | Has excellent read performance. Low cost. | Uses system processing resources.

For more detailed information about RAID, see the documentation for Windows NT Server and the Windows NT Resource Kit.


About Hardware-based Solutions

RAID levels 0, 1, 3, and 5 are the RAID implementations typically used in hardware-based solutions.

Hardware-based RAID uses an intelligent drive controller and a redundant array of disk drives to protect against data loss in the event of media failure and to improve the performance of read and write operations. A disk array is a collection of multiple disk mechanisms that are coordinated by an intelligent controller, and is an effective disk-storage solution for SQL Server computers.

Hardware-based RAID levels 1-5 automate redundancy and fault tolerance at the hardware level. All levels (0-5) incur no overhead on the system processor. Individual data files are typically spread across more than one disk. It is possible to implement a hardware-based RAID solution that provides your system with seamless, non-stop recovery from media failure.

In general, hardware-based RAID offers performance advantages over use of Windows NT software-based RAID. For example, you can improve data throughput significantly by implementing RAID level 5 through hardware that does not use system software resources. In either configuration, this is accomplished by using more disks at a given capacity as compared to a conventional storage solution. Reading and writing performance and total storage size can be further improved by using multiple controllers.

Depending on the configuration, hardware-based RAID generally provides very good performance. It also makes it much easier to manage multiple disks, by essentially allowing you to treat an array of disks as one disk. You may even be able to replace a failed drive without shutting down the system. The disadvantages of a hardware-based solution are that it can be very expensive and may lock you into a single-vendor solution.

For more information about implementing hardware-based RAID, contact your hardware vendor.


About Windows NT-based Disk Striping and Striping with Parity

Windows NT-based disk striping and disk striping with parity implement RAID features in software, using any vendor's hardware that is compatible with the operating system. Because these are software-based solutions provided with the operating system, they offer a cost advantage.

Disk striping writes data in stripes across a volume that has been created from areas of free space. These areas are all the same size and spread over an array of disks (up to 32). Striping writes files across all disks, so data is added to all partitions in the set at the same rate.

Windows NT-based disk striping implements RAID level 0. Disk striping provides the best performance of all Windows NT Server disk management strategies but does not provide fault-tolerance protection.

Disk striping with parity is similar to disk striping. It adds a parity-information stripe to each disk partition in the volume. This provides fault-tolerance protection equivalent to that of disk mirroring but requires much less space for the redundant data. Windows NT-based disk striping with parity implements RAID level 5.

When a member of a stripe set with parity fails in a severe manner¾such as loss of power or a complete head crash¾you can regenerate the data for that member of the stripe set from the remaining members.

Stripe sets with parity are a good solution for data redundancy in a computing environment in which most activity consists of reading data. Stripe sets with parity also improve write performance, but not as much as with striping alone. Creating a stripe set with parity requires at least three physical disks on the server.

Disk striping is available on both Windows NT Server and Windows NT Workstation. However, disk striping with parity is supported only for Windows NT Server (it is not supported for Windows NT Workstation). On a dual-boot computer, stripe sets, including those with parity, are not accessible when running the MS-DOS operating system.

Disk striping with parity provides a performance improvement for the reading of data compared to a single device or a mirrored device. Striping with parity is recommended over mirroring for applications that require redundancy and are read-oriented. However, the use of striping with parity requires more system memory than using mirroring. Also, when a member stripe is missing, it loses its performance advantage.

Disk striping and striping with parity are set up and managed using the Microsoft Windows NT Disk Administrator program that can be started from the Administrative Tools program group. For information on setting up disk striping or disk striping with parity, see your documentation for Windows NT Server or the online Help for Disk Administrator. Also see the Windows NT Resource Kit.


About Windows NT-based Disk Mirroring and Duplexing

Windows NT-based disk mirroring and duplexing implement RAID features in software, using any vendor's hardware that is compatible with the operating system. Because these are software-based solutions provided with the operating system, they have a cost advantage.

Disk mirroring protects against media failure by maintaining a fully redundant copy of a partition on another disk. This provides protection from the downtime and expense involved in recovering lost data and in restoring data from a backup storage facility. In a sense, mirroring is a form of continual backup. Mirroring also provides some performance benefits when reading data from disks under heavy I/O loads. Windows NT-based disk mirroring implements RAID level 1.

Disk duplexing is a form of mirroring that also provides protection against controller failures¾in addition to protecting against media failures¾by the use of a different disk controller on the mirror disk.

Disk mirroring and duplexing are features of Windows NT Server. They are not supported for Windows NT Workstation. On a dual-boot computer, they are not accessible when running the MS-DOS operating system.

Windows NT-based disk mirroring or duplexing has better write performance than does Windows NT-based disk striping with parity. It also requires less system memory and does not show performance degradation during a failure.

The entry cost is also lower, since Windows NT-based disk mirroring or duplexing requires only two or more disks (compared to striping with parity, which requires three or more disks). However, mirroring provides less usable disk space (compared to striping with parity), so the cost per megabyte is higher.

Disk mirroring and duplexing are implemented by using the Microsoft Windows NT Disk Administrator program that can be started from the Administrative Tools program group. For information on setting up disk mirroring or duplexing, see your documentation for Windows NT Server, or the online Help for Disk Administrator. Also see the Windows NT Resource Kit.

Note The term mirroring is frequently used in the Windows NT Server documentation to describe both disk mirroring and duplexing.


About SQL Server Device Mirroring

SQL Server mirroring protects against data loss in the event of media failure. Mirroring a device continuously duplicates information from one SQL Server device to another. All transactions to the device are copied to its duplicate mirror device. If one of the devices fails, the other contains an up-to-date copy of all transactions. When a read or write to a mirrored device is unsuccessful, it causes the bad device to become unmirrored, and the remaining device takes over.

Note In most cases, the use of hardware-based RAID or Windows NT software-based RAID is recommended over SQL Server mirroring.

For information about setting up SQL Server Mirroring, see Using SQL Server Mirroring, later in this chapter.


About SQL Server Segments

SQL Server segments can improve SQL Server performance by giving you more control over where you place data on database devices. A segment is a subset of one or more database devices and is available to a particular database. Particular segments can be allocated to specific tables or indexes.

Note The use of segments introduces administrative complexity and the possibility for error. In most cases, hardware-based RAID or Windows NT software-based RAID are recommended instead.

For information about setting up segments, see Using SQL Server Segments, later in this chapter.


Using SQL Server Mirroring

SQL Server mirroring can ensure full recovery and continued operation in the event of media failure. SQL Server mirroring continuously duplicates information from one SQL Server device to another. All transactions to the device are copied to its duplicate mirror device. If one of the devices fails, the other contains an up-to-date copy of all transactions. When a read or write to a mirrored device is unsuccessful, it causes the bad device to become unmirrored, and the remaining device takes over.

Note SQL Server mirroring is one way you can mirror a disk for recoverability, but disk mirroring can also be accomplished with the Windows NT Server software. You can also take advantage of hardware disk arrays that support various RAID levels. In most cases, the use of hardware-based RAID or Windows NT software-based RAID is recommended over SQL Server mirroring.

The following illustration shows how devices are continuously mirrored. As information is added or changed in DEVICE1, it is automatically reflected on the mirrored device. In this example, Chris James is added to the authors table, and then the addition is immediately reflected on the mirrored device.

For more information choose one of the following topics

Deciding What to Mirror

Mirroring

Unmirroring

Remirroring

Using the Master Database from a Mirror

Setting Up Mirroring using Transact-SQL Statements

Maintaining System Security in Case of Disk Failure


Deciding What to Mirror

You need to consider several factors to determine the best method for mirroring: the cost of system downtime, reduction or improvements in performance, and the cost of storage media. Three configurations (minimum, intermediate, and advanced) can be used to provide recovery with mirroring:

  • A minimum configuration mirrors the transaction log of a user database on a separate disk drive.

    This configuration, shown in the following illustration, uses the minimum amount of disk space possible when mirroring and does not provide nonstop recovery because the master and/or user databases must be recovered.

    For example, on partition D, store DEVICE1 (which contains the user database) and DEVICE2 (which contains the transaction log). On partition E, store the MASTER device and the mirror of the device that contains the user database's transaction log.

  • An intermediate configuration mirrors the user database, transaction log, and master database on a separate disk drive. This configuration, shown in the following illustration, uses additional disk space to provide nonstop recovery.

    For example, on partition D store the MASTER device, DEVICE1 (which contains the user database) and DEVICE2 (which contains the transaction log). On partition E mirror the MASTER device, DEVICE1, and DEVICE2.

  • An advanced configuration mirrors the user database, transaction log, and master database on several disk drives.

    This configuration, shown in the following illustration, stores a mirror image of the transaction log and master database on one separate disk, and a mirror image of the user database on another separate disk. This option provides nonstop recovery with the highest level of redundancy.

    For example, on partition D store the MASTER device and DEVICE2 (which contains the user transaction log). On partition E mirror the MASTER device and DEVICE2. On partition F store DEVICE1 (which contains the user database). On partition G mirror DEVICE1.

The following table summarizes each type of mirroring configuration.

Mirror type | Description/Benefit
No mirroring | Provides the greatest savings in disk space. However, transactions can be lost, since the database can be restored only to the latest transaction dump.
Minimum configuration | Mirror only the device containing the transaction log. Guarantees up-to-the-minute recovery with no lost transactions. Does not allow nonstop recovery. To recover, it is necessary to reload transaction logs. This option uses the least storage space of any mirroring configuration.
Intermediate configuration | Place devices containing transaction log, master database, and user database on one physical device, and a mirror copy of each on another physical device. Allows nonstop recovery. Consumes more disk space than a minimum configuration. Requires more time for write operations.
Advanced configuration | Store a mirror image of the transaction log and master database on one separate disk, and a mirror image of the user database on another separate disk Allows nonstop recovery. Requires more disk devices than other configurations. Requires more time for write operations but generally improves read times over the intermediate configuration. (The transaction log is on a different device from the user database, so less disk head travel is required for read operations). Provides the greatest redundancy for maximum data integrity.

If you want to mirror a database or log that spans more than one device, you must mirror all devices that contain the database.


Mirroring

Mirroring can be set up using SQL Enterprise Manager or the DISK MIRROR statement. This chapter primarily describes the use of SQL Enterprise Manager. For information about using DISK MIRROR and other statements, see the Microsoft SQL Server Transact-SQL Reference.

When you mirror a device, SQL Enterprise Manager creates a new physical device (the mirror device) and puts an exact copy of the existing device (the mirrored device) on it. If the mirrored device has a lot of information on it, it might take a few minutes when you first mirror it. You should place the mirror device on a separate disk. Use SQL Enterprise Manager to mirror a device while creating a new device or editing an existing device.

To mirror a device
  1. While creating or modifying a device, open the New Database Device or Edit Database Devices dialog box.

    For more information on creating or modifying devices, see Chapter 5, Managing Devices.

  2. Choose the Mirroring button.

    The Database Device Mirroring dialog box appears.

  3. In the Mirror Name box, type the physical name (the path) to where you want the mirror device to be located. You should place the mirror device on a separate drive from the original device.

    By default, the Mirror Name box is filled with the path to the MASTER.DAT file, followed by the first eight characters of the selected device's name plus the .MIR file extension. To place the mirror device on a separate drive, type a new path in the mirror name. For example: D:\MIRDIR\INVDATA.MIR.

    All directories in the path must already exist. SQL Enterprise Manager will not create them.

  4. Choose Mirror.

    The device is mirrored.


Unmirroring

A mirrored device can be unmirrored in several ways. You can switch to the mirror device while retaining the original device; replace the original device with the mirror device, pause mirroring, or stop mirroring and remove the mirror device.

You use SQL Enterprise Manager to unmirror a device while editing an existing device. For more information about editing devices, see Chapter 5, Managing Devices.

To unmirror a device
  1. While editing an existing device, choose the Mirroring button from the Edit Database Devices dialog box.

    The Unmirror Device dialog box appears.

  2. Select one of the mirroring options:
    • To switch to the mirror device while retaining the original device, select Switch to Mirror Device¾Retain. If you select this option, you can later change back to the original device and continue mirroring.
    • To replace the original device with the mirror device, select Switch to Mirror Device¾Replace.
    • To pause mirroring, select Turn Off Mirroring¾Retain Mirror Device. If you select this option, you can later remirror the device.
    • To stop mirroring and remove the mirror device, select Turn Off Mirroring¾Remove Mirror Device.
  3. Choose OK.

If a device is mirrored and one of the two devices fails, the device is automatically unmirrored. If the mirrored device is the one that fails, you can unmirror the mirror and then replace the failed device with the mirrored device.

When you stop mirroring and remove a mirror device, the device is removed but the physical file still remains. You must delete the device's filename from the directory where it is located, using the operating-system del command. It is not necessary to shut down and restart SQL Server.

Mirroring can also be stopped using the DISK UNMIRROR statement. For information, see the Microsoft SQL Server Transact-SQL Reference.


Remirroring

If a mirror process has been suspended because of device failure, if you have switched to the mirror device, or if you have temporarily paused mirroring, you can later restart the mirroring process.

The following procedure assumes that you are editing an existing device using SQL Enterprise Manager. For more information about editing devices, see Chapter 5, Managing Devices.

To remirror a device
  1. While editing an existing device, from the Edit Database Devices dialog box, choose the Mirroring button.

    The Re-mirror Device dialog box appears.

  2. Verify that the Mirror Name box contains the correct physical name of the existing mirror, including the path. If it does not, type the correct one.

    For example: D:\MIRDIR\INVDATA.MIR.

  3. Choose the Re-Mirror button.
  4. Choose OK.

Mirroring can also be restarted by using the DISK REMIRROR statement. For information, see the Microsoft SQL Server Transact-SQL Reference.


Using the Master Database from a Mirror

If the primary device used for the master database becomes unavailable or has been corrupted while the server is running, the mirror device for master automatically becomes active. However, when the primary device for the master database has failed and you need to restart the server, use the sqlservr executable with the -r option. The -r option enables the server to find and use the mirror device for the master database when restarting SQL Server.

For example, if the MASTER mirror device is D:\SQL60\MIRROR
\MASTMIR.DAT, the following example restarts the server using the mirror device:

sqlservr -c -dc:\sql60\data\master.dat -ec:\sql60\log\error.log
    -rd:\sql60\mirror\mastmir.dat

where

-c
Starts SQL Server independent of the Windows NT Service Control Manager.
-d
Is the path of the primary device for the master database.
-e
Is the path of the error log file for SQL Server.
-r
Is the path of the mirroring device to be used to mirror the master database.

Note The sqlservr utility requires that both the -d and -r options be present on the command line. The program always attempts to use the primary device specified by the -d option before it uses the -r option. When the primary device for master cannot be used, the server uses the device specified with the -r parameter. You cannot force the server to use the mirror device as the primary device if the original primary device works.

Configuring the server startup parameters to run SQL Server with the -r option allows SQL Server services to automatically use the mirror device for the master database when the primary device for master fails. The -r option requires the full path of the mirror device.

You can configure the server startup parameters by using either SQL Setup or SQL Enterprise Manager. The following procedure assumes you are using SQL Setup.

To modify the server options to specify -r
  1. From the Microsoft SQL Server 6.0 program group, double-click the SQL Setup icon.

  2. Follow the onscreen instructions until the Microsoft SQL Server 6.0 Options dialog box appears.

  3. Select Set Server Options and choose the Continue button.

    The Select Server Options dialog box appears.

  4. Choose the Parameters button.

    The Server Parameters dialog box appears.

  5. In the Parameter box, type the path of the mirror device. For example:
    -re:\mirdir\mastmir.dat
  6. Choose the Add button, and then choose the OK button.

    The Select Server Options dialog box reappears.

  7. Choose the Change Options button.
  8. Choose the Exit button.

If the -r option is present, sqlservr is always executed with both the -r and the -d options. This minimizes the chance that you will get a message stating that the MASTER device is unusable. If the -r option is present, the mirror file is used when the primary device fails.

Note You should periodically check the error log to determine if you are running SQL Server using the mirror of the master database, because it is possible to have a no longer operational primary device but not be aware of it. Since it is possible to not be aware of the primary device failure, you might want to use -r only if it becomes necessary because the primary device fails.


Setting Up Mirroring Using Transact-SQL Statements

In addition to using SQL Enterprise Manager, you can use the DISK MIRROR, DISK UNMIRROR, and DISK REMIRROR statements to set up mirroring.

The DISK MIRROR statement starts disk mirroring. The database device to be mirrored must have already been initialized by a DISK INIT statement. The device that contains the mirror should not be initialized with DISK INIT.

When you mirror a device, the DISK MIRROR command creates a physical device and puts an exact copy of the existing device on the newly created mirroring device. When you first execute the DISK MIRROR command, it may take a few minutes if the device you are mirroring has a lot of information on it. A disk and its mirror constitute one logical device, and the mirror name is added to the mirrorname column in the sysdevices table.

To mirror a device

DISK MIRROR
NAME = 'logical_name',
MIRROR = 'physical_name'
[, WRITES = {SERIAL | NOSERIAL }]

where

logical_name
Is the name of the device to be mirrored.
physical_name
Is the operating-system filename of the device. It cannot be an already existing operating-system file.
SERIAL
Specifies that writes to the original disk must finish before writes to the mirror disk begin. With Windows NT, mirroring is always SERIAL.
NOSERIAL
Specifies that writes can occur either simultaneously to the original disk and to the mirror disk, or serially to the original disk before the mirror disk. With Windows NT, mirroring is always SERIAL. NOSERIAL is retained for compatibility with other versions of SQL Server.

In the following example, TRANLOG is the database device name for the device to be mirrored. The TRANLOG device has been initialized with DISK INIT and is used as a transaction log device, as in CREATE DATABASE... LOG ON TRANLOG. For example, to mirror the EMPLOYEE device to the D: disk, type:

DISK MIRROR
NAME = 'employee',
MIRROR = 'd:\employee.mir'

To mirror the TRANLOG transaction log device to the F: hard disk:

DISK MIRROR
NAME = 'tranlog',
MIRROR = 'f:\tranmir.dat'

The DISK UNMIRROR statement stops the mirroring process. When you unmirror a device, you can choose to unmirror the device or its mirror. For example, if the device you're mirroring fails, you can unmirror the mirror and replace the device with it.

You can also unmirror the device, unmirror permanently, or temporarily pause mirroring.

To unmirror a device

DISK UNMIRROR
NAME = 'logical_name'
[, SIDE = {PRIMARY | SECONDARY}]
[, MODE = {RETAIN | REMOVE}]

where

logical_name
Is the name of the device to be unmirrored. This name is recorded in sysdevices.
PRIMARY
Is the device listed in the name column of sysdevices.
SECONDARY
Is the device listed in the mirrorname column of sysdevices.
RETAIN
Specifies that the unmirroring is temporary. RETAIN is the default.
REMOVE
Specifies that the unmirroring is permanent.

For example, to temporarily unmirror the EMPLOYEE device, type:

DISK UNMIRROR
NAME = 'employee',
SIDE = primary,
MODE = retain

To permanently unmirror the TRANLOG device, type:

DISK UNMIRROR
NAME = 'tranlog',
SIDE = primary,
MODE = remove

To temporarily unmirror the EMPLOYEE mirror, type:

DISK UNMIRROR
NAME = 'employee',
SIDE = secondary,
MODE = retain

A mirror process that has been suspended due to a device failure or with the DISK UNMIRROR statement can be restarted with DISK REMIRROR. If you set RETAIN when you unmirrored the device, you can use the DISK REMIRROR statement.

To remirror a device

DISK REMIRROR
NAME = 'logical_name'

where

logical_name
Is the device to be remirrored.

For example, to remirror the EMPLOYEE device, type:

DISK REMIRROR
NAME = 'employee'

For more information about the DISK MIRROR, DISK UNMIRROR, and DISK REMIRROR statements, see the Microsoft SQL Server Transact-SQL Reference.


Maintaining System Security in Case of Disk Failure

Since disk failure can impair system security, the WAITFOR statement can perform certain tasks when a disk becomes unmirrored. This is syntax for the WAITFOR statement:

BEGIN
WAITFOR MIRROREXIT
<commands to be executed>
END

The commands to be executed depend on the application. Some possibilities include adding warning messages in applications that perform updates and using sp_dboption to make certain databases read-only.

Note SQL Server can detect that a disk has become unmirrored only when it attempts to write to the mirror device. On mirrored databases, this occurs at a checkpoint or whenever the SQL Server buffer must be written to disk. On mirrored logs, a write occurs whenever a row is changed with UPDATE, INSERT, or DELETE. The WAITFOR MIRROREXIT statement is activated only by these events.


Using SQL Server Segments

A segment is a named collection of disk pieces. It is a subset of one or more database devices that is available to a particular database. Using segments can increase SQL Server performance by giving you more control over where you place specific database objects to optimize the space available on a device. Specific segments can be allocated to specific tables or indexes.

Important With Windows NT-based servers, there are several ways to spread a database over multiple disks. Segments are one way, but the use of segments introduces administrative complexity and the possibility for error. In most cases, hardware-based RAID or Windows NT software-based RAID are recommended instead. You can achieve essentially the same performance advantages as segments by using RAID and letting the disk subsystem distribute the I/O load among the disks.

Each SQL Server database can use up to 32 segments. Selective use of segments can increase the performance of SQL Server by improving disk access time for read and write operations. For example, it is possible to split a table and its index(es) onto separate segments. This approach can be very effective in improving performance, but it requires a detailed understanding of how data and indexes are arranged and accessed.

While data striping (using Windows NT or a disk array) guarantees that the data is spread over all devices, when using SQL Server segments, this can occur only when the database is full and the data accessed is distributed across the segments.

The following illustration shows the relationship between segments, databases, and database devices.

Although you can have more than one segment on a database device, it isn't advised, because any objects that you place on those segments will compete with each other for space. It is best to specify one segment per device.

These are typical uses for segments:

  • Placing a table on one physical device and its nonclustered indexes on a different physical device.
  • Splitting a large, heavily-used table across database devices on two separate disk controllers.
  • Storing data for text and image columns on separate physical devices.
  • Placing a transaction log on a separate device so it can be dumped.

When a database is created, the following segments are automatically created for the database:

Segment name | Function
SYSTEM | Stores the system tables.
LOGSEGMENT | Stores the transaction log.
DEFAULT | Stores all other database objects ¾ unless you create additional segments. If you don't specify a segment when creating the table or by using sp_placeobject, the database objects are stored on this segment.

Additional segments can be added to a database after database devices have been allocated and assigned to the database.

When you add, extend, or delete a segment, you should also dump the master database.

Caution When you restore a database with the LOAD DATABASE statement, the segments and device fragments must be set up in the same way as the database that was dumped.

For more information, choose one of the following topics:

Adding Segments

Creating Database Objects on Segments

Extending Segments

Adding Objects to Another Segment

Displaying Information About Segments

Dropping Segments

Example of Using Segments

Example of Splitting a Table Across Segments


Adding Segments

Segments are created after devices and databases. You create a segment and place it on a database device. The database you are creating the segment for must have access to the device where you are placing the segment. In other words, you must have either created or altered the database on the device on which you are creating the segment for the database to use that segment.

To use sp_addsegment, you must be in the database that you are creating the segment for.

To add a segment

sp_addsegment segname, logical_name

where

segname
Is the name of the segment. A segment name must follow the rules for identifiers (for example, FASTSEG2).
logical_name
Specifies the database device where segname will be located.

For example, to create the SEG_MYDISK1 segment on the MYDISK1 database device, type:

sp_addsegment seg_mydisk1, mydisk1

For more information about sp_addsegment, see the Microsoft SQL Server Transact-SQL Reference.


Creating Database Objects on Segments

After you add a segment, you can explicitly place database objects on that segment. The CREATE TABLE and the CREATE INDEX statements use the ON segment_name clause to create objects on a specific segment. If you do not use the ON segment_name clause, the object is created on the default segment.

To create a table on a specified segment

CREATE TABLE table_name (column_name datatype
[, column_name datatype...]) ON segment_name

where

table_name
Is the name of the table.
column_name
Is a column name in the table.
datatype
Specifies the datatype of the column. System or user-defined datatypes are accepted.
segment_name
Identifies the segment to create the table on.
To create the index for a table on a segment

CREATE [CLUSTERED | NONCLUSTERED] INDEX index_name
ON table_name (column_name [, column_name...]) ON segment_name

where

CLUSTERED | NONCLUSTERED
Specifies whether the index is clustered or nonclustered.

CLUSTERED means that the physical order of rows on the database device is the same as the indexed order of the rows. NONCLUSTERED means that there is a level of indirection between the index structure and the data itself. For more information about indexes, see the Microsoft SQL Server Transact-SQL Reference.

A clustered index, where the bottom, or leaf, level of the index contains the actual data, resides on the same segment as the table. If you create a table on one segment and then create its clustered index on a different segment, the table travels with its index to the new segment. If you create a clustered index without specifying a segment name, the entire table moves to the DEFAULT segment. A nonclustered index can reside on a different segment from the table.

index_name
Specifies the index to add to the segment.
table_name
Identifies the table containing the index to add to the segment.
column_name
Identifies the columns in the table.
segment_name
Is the name of the segment on which you want the index created.

For example, to place the mytable table on the segment seg_mydisk1 and its nonclustered index on segment seg_mydisk2, type:

CREATE TABLE mytable (c1 varchar(30), c2 char(15), c3 datetime)
    ON seg_mydisk1

CREATE NONCLUSTERED INDEX my_index ON mytable (c1, c2) ON seg_mydisk2

For the full syntax of the CREATE TABLE and CREATE INDEX statements, see the Microsoft SQL Server Transact-SQL Reference.


Extending Segments

When all databases and database objects on a SQL Server share a default pool of space (for example, when they share a segment), any table or index can grow to fill the space. To prevent this, use the sp_extendsegment system procedure to increase the size of an existing segment by mapping it to one or more additional database devices.

Before you can extend a segment, you must create the database device you are extending the segment on, and the database you are extending the segment for must have access to that database device.

To extend a segment

sp_extendsegment segname, logical_name

where

segname
Is the name of the existing segment (previously defined using the sp_segment system stored procedure).
logical_name
Specifies the database device to be added to the current device range for segname.

For example, to add the dev2 database device to an existing segment named bigseg, type:

sp_extendsegment bigseg, dev2

Default segments can also be extended. Since DEFAULT is a Transact-SQL keyword, you must enclose it in quotation marks to extend the default segment for your database. For example:

sp_extendsegment 'default', newdevice

For more information about sp_extendsegment, see the Microsoft SQL Server Transact-SQL Reference.


Adding Objects to Another Segment

The sp_placeobject system procedure causes all future disk allocation for the specified object to occur on a particular segment. The sp_placeobject system procedure does not remove objects from their allocated segments, nor does it move an object from one database device to another. Whatever pages have been allocated on the first database device remain allocated; whatever data was written to the first database device remain on that database device.

Do not use the sp_placeobject system procedure to move indexes, because splitting indexes across database devices affects system performance. Instead, drop the index and re-create it on the new segment.

A clustered index (in which the bottom level of the index contains the actual data) is on the same segment as a table. You can move a table by dropping its index and then creating a clustered index for the table on the desired segment.

To place an object on another segment

sp_placeobject segname, objname

where

segname
Specifies the segment to use for future space allocation for the database object.
objname
Specifies the table or index whose subsequent space allocation is to be put on the segname segment.

For example, to allocate additional space for the mytab table on bigseg, type:

sp_placeobject bigseg, mytab

Note Executing DBCC CHECKALLOC prints warning message 2558 for each object that is split across segments. You can ignore these messages if you intentionally want objects to span segments.

When you create a table with text or image columns, the data is stored on a separate chain of text pages. A table that contains text or image columns has an additional entry in sysindexes for the text chain, with the name column set to the name of the table preceded by the letter "t" and an index ID of 255. You can use sp_placeobject to store the text chain on a separate device, giving both the table name and the name of the text chain from sysindexes. For example:

sp_placeobject textseg, 'mytab.tmytab'

By default, a chain of text pages is placed on the same segment as its table. After you run sp_placeobject, whatever pages were previously written to the old device remain allocated, but all new allocations take place on the new segment.

For more information about sp_placeobject, see the Microsoft SQL Server Transact-SQL Reference.


Displaying Information About Segments

You can view detailed information about segments by using sp_helpsegment and sp_helpdb.

The sp_helpsegment system stored procedure reports information about a particular segment or about all of the segments in the current database.

To display information about segments

sp_helpsegment [segname]

where

segname
Specifies the segment about which you want information. If you omit this parameter, information about all segments in the current database is displayed. If the segname is DEFAULT, you must enclose it in quotation marks (because DEFAULT is a reserved word).

If you run the sp_helpsegment system stored procedure without a segname, it displays the number, name, and status for all segments in the database. The status is 1 for the default segment (the segment that is used if ON segment_name is not used in a CREATE statement). For example:

sp_helpsegment

segment name                      status
------- ------------------------- ---------
     0  system                    0
     1  default                   1
     2  logsegment                0
     3  seg1                      0
     4  seg2                      0

If you run the sp_helpsegment system stored procedure with a segname, it displays the number, name, and status of that segment and also displays the names of the database devices and their sizes, plus information about the tables and indexes on the segment. For example, to display information about the seg1 segment, type:

sp_helpsegment seg1

segment name                      status
------- ------------------------- ---------
3       seg1                      0

device                        size
----------------------------- -----------------
seg_mydisk1                   2MB

table_name             index_name   indid
---------------------- --------     --------
authors                au_ind       1

The sp_helpdb system procedure displays information about the relationship between database devices and segments within a particular database.

To display information about the segments in a database

sp_helpdb [dbname]

where

dbname
Specifies the database you want information about. Omitting this optional parameter results in a report on all databases.

For example, to display information about the segments in mydata, type:

sp_helpdb mydata

name

db_size

owner

dbid

created

status

-----

---------

-----

-------

---------

-------

mydata

6 MB

sa

4

May 5 1995

no options set

device_fragments

size

usage

------------------

-------------

----------

bigdevice

4 MB

data only

logdev

2 MB

logonly

device         segment
-------------  --------
bigdevice      default
bigdevice      system
logdev         logsegment

When the dbname parameter is omitted, information about all databases on the server is returned, but the displayed information does not include the device_fragments, size, and usage columns.

To display information about all databases on the server, type:

sp_helpdb

For more information about sp_helpsegment and sp_helpdb, see the Microsoft SQL Server Transact-SQL Reference.


Dropping Segments

The sp_dropsegment system stored procedure can be used to drop a segment from a database or unmap a segment from a database device.

When used only with a segment name, sp_dropsegment drops the named segment from a database and removes it from all devices. Segments cannot be dropped if they contain database objects. To drop a segment containing database objects, first assign the objects to another segment and then drop the segment.

To drop a segment from a database

sp_dropsegment segname

where

segname
Identifies the segment to be dropped.

When used with a segment name and a device name, sp_dropsegment removes the segment from that device while leaving it on others, thereby reversing the effects of sp_extendsegment. If you specify a database device, SQL Server does not drop the entire segment; it drops only the portion of the segment that is on the specified database device.

To remove a segment from a specific database device

sp_dropsegment segname, logical_name

where

segname
Specifies the segment to remove from a particular device.
logical_name
Specifies a database device that you want the segname segment to stop using. This parameter is optional, except when dropping the SYSTEM, DEFAULT, and LOGSEGMENT system segments from a database device.

For example, to remove bigseg from dev2, type:

sp_dropsegment bigseg, dev2

Note Dropping a segment removes it from the list of segments in the database but does not remove the database device from the allocation for that database.

If you drop all segments from a database device, the space is still allocated to the database, but it cannot be used for database objects. DBCC CHECKCATALOG will report "Missing segment in Sysusages segmap". You must use sp_addsegment 'default', logical_name to map the default segment to the database device, or you must create another segment for the database on that device.

For more information about sp_dropsegment, see the Microsoft SQL Server Transact-SQL Reference.


Example of Using Segments

Segments provide a flexible way to assign objects to a particular database device. For example, you can add a database device to a database, and then improve your system performance by assigning a particular high-use table to that database device. To improve performance, no other database objects should use the new segment.

The preceding topics presented the individual tasks performed to manage segments. The following example puts together some of these individual tasks to show you how to create a segment and remove all other segment mappings from the database device:

  1. Create a new database called mydata with one database device for objects and another for the transaction log:
    create database mydata on bigdevice = 4 log on logdev = 2
  2. Switch to mydata, and run sp_helpdb to view the segments the database contains:
    use mydata
<execute>
sp_helpdb mydata
name

db_size

owner

dbid

created

status
-----

---------

-----

-------

---------

-------

mydata

6 MB

SA

4
May 5 1995

no options set

device_fragments

size

usage

-------------------

------------

--------------

bigdevice

4 MB

data only

logdev

2 MB

log only

device

segment

----------------

-----------------------------

bigdevice

default

bigdevice

system

logdev

logsegment

Like all newly created databases, mydata has segments named DEFAULT, SYSTEM, and LOGSEGMENT. Since the CREATE DATABASE statement used LOG ON, the transaction log segment is mapped to its own device (logdev). The DEFAULT and SYSTEM segments are both mapped to bigdevice.

  3.
Expand the space allocated for mydata on the database devices, and run sp_helpdb again to display the entries for the added space:
    use master
<execute>
alter database mydata on bigdevice = 2, logdev = 1
<execute>
use mydata
<execute>

sp_helpdb mydata

    4.

name

db_size

owner

dbid

created

status

--------

---------

------

------

-----------

------------

mydata

9 MB

SA

4

May 5 1995

no options set

device_fragments

size

usage

----------------

------

-----------------------

bigdevice

2 MB

data only

bigdevice

4 MB

data only

logdev

1 MB

log only

logdev

2 MB

log only

device

segment

------------

----------------------------------------

bigdevice

default

bigdevice

system

logdev

logsegment

When additional fragments of disk space are allocated to a database on a device, the segments from the other fragments of the database device are mapped to the new fragments. Segments are mapped to the entire amount of space on a device used by the database, not just to the space fragments. If fragments are added, all segments are mapped to those fragments.

When a new database device is used (one that's not already in use by the database), the SYSTEM and DEFAULT segments are automatically mapped to the new device. Step 4 allocates a new database device that has not been used by mydata.

  4.
Allocate space for mydata on a new database device, and then run sp_helpdb again:
    use master
<execute>
alter database mydata on newdevice = 3
<execute>

use mydata
<execute>

sp_helpdb mydata

    5.

name

db_size

owner

dbid

created

status

------

--------

-----

---------

----------

-------------

mydata

12 MB

SA

4

Dec 2 1991

no options set

device_fragments

size

usage

----------------------

-----

------------

bigdevice

2 MB

data only

bigdevice

4 MB

data only

logdev

1 MB

log only

logdev

2 MB

log only

newdevice

3 MB

data only

device

segment

------------

------------------------------

bigdevice

default

bigdevice

system

logdev

logsegment

newdevice

default

newdevice

system

The DEFAULT and SYSTEM segments are mapped to the new space. In some cases, you might want to use the new space as default storage space for CREATE TABLE or CREATE INDEX statements. However, if you are adding space to assign a table or index to a specific segment (and therefore to specific devices), you will want to add your own segment and then drop the SYSTEM and DEFAULT segments.

  5.
Create a new segment, NEW_SPACE, on NEWDEVICE:
    sp_addsegment new_space, newdevice

Here is just the portion of the sp_helpdb report that has changed (the portion that lists segment mapping):

    6.

device

segment

-----------------

------------------------------

bigdevice

default

bigdevice

system

logdev

logsegment

newdevice

default

newdevice

new_space

newdevice

system

Note that the DEFAULT and SYSTEM segments are still mapped to NEWDEVICE. If you are planning to use NEW_SPACE to store a specific user table or index for improved performance and you want to ensure that other user and system objects are not stored on the database device you just created, use sp_dropsegment to drop the DEFAULT and SYSTEM segments.

  6.
Drop the SYSTEM and DEFAULT segments:
    sp_dropsegment system, newdevice
<execute>
sp_dropsegment 'default', newdevice

The quotation marks around DEFAULT are needed because it is a reserved word.

Here is the portion of the sp_helpdb report that shows the segment mapping:

    device         segment
-------------  --------------
bigdevice      default
bigdevice      system
logdev         logsegment
newdevice      new_space

Now only NEW_SPACE is mapped to NEWDEVICE. Users who create objects can use ON NEW_SPACE to place a table or index on the database device that corresponds to that segment (NEWDEVICE). Since the DEFAULT segment is not using that database device, users who create tables and indexes without using the ON clause will not be placing them on NEWDEVICE.

If the ALTER DATABASE statement is used on NEWDEVICE again, the new fragment acquires the same segment mapping as the existing fragment of that database device ¾ the NEW_SPACE segment only.

At this point, if you use CREATE TABLE and name NEW_SPACE as the segment, you will get results such as the following from sp_help and sp_helpsegment:

    create table mytable (c1 int, c2 datetime) on new_space

sp_help mytable
Name      Owner         Type           When_created
--------  ------------- -------------  --------------------
mytable   dbo           user table     May 05 1995   3:21PM

Data_located_on_segment
----------------------
new_space

Column_name  Type      Length  Prec   Scale  Nullable
-----------  ------    ------  -----  -----  ------------
c1           int       4                     yes
c2           datetime  8                     yes

Identity                       Seed      Increment
-----------------------------  --------  -----------
No identity column defined     (null)    (null)

Object does not have any indexes.

constraint_type    constraint_name    constraint_keys
-----------------  -----------------  -----------------

FOREIGN KEYS
No defined keys for this object.

sp_helpsegment new_space

segment    name            status
--------- --------------- --------
  3        new_space       0

device         size
---------      --------------
newdevice      3MB

table_name   index_name  indid
-----------  ----------- -------
mytable      mytable     0

    7.

For more information about the system stored procedures and Transact-SQL statements used in this example, see the Microsoft SQL Server Transact-SQL Reference.


Example of Splitting a Table Across Segments

You can improve performance for high-volume multiuser applications by splitting large tables across segments located on separate physical disks.

Note If the table is updated frequently, the balance of disk allocation can change over time. To guarantee that the speed advantages are maintained, it may be necessary to drop and re-create the table.

The following example shows how to split a table across two segments. This example uses a database called mydata and a table called riff to represent the user database and the table being split:

  1. Select physical devices to use. In this example, the physical devices are C:\SQL60\DATA\MYDEV1.DAT and D:\DATA\MYDEV2.DAT.
  2. Switch to the master database:
    use master
  3. Add the devices mydisk1 and mydisk2. Allocate 4 MB for mydisk1 and 2 MB for mydisk2:
    DISK INIT
NAME = 'mydisk1',
PHYSNAME = 'C:\sql60\data\mydev1.dat',
VDEVNO = 7,
SIZE = 2048
DISK INIT

NAME = 'mydisk2',
PHYSNAME = 'D:\sql60\data\mydev2.dat',
VDEVNO = 8,
SIZE = 1024
  4. Allocate additional storage space for the database by adding the mydisk1 and mydisk2 devices to mydata:
    alter database mydata
on mydisk1 = 4,
mydisk2 = 2
  5. Switch to the mydata database:
    use mydata
  6. Add a segment to mydisk1 and a segment to mydisk2:
    sp_addsegment seg_mydisk1, mydisk1
<execute>
sp_addsegment seg_mydisk2, mydisk2
<execute>
  7. Create a third segment called seg_bothdisks and extend it to span both mydisk1 and mydisk2:
    sp_addsegment seg_bothdisks, mydisk1
<execute>
sp_extendsegment seg_bothdisks, mydisk2
<execute>
  8. Drop the SYSTEM and DEFAULT segments from the new devices:
    sp_dropsegment 'default', mydisk1
<execute>
sp_dropsegment system, mydisk1
<execute>
sp_dropsegment 'default', mydisk2
<execute>
sp_dropsegment system, mydisk2
<execute>
  9. Create the table and clustered index on the seg_mydisk1 segment.
    create table riff (ri_id id, ri_lname varchar(40),
  ri_fname varchar(20), phone char(12), address varchar(40),
  city varchar(20), state char(2), zip char(5), contract bit)
  on seg_mydisk1
create clustered index ri_index
  on riff(au_id) on seg_mydisk1

    In this case, the table is riff and the clustered index is ri_index.

  10. Use the bcp utility to copy half of the rows into the riff table.
  11. Place the riff table on the second segment (seg_mydisk):
    sp_placeobject seg_mydisk2, riff
  12. Use bcp to copy the rest of the rows.
  13. Place the riff table on the segment that spans both disks (seg_bothdisks):
    sp_placeobject seg_bothdisks, riff

    Important You must create the clustered index before the table is placed on the second segment. If you create the clustered index after the table is placed on the second segment, both the table and the index move to the second segment. If you create the index after creating seg_bothdisks, the allocation of disk space is unpredictable.


File Systems

Server performance is not affected by the file system used (FAT or NTFS). Your choice of file system should be decided by factors other than performance.

  • The FAT file system allows dual booting with computers running MS-DOS.
  • The NTFS file system has security and recovery advantages. If you do not need to dual boot Windows NT with MS-DOS, NTFS is recommended.

    SQL Server can be installed on a compressed NTFS volume, but at a performance penalty.

For information about choosing the appropriate file system, see your documentation for Windows NT.


Part 4 Security

Security

SQL Server 6.0 security comprises several elements that¾working together¾allow you to define:

  • The users who can log on to a SQL Server
  • The users who can access each database on a SQL Server
  • The database objects (tables, views, stored procedures) that each user is allowed to access and/or modify
  • The Transact-SQL statements that each user is allowed to issue for each database that he or she has access to

SQL Server 6.0 gives you great flexibility for protecting your data. You can precisely determine which users are allowed to view and/or modify the information stored in your SQL Server 6.0 databases, in the tables and views of those databases, or even in individual columns. You also have the choice of administering users individually, or within the context of a group (thus simplifying some management tasks).

The chapters of this part explain how SQL Server 6.0 security interacts with security for Windows NT-based domains and computers, what the three types of SQL Server security are, what SQL Server 6.0 logins and database users are, and what SQL Server 6.0 object and statement permissions are. You will also learn about the tools that are used to perform each security management task, and how to perform these tasks.

Security topics are discussed in these chapters:

Chapter 8, Security Concepts

Chapter 9, Managing Security

Chapter 10, Remote Servers and Users


Chapter 8 Security Concepts

Security Concepts

SQL Server security protects a server and the data stored on that server. SQL Server security determines who can log on to the server; the administrative tasks each user is allowed to perform; which databases, database objects, and data each user can access; and much more.

This chapter provides an orientation to SQL Server 6.0 security elements and concepts. It provides a summary list of SQL Server security terms; explains the three server login security modes; discusses how SQL Server integrates with security for Windows NT–based domains and computers; and describes SQL Server logins, database users, and object and statement permissions.

Use this chapter to gain a fuller understanding of the elements that make up SQL Server 6.0 security. To learn about the procedures you will perform to manage SQL Server 6.0 security and the tools you will use to perform those procedures, see Chapter 9, Managing Security.

For information on security concepts, choose one of the following topics:

Security Terminology

About the Server Login Security Mode

Windows NT Security and SQL Server

About Server Login IDs

About Database Users

About Permissions

Security and the System Tables


Security Terminology

To help you understand the information presented in this chapter, we begin by defining some security-related terms. This brief list of definitions is not intended to serve as a comprehensive SQL Server glossary. It is provided as a quick reference to help you understand some of the security elements discussed throughout this chapter. You may find it useful to refer back to this list of security definitions as you read through this chapter and through Chapter 9, "Managing Security."

alias
An alias is a database username that is shared by several login IDs. A database alias allows you to treat more than one person as the same user inside a database, giving all of them the same permissions. Any username in a database can also serve as an alias.

Aliases are often used so that several users can assume the role of database owner.

database object owner
Database objects are tables, indexes, views, defaults, triggers, rules, and procedures. The user who creates a database object is the database object owner and is automatically granted all permissions on it. The database object owner can grant permission to other users to use that object. Database object ownership cannot be transferred.
database owner
The database owner (DBO) is the creator of a database. There is only one DBO. The DBO has full privileges inside the database that he or she owns, and determines the access and capabilities provided to other users.

In his or her own database, the user is recognized as DBO; in other databases, the database owner is known by his or her database username.

DBO status can be reassigned to a different user. Only one login ID can be DBO, although other login IDs can be aliased to DBO.

domain
In Windows NT security, a domain is a collection of computers that are grouped for viewing and administrative purposes, and that share a common security database.
group
In SQL Server, a database group is a collection of database users. The users receive the database permissions granted to the group. Using groups simplifies management of a large number of database users, because groups provide a convenient way to grant and revoke permissions to more than one user at the same time.

In Windows NT, a group is a collection of Windows NT users. The users received the Windows NT rights and permissions granted to the group. Groups provide a convenient way to manage the capabilities of a large number of users with similar needs, within the security scope of a domain or a computer.

integrated security
Integrated security allows a SQL Server to use Windows NT authentication mechanisms to validate logins for all connections. Only trusted (multi-protocol or named pipes) connections are allowed.
login ID
A login ID is a name by which a user is known to SQL Server. Login IDs are also referred to as logins.

To log in to a SQL Server that is running standard security, a user must provide a valid login ID and password.

login security mode
The login security mode determines the manner in which a SQL Server validates a login request. There are three types of login security: integrated, standard, and mixed.
mixed security
Mixed security allows login requests to be validated using either integrated or standard security. Trusted connections (as used by integrated security) and nontrusted connections (as used by standard security) can be established.
object permissions
Object permissions regulate the use of certain statements on certain database objects. They are granted and revoked by the owner of the object.
permissions
Microsoft SQL Server uses permissions to enforce database security. The SQL Server permissions system specifies which users are authorized to use which Transact-SQL statements, views, and stored procedures. The ability to assign permissions is determined by each user's status (as SA, database owner, or database object owner).

There are two types: object permissions and statement permissions.

standard security
Standard security uses SQL Server's own login validation process for all connections. To log in to a SQL Server, each user must provide a valid login ID and password.
statement permissions
Statement permissions provide the privilege to issue certain Transact-SQL statements. Statement permissions are not object-specific. They can be granted only by the SA or the database owner.

Statement permissions apply to these statements: CREATE DATABASE, CREATE DEFAULT, CREATE PROCEDURE, CREATE RULE, CREATE TABLE, CREATE VIEW, DUMP DATABASE, and DUMP TRANSACTION.

Statement permissions are also called command permissions.

system administrator
The system administrator (SA) is the person responsible for the administrative and operational functions that are independent of any particular application, and is likely to be a person with a comprehensive overview of SQL Server and all its applications.

Administering SQL Server typically includes such tasks as installing SQL Server; configuring servers and clients; managing and monitoring the use of disk space, memory, and connections; creating devices and databases; authorizing SQL Server users and granting them permissions; transferring data in and out of SQL Server databases; backing up and restoring databases; implementing and maintaining replication; scheduling unattended operations; monitoring and tuning SQL Server performance; and diagnosing system problems. The system administrator may also advise application designers about the data that already exists on SQL Server, make recommendations about standardizing data definitions across applications, and so on.

The system administrator operates outside the protection system, which means that SQL Server does no permission checking for the system administrator. The system administrator is also treated as the owner of whatever database he or she is using. Anyone who knows the SA password can log in and act as system administrator (unless the server is running in Integrated login security mode).

trusted connections
Integrated security requires network protocols that support authenticated connections between clients and servers. These are referred to as trusted connections. The multi-protocol and named pipe protocols provide trusted connections.

Note that nontrusted connections (connections over other network protocols that do not support authenticated connections) must be handled by using SQL Server standard security.

username
In SQL Server, a database username is a name assigned to a login ID for the purpose of allowing a user to have access to a database. The abilities a user has within a database depend on the permissions granted to the username (and to any groups the username is a member of).

In Windows NT, a username is the name by which the user is known to the domain, or to an individual Windows NT computer. A user logs on to a domain or computer by providing a valid username and password. The abilities of the user depend on the Windows NT rights and permissions granted to that username and to any Windows NT groups the username is a member of.


About the Server Login Security Mode

Each SQL Server must be configured for one of the three available security modes.

  • Integrated security allows a SQL Server to use Windows NT authentication mechanisms to validate SQL Server logins for all connections. Only trusted (multi-protocol or named pipes) connections are allowed.
  • Standard security uses SQL Server's own login validation process for all connections.
  • Mixed security allows SQL Server login requests to be validated by using either integrated or standard security methods. Both trusted connections (as used by integrated security) and nontrusted connections (as used by standard security) are supported.

In addition, regardless of the server's login security mode, ODBC and DB-Library client applications can be configured to always request a trusted connection from the server.

For more information, choose one of the following topics:

Integrated Security

Standard Security

Mixed Security

Client-Requested Trusted Connections


Integrated Security

Integrated security integrates SQL Server login security with Windows NT security. This allows a network user to log in to a SQL Server without supplying a separate login ID or password. Users can maintain one login ID and password for both Windows NT and SQL Server.

Integrated security lets SQL Server applications take advantage of Windows NT security features, including encrypted passwords, password aging, domain-wide user accounts, and Windows-based user administration. (For more information about these features, see your documentation for Windows NT.)

SQL Server achieves login security integration with Windows NT by using the Windows NT security attributes of a network user to control login access to SQL Server. A user's network security attributes are established at network login time and are validated by Windows NT through a sophisticated password encryption mechanism. When a network user tries to connect to SQL Server, SQL Server uses Windows NT – based facilities to determine with certainty the validated network username of the client. SQL Server then permits or denies login access based on that network username alone, without requiring a separate login name and password to be sent in the client connection request.

Login security integration operates over network protocols that support authenticated connections between clients and servers. Such connections are referred to as trusted connections.

Trusted connections include multi-protocol and named pipes sessions from other Windows NT – based workstations, from Windows for Workgroups–based clients, from Windows 95-based clients, and from Microsoft LAN Manager clients running under the Microsoft Windows or MS-DOS operating systems. Using the multi-protocol Net-Library, trusted connections can also be made over the NWLink IPX/SPX protocol from Windows 3.1 clients using Novell software. (In this case, the user will be prompted for a Windows NT username and password at SQL Server connect time.) Other network protocols do not support authenticated connections, so clients on these protocols must be handled according to SQL Server standard security.

When a user of integrated security logs in to SQL Server over a trusted connection, the user is mapped to a SQL Server login ID, to a default SQL Server login ID (usually called guest), or–if the user has administrative privileges–to SA.

Once the login process is complete, all other SQL Server security checks are handled as usual. Access to individual SQL Server tables, for example, is managed through the permissions granted within a SQL Server database.

If multiple SQL Server computers participate in a domain managed by a Windows NT Server, a single network login for each user is sufficient to enable access for all of the SQL Servers. For users defined on other domains, SQL Server provides map characters to map the domain name and username to a SQL Server login ID (for example, salesdomain_Chris). These map characters also provide a way to map Windows NT usernames that are not valid SQL Server login IDs to valid SQL Server login IDs.

The recommended way to implement SQL Server security integration is to create two or more locally defined Windows NT groups and then provide the users of those groups with access to SQL Server. The two recommended Windows NT groups are:

  • A SQLUsers group, to be assigned user privileges
  • A SQLAdmins group, to be assigned system administrator privileges. (Note that when SQL Server is set up with integrated security, the Administrators group on the local computer is automatically mapped to the sa login ID. This can be disabled if you prefer.)

For more information about the interaction of Windows NT security with SQL Server security, see Windows NT Security and SQL Server. For instructions on setting up integrated security (beginning with an overview of each task required to do so), see Chapter 9, Managing Security.


Standard Security

Standard security uses SQL Server's own login validation process for all connections. To log into a SQL Server, each user must provide a valid login ID and password.

When a server's login security mode is set to standard and a user attempts to log in to the server, SQL Server looks in the syslogins table for the user's login ID and password. If the login ID and password given are valid, the user is connected to the SQL Server.

For instructions on setting up standard security (beginning with an overview of each task required to do so), see Chapter 9, Managing Security.


Mixed Security

Mixed security allows SQL Server login requests to be validated using either integrated or standard security methods. Both trusted connections (as used by integrated security) and nontrusted connections (as used by standard security) are supported.

When a server's login security mode is set to mixed and a user attempts to log in to the server over a trusted (multi-protocol or named pipes) connection, SQL Server examines the login name.

  • If this login name matches the user's network username, or if the login name is blank or spaces, SQL Server uses the Windows NT integrated login rules (as for integrated security).
  • If the requested login name is any other value, the user must supply the correct SQL Server password, and SQL Server uses its own login validation process (as for standard security).

If the login attempt is not over a trusted connection, the user must supply the correct login ID and password to establish the connection, and SQL Server uses its own login validation process (as for standard security).

For instructions on setting up mixed security (beginning with an overview of each task required to do so), see Chapter 9, Managing Security.


Client-Requested Trusted Connections

Regardless of the server's login security mode, ODBC and DB-Library client applications can be configured to always request a trusted (integrated security) connection from the server. This feature allows SQL Executive to connect to remote servers as long as SQL Executive is running under a properly configured Windows NT user account, one that has been granted SA access to the SQL Server.

This feature forces a trusted connection, but the appropriate user privilege levels must exist if the login is to succeed. If desired, logging on over client-requested trusted connections can be prevented by performing these steps:

  1. Use the Windows NT User Manager utility to create a local Windows NT user group (for example, SQLAdmins) that contains no users.
  2. Use SQL Security Manager to grant System Administrator privilege to this empty group.
  3. Use SQL Security Manager to revoke System Administrator privilege from the local Administrators group.

For more information about integrated security, see Chapter 9, Managing Security.

For more information, see Microsoft SQL Server Programming DB-Library for C, Microsoft SQL Server Programming DB-Library for Visual Basic, and SQL Server ODBC Driver online Help.


Windows NT Security and SQL Server

Because security in Windows NT is assigned on a per user rather than a per resource basis, a user needs to remember only a single Windows NT user account name and password to log on and use local and network resources. With Windows NT security, all resources and actions are protected by discretionary access control, meaning that some users can be permitted access to a resource or perform an action, while other users can be prevented from accessing the same resource or action. Security is very flexible–for example, different permissions for different users can be set on different files in a directory. Windows NT security applies both to users working at the computer where the resource is located and to users accessing the resource over the network.

For Windows NT, the basic unit of security and centralized administration is the domain. A domain is a collection of computers that recognize a common security accounts database. Four types of computers participate in domain security: primary domain controllers (PDCs), backup domain controllers (BDCs), servers, and workstations.

Each domain has one PDC, which maintains the security accounts database for the domain. A domain can have any number of BDCs. Each BDC receives a copy of the domain's security accounts database and assists the PDC by sharing the load of authenticating domain logins. PDC and BDC computers always run the Windows NT Server operating system.

Other computers can be members of the domain. A member computer participates in domain security. It maintains its own local security accounts database and can authenticate local logins, but it can also accept login authentications of domain users that have been performed by the domain's PDC and BDCs. A computer running the Windows NT Server operating system can be a member server in the domain. A computer running the Windows NT Workstation operating system can be a member workstation in the domain.

Other types of computers–for example, Microsoft MS-DOS–based computers–do not store user accounts and do not participate in domain security. However, such computers usually have a default domain declared in order to support browsing of computer lists.

Microsoft SQL Server 6.0 is not recommended for installation on a PDC or a BDC, because those computers perform the resource-intensive tasks of maintaining and replicating the domain's security accounts database and performing network login authentications.

SQL Server will be installed on a computer running the Windows NT Server operating system, which in most instances will be acting as a member server in a domain. It can also be installed on a computer that is not a member of a domain, or even a computer that does not have any network capabilities.

Microsoft SQL Workstation 6.0 can be installed on a computer running the Microsoft Windows NT Workstation operating system. Microsoft SQL Workstation 6.0 has the same capabilities as Microsoft SQL Server, except that it is a single-user licensed product that supports a maximum of 15 simultaneous database connections.

When SQL Server is configured for security integration with Windows NT, it takes advantage of the security capabilities of Windows NT. Windows NT users can be authorized to log into the SQL Server. Windows NT user accounts can be mapped to login IDs. This allows a user to connect to and log in to a SQL Server without supplying a separate login ID or password. The user's original login to Windows NT is enough to allow (or, if appropriate, deny) access to SQL Server. With security integration, users maintain one login ID and password for both Windows NT and SQL Server.

With security integration, database-level security is still managed by the database owner. Database groups and users are created as for any SQL Server installation, and object and statement permissions are assigned in the normal fashion.

The following illustration shows that separate but interrelated security elements exist at the domain, computer, SQL Server, and database levels.

There can be more than one Windows NT domain in a network or enterprise. Trust relationships are security agreements between domains. These agreements enable pass-through user login authentication. Trust relationships and pass-through authentication allow a user to have only one user account in one domain, yet access the entire network.

When two domains are set up to trust each other, a user from one domain can be allowed (or denied) access to resources and actions for the computers of the other domain. The trusting domain accepts as valid the login authentications it receives from the trusted domain–in much the same way that a member computer of a domain accepts as valid the login authentications it receives from the PDCs and BDCs of its own domain.

For more information about Windows NT domains and security, see your documentation for Windows NT. For more information about security integration, see About the Server Login Security Mode. For more information about allowing a Windows NT user access to a SQL Server, see About Server Login IDs. For more information about allowing any user access to a database, see About Database Users.


About Server Login IDs

A login ID is a name by which a user is known to SQL Server. For more information, choose one of the following topics:

Login IDs

The Default Login ID

Visitor Login IDs

Login IDs Provided by SQL Server


Login IDs

To access a SQL Server, a user must be assigned a valid login ID: a unique name that follows the rules for identifiers and is used to identify a user on a SQL Server. A login ID is also sometimes referred to as a login.

The login IDs you need to create depend on the server's login security mode:

  • If a server is configured for integrated security with Windows NT, it is not necessary to create a login ID for each user. The SQL Security Manager utility provided with SQL Server can automatically map the Windows NT – based usernames to SQL Server login IDs or to a default login ID. For more information about using SQL Security Manager, see Chapter 9, Managing Security.
  • If a server is configured for standard security, you must create a separate login ID for each user who will connect to that SQL Server–except for those users who will always connect as system administrator by using the built-in sa login ID.

    You can create a visitor login ID to be shared by infrequent users who have common access and permission requirements. For more information, see Visitor Login IDs.

  • If a server is configured for mixed security, you will need to create login IDs for each user who will connect over nontrusted connections, using the standard security rules described above. You may also want to create a visitor login ID.

    For each user who will connect over trusted connections using integrated security rules, you will need to use SQL Security Manager to map the Windows NT – based usernames to SQL Server login IDs or to a default login ID.

Other information is associated with a login ID. When you create a login ID, you will usually also:

  • Provide a password for that login ID.

    The default password is NULL. Unless you assign some other password when a user's login is established, the user will not have a password. When using standard or mixed security, you should not allow a NULL password.

    With integrated security, there is no need to maintain passwords. However, if you change to standard or mixed security, anyone can log in if there are no passwords, so it is a good idea to set random passwords. (SQL Security Manager will do this for you.)

  • Assign a default language.

    The user will be automatically logged in as using that language. Only the languages available to the server are available to the user. If no language is specified, SQL Server's default language is used.

  • Assign a default database.

    A default database is the database that the user is connected to immediately after logging in to SQL Server. However, before a user can access objects in the default database, the user must be granted permissions for the database.

    If no database is specified, the master database becomes the default database. Although you should have master as the SA's default database, you should assign default databases other than master to other users to discourage them from creating database objects in the master database.

  • Specify the databases the login ID will be permitted access to.
  • Assign a username (or alias) and, optionally, a group for each database the login ID is permitted access to.

For information about creating a login ID and specifying the above information, see Chapter 9, Managing Security. For information about usernames, aliases, and groups, see About Database Users.

The SA can manage all aspects of login IDs. A user is allowed to change his or her own password, default language, and default database.

If you no longer want a user to have access to a particular SQL Server, you must drop the user's login ID from that server. You cannot drop the login ID of a user who is the owner of the current database or a database object in the current database. You must transfer the ownership of the current database and drop owned objects from the current database before dropping the owner's login ID.

A login ID provides access to a SQL Server but does not allow a user to access any user databases. A database username and appropriate permissions are required to access and use a database. For information about providing database access, see About Database Users and About Permissions.


The Default Login ID

If the server has been set up for integrated or mixed security, at the time the login security mode was set, the name of a default login ID (usually guest) could have been specified. Under integrated security, when an authorized user (one granted login permission by SQL Security Manager or xp_grantlogin) who does not have a SQL Server login ID logs in to SQL Server, the user is automatically mapped to the default login ID. If a default login has not been specified, then such a user is denied access to SQL Server.

If a default login was specified when the login security mode was set to integrated or mixed, then that login is added automatically by SQL Server.

A default login ID on SQL Server only allows a user to log in to the server. To allow a user access to a database (without adding a username), a guest user must be added to the database. For information, see About Database Users.


Visitor Login IDs

A visitor login ID is a general-purpose login ID. Creating a visitor login on a server enables anyone who knows that login ID and the password to log in to SQL Server. If this is desired, the SA must add a login ID (for example, visitor) and provide that login ID and password to selected users.

A visitor login ID on SQL Server only allows a user to log in to the server. To allow a user access to a database (without adding a username), a guest user must be added to the database. For information, see About Database Users.


Login IDs Provided by SQL Server

When SQL Server is installed, two login IDs are automatically created: sa and probe. When a server is configured to participate in replication, one or both of these additional login IDs are automatically created: repl_publisher and repl_subscriber.

For more information, choose one of the following topics:

The sa Login ID

The probe Login ID

The repl_publisher Login ID

The repl_subscriber Login ID


The sa Login ID

The system administrator (SA) is responsible for administrative tasks unrelated to specific applications. Anyone who knows the system administrator's password can log in using the sa login ID and act in the role of system administrator.

A SQL Server system administrator is responsible for setting up and maintaining SQL Server. Administering SQL Server includes such tasks as:

  • Installing SQL Server
  • Creating devices and databases
  • Managing and monitoring the use of disk space, memory, and connections
  • Authorizing SQL Server users and granting permissions to them
  • Transferring data in and out of SQL Server databases
  • Backing up and restoring databases
  • Configuring the server for replication
  • Managing extended stored procedures
  • Diagnosing system problems
  • Fine-tuning SQL Server to achieve the best performance

The system administrator is sometimes responsible for managing database objects, including:

  • Tables and indexes
  • Defaults and rules
  • Views
  • Stored procedures
  • Triggers

In addition, a system administrator might also add, change, or delete data in a database.

For information about managing database objects and data, see the Microsoft SQL Server Transact-SQL Reference.

The system administrator operates outside the protection system, which means that SQL Server does no permission checking for the system administrator. (However, the SA can use SETUSER ['ID'] to impersonate another user.) There are several commands and system procedures that only the system administrator can issue (and that cannot be transferred to other users). For detailed information about system administrator permissions, see About Permissions.

The system administrator can transfer many responsibilities to other users by assigning appropriate permissions. For information, see Chapter 9, Managing Security.

When SQL Server is installed, the system administrator is the database owner of the master database. The system administrator is also treated as database owner of any databases he or she uses. For information about database ownership, see Owners.

The following illustration outlines the responsibilities of a typical system administrator.

For more information about system administrators, see Permissions of the SA.


The probe Login ID

This is a special login ID that is installed by the setup program and is used as the security context within which some administrative applications (for example, SQL Performance Monitor) connect to a SQL Server that is configured for standard security. Note that if a SQL Server is set up for integrated security, sa is used for this purpose, instead of probe.

Users should not log in using this login ID.


The repl_publisher Login ID

The repl_publisher login ID is created automatically when a server is set as a subscription server. It allows replication processes on the distributor (which may be a separate distribution server or a combined publication/distribution server) to connect to a subscription server and replicate table schema and data to destination databases. This login ID should not be modified, nor should users use it to log in.

When replication is set up, a subscription server is automatically set up as remote server to its distributor. When replication processes from the distributor connect to the subscription server, they connect using the repl_publisher login ID.

When a database on the subscription server is marked for subscription, the repl_publisher login ID is aliased to DBO on that destination database. This allows replication processes to create tables and schemas, and to perform inserts, updates, and deletes.

It is possible to manually alias the repl_publisher login ID to a user with lesser database privileges than DBO, but this should be done with care because all replicated objects within the database will be created and maintained using this login ID.

For more information about replication, see Part 6, Replication.


The repl_subscriber Login ID

The repl_subscriber login ID is created automatically when a server is set as a publication server. It allows replication processes on a subscription server to connect to a publication server and execute stored procedures. This login ID should not be modified, nor should users use it to log in.

When replication is set up, a publication server is automatically configured as remote server to each of its subscription servers. Unless a previous mapping for the SA exists, when replication processes from the subscription server connect to the publisher, the SA account from the subscriber is mapped to the repl_subscriber login ID on the publisher. Also, repl_subscriber is set as a user in the master, distribution, and msdb databases and in all publication databases. This allows the subscriber to execute a specific set of remote stored procedures on the publisher.

If the publication server is configured to use a remote distribution server, then the distribution server is set as a remote server to the subscriber, the repl_subscriber login ID is created on the distribution server, and repl_subscriber is set as a user in the master, distribution, and msdb databases of the distributor. This allows the subscriber to execute specific remote stored procedures on the distributor.

For more information about replication, see Part 6, Replication.


About Database Users

You allow a user to access a database by assigning a database username to the user's login ID. The username can be one created specifically for that login ID, or it can be someone else's username in the database (called an alias).

When you add a user to the database, you can also specify which group the user will belong to. A group is a collection of users and is a convenient way to provide common permissions to those users. There is a built-in group, called public, that users belong to by default.

A user who creates a database becomes the database owner (DBO) and has full privileges for that database. A user who creates a database object (for example, a table or a view) becomes the database object owner and has full privileges for that object.

For more information, choose one of the following topics:

Usernames

Aliases

The guest User

Groups

Owners

The repl_subscriber User


Usernames

A database username is a name known to the database, and assigned to a login ID for the purpose of allowing a user to have access to a database. A database username is often simply called a user. The abilities a user has within a database depend on the permissions granted to the username, and the permissions granted to any groups the username is a member of.

The user must already have a login ID on a SQL Server. You must add a login ID for the user on a SQL Server before you can add the username to a database. If you add a new user to a database without specifying a username, the username is automatically the same as the login ID.

Because usernames are separate from login IDs, user preferences can be accommodated. For example, if there are five SQL Server users named Mary, all of them will have different login IDs. However, if they don't use the same databases, each Mary might prefer to be known simply as mary inside a particular database.

Users who have been given access to a database still need permission to do things inside it. These permissions are set up by the database owner or the database object owner. For information about permissions, see About Permissions.


Aliases

An alias is a database username that is shared by several login IDs. An alias allows you to treat more than one person as the same user inside a database, giving all of them the same permissions. A common use for aliases is to allow several users to assume the role of database owner (DBO).

To create an alias, you assign a login ID to an existing database username, instead of creating a unique username specifically for that login ID. Any username in a database can serve as an alias.

If you assign a login ID to an alias, that login ID cannot be assigned any other username in that database. Nor can that login ID be assigned to a database group, since it automatically belongs to the groups (public and, optionally, one other) that the alias belongs to.

Aliases can be used to set up a collective user identity, within which the identities of individual users can be traced. For example, suppose several vice presidents want to use a database with identical privileges and ownerships. You could:

  1. Add a separate SQL Server login ID for each vice president.
  2. Assign a new username in the database, vp, to one of the login IDs.
  3. Provide appropriate permissions in the database to the user vp.
  4. Assign the other login IDs to the alias vp.

In the preceding example, all the vice presidents have common capabilities within the database.

If a user is already authorized to use the database, you must drop the username for that login ID before you can assign an alias to it.


The guest User

Creating a user named guest in a database enables any user with a login ID for SQL Server to access the database as a guest user. If a user attempts to access the database but does not have a username (his or her username is not found in the database's sysusers table), SQL Server looks for a user named guest. If there is one, the user is allowed to use the database, under the permissions assigned to guest.

When the guest username is first added to a database, the username inherits the privileges of the public group. The database owner and the owners of database objects can change these permissions, to make the privileges of guest either more or less restrictive than those of public.

If you are using integrated security and have not created individual login IDs for users, you can provide a database username for the default login ID, or you can add the guest user. In both cases, be aware that any user of integrated security can access the database and acquires the permissions you assign to the default login ID or to the guest user. (This is also true for connections from a client configured to force trusted connections. For information, see Client-Requested Trusted Connections, earlier in this chapter.)

In databases, the database owner is responsible for setting up a guest user. A guest user in a database allows the database owner to extend database use to all SQL Server users without explicitly naming each one.

When SQL Server is installed, the master, tempdb, msdb, and pubs databases contain the guest user. The model database, and user databases that are later created, do not. Each database owner can add, if appropriate, a guest user to any user database, thus extending database access to all SQL Server users, without explicitly naming each one.

The guest user in the master database means that any user with a login ID for SQL Server (or, with integrated security, any user granted user-level privilege to access SQL Server) can successfully connect to SQL Server by logging in with his or her own name. If the username is not found (in master..sysusers), the user is recognized as guest and inherits whatever permissions the public group has been granted.


Groups

A group is a collection of database users. The users receive the database permissions granted to the group. Using groups simplifies management of a large number of database users who share common requirements, because groups provide a convenient way to grant and revoke permissions to more than one user at the same time. For a SQL Server installation that has a large number of users, consider using one or more groups.

It is a good idea to create groups before you create users, so that when users are added they can be assigned to the appropriate groups.

There is a built-in group, public, in every database. Each user automatically belongs to public and can be added to one other group. You cannot remove a user from the public group.

When you drop a group, all users in that group are automatically removed from the group. However, dropping a group does not drop its users. Users who were members of the dropped group are still valid users in the database and members of the public group.

If you are using integrated security and have created groups with Windows NT, those groups are not automatically tied to database groups. If you want all members of a Windows NT group to be assigned to a database group, you must first assign all users of the group explicit login IDs, add all those login IDs as users in the database, and then assign those users to the database group you create. (The SQL Security Manager utility can automatically create a SQL Server group for a selected Windows NT group.)

Note that a SQL Server database user can be a member of only the public group plus one other group. However, a Windows NT user under Windows NT security can be a member of many Windows NT groups.


Owners

Within each database SQL Server recognizes two types of owner:

Database Owner

Database Object Owner


Database Owner

The database owner (DBO) is the creator of a database. The system administrator grants to users the authority to create databases.

The DBO has full privileges inside the database that he or she owns. The DBO can:

  • Allow users access to the database.
  • Grant users permission to create objects and execute commands within the database.
  • Set up groups (which make it easy to grant and revoke permissions). By default, each user is a member of the public group unless explicitly assigned to another group.
  • Assign users to groups and add guest accounts, which give users limited access to a database.

A database owner logs in to SQL Server by using an assigned login ID and password. In his or her own database, the user is recognized as DBO; in other databases, the database owner is known by his or her database username.

When SQL Server is installed, the system administrator is the database owner of the master database. The system administrator is also treated as database owner of any databases he or she uses.

DBO status can be reassigned to a different user. Only one login ID can be DBO, although other login IDs can be aliased to DBO.

For more information on database owners, see Permissions of Database Owners.


Database Object Owner

Database objects are tables, indexes, views, defaults, triggers, rules, and procedures. The user who creates a database object is the database object owner. The database owner must first grant to the user permission to create the particular type of object. The database object owner can then create an object and grant permission to other users to use that object.

Database object owners have no special login IDs or passwords. The creator of a database object is automatically granted all permissions on it. A database object owner must explicitly grant permissions to other users before they can access the object. Even the database owner cannot use an object unless the object owner has granted the appropriate permission. However, the database owner and system administrator can impersonate any other user in the database.

There is no command to transfer ownership of objects. If a database object owner must be dropped from a database, the owned objects must first be dropped.

For more information on database object owners, see Permissions of Database Object Owners.


The repl_subscriber User

When replication is set up, some databases on the publication server automatically have the repl_subscriber user added. This database user should not be modified, nor should users use it to access the database.

Replication processes from a subscription server are aliased to the repl_subscriber login ID. Replication processes from the subscriber server can execute stored procedures on the publisher in those databases that have the repl_subscriber database user. On a publication server, repl_subscriber is automatically added as a user in the master, distribution, and msdb databases and in all publication databases. (Note that two security elements are discussed here: the repl_subscriber login ID and the repl_subscriber database user.)

If the publication server is configured to use a remote distribution server, then the repl_subscriber database user is automatically added to the master, distribution, and msdb databases of the distributor.

For more information about replication, see Part 6, Replication.


About Permissions

Microsoft SQL Server uses permissions to enforce database security. The SQL Server permissions system specifies which users are authorized to use which Transact-SQL statements, views, and stored procedures. The ability to assign permissions is determined by each user's status (as SA, database owner, or database object owner). Permissions are set on database users or groups, not on login IDs.

The topics that follow provide an orientation to SQL Server permissions. To learn about the tools you will use and the procedures you will perform to manage permissions, see Chapter 9, Managing Security.

For more information about permissions, choose one of the following topics:

Permissions Summary

Object and Statement Permissions

Permission Hierarchy

Permissions on Views and Stored Procedures


Permissions Summary

The following table summarizes the SQL Server permissions system. The type of user listed as the one the statement defaults to is the lowest user level to which the permission is automatically granted. This user can grant the permission to other users or revoke it from other users, if it is transferable.

 | Defaults to |  |  |  |  | Can be granted / revoked
Statement | System admin |  | DB owner | Table owner | Public |  | Yes |  | No |  | N/A
ALTER DATABASE |  | – | X | – | – |  |  | (1) |  | – |  | –
ALTER TABLE |  | – | – | X | – |  |  | – |  | X |  | –
BEGIN TRANSACTION |  | – | – | – | X |  |  | – |  | – |  | X
CHECKPOINT |  | – | X | – | – |  |  | – |  | X |  | –
COMMIT TRANSACTION |  | – | – | – | X |  |  | – |  | – |  | X
CREATE DATABASE |  | X | – | – | – |  |  | X |  | – |  | –
CREATE DEFAULT |  | – | X | – | – |  |  | X |  | – |  | –
CREATE INDEX |  | – | – | X | – |  |  | – |  | X |  | –
CREATE PROCEDURE (2) |  | – | X | – | – |  |  | X |  | – |  | –
CREATE RULE |  | – | X | – | – |  |  | X |  | – |  | –
CREATE TABLE |  | – | X | – | (3) |  |  | X (2) |  | – |  | –
CREATE TRIGGER |  | – | – | X | – |  |  | – |  | X |  | –
CREATE VIEW |  | – | X | – | – |  |  | X |  | – |  | –
DBCC |  | – | X | – | – |  |  | – |  | X |  | –
DELETE |  | – | – | X (4) | – |  |  | X |  | – |  | –
DISK INIT |  | X | – | – | – |  |  | – |  | X |  | –
DISK MIRROR |  | X | – | – | – |  |  | – |  | X |  | –
DISK REFIT |  | X | – | – | – |  |  | – |  | X |  | –
DISK REINIT |  | X | – | – | – |  |  | – |  | X |  | –
DISK REMIRROR |  | X | – | – | – |  |  | – |  | X |  | –
DISK UNMIRROR |  | X | – | – | – |  |  | – |  | X |  | –
DROP any object (5) |  | – | – | – | – |  |  | – |  | X |  | –
DUMP DATABASE |  | – | X | – | – |  |  | X |  | – |  | –
DUMP TRANSACTION |  | – | X | – | – |  |  | X |  | – |  | –
EXECUTE (6) |  | – | – | – | – |  |  | X |  | – |  | –
GRANT |  | – | X | – | – |  |  | – |  | X |  | –
GRANT on object (5) |  | – | – | – | – |  |  | – |  | X |  | –
INSERT |  | – | – | X (4) | – |  |  | X |  | – |  | –
KILL |  | X | – | – | – |  |  | – |  | X |  | –
LOAD DATABASE |  | – | X | – | – |  |  | – |  | X |  | –
LOAD TRANSACTION |  | – | X | – | – |  |  | – |  | X |  | –
PRINT |  | – | – | – | X |  |  | – |  | – |  | X
RAISERROR |  | – | – | – | X |  |  | – |  | – |  | X
READTEXT |  | – | – | X | – |  |  | (7) |  | – |  | –
RECONFIGURE |  | X | – | – | – |  |  | – |  | X |  | –
REFERENCE |  | – | – | X | – |  |  | X |  | – |  | –
REVOKE |  | – | X | – | – |  |  | – |  | X |  | –
REVOKE on object (5) |  | – | – | – | – |  |  | – |  | X |  | –
ROLLBACK TRANSACTION |  | – | – | – | X |  |  | – |  | – |  | X
SAVE TRANSACTION |  | – | – | – | X |  |  | – |  | – |  | X
SELECT |  | – | – | X (4) | – |  |  | X |  | – |  | –
SET |  | – | – | – | X |  |  | – |  | – |  | X
SETUSER |  | – | X | – | – |  |  | – |  | X |  | –
SHUTDOWN |  | X | – | – | – |  |  | – |  | X |  | –
TRUNCATE TABLE |  | – | – | X | – |  |  | – |  | X |  | –
UPDATE |  | – | – | X (4) | – |  |  | X |  | – |  | –
UPDATE STATISTICS |  | – | – | X | – |  |  | – |  | X |  | –
UPDATETEXT |  | – | – | X | – |  |  | – |  | – |  | –
WRITETEXT |  | – | – | X | – |  |  | (8) |  | – |  | –
1) Transferred with CREATE DATABASE permission |  |  |  |  |
(2) Permissions to create temporary procedures are granted by default. A user can create and execute temporary procedures in a database even if not explicitly granted CREATE PROCEDURE permission.
(3) Members of public can create temporary tables; no permission required |  |  |  |  |  |  |  |  |
(4) If a view, permission defaults to view owner |  |  |  |  |
(5) Defaults to object owner |  |  |  |  |
(6) Defaults to stored-procedure owner |  |  |  |  |
(7) Transferred with SELECT permission |  |  |  |  |
(8) Transferred with UPDATE permission |  |  |  |  |


Object and Statement Permissions

SQL Server has two categories of permissions: object and statement. Some statement permissions (for the SELECT, UPDATE, INSERT, DELETE, and EXECUTE statements) are handled as object permissions because these statements always apply to database objects (in the current database).

For more information choose one of the following topics:

Object Permissions

Statement Permissions


Object Permissions

Object permissions regulate the use of certain statements on certain database objects. They are granted and revoked by the owner of the object. Object permissions apply to the following statements and objects:

Statement | Object
SELECT | Table, view, columns
UPDATE | Table, view, columns
INSERT | Table, view
DELETE | Table, view
REFERENCE | Table
EXECUTE | Stored procedure

With SQL Server 6.0, REFERENCE permission provides for ANSI compatability of referential constraints. It allows foreign key references to a given table without having SELECT permissions on that table. This permission is checked when a table is created, and the user creating the table must have either SELECT or REFERENCE permission on any referenced tables. (Creating a reference to a table implies that the referenced table has permissions to verify any references back to the table in the CREATE statement.)

To grant or revoke object permissions, use SQL Enterprise Manager or the GRANT and REVOKE statements. For information about managing permissions with SQL Enterprise Manager, see Chapter 9, Managing Security. For information about the GRANT and REVOKE statements, see the Microsoft SQL Server Transact-SQL Reference.


Statement Permissions

Statement permissions are not object-specific. They can be granted only by the SA or the database owner. Statement permissions apply to these statements:

  • CREATE DATABASE (can be granted only by the SA and only to users in the master database)
  • CREATE DEFAULT
  • CREATE PROCEDURE
  • CREATE RULE
  • CREATE TABLE
  • CREATE VIEW
  • DUMP DATABASE
  • DUMP TRANSACTION

Each database has its own independent permissions system. In other words, being granted permission to use a certain statement in one database has no effect in other databases.

If you try to use a statement or database object for which you do not have permission, SQL Server returns an error message.

To grant or revoke statement permissions, use SQL Enterprise Manager or the GRANT and REVOKE statements. For information about managing permissions with SQL Enterprise Manager, see Chapter 9, Managing Security. For information about the GRANT and REVOKE statements, see the Microsoft SQL Server Transact-SQL Reference.


Permission Hierarchy

SQL Server's permissions system recognizes four types of users: the SA, database owners, database object owners, and other users of the database.

The different types of users exist in a hierarchy (explained in the following sections and illustrated below).

Only the SA and database owners can grant statement permissions to other users.

The SA is recognized by SQL Server as a "superuser" who works outside SQL Server's permissions system. The SA is not necessarily an individual user but, rather, is a role in SQL Server.

For more information, choose one of the following topics:

Permissions of the SA

Permissions of Database Owners

Permissions of Database Object Owners

Permissions on System Tables

Permissions on System Procedures

Permission Impersonation

Permission Conflicts


Permissions of the SA

The SA handles tasks not specific to an application. There are no restrictions on what the SA can do within SQL Server. This gives the SA the ability to repair any damage inadvertently done to the permissions system.

There are several statements that only the SA can execute; these cannot be granted to any other user:

  • DISK INIT
  • DISK REFIT
  • DISK REINIT
  • DISK MIRROR
  • DISK REMIRROR
  • DISK UNMIRROR
  • KILL
  • RECONFIGURE
  • SHUTDOWN
  • Some DBCC operations (for example, pintable)

Only the SA can grant CREATE DATABASE permission. Control of this statement is reserved for the SA because it determines the amount and location of the storage allocated for each database. ALTER DATABASE permission on a database defaults to the owner of that database, but only if he or she has CREATE DATABASE permission. ALTER DATABASE permission cannot be transferred. In addition, the SA is the only user allowed to add and drop extended stored procedures.


Permissions of Database Owners

The database owner has full permission to do anything inside his or her database and must explicitly grant permissions to other users.

These permissions are automatically granted to the database owner and cannot be transferred to other users:

  • CHECKPOINT
  • DBCC
  • DROP DATABASE
  • GRANT and REVOKE statement permissions
  • LOAD DATABASE
  • LOAD TRANSACTION
  • SETUSER

Database owners can grant permissions on these statements to other users:

  • CREATE DEFAULT
  • CREATE PROCEDURE
  • CREATE RULE
  • CREATE TABLE
  • CREATE VIEW
  • DUMP DATABASE
  • DUMP TRANSACTION


Permissions of Database Object Owners

A user who creates a database object (a table, view, or stored procedure) is its owner and is automatically granted all object permissions on it. Users other than the object owner, including the owner of the database, are automatically denied all permissions on that object unless explicitly allowed by the owner.

Object permissions are granted on the statements SELECT, UPDATE, INSERT, DELETE, REFERENCE, and EXECUTE.

As an example, say that Mary is the owner of the pubs database and has granted Joe permission to create tables in it. Joe creates the table authors; he is the owner of this database object.

Initially, object permissions on authors belong to Joe. Joe can grant object permissions for this table to other users, including Mary, the database owner. (Note, however, that the database owner can use the SETUSER statement to impersonate Joe.)

These statement permissions default to the owner of a table and cannot be transferred to other users:

  • ALTER TABLE
  • CREATE INDEX
  • DROP INDEX
  • CREATE TRIGGER
  • DROP TRIGGER
  • DROP TABLE
  • TRUNCATE TABLE
  • UPDATE STATISTICS

Permission to use the GRANT and REVOKE statements cannot be transferred.

Permission to drop an object – a table, view, index, stored procedure, rule, or default – defaults to its owner and cannot be transferred. Since there is no command to transfer ownership of objects, if you will be dropping the username, you must first drop the objects.


Permissions on System Tables

The SQL Server setup program sets permissions on the system tables in a database so that all database users can read the system tables.

However, the default is that no users – including database owners – can modify the system tables directly with SQL statements. Rather, the graphical tools (such as SQL Enterprise Manager) or system procedures are used to modify the system tables. (The SA can change this situation so that ad hoc modifications to the system tables are allowed. For more information, see Chapter 3, Configuring Servers.)

Important Never update the system tables unless instructed to do so by Microsoft technical support personnel.


Permissions on System Procedures

Because system procedures are located in the master database, their permissions are set there.

Some of the system procedures can be run only by database owners. These procedures check whether the user executing the procedure is the owner of the database from which it is being executed.

Other system procedures (for example, all the sp_help procedures) can be executed by any user who has been granted permission – but this permission must be granted in master. In other words, a user must have permission to execute a system procedure in all databases or in none of them.

SQL Server users who do not have usernames in the master database are treated as guests in master and thus are automatically granted permission on many of the system procedures. To deny a user permission on a system procedure, the SA must add that user to the master database and write a REVOKE statement that applies to that procedure. Because permissions for system procedures are set in the master database, the owner of a database cannot directly control permissions on the system procedures within his or her own database.


Permission Impersonation

If you are the database owner, you can impersonate another user who owns objects in the database. This allows you to grant and revoke permissions on those objects. If you are the system administrator, you can create objects that will be owned by another user.

With the SETUSER statement, a database owner can impersonate another user's identity and permission status in the current database. The SETUSER statement allows a database owner to access an object owned by another user, to grant permissions on an object owned by another user, to create an object that will be owned by another user, and to temporarily take on the permissions of another user. SETUSER permission defaults to the database owner and cannot be transferred.

The SA can use SETUSER to create objects that will be owned by another user and can do so until another SETUSER statement is given. SETUSER allows the SA to take on a user's identity temporarily.

SETUSER is not necessary when you drop objects. The SA and DBO can drop all database objects.

For information about using the SETUSER statement, see the Microsoft SQL Server Transact-SQL Reference.


Permission Conflicts

Permissions can be administered for both groups and users. The permissions granted to a group are provided to the users who are members of that group. However, permissions are sensitive to the order in which they are granted or revoked. The examples that follow demonstrate how.

There are two basic ways to set up permissions in a database or on a database object. The most straightforward is to assign specific permissions to specific users. However, if most users are going to be granted most privileges, it's easier to assign all permissions to all users and then revoke specific permission from specific users. For example, the database owner of titles could:

  1. Grant permissions on the titles table to all users by granting all object permissions to the public group.
  2. Revoke update permissions from public for the royalty and advance columns on titles.
  3. Revoke delete permissions on titles from the user mary, the group sales, and the user john.

In this example, most users have all permissions on titles except for update permissions on the royalty and advance columns. Users in the sales group, plus mary and john, are also denied delete permissions for the table.

As another example, if the user joe is in the opers group, the opers group is granted SELECT permission on the titles table, and joe's permission to select the advance column is revoked, then joe can select all the columns except advance, while the other users in his group can still select all the columns.

Granting or revoking permissions for a group will change any conflicting permissions that have been assigned to any member of a group. As an example, say the owner of the titles table has granted different permissions to various members of the sales group and then decides to standardize. This database owner could:

  1. Revoke all permissions on titles from the sales group.
  2. Grant select permission on the title, title_id, type, and pub_id columns of titles to the sales group.

In this example, all users in sales now have the same permissions for titles.

Granting or revoking permissions to the public group changes, for all users, any previously issued permissions that conflict with the new statement.

Permissions granted and revoked in different orders can create entirely different situations. For example, the following steps leave the user joe without any SELECT permission on titles (assuming Joe belongs to the public group):

  1. Grant select permission on the title_id and title columns of the titles table to joe.
  2. Revoke select permission on the titles table from the public group.

In contrast, suppose the same permissions are issued in the opposite order:

  1. Revoke select permission on the titles table from the public group.
  2. Grant select permission on the title_id and title columns of the titles table to joe.

In the second example, only joe has select permission for titles, and only on the title_id and title columns.

When you administer permissions for the public group, you are including yourself (if you are a member of the public group).

To grant or revoke permissions, use SQL Enterprise Manager or the GRANT and REVOKE statements. For information about managing permissions with SQL Enterprise Manager, see Chapter 9, Managing Security. For information about using the GRANT and REVOKE statements, see the Microsoft SQL Server Transact-SQL Reference.


Permissions on Views and Stored Procedures

A user can be granted permission on a view or on a stored procedure even if he or she has no permissions on objects that the view or procedure references.

For more information, choose one of the following topics:

Views as Security Mechanisms

Stored Procedures and Permissions

Ownership Chains

Triggers and Permissions


Views as Security Mechanisms

Views can serve as security mechanisms. Through a view, users can query and modify only the data they can see. The rest of the database is neither visible nor accessible.

Permission to access the subset of data in a view must be granted or revoked, regardless of the set of permissions in force on the view's underlying tables. Data in an underlying table that is not included in the view is hidden from users who are authorized to access the view but not the underlying table.

By defining different views and selectively granting permissions on them, a user (or any combination of users) can be restricted to different subsets of data. The following examples illustrate the use of views for security purposes:

  • Access can be restricted to a subset of the rows of a base table (a value-dependent subset). For example, you might define a view that contains only the rows for business and psychology books and keep information about other types of books hidden from some users.
  • Access can be restricted to a subset of the columns of a base table (a value-
    independent subset). For example, you might define a view that contains all the rows of the titles table but omits the royalty and advance columns, since this information is sensitive.
  • Access can be restricted to a row-and-column subset of a base table.
  • Access can be restricted to the rows that qualify for a join of more than one base table. For example, you might define a view that joins the titles, authors, and titleauthor table to display the names of the authors and the books they have written. This view would hide personal data about the authors and financial information about the books.
  • Access can be restricted to a statistical summary of data in a base table. For example, you might define a view that contains only the average price of each type of book.
  • Access can be restricted to a subset of another view or of some combination of views and base tables.

For information about creating views, see the Microsoft SQL Server Transact-SQL Reference.

As an example, say you want to prevent some users from accessing the columns in the titles table that have to do with money and sales, while allowing all users to see the other columns. You could:

  1. Create a view – named bookview – of the titles table that omits the price, advance, royalty, and ytd_sales columns.
  2. Grant all object permissions on bookview to the public group.
  3. Grant all object permissions on titles to the sales group.

To set up equivalent permission conditions without using a view, you could:

  1. Grant all object permissions on titles to public.
  2. Revoke select and update permissions on titles from the public group for the price, advance, royalty, and ytd_sales columns
  3. Grant select and update permissions on titles to the sales group for the price, advance, royalty, and ytd_sales columns.

One possible problem with the second scheme is that users not in the sales group who enter the statement "SELECT * FROM titles" might be surprised to see a "permission denied" message. SQL Server expands the asterisk into a list of all the columns in the titles table and, since permission on some of these columns has been revoked from nonsales users, refuses access to them. The error message lists the columns for which the user does not have access.

To see all the columns for which they do have permission, the nonsales users would have to name the columns specifically. For this reason, creating a view and granting the appropriate permissions on it is a better solution.

In addition to protecting data based on a selection of rows and/or columns, views can be used for context-sensitive permission. For example, you can create a view that gives a data entry clerk permission to access only those rows that he or she has added or updated. You could:

  1. Add a user_-name column to a table in which the login ID of the user entering each row will be automatically recorded with a default.
  2. Define a view that includes all the rows of the table where user_name is the current user, which can be checked with the SUSER_NAME() function. For example:
    where user_name = SUSER_NAME()

    The rows retrievable through the view now depend on the identity of the person who executes the SELECT statement against the view.

For information on managing and using tables, view, columns, and defaults and on using the user_id system function, see the Microsoft SQL Server Transact-SQL Reference. For information on managing permissions, see Chapter 9, Managing Security.


Stored Procedures and Permissions

A user with permission to execute a stored procedure can do so even if he or she does not have permissions on tables or views referenced by the stored procedure. For example, a user might be given permission to execute a stored procedure that updates a row-and-column subset of a specified table even though that user does not have any other permissions for that table.

If a stored procedure updates system tables, updates to the system tables must be allowed when the stored procedure is created. Then the stored procedure can run successfully later even if the system is reconfigured not to allow updates to the system tables.

Note that EXEC ('string') permissions are checked at execution time, even if the execution statement is part of a stored procedure.

For information on managing and using stored procedures, see the Microsoft SQL Server Transact-SQL Reference. For information on managing permissions, see Chapter 9, Managing Security.


Ownership Chains

Views can depend on other views and/or tables. Procedures can depend on other procedures, views, and/or tables. These dependencies can be thought of as an ownership chain.

Typically, the owner of a view also owns its underlying objects (other views and tables), and the owner of a stored procedure often owns all the procedures, tables, and views that the procedure references. Also, a view and its underlying objects are usually all in the same database, as are a stored procedure and all the objects it references.

For efficiency, when a user with permission to access a view does so, SQL Server does not check permissions on any of the view's underlying objects if these objects and the view are all owned by the same user, and if the view and all its underlying objects are in the same database.

Similarly, if the same user owns a stored procedure and all the views or tables it references, and if the procedure and the objects it references are all in the same database, SQL Server checks only the permissions on the procedure.

However, if the ownership chain of a procedure or view is broken – that is, if not all the objects in the chain are owned by the same user – SQL Server checks permissions on each object in the chain whose next lower link is owned by a different user. In this way, SQL Server allows the owner of the original data to retain control over who is authorized to access it.

Ordinarily, a user who creates a view only has to grant permissions on that view. For example, say Mary has created a view called auview1 on the authors table, which she also owns. If Mary grants Sue permission to use auview1, SQL Server will let Sue access it without checking permissions on authors.

However, a user who creates a view or stored procedure that depends on an object owned by another user must be aware that any permissions he or she grants depend on the permissions allowed by those other owners.

For example, Joe creates a view called auview2, which depends on Mary's view auview1. Joe grants Sue permission to use auview2. The object owner is given in parentheses after the object name:

SQL Server checks the permissions on auview2 and auview1 and finds that Sue is allowed to use them.

SQL Server performs no authorization checks at the time the view is created but performs authorization checks when the view is used. In fact, if Joe has permission on the CREATE VIEW statement, he can define a view based on the authors table even if he does not have SELECT permission on authors. However, the view would be useless to everyone, including Joe.

Taking this example a step further, suppose that Joe's view, auview2, depends on auview1, which depends on authors. Mary decides that she likes Joe's auview2 and creates auview3 on top of it. As you may recall, both auview1 and authors are owned by Mary. The situation can be depicted like this, with the object owner given in parentheses after the object name:

When Sue tries to access auview3, SQL Server checks permissions on auview3, auview2, and auview1. If Joe has granted Sue access on auview2 and Mary has granted her permission on auview3 and auview1, SQL Server allows the access. SQL Server checks permissions only if the object immediately before it in the chain has a different owner (or if it is the first object in the chain). For example, it checks auview2 because the object before it – auview3 – is owned by a different user. It does not check permission on authors because the object which immediately depends on it, auview1, is owned by the same user.

Procedures follow the same rules. As an example, suppose the situation is this:

To execute P4, Sue must have permission to execute P4, P2, and P1. Permission to execute P3 is not necessary, since P3 and P4 have the same owner.

SQL Server checks Sue's permissions on P4 and all objects it references each time she executes P4. However, SQL Server knows which referenced objects to check because it has determined this the first time Sue executes P4 and has saved this information with the procedure's execution plan. Unless one of the objects referenced by the procedure is dropped or otherwise redefined, SQL Server sticks with its initial decision about which objects to check.

The following illustration shows a situation in which procedures and views owned by two different users depend on each other in a fairly complex way.

If a user tries to execute procedure1, SQL Server checks permissions on procedure1, procedure3, view2, table2, and table3.

In summary, the purpose of this permission hierarchy is to allow every object's owner to fully control access to the object. Owners can control access to views and stored procedures, as well as to tables.


Triggers and Permissions

Triggers are a special kind of stored procedure. (For details, see the Microsoft SQL Server Transact-SQL Reference.) Triggers are never executed directly, but only as a side effect of modifying a table. There is no need to grant or revoke permissions for triggers.

Only the owner of an object can create a trigger on it. However, the ownership chain can be broken if a trigger on a table references objects owned by different users. The permission hierarchy rules that apply to procedures also apply to triggers.

While the objects that a trigger affects are usually owned by the same user who owns the trigger, you can write a trigger that modifies an object owned by another user. In this case, any users modifying your object in a way that initializes the trigger must have permission on the other object as well.

If SQL Server denies permission on a data modification statement because of a trigger that affects an object for which the user does not have permission, the entire data modification statement is canceled.


Security and the System Tables

The following topics provide summary descriptions of effects on system tables when login IDs, users, groups, and aliases are managed. For more information, see the Microsoft SQL Server Transact-SQL Reference.

For information choose one of the following topics.

Login IDs and System Tables

Groups and System Tables

Users and System Tables

Aliases and System Tables


Login IDs and System Tables

When a login ID is added to a server, SQL Server adds a row to master.dbo.syslogins, assigning a unique server user ID for the new user and filling in the login ID, the password, and the user's default language. The passwords in syslogins are encrypted.

The suid column in syslogins uniquely identifies the user on SQL Server. A user's suid remains the same no matter what database he or she is using. The suid "1" is always assigned to the system administrator. Other users' server user IDs are small integers assigned arbitrarily by SQL Server when the login ID is added.


Groups and System Tables

When a group is added to a database, a row is added to the sysusers table in that database.


Users and System Tables

When a user is added to a database, a row is added to the sysusers system table in that database. Once a user has an entry in the sysusers table of a database, the user can use and open that database, and use that database as the default database.


Aliases and System Tables

When a user is assigned a database alias, the user's login ID is mapped to an existing username in the database. This is done by adding a row to the sysalternates system table.

When a user tries to access a database, SQL Server checks for the user's server ID number, or suid, in sysusers. If the user's server ID is not found, SQL Server then checks sysalternates. If the user's suid is found there mapped to another user's suid, the first user is treated as the second user while using the database.


Chapter 9 Managing Security

Managing Security

To manage SQL Server security, you set the server login security mode, authorize Windows NT users to access SQL Server, manage SQL Server login IDs, manage database users, manage object and statement permissions, change database ownership, and use the security management tools provided with SQL Server 6.0. This chapter presents the procedures you will use and also provides quick-reference summaries of the tasks you will perform to administer security under each of the three SQL Server login security modes.

To gain a fuller understanding of SQL Server security strategies and the elements that make up SQL Server security, see Chapter 8, Security Concepts.

For more information, choose one of the following topics:

Administration Overview

Setting the Server Security Options

Managing Access for Windows NT Groups and Users

Managing SQL Server Logins

Managing Database Users

Managing Object Permissions

Managing Statement Permissions

Changing Database Ownership


Administration Overview

As an overview and orientation to SQL Server security administration, three different security summaries are presented here. Each summarizes the tasks you will perform to administer security under each of the three SQL Server login security modes: integrated, standard, and mixed. Each is intended to serve only as a high-level guide to the tasks that will be performed. For more detailed information about setting up each security element, see the other topics in this chapter. For background and conceptual information about SQL Server security, see Chapter 8, Security Concepts.

Also provided in this section is a quick guide to the tools you will use to manage SQL Server security.

For more information, choose one of the following topics:

Setting Up Integrated Security

Setting Up Standard Security

Setting Up Mixed Security

Denying Client-Requested Trusted Connections

Security Tools


Setting Up Integrated Security

In integrated login security mode, SQL Server uses Windows NT authentication mechanisms for all connections. Only trusted (multi-protocol or named pipes) connections are allowed. For more information about the integrated login security mode, see Chapter 8, Security Concepts."

The following procedure summarizes the tasks performed to set up integrated security. Only the system administrator can perform steps 1 and 3. Only a Windows NT administrator, domain administrator, or account operator can accomplish step 2. Steps 4 and 5 can be performed by either the system administrator or the database owner.

To set up integrated security
  1. Set the server's security options.

    Use SQL Enterprise Manager to set the login security mode to Integrated. Also set the other security options: Default Login, Default Domain, Set HostName to Username, Audit Level, and Mappings.

    For information on setting these options, see Setting the Server Security Options.

  2. Create the Windows NT groups and users authorized to access SQL Server over trusted (multi-protocol and named pipes) connections.

    Use Windows NT User Manager. If you have not been granted access to User Manager to administer Windows NT groups and users, have a Windows NT Administrator perform this task for you. For more information, see Managing Access for Windows NT Groups and Users.

  3. Authorize selected Windows NT-based groups and users to access SQL Server.

    Use SQL Security Manager to map Windows NT groups and users to SQL Server login IDs. You will decide whether each user will use a separate SQL Server login ID or will access SQL Server through the default login ID. You will also choose a default database for the users. For more information, see Managing Access for Windows NT Groups and Users.

    Note that the setup program, by default, grants SA access for the local Windows NT Administrators group on the server.

  4. Set object permissions for each database.

    Use SQL Enterprise Manager to grant¾to users or groups¾select, insert, update, or delete permission for tables and views; reference permissions for tables; and execute permission for stored procedures. You can optionally specify column-level permissions for tables and views. For more information, see Managing Object Permissions.

  5. Set statement permissions for each database.

    Use SQL Enterprise Manager to assign permissions that allow users or groups to perform various database tasks, such as creating rules and defaults on a database, creating tables and views on a database, creating stored procedures, and backing up a database. For more information, see Managing Statement Permissions.

The following illustration depicts the tasks performed to set up integrated security.


Setting Up Standard Security

In standard login security mode, SQL Server manages its own login validation process for all connections. For more information about the standard login security mode, see Chapter 8, Security Concepts.

The following procedure summarizes the tasks performed to set up standard security. Only the system administrator can perform steps 1 and 2. Steps 3 through 5 can be performed by either the system administrator or the database owner.

To set up standard security
  1. Set the server's security options.

    Use SQL Enterprise Manager to verify that the login security mode of the server is Standard and to set the Audit Level options.

    Note that Standard is the default login security mode. For more information, see Setting the Server Security Options.

  2. Allow user access to SQL Server.

    Use SQL Enterprise Manager to create a login ID and password, and specify a default language for each user. For more information, Managing SQL Server Logins.

  3. Define database users.

    Use SQL Enterprise Manager to specify the databases that can be accessed by each login ID. For more information, see Managing Database Users.

  4. Set object permissions for each database.

    Use SQL Enterprise Manager to grant¾to users or groups¾select, insert, update, or delete permission for tables and views; reference permissions for tables; and execute permission for stored procedures. You can optionally specify column-level permissions for tables and views. For more information, see Managing Object Permissions.

  5. Set statement permissions for each database.

    Use SQL Enterprise Manager to assign permissions that allow users or groups to perform various database tasks, such as creating rules and defaults on a database, creating tables and views on a database, creating stored procedures, and backing up a database. For more information, see Managing Statement Permissions.

The following illustration depicts the tasks performed to set up standard security.


Setting Up Mixed Security

In mixed login security mode, SQL Server allows both trusted connections (as used by Integrated login security mode) and nontrusted connections (as used by Standard login security mode). For more information about mixed login security mode, see Chapter 8, Security Concepts.

The following procedure summarizes the tasks performed to set up mixed security. Only the system administrator can perform steps 1, 3, and 4. Only a Windows NT administrator, domain administrator, or account operator can accomplish step 2. Steps 5 through 7 can be performed by either the system administrator or the database owner.

To set up mixed security
  1. Set the server's security options.

    Use SQL Enterprise Manager to set the login security mode to Mixed. Also set the other security options: Default Login, Default Domain, Set HostName to Username, Audit Level, and Mappings.

    For information on setting these options, see Setting the Server Security Options.

  2. Create the Windows NT groups and users authorized to access SQL Server over trusted (multi-protocol and named pipes) connections.

    Use Windows NT User Manager. If you have not been granted access to use User Manager to administer Windows NT groups and users, have a Windows NT Administrator perform this task for you. For more information, see Managing Access for Windows NT Groups and Users,

  3. Authorize selected Windows NT-based groups and users to access SQL Server.

    Use SQL Security Manager to map Windows NT groups and users to SQL Server login IDs. You will decide whether each user will use a separate SQL Server login ID or will access SQL Server through the default login ID. You will also choose a default database for the users. For more information, see Managing Access for Windows NT Groups and Users.

    Note that the setup program, by default, grants SA access for the local Windows NT Administrators group on the server.

  4. Allow access to the server for those users who will not be connecting to the server over trusted (multi-protocol or named pipes) connections.

    Use SQL Enterprise Manager to create a login ID and password and specify a default language, for each user. For more information, Managing SQL Server Logins.

  5. Define database users.

    Use SQL Enterprise Manager to specify the databases that can be accessed by each login ID. For more information, see Managing Database Users.

  6. Set object permissions for each database.

    Use SQL Enterprise Manager to grant¾to users or groups¾select, insert, update, or delete permission for tables and views; reference permissions for tables; and execute permission for stored procedures. You can optionally specify column-level permissions for tables and views. For more information, see Managing Object Permissions.

  7. Set statement permissions for each database.

    Use SQL Enterprise Manager to assign permissions that allow users or groups to perform various database tasks, such as creating rules and defaults on a database, creating tables and views on a database, creating stored procedures, and backing up a database. For more information, see Managing Statement Permissions.

The following illustration depicts the tasks performed to set up mixed security.


Denying Client-requested Trusted Connections

Regardless of the server's login security mode (integrated, mixed, or standard), ODBC and DB-Library client applications can be configured to always request a trusted (integrated security) connection from the server. This feature allows SQL Executive to connect to remote servers as long as SQL Executive is running under a properly configured Windows NT user account, (one that has been granted SA access to the SQL Server).

This also allows users who have been granted SA privileges to access the SQL Server when they use a client application that is configured to force trusted connections (for example, ISQL/w). Note that the setup program, by default, automatically grants SQL Server system administrator privileges to members of the server's Administrators local group.

Because the appropriate user privilege levels must exist if the login is to succeed, logging on over client-requested trusted connections can be prevented by performing these steps:

  1. Use the Windows NT User Manager utility to create a local Windows NT user group (for example, SQLAdmins) that contains no users.
  2. Use SQL Security Manager to grant System Administrator privilege to this empty group.
  3. Use SQL Security Manager to revoke System Administrator privilege from the local Administrators group.

Note that this will restrict applications and features that use forced trusted connections (such as SQL Enterprise Manager and replication).


Security Tools

The tools provided and recommended for managing SQL Server security are SQL Security Manager and SQL Enterprise Manager. Each of these tools is started by choosing its icon from the Microsoft SQL Server 6.0 program group. You can also use a Windows NT tool, User Manager, to create Windows NT users and groups.

These are the SQL Server security tasks you will perform with each tool.

To perform this task | Use this tool
Set Server Security Options | SQL Enterprise Manager or SQL Setup
Create Windows NT users and groups | User Manager
Authorize Windows NT groups and users to access SQL Server | SQL Security Manager
Manage SQL Server login IDs | SQL Enterprise Manager
Manage database users | SQL Enterprise Manager
Manage object permissions | SQL Enterprise Manager
Manage statement permissions | SQL Enterprise Manager

Note that this is a summary table and that each tool offers capabilities beyond those listed here. For more detailed information on the capabilities of each tool, see its online Help. For an overview of SQL Enterprise Manager capabilities, see Chapter 2, Introducing the SQL Distributed Management Framework.

If you have been granted appropriate access, you can also use Windows NT User Manager to create the Windows NT groups and users authorized to access SQL Server. User Manager is an administration tool provided as part of the Windows NT operating system software. On computers running the Windows NT Workstation operating system, this tool is named User Manager and can manage security for the local computer. On computers running the Windows NT Server operating system, this tool is named User Manager for Domains and can manage both domain- and computer-level security. Throughout this documentation, we refer to both versions of this tool simply as "User Manager."

Start User Manager by choosing its icon from the Administrative Tools program group. For more information, see the User Manager online Help. If you have not been granted access to use User Manager, have a Windows NT Administrator use this tool for you.

You can also administer SQL Server security by using a number of system stored procedures and extended stored procedures. A summary of these stored procedures follows. For more information on using these stored procedures, see the Microsoft SQL Server Transact-SQL Reference. Note that you are not required to use these stored procedures to manage security; SQL Security Manager and SQL Enterprise Manager are the recommended tools.

Stored procedure | Description
sp_addlogin | Authorizes a new SQL Server user by adding an entry to the syslogins table
sp_addalias | Maps one database user to another.
sp_addgroup | Adds a new group to a database
sp_addremotelogin | Authorizes a new remote SQL Server user by adding an entry to the sysremotelogins table.
sp_adduser | Adds a new user to a database.
sp_changegroup | Changes a user's database group.
sp_defaultdb | Changes a user's default database.
sp_defaultlanguage | Changes a user's default language.
sp_dropalias | Removes an alias login ID.
sp_dropgroup | Removes a group from a database.
sp_droplogin | Removes a SQL Server login ID.
sp_dropremotelogin | Removes a remote user login ID.
sp_dropuser | Removes a user from the current database.
sp_helpgroup | Reports information about one or all groups.
sp_helpremotelogin | Reports information about one or all remote server logins.
sp_helpprotect | Reports permissions by database object and, optionally, by user for that object.
sp_helpuser | Reports information about the users of a database.
sp_password | Adds or changes a password for a SQL Server login ID.
sp_remoteoption | Displays or changes remote login options.
xp_enumgroups | Provides a list of local Windows NT groups or groups defined in a specified Windows NT domain.
xp_grantlogin | Grants SQL Server access to a Windows NT - based group or user.
xp_loginconfig | Reports the login security configuration of the server.
xp_logininfo | Reports the type of account (group or user), the privilege level of the account, the map name of the account, and the permission path by which the account has access to SQL Server.
xp_revokelogin | Revokes SQL Server access from a Windows NT - based group or user.


Setting the Server Security Options

The security options determine the server's login security mode, login auditing level, and mapping of characters in Windows NT usernames to SQL Server characters. To set or change the security options, use either SQL Setup or SQL Enterprise Manager. The procedures in this section assume you are using SQL Enterprise Manager.

To set server security options
  1. From the Microsoft SQL Server 6.0 program group, start SQL Enterprise Manager.
  2. From the Server Manager window, open a server group and select the server to be administered.
  3. From the Server menu, choose Configurations.
  4. From the Server Configuration dialog box, choose the Security Options tab.

    The Security Options window displays the current setting of the options.

  5. Review and change the options as necessary.

    An explanation of each option is provided following this procedure.

  6. When you finish configuring the security options, choose the OK button.

SQL Server 6.0 offers you the choice of three login security modes. The login security mode you choose significantly affects how the server handles security. The information that follows only summarizes each login security mode (standard, integrated, or mixed). For a comprehensive discussion of the login security modes, see Chapter 8, Security Concepts.

Standard
Standard mode is the default. In Standard mode, SQL Server manages its own login validation process for all connections (except client applications that explicitly request integrated security over the trusted connections).

Note The server can be set up to deny client-requested trusted connections, but this will restrict applications and features that use forced trusted connections (such as SQL Enterprise Manager, and replication). For more information, see Denying Client-Requested Trusted Connections, earlier in this chapter.

Windows NT Integrated
Integrated mode uses Windows NT - based authentication mechanisms for all connections. Only trusted connections are allowed into SQL Server. The login name and SQL Server password submitted in the login request from a DB-Library or Open Database Connectivity (ODBC) client application are always ignored by SQL Server. Network users who were assigned user-level privileges to SQL Server log in using their network username or the default login ID (if the network username is not found in syslogins). Network usernames that are assigned system administrator - level privilege log in as sa.

With this option, only multi-protocol and named pipe clients are supported. If you have installed additional Net-Libraries, this option is not available. In addition, if you are using this option, you cannot install additional server Net-Libraries.

Mixed
Mixed mode allows both trusted and nontrusted connections¾it is a combination of integrated and standard modes. For trusted (multi-protocol or named pipes) connections, SQL Server examines the requested login name as specified by the client DB-Library or ODBC application. If this login name matches the user's network username, or if the login name is null or spaces, SQL Server first tries the Windows NT integrated login rules as described above. If this fails, SQL Server uses the standard rules. If the requested login name is any other value, the user must supply the correct SQL Server password, and SQL Server handles the login using the standard rules described above. All login requests from nontrusted connections are handled using the standard rules.

Mixed mode offers users the convenience of login security integration without forcing all clients and applications to use this mechanism. For example, existing applications that embed a hard-coded login name and password for all users continue to operate as before. Non-PC clients (such as Apple® Macintosh® - and UNIX-based workstations) can also access a SQL Server running in mixed mode. Users accessing SQL Server over trusted connections can avoid a separate SQL Server password validation by entering their network username or blanks in their login request.

In all login security modes, server-to-server communications (remote stored procedures) are handled using the standard SQL Server mechanisms.

SQL Server also lets you specify the following parameters:

Default Login
The SQL Server login name used by an authorized user on trusted connections when the user's network username does not appear in syslogins. If this box is left blank, users without an entry for their network usernames in syslogins will be denied access to the server, even if they have been given user privileges as described below.

Note that the SA must add a login ID of the name specified as the default login. Entering a name in the Default Login box does not automatically create the login ID.

This parameter is not used in standard mode, except for client applications that explicitly request a trusted connection.

Default Domain
The Windows NT domain name that is the default for matching network usernames to SQL Server login names. Because the same network username can be defined in two different domains for two different users and both can be authorized to access SQL Server, SQL Server must distinguish between the two names in the login process for a trusted connection. For network usernames defined in domains other than the specified default, SQL Server adds the domain name and a map character such as an underscore ( _ ) to the network username before attempting the lookup in syslogins.

For example, suppose the domain MARKETING is defined as the SQL Server default, and network username john is used by two different users ¾ one in the MARKETING domain and the other in the ENGINEERING domain. If John in Marketing is using a trusted connection, he accesses SQL Server using a login name of john (assuming such an entry exists in syslogins). John in Engineering accesses the same SQL Server using a login name of ENGINEERING_ john. If there is one domain to which the majority of your users belong, set the Default Domain to that domain name. If your server computer does not participate in a domain, set the Default Domain to the server computer name.

This parameter is not used in standard mode, except for client applications that explicitly request a trusted connection.

Set Host Name to User Name
Determines whether the host name from the client login record is replaced with the Windows NT network username for users under trusted connections. If this is selected, for example, the network username will appear in the output of the sp_who system procedure. The default for this option is cleared (deselected).
Audit Level
Attempted user accesses can be recorded along with other SQL Server log information. Auditing can be enabled for all three security modes and will record information on both trusted and nontrusted connections.

You can choose no auditing (the default), or you can record successful login attempts, failed login attempts, or both successful and failed attempts. Log records for these events appear in the Windows NT event log or the SQL Server error log, or in both, depending on how you configure logging for your SQL Server. For information on setting up SQL Server logging, see Chapter 3, Configuring Servers.

Mappings
Windows NT usernames include certain characters that are not valid in SQL Server login IDs (for example, hyphens, spaces, and periods). When you're using any of the integrated security options or client-requested trusted connections, mappings let you indicate how to map these characters in SQL Server. For example, the Windows NT username t-johns, which would be invalid to SQL Server, can be mapped to t_johns by mapping the SQL Server underscore (_) to the Windows NT hyphen (-). Possible values for map characters are domain separator (\), space ( ), hyphen (-), period (.), single quotation mark ('), exclamation point (!), "at" sign (@), percent sign (%), caret (^), ampersand (&), and "not used" (which indicates no mapping).

SQL Server lets you map special characters to an underscore (_), a pound sign (#), or a dollar sign ($), as follows:

Map _
Determines which Windows NT character will be mapped to the valid SQL Server character underscore (_). The default is domain separator (\).
Map #
Determines which Windows NT character will be mapped to the valid SQL Server character pound sign (#). The default is hyphen (-).
Map $
Determines which Windows NT character will be mapped to the valid SQL Server character dollar sign ($). The default is space ( ).


Managing Access for Windows NT Groups and Users

When a server is set for integrated or mixed security, after you set the server security options, you create the Windows NT groups and users that will be authorized to access that SQL Server and then provide those Windows NT groups and users with appropriate access to that SQL Server.

You manage Windows NT groups and users by using Windows NT User Manager. You provide them access to SQL Server by using SQL Security Manager. For more information, choose one of the following topics:

Creating Windows NT Groups and Users

Providing Access to SQL Server for Windows NT Users and Groups


Creating Windows NT Groups and Users

To take advantage of integrated or mixed security for SQL Server, you must first create the Windows NT groups and users that will be authorized to access SQL Server. User Manager¾provided as part of the Windows NT operating system software¾is the tool you use to accomplish this.

Start User Manager by choosing its icon from the Administrative Tools program group. For information about using this tool, see the User Manager online Help. If you have not been granted access to User Manager, have a Windows NT Administrator use this tool for you.

When the Windows NT operating system is installed, an Administrators group is created. When SQL Server is installed, all users in this Administrators group are given system administrator privilege (SA) on the SQL Server.

The recommended way to implement SQL Server security integration is to create two locally defined groups to access SQL Server. You could, for example, use User Manager to create a local group named SQLUsers that has user-level privileges, and another named SQLAdmins that has system administrator privileges. Then you can add individual users to these groups.

Members of local groups can be locally defined users, users defined in the domain, or global groups defined in the domain. If you are using domain security, you will most likely want to add usernames that are defined in the domain, so that a separate set of Windows NT accounts do not need to be maintained on the Windows NT-based computer running SQL Server.

The following guidelines will help you smoothly set up accounts with the Windows NT User Manager that can then be mapped to SQL Server login IDs:

  • When you create names for Windows NT users and groups, it is advisable to use only valid SQL Server identifiers. Do not use spaces, periods, or other characters that Windows NT allows but SQL Server does not, and limit group names to 30 characters or less. In addition, do not use the underscore (_), dollar sign ($), or pound sign (#) in the user or group names because these characters are used by SQL Server as special mapping characters.
  • Avoid placing Windows NT users in more than one Windows NT group that can access SQL Server, because SQL Server does not allow overlapping group membership within databases. Keeping your Windows NT users limited to membership in only one group that has SQL Server access privilege will allow you to use SQL Security Manager to keep database groups consistent with Windows NT groups.
  • Create one administrator-level group and one or more user-level groups for the accounts that will access SQL Server. The groups should correspond to the security levels that you want to grant in your SQL Server databases (for example, OrderEntry and OrderEntryManagers). If you want your Windows NT administrators to be the same as your SQL Server system administrators, you can leave the default permissions created by the setup program. Otherwise, you can create a separate group for SQL Server administrators and grant that group administrative privilege on both Windows NT and SQL Server. After you create a separate administrators group for SQL Server system administrators, you can revoke privilege from the Windows NT Administrators group.


Providing Access to SQL Server for Windows NT Users and Groups

SQL Security Manager provides a graphical way to map Windows NT users and groups to SQL Server login IDs for integrated or mixed security. (If you are using standard security, use SQL Enterprise Manager to set up login IDs.)

SQL Security Manager also allows you to grant and revoke SQL Server privileges to Windows NT groups, including setting up SQL Server login IDs and passwords for the group and adding users to SQL Server databases. In addition, you can use SQL Security Manager to search for the SQL Server access permissions for a given Windows NT account.

For more information, choose one of the following topics:

Logging In to a SQL Server

Granting Privileges

Viewing Users with User Privilege

Viewing Users with System Administrator Privilege

Reviewing Account Details

Revoking Privileges

Searching for Account Information


Logging In to a SQL Server

Before you can manage integrated security accounts, you must start SQL Security Manager and log in to a SQL Server.

To start SQL Security Manager and log into a SQL Server
  1. From the Microsoft SQL Server 6.0 program group, choose the SQL Security Manager icon.

    SQL Security Manager starts, and the Connect Server dialog box appears.

  2. In the Server box, type or select the name of the server for which you will manage integrated security.

    The Server box contains a list of the last five servers logged in to. To see a list of servers on the network, choose the List Servers button.

  3. In the Login ID box, type your login ID. Then, in the Password box, type your password.

    For integrated security connections, you do not need to supply a login ID or password.

  4. Choose the Connect button.

    The SQL Security Manager window opens, and SQL Security Manager connects to the server.


Granting Privileges

When you grant privileges to a Windows NT group, you are granting access to SQL Server to each member of that group. You can grant either user privilege or system administrator privilege.

To grant user privilege
  1. Choose the User Privilege button. Or from the View menu, choose User Privilege.

  2. From the Security menu, choose Grant New.

    The Grant User Privilege dialog box appears.

  3. In the Grant privilege box, select the group that will have access to SQL Server.

    To see all local groups on the Windows NT-based computer, choose Local Groups. To see all groups on the default domain, select Groups on Default Domain.

    The Add login IDs for individual group members box is selected. This specifies that you want to create SQL Server login IDs for each user in the group.

  4. If you do not want each user in the group to have a separate SQL Server login ID, clear the Add login IDs for group members check box. If you do not assign each user an individual login ID, the only way the user can access SQL Server is through the default login ID (usually guest). If you want to set up security like this, be sure you have specified a default login ID when you set security options with SQL Enterprise Manager.
  5. To add users in the group to a database and make that database their default database when they log in to SQL Server, select the Add Users to Database box, and then select the database from the list.

    SQL Security Manager will try to create a SQL Server group in the database that matches the Windows NT group name and will include all of the new database users in that group.

    It is recommended that you assign users to a default database other than master, to discourage users from creating database objects in master. If you do not assign users to a default database, master becomes their default database.

  6. Choose the Grant button.
To grant system administrator privilege
  1. Choose the SA Privilege button. Or from the View menu, choose SA Privilege.

  2. From the Security menu, choose Grant New.

    The Grant System Administrator Privilege dialog box appears.

  3. In the Grant Privilege box, select the group that will have access to SQL Server.

    To see all local groups on the Windows NT-based computer, choose Local Groups.

    To see all groups on the default domain, select Groups in Default Domain.

    Note that when you grant system administrator privilege, the Add Login IDs and Add Users to Database boxes are dimmed. This is because when you grant to a group system administrator privilege to SQL Server, the users in the group are automatically mapped to the SA login ID, and master is the default database.

  4. Choose the Grant button.

Note If you grant permission to the Domain Users group on the default domain, you will see as domain members all the Windows NT computer accounts (ending in a $), in addition to all the user accounts defined on the domain.

Since computer accounts do not need SQL Server login permissions, it is a better idea to create a separate group on the domain containing only the valid user accounts, and then grant permission to this group.


Viewing Users with User Privilege

When SQL Security Manager is open, a tree displaying the groups added to SQL Server is displayed. You can view a list of users having user privilege.

To view users having user privilege
  1. Choose the User Privilege button. Or from the View menu, choose User Privilege.

    The groups with user privilege are listed.

  2. To view a list of the users in a group, double-click the group name.

  3. To collapse a list of usernames, double-click the group name again.


Viewing Users with System Administrator Privilege

When SQL Security Manager is open, a tree displaying the groups added to SQL Server is displayed. You can view groups having system administrator privilege.

To view users having system administrator privilege
  1. Choose the SA Privilege button. Or from the View menu, choose SA Privilege.

    The groups with system administrator privilege are listed.

  2. To view a list of the individual members of a group, double-click the group name.

  3. To collapse a list of usernames, double-click the group name again.

All users with system administrator privilege access SQL Server by using the SA login ID, so there are no account details for these accounts.


Reviewing Account Details

You can get details about a group or about a user within the group. For an individual user, you can add a login ID that matches the user's mapped username, or you can drop a matching login ID if one already exists. You can also add or drop a user from a database or set the default database. For a group account, the same actions apply to all members of the group. For example, you can update login IDs for a group, which will add login IDs that match the mapped usernames of the group's members, if the login ID does not already exist.

To review details about a user account
  1. Choose the User Privilege button. Or from the View menu, choose User Privilege.

  2. Double-click the group name that contains the user you want to get information about.

    The users within the group are displayed.

  3. Select the user, and then from the Security menu, choose Account Detail. Or double-click the username.

    The Account Detail dialog box appears. The Windows NT account name information for the user is displayed, as is the user's mapped username.

  4. Change any account information, as necessary.
  5. Choose the Close button.
To review details about a group
  1. Choose the User Privilege button. Or from the View menu, choose User Privilege.

    The groups with user privilege are displayed.

  2. Select a group, and then from the Security menu, choose Account Detail. Or press the ctrl key and double-click the group name.

    The Account Detail dialog box appears. The Windows NT account information for the group is displayed, as well as the group's mapped SQL Server name.

  4. Change account information as necessary.
  5. Choose the Close button.


Revoking Privileges

When you revoke privileges, all users in the group that you are revoking permission from are dropped from SQL Server databases, and their login IDs are removed from SQL Server.

To revoke privileges
  1. Choose the User Privilege or SP Privilege button. Or from the View menu, choose User Privilege or SP Privilege.

    The groups with that privilege are displayed.

  2. Click the name of the group to revoke privilege from.
  3. From the Security menu, choose Revoke.

    A confirmation message appears.

  4. Choose Yes.

If you want to deny SQL Server access to a member of a group that has SQL Server privilege, use the Windows NT User Manager to remove the user from the group. The SQL Server login ID and any database usernames associated with that Windows NT account will remain in SQL Server but will be inaccessible to that user. You can periodically clean up these login IDs and usernames by using the Find Orphan SQL Login IDs option in the Search for Account Information dialog box.


Searching for Account Information

You can display information about individual user accounts. The information includes the permission paths for a given user account.

A permission path indicates how a user account is authorized to access SQL Server (for example, by membership in a local group that has been granted user privilege). A given user account might belong to multiple groups that have been granted user or SA privilege. When such a user connects, SQL Server will let the account access via a permission path that gives it the highest privilege access to the server. If you wish to remove a given Windows NT user account from all groups that have access to SQL Server, you can use the option to list all permission paths for the user. Then run the User Manager application to remove the user account from all those groups.

You can also view SQL Server login IDs of users who exist in SQL Server but no longer exist in a Windows NT group that has access permission.

To search for account information for a user
  1. From the Security menu, choose Search.

    The Search For Account Information dialog box appears.

  2. In the Account box, type the name of a user.
  3. Select the appropriate search:
    • To verify the highest permission path for the account, select the Verify Permissions for Account box.
    • To find all permission paths the account uses to access SQL Server, select the Find All Permissions for Account box.
  4. Choose the Search button.

    The results are displayed, including the full name of the account, the highest level permission the user has in SQL Server, and the permission paths the user is accessing SQL Server through.

  6. Choose the Cancel button.
To search for SQL Server Login IDs that do not have corresponding Windows NT accounts
  1. From the Security menu, choose Search.

    The Search For Account Information dialog box appears.

  2. Select the Find Orphan SQL Login IDs box.
  3. Choose the Search button.

    The results of the search are displayed.

  4. To drop SQL Server login IDs (other than sa, probe, repl_publisher, or repl_subscriber) that do not match Windows NT users with valid permissions, choose the Drop button.
  5. Choose the Cancel button.


Managing SQL Server Logins

To access a SQL Server, a user must use a valid login identification (login ID). A login ID is a unique name that identifies a user on a SQL Server. When assigning a login ID, you can also assign a password and a default language, select databases to permit access to, and assign a default database. Only a system administrator (SA) can manage login IDs.

This section presents the procedures you will use to manage SQL Server login IDs. For an understanding of how SQL Server login IDs function within SQL Server security¾and for descriptions of the login IDs installed with SQL Server¾see Chapter 8, Security Concepts.

If the server is set up for integrated security, you may not need to create login IDs. If you have used Microsoft SQL Security Manager to map Windows NT users and groups to SQL Server users, you may not need to create more login IDs. For information about using SQL Security Manager, see Managing Access for Windows NT Groups and Users.

A login ID simply allows a user to log in to a SQL Server. To allow a user access to a database, you must add a username to the database. For more information, see Managing Database Users.

For information about managing login IDs, choose one of the following topics:

Accessing the Logins Dialog Box

Adding a Login ID to a Server

Modifying a Login ID

Dropping a Login ID from a Server

Summary of Login ID Information


Accessing the Logins Dialog Box

Login IDs are administered from the Manage Logins dialog box of SQL Enterprise Manager. This dialog can be accessed in several ways.

To access the Manage Logins dialog box
  1. From the Microsoft SQL Server 6.0 program group, double-click the SQL Enterprise Manager icon.
  2. From the Server Manager window, select a server.
  3. Open the Manage Logins window by using one of these techniques:
    • From the toolbar, choose the Manage Logins button.

    • From the Manage menu, choose Logins.
    • In the Server Manager window, under the selected server, double-click the Logins folder.
    • In the Server Manager window, click the right mouse button on the Logins folder, and then from the drop-down menu that appears, choose New Login.
    • In the Server Manager window, double-click on a login name located under the Logins folder.
    • In the Server Manager window, click the right mouse button on a login name located under the Logins folder, and then from the drop-down menu that appears, choose Edit.

    After you perform one of these techniques, the Manage Logins window appears. If you performed one of the last two techniques listed, the dialog box is filled with the information for the selected account.

For simplicity, each of the procedures that follow will present only one way to open the Manage Logins dialog box. However, you can substitute the other techniques where appropriate.


Adding a Login ID to a Server

Before a user can gain access to a SQL Server, a login ID for that user must be added to the server. When you add a login ID, you can also assign the user a password, a username, a default language, and a default database. Only the SA can add a login ID.

If the user is not given a separate username in the default database, the username will be the same as the user's login ID. If the user is not assigned to a default database, the master database is used as the default. To discourage users from creating database objects in the master database, it is a good idea to assign default databases other than master to most users.

Use the following procedure to add a login ID. You can also use the following procedure to add a visitor login ID.

To add a SQL Server login ID
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Manage Logins button.

    The Manage Logins dialog box appears.

  2. In the Login Name box, type the login name for the new user.

    If the Login Name box is not empty, select <New Login> from the list, and then type the login name for the new user.

  3. In the Password box, type a password for the user.
  4. From the list in the Default Language box, select a default language for the user.
  5. Under Database Access, select the Permit box for each database the user with this login ID will be allowed to access. For each database set to permit access, complete the remaining boxes as appropriate.
    • Set the user's default database by selecting the Default box.
    • The User box displays the name this login ID will use to access the database. By default, the user's login ID is entered. You can change the name by typing a different one in the box.
    • The Alias box lets you select an alias in the database for the login. To set an alias, select the box, and then select an alias name from the list.
    • The Group box lets you select a database group for that login. To choose a group, select the box, and then select a group name from the list.
  6. Choose Add.

    The Confirm Password dialog box appears.

  7. Reenter the password to confirm it, and then choose OK.

    The login ID is added.

  8. Optionally, to add another login, choose <New Login> from the Login Name box, and repeat steps 2 through 8.
  9. To exit, choose Close.

    For more information about the settings you can make while administering login IDs, see Summary of Login ID Information.


Modifying a Login ID

The SA can change the password, default language, and database access (including default database) for a login ID.

To modify a login ID
  1. From the Server Manager window, select a server, and then open its Logins folder.
  2. Double-click a login ID.

    The Manage Logins dialog box appears, displaying information about that login ID.

  3. Change the appropriate information.
  4. Choose Modify.

For more information about the settings you can modify for a login ID, see Summary of Login ID Information.


Dropping a Login ID from a Server

If you no longer want a user to have access to a particular SQL Server, you must drop the user's login ID from that server. Only the SA can drop a login ID.

You cannot drop the login ID of a user who is the owner of any database or a database object in the current database. You must transfer the ownership of the any database owned by the login ID, and drop owned objects from the current database before dropping the owner's login ID.

To drop a login ID
  1. From the Server Manager window, select a server, and then open its Logins folder.

    The logins for that server are listed.

  2. Use the right mouse button to click on the login ID name, and then from the drop-down menu that appears, choose Delete. Or press the Del key.

    The login ID is removed.


Summary of Login ID Information

Following are brief descriptions of the information you manage while administering login IDs. This is summary information presented for quick reference purposes only. For more information about login IDs and how they act within the overall scheme of SQL Server security, see Chapter 8, Security Concepts.

Login Name
Specifies the SQL Server login identifier (login ID). A login ID allows user access to a SQL Server. It can have as many as 30 characters and must be unique for that server. The characters can be alphanumeric, but the first character must be a letter or the symbols # or _ (for example, CHRIS or TELLER8).
Password
Provides for secure use of the login ID. A password can have as many as 30 characters.

Because a password is confidential, it does not appear on the screen when you type it. The default password is NULL. If you leave the password box empty, the login ID will not have a password associated with it. Passwords that include characters other than A through Z or a through z or that begin with 0 through 9 must be enclosed in quotation marks.

When using standard or mixed security, you should not use a NULL password. With integrated security, there is no need to maintain passwords. However, if you change to standard or mixed security, anyone can log in if there are no passwords, so it is a good idea to set random passwords.

Default Language
Specifies the default language that a user uses for communicating with a server. Once the default language is set, the user is automatically logged in as using that language. Only the languages available to the server are available to the user. If when creating a login ID you do not specify a language, the server's default language is assigned.
Database Access
Provides settings that allow you to determine which databases the login ID can access.
Permit
Allows access to the database by the login ID user.
Default
Is the database that the user is connected to immediately after logging in to SQL Server. After the default database is changed, the user is connected to the new default database at the next login. However, before a user can access objects in the new default database, the user must have user permissions for the database.

If a default database is not assigned, the default database is master. It is recommended that you assign users to a default database other than master, to discourage users from creating database objects in the master database.

User
Specifies a username the login ID will use to access the database. By default, the user's login ID is entered. You can change the name. When you add the login ID, the specified database usernames are also added to the database.

A database username can have as many as 30 characters. The characters can be alphanumeric, but the first character must be a letter or the symbols # or _. If you don't type a username, the username is the same as the user's login ID.

Alias
Allows you to treat more than one person as the same user inside a database, giving all of them the same privileges. You can assign a login ID to an alias (instead of giving it a unique username). You cannot create database aliases while adding login IDs. You can only select from those aliases that already exist.

Aliases are often used so that several users can assume the role of database owner. Aliases can also be used to set up a collective user identity, within which the identities of individual users can be traced.

Group
Groups provide a convenient way to grant or revoke permissions to more than one user with a single statement. You can assign a database group to a login ID. While adding login IDs, you cannot create database groups; you can only select from those groups that already exist.

When a user is added to a database, if no group is specified, the user belongs to the public group.

For more information about database users, database aliases, and database groups, see Managing Database Users.


Managing Database Users

Before a user can use a database, you must assign a username in that database to the user's login ID. The username can be the user's login ID, or it can be someone else's username in the database (called an alias). If you assign a user to a database with an alias, the user cannot access the database with any other username.

When you add a user to the database, you can also specify which group the user will belong to. By default, new users belong to the built-in public group. Users can be added to one other group.

Users who have been given access to a database still need permission to do things inside it. For information about setting up permissions, see Managing Object Permissions and Managing Statement Permissions.

For information about managing database users, choose one of the following topics:

Adding a Group to a Database

Adding a User to a Database

Managing Group Membership

Removing a User from a Database

Removing a Group from a Database


Adding a Group to a Database

A database group is a collection of database users. Using groups simplifies management of a large number of database users. Groups provide a convenient way to grant and revoke permissions to more than one user at the same time. The default is to add new users to the built-in public group. Each user can be a member of one group, in addition to public.

Groups can be created at any time. Before adding users to a database, create groups.

If you are using integrated security and have created groups with Windows NT, those groups are not automatically tied to database groups. If you want all members of a Windows NT group to be assigned to a database group, you must first assign explicit login IDs to all users of the group, then add all those login IDs as users in the database, and then assign those users to the database group you create. SQL Security Manager can automatically create login IDs and a SQL Server group for a selected Windows NT group. For more information, see Managing Access for Windows NT Groups and Users.

To add a group to a database
  1. Using SQL Enterprise Manager, from the Server Manager window, select a server and open the Databases folder for that server.

    The databases of that server are listed.

  2. Select a database, and then from the Manage menu, choose Groups.

    Or open the tree for that database (choose the "" button), use the right mouse button to click on the Groups/Users folder, and from the drop-down menu that appears, choose New Group.

    The Manage Groups dialog box for the selected database appears.

  3. In the Group box, type a name for the group.

    If the Group box is not empty, choose <New Group> from the list, and then type the name for the group.

    A group name can have as many as 30 characters and must be unique within the database. The characters can be alphanumeric, but the first character must be a letter or the symbols # or _ (for example, DATAOPS or OPERS8).

  4. Optionally, from the Users list, select a user to add to the group, and then choose the Add button inside the Database Users frame.

    The username moves to the Users in Group box.

    Repeat for each user you want to add to the group.

  5. Choose the Add button adjacent to the Group box.

    The group is added to the database.

For more information about database groups, see Security Concepts.


Adding a User to a Database

Before a user can use a database, you must set up a username for that user's login ID for that database. The abilities of the user within the database depend on the permissions granted to the username (and to any groups the username is a member of).

It may not be necessary to use the following procedure to add users to the database, because when you add a login ID to SQL Server, you have the option of adding a username for each login ID to each database. (For information, Managing SQL Server Logins.) If you did not add the database user at the time you added the login ID, then use the following procedure to add the user.

You can also use the following procedure to add the guest user to a database, or to add a user for the default login. For information about the guest user and the default login, see Chapter 8, Security Concepts.

To add a user to a database
  1. Using SQL Enterprise Manager, from the Server Manager window select a server and then open the Databases folder for that server.

    The databases of that server are listed.

  2. Select a database, and then from the Manage menu, choose Users.

    Or open the tree for that database (choose the "" button), click with the right mouse button on the Groups/Users folder, and then from the drop-down menu that appears, choose New User.

    The Manage Users dialog box appears.

  3. In the User Name box, type a username. It can be the same as the login ID.

    If the User Name box is not empty, choose <New User> from the list, and then type the username.

    A username can have as many as 30 characters and must be unique within the database. The characters can be alphanumeric, but the first character must be a letter or the symbols # or _ (for example, CHRIS or USER8). If you don't type a username, the username will be the same as the login ID.

  4. From the list in the Login box, select the login ID for which you will provide a database username.
  5. Optionally, to add the user to a group, select a group from the list in the Group box.

    All users automatically belong to the public group. You have the option of adding the user to one other group.

  6. Choose Add.

    The user is added to the database. The Add button changes to the Modify button.

  7. Optionally, to create an alias for the user, select an alias from the Available Logins list, choose Add, and then choose Modify.

For more information about database users, see Security Concepts.


Managing Group Membership

After you have created a group, you can add new users to the group at any time. In each database, each user can be a member of only one group besides public.

You can remove users from any group¾except public¾at any time. You cannot remove any users from the public group.

To manage the user membership of a group
  1. From the Server Manager window, select a server, and then open its Databases folder.

    The databases of that server are listed.

  2. Select a database and open the Groups/Users folder for that database.

    The groups and users of that database are listed.

  3. Double-click a group.

    Or use the right mouse button to click on the group name, and then from the drop-down menu that appears, choose Edit.

    The Manage Groups dialog box appears, displaying information for that group.

  4. To add a user to the group, from the Users list, select the username to be added, and then choose Add.

    The username moves to the Users in Group list.

  5. To remove a user from the group, from the Users In Group list, select the username to be removed, and then choose Remove.

    The username moves to the Users list.

  6. Choose Modify.


Removing a User from a Database

Dropping a user removes that user from the database. You cannot drop a user who owns objects. Since there is no command to transfer ownership of objects, you must drop the objects before you can drop the username. To deny access to a user who owns objects, you can change his or her SQL Server password.

To remove a user from a database
  1. From the Server Manager window, select a server, and then open the Databases folder for that server.

    The databases of that server are listed.

  2. Select a database, and open the Groups/Users folder for that database.

    The groups and users of that database are listed.

  3. Select a username, and then press the Delete key.

    Or use the right mouse button to click on the username, and then from the drop-down menu that appears, choose Delete.

    The username is removed from list, and the user can no longer access the database.


Removing a Group from a Database

When you drop a group, all users in that group are automatically removed from the group. Users who were members of the dropped group are still users in the database, and members of the public group.

To remove a group from a database
  1. From the Server Manager window, select a server, and then open the Databases folder for that server.

    The databases of that server are listed.

  2. Select a database, and open the Groups/Users folder for that database.

    The groups and users of that database are listed.

  3. Select a group, and then press the Delete key.

    Or use the right mouse button to click on the group name, and then from the drop-down menu that appears, choose Delete.

    The group is removed from the list.


Managing Object Permissions

Object permissions regulate the use of certain statements on certain database objects. They are granted and revoked by the owner of the object. Object permissions apply to the following statements and objects.

Statement | Object
SELECT | Table, view, columns
UPDATE | Table, view, columns
INSERT | Table, view
DELETE | Table, view
REFERENCE | Table
EXECUTE | Stored procedure

With SQL Server 6.0, REFERENCE permission provides for ANSI compatibility of referential constraints. It allows references to a given table without having SELECT permissions on that table. This permission is checked at the time the reference is created, as well as at run time. When the reference is checked, the user creating the table must have either SELECT or REFERENCE permission on any referenced tables. (Creating a reference to a table implies that the referenced table has permissions to verify any references back to the table in the CREATE statement.) In the SQL Enterprise Manager interface, REFERENCE permission is labeled "DRI."

SQL Enterprise Manager allows you to administer object permissions by user (the object permissions granted to a user or group) or by object (the users or groups who have permissions for that object). Only a system administrator (SA) or a database owner (DBO) can administer object permissions.

For more information, see Granting and Revoking Object Permissions


Granting and Revoking Object Permissions

For users and groups of each database, you can grant and revoke permissions for tables, views, and stored procedures. If the user or group already has permissions on those objects, any new permissions that you grant will be added to the existing permissions.

You administer object permissions by clearing or selecting checkboxes.

This checkbox indicator | Means
Empty | No change from the inherited permission.
Blue check | The permission is granted.
Red check | The permission is revoked (cancels an inherited grant).
Green check | A pending grant. (The permission is granted when the Set button is chosen.)
Red circle and slash | A pending revoke. (The permission is revoked when the Set button is chosen.)

You can manage object permissions from the perspective of the group or user or from the perspective of the object. Note that any changes you make are only pending until you select the Set button.

To manage object permissions by group or user
  1. From the Server Manager window, select a server, open its Databases folder, and select a database.
  2. From the Object menu, select Permissions.

    The Object Permissions dialog box appears.

  3. Select the By User tab.

  4. From the User/Group list, select a user or group.

    Object permissions are shown for this user or group. If a group is selected, the Group members box lists all users of that group.

  5. To limit the amount of information displayed, select or clear the Object Filters options.
  6. To grant to the selected user or group all permissions for all displayed objects, choose Grant All.

    Or to revoke from the selected user or group all permissions for all displayed objects, choose Revoke All.

  7. To grant or revoke specific permissions for specific objects, click on the appropriate check boxes in the object list.
  8. Optionally, to set column-level SELECT and UPDATE permissions, select an object name from the object list, and also select the Column Level Permissions option. Then in the column list, grant or revoke specific permissions for specific columns by clicking on the appropriate check boxes.

    Column-level permissions apply only to tables and views (not stored procedures).

  9. Choose Set.

    The pending permissions are granted and/or revoked.

    Note Any changes you make in this dialog box are only pending until you select the Set button.

To manage object permissions by object
  1. From the Server Manager window, select a server, open its Databases folder, and select a database.
  2. From the Object menu, select Permissions.

    The Object Permissions dialog box appears with the By Object tab selected.

  3. From the Object list, select an object.

    This is the object that will have its permissions managed.

  4. To grant all permissions for this object to all users and groups of this database, choose Grant All.

    Or to revoke all permissions for this object from all users and groups of this database, choose Revoke All.

  5. To grant or revoke specific permissions for specific users or groups, click on the appropriate check boxes in the user and group list.
  6. Optionally, to set column-level SELECT and UPDATE permissions, select a user or group name from the object list, and also select the Column Level Permissions option. Then in the column list, grant or revoke specific permissions for specific columns by clicking on the appropriate check boxes.

    Column-level permissions apply only to tables and views (not stored procedures).

  7. Choose Set.

    The pending permissions are granted and/or revoked.

    Note Any changes you make in this dialog box are only pending until you select the Set button.

For more information about object permissions, see Chapter 8, Security Concepts.


Managing Statement Permissions

A system administrator or database owner can assign statement permissions that allow individual users or groups to perform various database tasks, such as:

  • Creating a database
  • Creating rules and defaults on a database
  • Creating tables and views on a database
  • Creating stored procedures
  • Backing up the database

Each database has its own independent permissions system. Being granted permission to use a certain statement in one database has no effect on other databases. Only a system administrator (SA) or a database owner (DBO) can administer statement permissions.

  • For more information, choose one of the following topics.
  • Granting or Revoking Statement Permissions
  • Summary of Statement Permissions


Granting or Revoking Statement Permissions

You administer statement permissions by clearing or selecting check boxes.

This checkbox indicator | Means
Empty | No change from the inherited permission.
Blue check | The permission is granted.
Red check | The permission is revoked (cancels an inherited grant).
Green check | A pending grant. (The permission is granted when the OK button is chosen.)
Red circle and slash | A pending revoke. (The permission is revoked when the OK button is chosen.)

To grant or revoke statement permissions for a user or a group
  1. Open the Edit Database dialog box for the database that will have its statement permissions administered.

    One way to do this is to select the server name from the Server Manager window, open its Databases folder, and double-click on the database.

    The Edit Database dialog box appears.

  2. Choose the Permissions tab.

    The Permissions window appears. Existing permissions are indicated by blue checks.

  3. To assign a permission, select that box.

    When a permission is newly selected, a green check appears in the check box.

    Note If you grant a permission to a group, you do not need to also grant it to a user who is a member of the group.

  4. To remove a permission, click on that check box.

    When a permission is selected for revocation, a red circle and slash appear on top of its check box.

  5. Choose OK.

    The permissions are not actually granted or revoked until you choose the OK button.

For a description of each statement permission, see Summary of Statement Permissions.


Summary of Statement Permissions

Following are brief descriptions of each statement permission. Statement permissions are not object-specific. They can be granted only by a system administrator (SA) or database owner (DBO). For more information about statement permissions, see Chapter 8, Security Concepts.

Create DB
User can create a database. This permission can be granted only by an SA, and only to users of the master database.
Create Table
User can create a table.
Create View
User can create a view.
Create SP
User can create a stored procedure for the database.
Create Default
User can create a default. (A default is a value that SQL Server inserts into a column if the user does not explicitly enter one.)
Create Rule
User can create a rule. (A rule determines what a user can enter in a particular column, or in any column that has a given user-defined datatype.)
Dump DB
User can back up the database.
Dump Trans
User can dump the transaction log.


Changing Database Ownership

You can change the owner of a database. This drops the aliases of users who could act as the old DBO. You might want to change the database owner, for example, when you create a new database yourself but want to assign ownership of the database to another user.

The new owner must not already be known in the database as a user or have an alias. It may be necessary to drop a user from a database or from an alias before changing a database's ownership.

You must be in the database for which the ownership is being changed.

To change the database owner
  • sp_changedbowner login_id [, true]

    where

    login_id
    Is the name of the new owner of the current database. The new owner must not already be known as a user or have an alias in this database.
    true
    Transfers aliases and their permissions to the new database owner.

For example, to make maryd the owner of the current database and drop aliases of users who could act as the old DBO, type:

sp_changedbowner maryd

You cannot change the ownership of the master database.

For more information on using sp_changedbowner, see the Microsoft SQL Server Transact-SQL Reference.


Chapter 10 Remote Servers and Users

Remote Servers and Users

A remote server is a SQL Server on the network that a user can access through his or her local server, allowing the user to execute stored procedures on the remote server. This chapter describes remote servers and their remote users, shows you how to set up and configure a remote server, and details how to add remote login IDs for those users who need to access the remote server.

When setting up remote servers and users, you will also need to grant object permissions for the stored procedures. To learn how to grant object permissions, see Chapter 9, Managing Security

For more information on remote servers and users, select one of these topics:

About Remote Servers and Users

Managing Remote Servers

Managing Remote Users


About Remote Servers and Users

A remote server is a SQL Server on the network that users can access by using their local server. When a server is set up as a remote server, users can use the system procedures and the stored procedures on it without explicitly logging in to it.

A remote user is a user who accesses the remote server. You will add a remote login ID for each remote user.

For example, suppose all the people in your department use the ACCOUNTS server as their local server, but they sometimes need to use stored procedures on the EXPENSES server. Each time they need information from EXPENSES, they must log in to it. However, if you set up EXPENSES as a remote server for ACCOUNTS and add remote login IDs for the users from your department, then they can access the stored procedures without having to log into EXPENSES.

The following figure illustrates how users can access a remote server through their local server.

Note The type of SQL Server security chosen (integrated, mixed, or standard) does not affect the management of remote users. The security described in this chapter is used when executing remote stored procedures are executed across server-to-server connections.


Managing Remote Servers

Remote servers are set up in pairs. To set up a pair of remote servers, you will:

  • Configure both servers to recognize each other as remote servers.
  • Verify that certain configuration options are properly set for both servers, so that SQL Server allows remote users to execute procedure calls.

Note If you have set up servers in your enterprise for SQL Server 6.0 replication, then each pair of publication and subscription servers has already been set up as remote servers for each other. For replication server pairs (displayed as servers linked together in the Replication Topology window of SQL Enterprise Manager), it is unnecessary to perform the procedures for adding a remote server that are described in this section.

The topics that follow tell you how to perform those tasks. You will also learn how to temporarily replace a server, display information about remote servers, and drop remote servers. For more information choose one of the following topics:

Adding Remote Servers

Setting Configuration Options for Remote Servers

Aliasing a Remote Server

Displaying Information About Remote Servers

Dropping Remote Servers


Adding Remote Servers

To add a remote server, you must set up both the local server and the remote server. On the local server, you must add the server name of the remote server. On the remote server, you must add the server name of the local server. To do this, you use the sp_addserver system procedure to add entries to the sysservers system table.

After you have added the remote server, you must reset certain configuration options on both the local and the remote server as described in Setting Configuration Options for Remote Servers.

Before you add a remote server, be sure that you can access the remote server as a client using isql.

To check that you can access the remote server
  • On both the local and remote servers, type:

    isql /Usa /Psa_password /Sservername

    where

    sa_ password
    Is the system administrator's password.
    servername
    Specifies the remote server to connect to.

If you have difficulty connecting to the remote server, you can use the SQL Client Configuration Utility to configure access to the server. For more information about using the SQL Client Configuration Utility, see Chapter 4, Configuring Clients.

After you have verified that you can connect to the remote servers as a client, you can set up the servers for remote access. You must execute sp_addserver on both the local server and the remote server.

To add a remote server
  • Type:

    sp_addserver server_name [, local]

    where

    server_name
    Is the name of the server.
    local
    Sets server_name as the @@SERVERNAME global variable. For Windows NT - based servers, the @@SERVERNAME global variable is set at installation to the computer name, so you will usually not need to use this option, (unless you decide you want to change the server name).

    One reason to use the local option occurs when you are running both SQL Server 4.2 and SQL Server 6.0 servers at the same time on the same computer. In order to be supported by the graphical tools the servers must use different names. For example, if you want to use SQL Transfer Manager to transfer data between the two, each must use a different server name.

For example, to add EXPENSES as a remote server for the ACCOUNTS server, from ACCOUNTS, type:

sp_addserver expenses

From the remote server EXPENSES, type:

sp_addserver accounts

When you add a new entry with sp_addserver, the srvname and srvnetname are entered in the sysservers table. The srvname is the name that users must supply when executing calls to remote procedures. The srvnetname is the server's network name. The srvname must be unique on each server; the srvnetname does not have to be unique. When you add a new server, the srvname and the srvnetname store the same value.

In the sysservers table, a srvstatus of 0 indicates that the server is the local server, and 1 indicates the server is a remote server.


Setting Configuration Options for Remote Servers

In most cases, you will not need to take any action to set configuration options for remote servers, because the defaults are set appropriately by the setup program. However, if you suspect the default setting of the server's remote access option has been altered, perform the following procedure, and then restart the server.

To check and if necessary set remote configuration options
  1. From the Microsoft SQL Server 6.0 program group, start SQL Enterprise Manager.
  2. From SQL Enterprise Manager's Server Manager window, open a server group, and select a server.
  3. From the Server menu, choose Configurations.

    The Server Configuration dialog box appears.

  4. Choose the Configuration tab.

    The Configuration window displays the configuration settings for this server.

  5. Review and, if appropriate, change the values for remote access, remote login timeout, and remote query timeout.
    • remote access, if set to 1, allows remote servers and users to access this server. Set to 0 to prevent remote server access and remote user connections to this server. The default is 1. Takes effect when SQL Server is restarted.
    • remote login timeout specifies the number of seconds to wait before returning from a login attempt. A value of 0 will allow an infinite wait. The default is 5. This is an advanced configuration option and will be displayed only if show advanced option is set to 1.
    • remote query timeout specifies the number of seconds to wait before returning from processing a query. A value of 0 will allow an infinite wait. The default is 0. This is an advanced configuration option and will be displayed only if show advanced option is set to 1.
  6. When configuration options are set, choose OK.

    If you have changed a configuration option, you must also restart the server. If so, proceed to step 7. If not, skip to step 10.

  7. From the toolbar, select the Services icon (the stoplight).

    The SQL Server Manager services window appears.

  8. Double-click the red Stop light.

  9. After the server has stopped, restart it by choosing the green Start/Continue light.
  10. Return to step 2, select the other server of the remote server pair, and then complete steps 3 through 9.

You can also start and stop the server by clicking with the right mouse button on the server name in the Server Manager window and then selecting Stop or Start from the drop-down menu that appears.

You can also change the server configuration options by using the sp_configure system procedure and then running RECONFIGURE. For information on sp_configure, see the Microsoft SQL Server Transact-SQL Reference.


Aliasing a Remote Server

SQL Server on Windows NT uses DB-Library to connect to remote servers. A connection is made using the srvnetname from the sysservers table. If you need to alias the srvnetname to another network connection string or use a non-default network, use the SQL Client Configuration Utility on the server computer. For more information, see Chapter 3, Configuring Servers.


Displaying Information About Remote Servers

You can use sp_helpserver to determine which servers are set as remote servers of the local server. You can use sp_helpserver without an argument to provide information for all servers listed in sysservers. You can specify a server name to return information for that server only.

The sp_helpserver system procedure returns the server name, server network name, server status, and server ID from the sysservers table. A server status of rpc indicates a remote server.

To display information about servers
  • Type:

    sp_helpserver [server_name]

    where

    server_name
    Is the name of the server.

For example, to display information about a server named WOLFHOUND:

sp_helpserver WOLFHOUND

name

network_name

status

id

-----------

-------------

--------

------

WOLFHOUND

WOLFHOUND

rpc

2

There are other uses for the information returned by sp_helpserver. For information, see the Microsoft SQL Server Transact-SQL Reference.


Dropping Remote Servers

You drop a remote server with the sp_dropserver system procedure, which deletes the entry for that server from the sysservers table. When you drop a remote server, a user can no longer access its information through the local server.

To drop a remote server
  • Type:

    sp_dropserver server_name [, droplogins]

    where

    server_name
    Is the server to be dropped.
    droplogins
    Drops all remote logins for the remote server that is being dropped. You must either explicitly drop the remote logins before you drop the remote server, or you must use this option. For more information about remote logins, see Managing Remote Users, later in this chapter.

    The droplogins option is not needed to drop the local server's entry, because the local server does not have remote login information associated with it.

For example, to drop EXPENSES and its remote logins, type:

sp_dropserver expenses, droplogins

For more information about sp_dropserver, see the Microsoft SQL Server Transact-SQL Reference.


Managing Remote Users

After you set up a remote server, you will set up remote login IDs for the users who need to access that remote server. You will also grant permissions to execute the stored procedures. This chapter explains how to add remote users. To learn how to grant permissions, see Chapter 9, Managing Security.

The type of SQL Server security chosen (integrated, mixed, or standard) does not affect the management of remote users, since the security described in this chapter is used when executing remote stored procedures are executed across server-to-server connections.

The following steps summarize the actions you perform to set up remote users. As part of this summary we provide an example, where the server GREYHOUND is the local server and the server RABBIT is the remote server. These two servers are set up as remote servers to each other, and then the login ID dan on GREYHOUND is mapped to the remote login ID danshelly on RABBIT.

These are the steps you perform to set up a remote user:

  1. The local server adds the remote server as a remote server.

    In this example, the SA on GREYHOUND types:

    sp_addserver rabbit
  2. The remote server adds the local server as a remote server.

    Viewed from the perspective of the remote server, the local server becomes a remote server to it. In this example, the SA on RABBIT types:

    sp_addserver greyhound
  3. If the necessary login ID does not already exist on the remote server, add it.

    In this example, if the login ID danshelly does not already exist on RABBIT, the SA of RABBIT adds it by using SQL Enterprise Manager or sp_addlogin.

    For information about using SQL Enterprise Manager or sp_addlogin, see Chapter 9, Managing Security.

  4. If the necessary login ID does not already exist on the local server, add it.

    In this example, if the login ID dan does not already exist on GREYHOUND, the SA of GREYHOUND adds it by using SQL Enterprise Manager or sp_addlogin.

  5. Map the login ID on the local server to the remote login ID on the remote server.

    This is accomplished on the remote server. In this example, the SA of RABBIT maps the login ID dan on GREYHOUND to the login ID danshelly on RABBIT.

    sp_addremotelogin greyhound, danshelly, dan

    Note This example shows one way to map login IDs. There are other possible mapping configurations. For information, see the topics that follow.

  6. Set the remote login option on the remote server.

    In this example, the SA of RABBIT sets the remote login option to true, which specifies that RABBIT will accept remote logins from GREYHOUND for the danshelly remote login ID without verifying the password. The SA of RABBIT would type:

    sp_remoteoption greyhound, danshelly, dan, trusted, true

The preceding procedure provides an overview of a simple implementation. Other options and more complex configurations are possible. For more information about setting up the remote server relationships, see Managing Remote Servers, earlier in this chapter. For more information about setting up remote users, choose one of the following topics:

Adding Remote Users

Setting the Remote Login Option

Displaying Information About Remote Users

Dropping Remote Users


Adding Remote Users

There are three ways to set up login IDs for a remote server:

  • A user can have a remote login ID that is different from his or her local login ID.

  • A group or all users can have their remote login IDs the same as their local login IDs.

  • A group or all users can be assigned to one remote login ID.

The techniques used to accomplish these login ID mappings are discussed in the topics that follow.

For more information, choose one of the following topics:

Setting Up Remote Users

Understanding Remote User Mapping

Example of Adding Remote Users


Setting Up Remote Users

When you add a remote user, you must add both the login ID and the remote login ID on the server being set up as the user's remote server. The login ID is the ID on the server that is set up as the user's remote server. The remote login ID maps the login ID on the remote server to the login ID on the user's local server.

To add a login ID
  1. Using SQL Enterprise Manager, select the server set up as the user's remote server.
  2. From the Manage menu, choose Logins.
  3. From the Manage Logins dialog box, add a new login ID and password.

This login ID will be used as the remote user's login ID on this remote server.

To add a remote login ID, you use sp_addremotelogin to map the user's login ID on the user's local server to the new login ID on this remote server.

To add a remote login ID
  • Type:

    sp_addremotelogin remoteserver [, login_ID [, remotename]]

    where

    remoteserver
    Specifies the server to which the remote login applies. This is the user's local server. For example, if you're logged in to AIRLINES and want to add a remote login, RESERVATION is the remoteserver.
    login_ID
    Is the login ID that identifies the remote login. This is the login ID added using SQL Enterprise Manager¾for example, manage, account, agents. If you don't specify login_ID or remotename, all users will have the same remote and local login IDs (this inserts a -1 in the sysremotelogins table).
    remotename
    Is the login ID that maps to the login_ID. This is the user's login ID for his or her local server,¾for example, margie, dan, and robin. If you don't specify remotename, all users are mapped to the login_ID you specified (this inserts a NULL in the sysremotelogins table).

When a remote login is received, the local server tries to map the remote user to a local user in three different ways.

  • First, the local server looks for an entry in sysremotelogins that matches the remote server name and the remote login ID. If one is found, then the local server login ID for that row is used to log in the remote user.
  • If no entry is found, the local server searches for an entry that has a remote login ID of NULL and a local login ID that is not -1. In this case, the remote user is mapped to the local server login ID.
  • If the previous attempts fail, the sysremotelogins table is checked for an entry that has a remote login ID of NULL and a local login ID of -1. In this case, whatever remote login ID was supplied by the remote server is used to look for a local login ID in the syslogins table.

The following examples show the different ways to add remote users. If you want to change from one method to the other, you must use sp_dropremotelogin to remove the old mapping, as described later in this chapter in Dropping Remote Users.

For example, suppose all the users in your business use the local server ACCOUNTS. You set up the EXPENSES server as a remote server for ACCOUNTS. Before users can access remote procedures on EXPENSES from ACCOUNTS, you must give them remote login IDs.

You must use the remote server EXPENSES to do the following procedures. The first example maps a user to a particular login ID.

To map the user who has the login ID of chris on the ACCOUNTS server to the login ID of salesmgr on the EXPENSES server
  1. Use SQL Enterprise Manager add the salesmgr login ID to the EXPENSES server.

    From the Server Manager window, select EXPENSES. From the Manage menu, choose Logins. From the Manage Logins dialog box, add the salesmgr login ID.

  2. Use sp_addremotelogin to map salesmgr to chris.
    sp_addremotelogin accounts, salesmgr, chris

The next example maps all users to one remote login ID.

To map all of the users on the ACCOUNTS server to the salesgroup login ID on the EXPENSES server
  1. Use SQL Enterprise Manager to add the salesgroup login ID to the EXPENSES server.

    From the Server Manager window, select EXPENSES. From the Manage menu, choose Logins. From the Manage Logins dialog box, add the salesgroup login ID.

  2. Use sp_addremotelogin to map salesgroup to all of the users on the ACCOUNTS server.
    sp_addremotelogin accounts, salesgroup

    This inserts a NULL in the sysremotelogins table. Note that you can only map users on a server once with a NULL.

The last example maps all users to the same local and remote login IDs.

To map all the users on the ACCOUNTS server to identical login IDs on the EXPENSES server
  1. Use SQL Enterprise Manager to add the login IDs of the users to the remote server.

    From the Server Manager window, select EXPENSES. From the Manage menu, choose Logins. From the Manage Logins dialog box, add the following login IDs: john, steve, mary, and john.

  2. Use sp_addremotelogin to map them to their respective login IDs on the ACCOUNTS server.
    sp_addremotelogin accounts

    This inserts NULL in the remoteusername column in the sysremotelogins table and - 1 in the suid column.

    You can map users only once with a null value. You can have only one NULL value per server in the sysremotelogins table.

When you add a login ID, the login ID is entered in the syslogins table. When you add a remote login ID, SQL Server checks the syslogins table and then adds the remote login ID to the sysremotelogins table. When you view the sysservers table, the local server (the server you are logged in to) has a srvid (server identification) of 0.


Understanding Remote User Mapping

If AIRLINES is set up as a remote server for the local server RESERVATION, then from AIRLINES you can view information about the servers and remote logins.

Assume that you have the following servers listed in sysservers on the AIRLINES server:

select srvid, srvname from sysservers

srvid    srvname
-----  ----------
    0    airlines
    1    reservation
    2    marketing
    3    publications
    4    engineering

The following entries are in sysremotelogins:

select remoteserverid, remoteusername, suid from sysremotelogins
remoteserverid   remoteusername         suid
-------------- ---------------------- ------
             1   margie                  3
             1   dan                     4
             1   robin                   4
             3   NULL                    5
             1   NULL                    6
             4   NULL                   -1

The following entries are in syslogins:

select suid, name from syslogins

suid     name
------ ------------
     1   sa
     2   probe
     3   manage
     4   account
     5   writer
     6   agents
     7   doug
     8   mary
     9   steve

The preceding tables show that:

  • The user margie from the RESERVATION server is known as manage on AIRLINES.
  • The users dan and robin from RESERVATION are mapped to account.
  • All other users from RESERVATION are mapped to agents.
  • All users from PUBLICATIONS are mapped to writer.
  • All users from ENGINEERING are mapped with the same local and remote login IDs.
  • Users from MARKETING cannot execute calls to remote procedures on this server because there is no entry for MARKETING in the sysremotelogins table.

The remote user mapping procedures, plus the ability to set permissions for individual stored procedures, let the local SA control which remote users can access local procedures.

Note The password for a user's local login ID can be required to match the password for the user's remote login ID, as explained in Setting Up Remote Users.


Example of Adding Remote Users

Following is an example that shows how remote users are added and mapped on a remote server. The example is provided for overview and orientation. The procedures you need to use to add remote users are more fully explained in Setting Up Remote Users.

This example shows how to set up a remote server for users at a travel agency. RESERVATION is the local server for all users. The remote server is AIRLINES, and you need to give the users on RESERVATION the appropriate remote login IDs. Most of the users are travel agents, and they need access to the same stored procedures from AIRLINES. There are also two accountants, who need access to a different set of stored procedures. And then there is the manager, who needs access to all of the stored procedures. You decide to map all of the travel agents to agents, the accountants to account, and the manager to manage.

Carry out these steps from the remote server AIRLINES:

  1. Add the new login IDs on the remote server (AIRLINES):

    Using SQL Enterprise Manager, from the Server Manager window select AIRLINES; from the Manage menu, choose Logins; and from the Manage Logins dialog box, add the following login IDs and passwords.

    manage, password
account, password2
agents
  2. Use the sp_addremotelogin system procedure to add the remote login IDs for the users (this step maps the login ID on the remote server to the login ID on the local server):
    sp_addremotelogin, reservation, manage, margie
<execute>
sp_addremotelogin, reservation, account, dan
<execute>
sp_addremotelogin, reservation, account, robin
<execute>
sp_addremotelogin, reservation, agents

    The last sp_addremotelogin statement above maps all of the remaining unmapped users on RESERVATION to the remote login ID agents on AIRLINE. It also inserts a NULL value in the sysremotelogins table. You can have only one NULL value per server in the sysremotelogins table.

  3. Set agents to trusted so that the servers do not need to verify passwords:
    sp_remoteoption reservation, agents, null, trusted, true

    For more information about setting this option, see Setting the Remote Login Option, later in this chapter.

  4. Grant appropriate permissions for the remote procedures for each user.

    For information about granting object permissions, see Chapter 9,Managing Security.

    A remote procedure can also be run by a server application. For more information about server applications, see Microsoft SQL Server Programming Open Data Services.


Setting the Remote Login Option

You can set a user's remote login option to Trusted or Untrusted mode. Trusted mode specifies that the local server accepts remote logins from other servers and front-end applications without verifying passwords for login IDs. Untrusted mode specifies that passwords are verified before the local server accepts remote logins. The default is Untrusted.

To specify trusted or untrusted mode
  • Type:

    sp_remoteoption [remoteserver, loginame, remotename, optname, {true | false}]

    where

    remoteserver
    Specifies the remote server that has the remote login to which the option should apply.
    loginame
    Is the login name that identified the remote login for the remoteserver, loginname, remotename combination.
    remotename
    Is the remote username that identifies the remote login for the remoteserver, loginname, remotename combination.
    optname
    Is the name of the option that you want to set or unset. Currently, trusted is the only option.
    true | false
    Specifies trusted or untrusted mode. For trusted, use true; for untrusted, use false.

For example, to set the trusted option for chris, type:

sp_remoteoption accounts, salesmgr, chris, trusted, true

The effects of untrusted mode depend on the user's front-end. The isql utility and some front-end applications require that users have the same password on the remote server and the local server. DB-Library applications can be written to allow local users to have different passwords on different servers. For more information, see Microsoft SQL Server Programming DB-Library for C.

If you are configuring for remote access between SQL Servers that have different system administrators, remember that setting trusted mode for the SA allows the remote SA to run all stored procedures, including sp_configure and sp_dboption, on your local server.

For more information about sp_remoteoption, see the Microsoft SQL Server Transact-SQL Reference.


Displaying Information About Remote Users

The sp_helpremotelogin stored procedure displays information about a particular remote server's logins or about all remote servers' logins.

To display information about remote logins
  • Type:

    sp_helpremotelogin [remoteserver [, remotename]]

    where

    remoteserver
    Specifies the server about which remote login information is to be displayed. Omitting this optional parameter results in a report about remote logins for all remote servers.
    remotename
    Specifies a particular remote user on the remote server.

For example, to display information about all remote users of the remote server ACCOUNTS:

sp_helpremotelogin ACCOUNTS

server  remote_user_name     local_user_name      options
------- -------------------- -------------------- ---------
ACCOUNTS ** mapped locally ** ** use local name **
ACCOUNTS    chris             salesmgr             trusted

For more information about sp_helpremotelogin, see the Microsoft SQL Server Transact-SQL Reference.


Dropping Remote Users

Dropping a remote login deletes the remote login ID from the sysremotelogins table and prevents that user from accessing the remote server through his or her local server.

To drop a remote login
  • Type:

    sp_dropremotelogin remoteserver [, loginame [, remotename]]

    where

    remoteserver
    Specifies which server has the remote login to be dropped.
    loginame
    Is the local server's username associated with the remote server in the sysremotelogins table.
    remotename
    Is the remote username that gets mapped to loginame when logging in from the remote server.

For example, to drop the remote user chris from the remote server ACCOUNTS who was mapped to the local user salesmgr:

sp_dropremotelogin accounts, salesmgr, chris

For more information about sp_dropremotelogin, see the Microsoft SQL Server Transact-SQL Reference.


Part 5 Data Management

Data Management

The chapters in this part show you how to transfer data to and from a SQL Server and how to back up and restore databases.

  • Chapter 11, Exporting and Importing Data, shows you how to use SQL Transfer Manager and the bcp utility to transfer data to and from a SQL Server. It also tells you how to create SQL Scripts (which are files containing the statements used to create database objects).
  • Chapter 12, Backing Up and Restoring, shows you how to back up a database or transaction log, how to restore from a backup, how to truncate the transaction log, how to schedule backup tasks for automatic execution, and how to recover from storage media failure.


Chapter 11 Exporting and Importing Data

Exporting and Importing Data

Two SQL Server utilities can be used to transfer data. SQL Transfer Manager provides an easy, graphical way to transfer both objects and data from one SQL Server database to another. Bulk copy program (bcp) is a command line utility that copies SQL Server data to or from an operating-system file in a user-specified format. In addition, SQL Enterprise Manager can be used to generate SQL Scripts, which are the statements that are used to create database objects.

This chapter explains how to use SQL Transfer Manager and the bcp utility to transfer data. You can also transfer data using DB-Library functions from inside an application program or by using the SELECT statement to transfer data out and the INSERT statement to transfer data in. This chapter also explains how to use SQL Enterprise Manager to generate SQL scripts.

For information about DB-Library, see Microsoft SQL Server Programming DB-Library for C. For more information about the SELECT and INSERT statements, see the Microsoft SQL Server Transact-SQL Reference. There are no SQL commands for the bulk transfer of data.

For more information choose one of the following topics:

Using SQL Transfer Manager

Using the Bulk Copy Program

Generating SQL Scripts

Transferring Data Between Processor Architectures

Transferring Data Between SQL Server Versions


Using SQL Transfer Manager

SQL Transfer Manager provides an easy, graphical way to transfer objects and data from one SQL Server database to another. It can export from a Microsoft-based or non-Microsoft based SQL Server and can import into a Windows NT-based Microsoft SQL Server.

SQL Transfer Manager can transfer objects and data from one processor architecture to another¾ for example, from a SQL Server running on an Alpha AXP-based computer to a SQL Server running on an Intel-based computer.

You can use SQL Transfer Manager to transfer data from SQL Server 4.21 or SQL Server 6.0 to SQL Server version 6.0. However, you cannot include version 6.0-specific datatypes in the source objects. Version 6.0-specific schema additions, such as identity columns and declarative referential integrity will not be included in the transfer. Additionally, if your source server is version 4.21, some stored procedures or views may contain Transact-SQL statements that are no longer accepted in version 6.0 and some version 4.21 object names may now be key words or reserved words in version 6.0. If so, the transfer will fail for these objects and will not complete correctly for objects that depend on them.

You can also use SQL Transfer Manager to transfer data from a server with one sort order to a server with a different sort order. However, SQL Transfer Manager does not convert extended characters, so you cannot use it for conversion from one code page to another.

If you are transferring data between servers with different case sensitivity, errors will occur if you were not consistent in case when you created your objects and added your data. For example, on a case-insensitive server, if you create a table called abc and then create a view called xyz as SELECT * FROM ABC, the CREATE VIEW statement will work. However, if you transfer the information to a case-sensitive server, the CREATE VIEW statement will fail.

For more information choose one of the following topics:

Starting SQL Transfer Manager and Connecting to Servers

Transferring Objects and Data Using SQL Transfer Manager

Files Created by SQL Transfer Manager


Starting SQL Transfer Manager and Connecting to Servers

Before starting SQL Transfer Manager and connecting to source and destination servers, make sure that the SQL Server service is started on both servers. Review a service's status¾and if necessary start it¾using SQL Service Manager from the Microsoft SQL Server 6.0 program group.

A source server can be a Windows NT-based Microsoft SQL Server, a Microsoft SQL Server for OS/2, or a non-Microsoft-based SQL Server. A destination server can only be a Windows NT-based SQL Server.

To start SQL Transfer Manager and connect to source and destination servers
  1. From the Microsoft SQL Server 6.0 program group, double-click the SQL Transfer Manager icon.

    The SQL Transfer Manager Connect dialog box appears.

  2. Specify the source server.
    • In the Server box, type the name of the SQL Server to export objects and data from.
    • In the ID box, type a valid login identification for the source server (for example, SA).
    • In the Password box, type the password for that login ID on the source server.
  3. Specify the destination server.
    • In the Server box, type the name of the SQL Server to import objects and data to.
    • In the Login ID box, type a valid login identification for the destination server.
    • In the Password box, type the password for that login ID on the destination server.

    Note If the source server is a Windows NT-based SQL Server, the destination server can be the same server as the source server. The supplied login ID must be the database owner of the destination database

  4. Review the setting of the ANSI to OEM option.

    The ANSI to OEM box is checked if the DB-Library "AutoAnsiToOem" option is set on in your system. If this box is checked, TEXT values will be converted during the transfer. Clear the check box if you do not want TEXT values to be converted.

  5. Choose the Connect button to connect SQL Transfer Manager to the specified servers.

    The SQL Transfer Manager window appears.

    For more information, see Transferring Objects and Data Using SQL Transfer Manager, next in this chapter.


Transferring Objects and Data Using SQL Transfer Manager

Before using SQL Transfer Manager to transfer data, the destination database must exist, and it must be large enough to contain all objects and data that you will transfer.

To transfer data, you must have SELECT permission in the source database, and you must be the database owner of the destination database. If the source server is a non-Microsoft-based SQL Server, and you have not run the OBJECT42.SQL script on that server, you must also have CREATE PROCEDURE permission in the source database.

If your source server is Microsoft SQL Server version 6.0, the OBJECT60.SQL script must have been run on the server if you are including dependencies. Otherwise, SQL Transfer Manager will try to create the 4.21 dependency-evaluator stored procedure, which will fail due to parser changes in version 6.0.

The following procedure assumes you have started SQL Transfer Manager and have connected to a source and destination server.

To transfer objects and data using the SQL Transfer Manager window
  1. In the From Database box, select the database to transfer data from.

  2. In the To Database box, select the database to transfer data to.

    The destination database must already exist and have enough space to contain the objects and data you are transferring.

  3. Review the path and name of the directory where SQL Transfer Manager will save scripts and other files.

    To change the location where the files will be saved, in the Script directory box, type a new path and/or directory name. If this directory does not already exist, when the transfer occurs, SQL Transfer Manager will create it.

    For information about the scripts and other files saved in this directory, see Files Created by SQL Transfer Manager, later in this chapter.

  4. Specify the objects that will be transferred.
    • To transfer all database objects, select the All Objects check box. This is the default selection.
    • To transfer all objects of a type, select the check box for that object type.

      You can select one or more object types: tables, views, triggers, rules, defaults, user-defined datatypes, and/or stored procedures.

    • To transfer specific objects, clear the All Objects check box, select one or more objects from the Available Objects list, and then choose the Add button.
  5. Specify whether data will also be transferred.

    To also transfer the data from the source database to the destination database, select the Include Data check box.

  6. If you selected Include Data, to create unique clustered indexes after the data transfer (by using the WITH SORTED DATA clause), select the Sorted Data check box.

    If this box is not selected, unique clustered indexes are created prior to data transfer. Nonunique clustered indexes are always created prior to data transfer, whether or not this box is selected. Creating the clustered indexes prior to data transfer is slower during the actual data transfer process, but it eliminates the full table sort that is required if the clustered index is created after the transfer. Nonclustered indexes and triggers are always created after the data is transferred.

    If the destination server's sort order does not match that of the source server, using the SORTED DATA clause is likely to fail. If this happens, there will be an error message in the .LOG file, and after the transfer you must build the indexes yourself without the SORTED DATA clause.

  7. To also transfer all objects that depend on the selected object(s) or object type(s), select the Include Dependencies check box.

    If you select this option and the source server is Microsoft SQL Server version 6.0, the OBJECT60.SQL script must have been run on that server. Otherwise, SQL Transfer Manager will try to create the 4.2 dependency-evaluator stored procedure, which will fail due to parser changes in version 6.0. For information about running the OBJECT60.SQL script, see Appendix A, Interoperation with Microsoft SQL Server 4.2.

  8. To drop existing objects in the destination database before transferring objects from the source database, select the Include Drops check box.
  9. To also transfer segment information to the destination database, select the Include Segments check box.

    Segments must already exist at the destination database. There must be sufficient space on the segment(s) to accommodate the tables you will be transferring. If you are not sure of the segment space requirements, you can check them by selecting the Export Only option, choosing the Transfer button, and then reading the generated .TAB file. For more information about .TAB files, see Files Created by SQL Transfer Manager, later in this chapter. For more information about segments, see Chapter 7, Managing Drives.

  10. Specify whether or not security information will be transferred.
    • To add the users from the source database to the destination database, select the All Users check box. Note that if you have a guest user created in the source database, you must also create a guest user in the destination database.
    • To add the groups from the source database to the destination database, select the All Groups check box.
    • To add the login IDs for the users from the source server to the destination server, select the All Logins check box.
    • To include all the user's permissions from the source database, select the Include Permissions check box.
  11. Determine the setting of the Export Only option.
    • To generate scripts and also transfer the specified data and objects, clear the Export Only option. This is the default setting.
    • To generate scripts without actually transferring the data or objects, select the Export Only option. For example, to view segment and size usage information about tables without actually performing a transfer, you can use this option and then view the information about the tables in the .TAB file that is created in the script directory.
  12. Choose the Transfer button.
    • If the Export Only option is cleared, several files are created in the script directory, and the objects and data you specified are transferred.
    • If the Export Only option is selected, the files are created in the script directory, but no objects or data are actually transferred.

    You can interrupt a transfer once it has begun by pressing CTRL+C.


Files Created by SQL Transfer Manager

When a transfer is performed, a number of files are created and are saved on the export server in a subdirectory that SQL Transfer Manager creates under \SQL60\BINN. For example, if the server TERRIER exports from the pubs database, a TERRPUBS subdirectory is created (\SQL60\BINN\TERRPUBS), during the export the files are placed there.

The types of files created by SQL Transfer Manager are:

.DRP file
A file of this type is created if the check box for the Include Drops option was selected. The .DRP file contains the DROP statements for the objects.
.IDX file
The .IDX file contains the scripts for index creation.
.LOG file
The .LOG file contains all server messages and errors, and informative messages that will help you recover from errors.
.SCH file
The .SCH file contains the database scripts that are used for transferring data and objects.
.TAB file
The .TAB file contains summary information about the tables in the database, including their names, segment information, size usage, and the number of rows in each table.
.TRG file
The .TRG file contains the scripts for trigger creation.


Using the Bulk Copy Program

Command-line utilities are executable programs run from a command prompt. The bulk copy program (bcp) is a command-line utility that copies SQL Server data to or from an operating-system file in a user-specified format. Because the bcp utility can be used to copy data in different ways, read this entire chapter before using bcp to copy information.

The following topics discuss using the bcp utility interactively as well as automatically, with the frequently used defaults. They discuss how you should copy a table that has indexes, and what happens to tables with triggers, rules, and defaults. Finally, they give several examples and scenarios showing the different ways you can use the bcp utility.

The bcp utility is most frequently used to transfer data into a SQL Server database from another program, usually another database management system. The data to be transferred must be put into an operating-system file or onto a diskette with a backup facility provided by the old program.

The bcp utility is also used for temporary transfers of data for use with other programs¾ for example, with spreadsheet programs. The data is moved from SQL Server into an operating-system file or onto a diskette; from there, the other program can import the data.

SQL Server can accept data in any ASCII or binary format as long as the terminators (the characters used to separate columns and rows) can be described. The table structures need not be identical. Data copied into SQL Server is appended to any existing contents of a table; data copied to a file overwrites any previous contents of the file.

To use bcp, a user must have a SQL Server login account and the appropriate permissions on the database tables, views, and operating-system files.

For more information choose one of the following topics:

Permissions Needed to Copy Data

Running bcp

Using Native and Character Format bcp

Setting bcp Defaults

Using the bcp Format File

Copying Tables With or Without Indexes

Copying Tables with Defaults, Rules, and/or Triggers

Copying In or Out of a Temporary Table

Copying Views

Transferring Data with bcp

Common bcp Issues


Permissions Needed to Copy Data

The bcp utility can be used to copy data, from a table or view into an operating system file, or from an operating system file into a table. To copy data from an operating system file into a table, a user must have INSERT permission on the table. To copy a table or view to an operating-system file, the user must have SELECT permission on the following:

  • The table or view being copied
  • sysobjects
  • syscolumns
  • sysindexes

For information about granting permissions, see Chapter 9, Managing Security.


Running bcp

The bcp utility transfers data between an existing database table or view and an operating-system file in a format that can be specified by the user. The bcp utility is executed from the operating system.

In general, you must supply the following information for transferring data to and from SQL Server:

  • The name of the database
  • The name of the table or view
  • The name of the operating-system file or disk drive
  • The direction of the transfer (in or out)

In addition, for each column, you can modify the datatype, length, and terminator.

To transfer data with the bcp utility

bcp [[database_name.]owner.]table_name {in | out} datafile
[/m maxerrors] [/f formatfile] [/e errfile]
[/F firstrow] [/L lastrow] [/b batchsize]
[/n] [/c] [/E]
[/t field_term] [/r row_term]
[/i inputfile] [/o outputfile]
/U login_id [/P password] [/S servername] [/v] [/a packet_size]

where

database_name
Specifies the database name. This name is optional if the table or view being copied is in your default database. Otherwise, you must specify a database name.
owner
Is the owner's name. This name is optional if you own the table or view being copied. If no owner is specified and you do not own a table of that name, the program will not execute.
table_name
Specifies which database table or view to copy.
in | out
Specifies the direction of the copy. The in option copies from a file into the database table; the out option copies to a file from the database table or view.
datafile
Is the full path of an operating-system file when copying to or from a hard-disk file or a single diskette. The path can have from 1 to 255 characters. To copy to or from multiple diskettes, datafile is a drive specifier only (such as A:).
/m maxerrors
Is the maximum number of errors that can occur before the copy is canceled. Each row that cannot be rebuilt by bcp is thrown out and counted as one error. If this option is not included, the default is 10.
/f formatfile
Is the full path of a file with stored responses from a previous use of bcp on the same table; creation of the format file is optional. Use this option when you have already created a format file that you want to use to copy in or out. After you answer format questions, bcp asks whether you want to save your answers in a format file. The default filename is BCP.FMT. The bcp utility can refer to a format file when you copy data, so that you do not have to duplicate your previous format responses interactively. If this option is not used, bcp queries you for format information.
/e errfile
Is the full path of an error file where bcp stores any rows that it was unable to transfer from the file to the database. Error messages from the bcp utility go to the user's workstation. If this option is not used, no error file is created.
/F firstrow
Is the number of the first row to copy (the default is the first row).
/L lastrow
Is the number of the last row to copy (the default is the last row).
/b batchsize
Is the number of rows per batch of data copied (the default copies all the rows in one batch).
/n
Performs the copy operation using the data's native (database) datatypes as the default. This option does not prompt for each field; it uses the default values.
/c
Performs the copy operation with a character datatype as the default. This option does not prompt for each field; it uses char as the default storage type, no prefixes, \t (tab) as the default field separator, and \n (new line) as the default row terminator.
/E
Is used when identity values are present within the table to be imported.

When importing data, an identity column is temporarily assigned an identity value of 0. As the rows are inserted into the table, SQL Server assigns unique values based on the seed and increment values specified during table creation. Use the /E flag if identity values already exist in the file. If SQL Server-generated identity values are preferred, place only nonidentity columns in the file.

This option is in effect only during bcp in. It has no effect during bcp out.

/t field_term
Is the default field terminator.
/r row_term
Is the default row terminator.
/i inputfile
Is the name of a file that redirects input to bcp.
/o outputfile
Is the name of a file that receives output redirected from bcp.
/U login_id
Is a login ID.
/P password
Is a user specified password. If the /P option is not used, bcp prompts for a password. If the /P option is used at the end of the command line without any password, bcp uses the default password (NULL).
/S servername
Specifies which SQL Server to connect to. The servername is the name of the server computer on the network. This option is required when you are executing bcp from a remote computer on the network.
/v
Reports the current DB-Library version number.
/a packet_size
Is the number of bytes, per network packet, sent to and from the server. A server configuration option can be set using SQL Enterprise Manager (or the sp_configure system stored procedure). However, this option can be overridden on an individual basis with the bcp /a option. The valid values for packet_size are 512 through 65535. The server default is 4096, and the default value for the Windows NT - based bcp is 4096. The default value is 512 for MS-DOS, though larger sizes can be requested.

Increased packet size may enhance performance on bulk copy operations. Microsoft testing indicates that 4096 to 8192 is typically the fastest setting for bulk copy operations. Packet sizes over 512 will work only for clients connected to a Windows NT - based SQL Server. If a larger packet is requested but cannot be granted, the client will default to 512. The performance statistics generated at the end of a bcp run will show the actual packet size used.


Using Native and Character Format bcp

The bcp utility provides two options that create files with frequently used default formats.

  • The /n option uses native (database) datatypes. Storing information in native file format data is useful when information is to be copied from one SQL Server into another SQL Server. The use of the native format saves time, preventing unnecessary conversion of datatypes into and out of character format.
  • The /c option uses the character (char) format for all columns, providing tabs between fields in a row and a new line at the end of each row. Storing information in character file format is useful when the data is used with another program such as a spreadsheet, or when the data needs to be copied into SQL Server from another database.

If you use the /n or /c option, bcp does not query you for information on a column-by-column basis. Otherwise, bcp operates interactively and queries for further information needed to specify the data format in the output file.

For more information, choose one of the following topics:

Native Format bcp

Character Format bcp


Native Format bcp

The following example shows how to copy the publishers table to the PUBL_OUT file using native data format:

bcp pubs..publishers out publ_out /n /Sservername /Usa
/Ppassword

In the output file the bcp utility adds to the beginning of each field an ASCII character equivalent to the length of the data in a char or varchar field. In a table with numeric data, the information is written to the file in the operating-system data format.


Character Format bcp

The following example shows how to copy the publishers table to the PUBL_OUT file using character format:

bcp pubs..publishers out publ_out /c /Sservername /Usa
/Ppassword

This is the output:

0736

New Moon Books

Boston

MA

USA

0877

Binnet & Hardley

Washington

DC

USA

1389

Algodata Infosystems

Berkeley

CA

USA

1622

Five Lakes Publishing

Chicago

IL

USA

1756

Ramona Publishers

Dallas

TX

USA

9901

GGG&G

München

Germany

9952

Scootney Books

New York

NY

USA

9999

Lucerne Publishing

Paris

France

When using character format, if you don't want to use the default terminators with the /c option, use the /t and /r options to change the terminators. The following example uses the comma as a field terminator and the newline character (\n) as the row terminator:

bcp pubs..publishers out publ_out /c /t , /r \n /Sservername /Usa /Ppassword

Here are the contents of PUBL_OUT:

0736,New Moon Books,Boston,MA,USA
0877,Binnet & Hardley,Washington,DC,USA
1389,Algodata Infosystems,Berkeley,CA,USA
1622,Five Lakes Publishing,Chicago,IL,USA
1756,Ramona Publishers,Dallas,TX,USA
9901,GGG&G,München,,Germany
9952,Scootney Books,New York,NY,USA
9999,Lucerne Publishing,Paris,,France


Setting bcp Defaults

If you do not use the /n or /c options, the bcp utility prompts you for further information, including the storage type, prefix length, and terminator for each column of data being copied. For fields that are to be stored as char or binary, bcp also prompts for a field length.

The default values at these prompts produce exactly the same results as the /n option and provide a way to copy data out of a database for later reloading into SQL Server. If you are copying data to or from SQL Server for use with other programs, your answers to the prompts depend on the format required by the other program.

Note You can skip a table column on input (but not on output) by specifying 0 prefix length, 0 length, and no terminator.

For example, to interactively copy the publishers table to the PUBL_OUT file:

bcp pubs..publishers out publ_out /Sservername /Usa
/Ppassword

A series of four prompts appears for each column. This example is for the pub_id column in publishers. For each prompt, the default is displayed within brackets. You can press ENTER to accept the default, or type a new value and then press ENTER.

Enter the file storage type of field pub_id [char]:
Enter prefix length of field pub_id [0]:
Enter length of field pub_id [4]:
Enter field terminator [none]:

The following table shows the defaults and possible responses for each of the four prompts:

Prompt | Default provided | Possible responses
File storage type | Database storage type for most fields: char for varchar; binary for varbinary. | char to create or read an ASCII file (any SQL Server datatype where implicit conversion is supported).
Prefix length | 0 for fields defined with datatype (not storage type) char and all fixed-length datatypes, 1 for most other datatypes, 2 for binary and varbinary, 4 for text and image. | 0 if no prefix is desired; defaults are recommended in all other cases.
Field length | Defined length for char and varchar. Defined length * 2 for binary and varbinary saved as char. Maximum length needed to avoid truncation or data overflow for all other datatypes. | Default values or greater are recommended.
Field terminator | None. | Up to 30 ASCII characters or one of the following: \t tab \n newline \r carriage return \0 null terminator \\ backslash

The responses to these four prompts provide a flexible system for writing a file that requires little or no editing to conform to other data formats or to read files from other software. The following sections describe each of these prompts and the ways they interact to affect the data. The default responses to these prompts are designed to provide the fastest and easiest method of copying data to and from SQL Server.

For more information, choose one of the following topics:

File Storage Type

Prefix Length

Field Length

Field Terminator


File Storage Type

The file storage type describes how data is stored in the file. You can copy data into a file as its database table type, as a character string in ASCII format, or as any datatype for which implicit conversion is supported for the datatype. User-defined datatypes are copied as their base types. The following table shows the storage types that can be used with bcp and the abbreviations (if any) that can be entered at the command prompt.

For the most compact storage, use the default; for ASCII files, use char.

Storage type | Abbreviation
char | c[har]
varchar | c[har]
text | T[ext]
binary | x
varbinary | x
image | I[mage]
datetime | d[ate] *
smalldatetime | D
decimal | n
numeric | n
float | f[loat] *
real | r
int | i[nt] *
smallint | s[mallint] *
tinyint | t[inyint] *
money | m[oney] *
smallmoney | M
bit | b[it]
timestamp |
* Length is dependent on the data. For example, an int of 23 has a storage length of 2 bytes plus the prefix and terminator (if any); an int of 5,238,876 has a storage length of 7 bytes plus the prefix and terminator (if any).

Giving a type other than char or a datatype that represents an illegitimate implicit conversion causes bcp to fail. For example, you cannot use smallint for int data (you will get overflow errors), but you can use int for smallint.

When integer datatypes (float, money, and numeric) are stored as their database types, the data is written to the file in the operating-system data representation format, rather than in human-readable form.


Prefix Length

To provide the most compact file storage, bcp precedes each field, except those defined as char, with a string of one or more characters that indicate the length of the field. The default values in the prompts indicate the most efficient prefix lengths.

For fields of 255 characters or less, the default prefix length is 1. For text or image datatypes, the default prefix length is 4. When binary and varbinary datatypes are being converted to char storage types, the default prefix length is 2, since 2 bytes of storage are required for each byte of table data.

To store data with no prefix before the column, use a prefix length of 0. Each stored field is padded with spaces to the full length specified at the next prompt for length of field.


Field Length

In almost all cases, you should accept the bcp default value for the storage length. If you are making a file for later reloading into SQL Server, using a prefix with the default storage type and the default length keeps the storage space to a minimum. If you are creating an ASCII file, using the default length ensures that you will not truncate the data or create overflow errors that cause bcp to fail.

You can change the default length by supplying another value.

If the storage type is noncharacter, the data is stored in the operating system native data representation. You are not asked to provide a length.

When bcp converts noncharacter data to character storage, it suggests a default field length large enough to store the data without truncating datetime data or causing overflow of numeric data.

These are the default field lengths for noncharacter fields:

Datatype | Default length (bytes)
bit | 1
datetime | 26
smalldatetime | 26
float | 25
real | 25
int | 12
smallint | 6
tinyint | 3
money | 24
smallmoney | 24
decimal | 28
numeric | 28

If you specify a field length that is too short for number data when you are copying data out, bcp prints an overflow message and does not copy the data. When datetime data is stored as a character string of less than 26 bytes, the data is silently truncated.

The default length for binary and varbinary fields is twice the length defined for the column, since 2 bytes of storage are required for each byte of the field. If you accept the default, the actual amount of storage space allocated depends on whether you specify a prefix length and/or terminators:

  • If you specify a prefix length of 1, 2, or 4, the storage space used is the actual length of the data, plus the length of the prefix, plus any terminators.
  • If you specify a prefix length of 0 and no terminator, bcp allocates the maximum amount of space shown in the prompt, which is the maximum space that might be needed for the datatype in question. In other words, the field is treated as if it were of fixed length so that it is possible to determine where one field ends and the next begins.

    For example, if the field is defined as varchar(30), bcp uses 30 characters for each value, even if some of the values are only 1 character long. The char datatypes are always padded to their full specified length.

The following tables show the interaction of prefix lengths, terminators, and field length on the information in the file. "P" indicates the prefix in the stored table, "T" indicates the terminator, and dashes (--) indicate appended spaces. An ellipsis (...) indicates that the pattern repeats for each field. The field length is 8 for each column, and the 6-character field "string" is stored each time.

SQL Server char Data

 | Prefix length = 0 | Prefix length 1, 2, or 4
No terminator | string--string--... | Pstring--Pstring--...
Terminator | string--Tstring--T... | Pstring--TPstring--T...

Other Datatypes Converted to char Storage

 | Prefix length = 0 | Prefix length 1, 2, or 4
No terminator | string--string--... | PstringPstring...
Terminator | stringTstringT... | PstringTPstringT...


Field Terminator

You can use an optional terminator to mark the end of a column, separating one column from the next. The default is no terminator. To accept the default, press ENTER when prompted.

When you are preparing data for use with other programs and when you want to use bcp to prepare tabular data, you will usually want to supply your own terminators. The following terminators can be used:

Terminator | Indicated by
Tabs | \t
New lines | \n
Carriage returns | \r
Backslash | \\
Null terminators (no visible terminator) | \0
Any printable character | (*, A, t, l, and so on)
Strings of up to 10 printable characters, including some or all of the terminators listed previously (**\t**, end, !!!!!!!!!!, \t--\n, and so on; control characters are not printable) |

The /t and /r options let you change the default terminators. When you use these options, the default that is listed in the prompt changes to the value you specify on the command line. The following example changes the default field terminator to the tab character (\t) and the default row terminator to the newline character (\n):

bcp pubs..publishers out publ_out /t \t /r \n
/Sservername /Usa /Ppassword

Important Terminators must be chosen to ensure that their pattern does not appear in any of the data. For example, using tab terminators with a string that contains a tab results in an ambiguity: which tab represents the end of the string? The bcp utility always looks for the first possible terminator, which in this case would be incorrect.

Native format data can also conflict with terminators. Given a column that contains a 4-byte integer in native (non-ASCII) format, if the values of these integers are not strictly limited, it is impossible to choose a terminator that is guaranteed not to appear inside the data.

Any data column that can contain null values is considered variable length for bcp purposes. Therefore, a length prefix or terminator should be used to specify the length of each row's data.

Note The no terminator value is different from the null terminator value. The no terminator value puts no terminator after the column. The null terminator value puts a null character after the column. A null character is an invisible but real character.


Using the bcp Format File

If you do not use the /n or /c options, but instead set the bcp default values yourself after information is gathered about each field in the table, bcp prompts you to save a format file and then prompts you for the filename. For example:

Do you want to save this format information in a file? [Y/n] y
Host filename: [bcp.fmt]

This format file can be used to copy the data back into SQL Server or to copy data out from the table at another time. When you are copying data in or out using an existing format file, you are not prompted for information; the format file provides the information needed.

The default name for the format file is BCP.FMT, but you can specify a different filename. For more information about using format files, see Using a Format File to Selectively Copy Data, later in this chapter.

A typical format file is shown below.

The following table explains each area of the bcp format file:

Field | Field description
Version | Version number of bcp.
Prefix length | Used to specify the most efficient file storage. For ASCII data files, use 0. A 4 represents the length of the particular data file field.
Terminator | A delimiter to separate the fields in a data file. Common terminators are commas and end of line (\r \n).
Server column name | The name of the field taken from the SQL Server table. It is not necessary to use the actual name of the field. The only condition is that the field not be blank.
Number of columns | The number of columns in the data file.
Host file column order | The field number of the data file.
Host file datatype | The datatype stored in the particular field of the data file. With ASCII data files, use sqlchar; for native format data files, use default datatypes.
Host file data length | The length, in bytes, of the datatype stored in the particular field of the data file.
Server column order | The order in which columns appear in the SQL Server database.


Copying Tables With or Without Indexes

For copying data in, the bcp utility is fastest if your database table has no indexes. Fast bcp does not log data inserts in the transaction log.

Important Before a user can do non-logged inserts with bcp, the SA or database owner must first use SQL Enterprise Manager (or the sp_dboption system procedure) to set the Select Into/Bulk Copy option for that database to true. If the option is not set and a user tries to copy data into a table that does not have indexes, SQL Server generates a warning message and will log the bulk inserts.

For a table that has indexes, you do not need to set the Select Into/Bulk Copy option to copy data in, because bulk inserts into tables with indexes are always logged.

When you copy into a table that has indexes, the server logs data inserts in the transaction log, which can cause the transaction log to become very large. After backing up your database with DUMP DATABASE, you can remove the committed transactions from the log by backing up the transaction log to a dump device.

Note If you back up the transaction log with TRUNCATE_ONLY, you will not be able to load any subsequent log dumps unless they have been made after another DUMP DATABASE.

When copying data in, if a target table has no indexes, and if the Select Into/Bulk Copy database option is on, you can use non-logged bcp. Otherwise, you can only use logged bcp.

By default, the Select Into/Bulk Copy option is off in newly created databases. To change the default for all new databases, set this option in the model database.

There is a performance penalty for copying data into a table that has indexes in place. If you are copying a large number of rows, it can be faster to drop all the indexes beforehand with DROP INDEX, set the database option, copy the data into the table, dump the database, and then re-create the indexes. If the bulk data is sorted prior to the copy, you can use the WITH SORTED DATA option to build the clustered index in place on the newly loaded table.


Copying Tables with Defaults, Rules, and/or Triggers

When data is copied into a table, any defaults defined for the columns and datatypes in the table are observed. That is, if there is a null field in the data in a file, the default value is loaded instead during the copy. For example, here are two rows in a file that are to be loaded into authors:

409-56-7008,Bennet,Abraham,415 658-9932,6223 Bateman St.,Berkeley,CA,94705,1
213-46-8915,Green,Marjorie,,309 63rd St. #411,Oakland,CA,94618,1

Commas separate the fields; a new line separates the rows. Note that there is no phone number for Marjorie Green. If the phone column of the titles table had a default of unknown, the rows in the loaded table would look like this:

409-56-7008    Bennet    Abraham        415 658-9932    6223 Bateman St.
    Berkeley CA     94705    1
213-46-8915    Green    Marjorie        unknown         309 63rd St. #41
    Oakland  CA     94618    1

However, rules, triggers and constraints are ignored to load data at the maximum speed. To find any rows that violate rules and triggers, copy the data into the table and run queries or stored procedures that test the rule or trigger conditions. For example:

UPDATE pubs..authors SET au_fname = au_fname


Copying In or Out of a Temporary Table

When using the bcp utility to copy data in or out of a temporary table, you must give the entire 30-character table name, including the initial pound signs (##).


Copying Views

The bcp utility also supports copying data out of a view. This allows you to copy specific columns, add a WHERE clause, or perform special formatting such as changing data formats using the CONVERT function.


Transferring Data with bcp

To copy data from one SQL Server to another, you must copy the data from one SQL Server to a file and then copy the data from the file to the other SQL Server.

The topics that follow provide examples of copying data from SQL Server to a file, copying data from a file to SQL Server, and using a format file to selectively copy data. For more information, choose one of the following topics:

Copying Data from SQL Server to a File

Copying Data from a File to SQL Server

Using a Format File to Selectively Copy Data

After you have copied data into a table, it is a good idea to back up the database. Then as necessary you can re-create any indexes on that table, reset any database options, check for rule violations, and make sure the Select Into/Bulk Copy option is set to false.


Copying Data from SQL Server to a File

You can copy tables out of SQL Server for use with other programs, such as a spreadsheet program, or for use on other SQL Servers. The following examples show how to copy a database table to a file in its current format, as well as how to copy a database table to a file in a new format.

Copying a Database Table to a File

In the following example, bcp copies data from the publishers table to an output file called PUBL_OUT for later reloading into SQL Server using the format file PUBL_FMT. It creates an output file with a new line at the end of each row and a comma between each field in a row.

bcp pubs..publishers out publ_out /Sservername /Usa /Ppassword

    Enter the file storage type of field pub_id [char]:
    Enter prefix length of field pub_id [0]:
    Enter length of field pub_id [4]:
    Enter field terminator [none]: ,

    Enter the file storage type of field pub_name [char]:
    Enter prefix length of field pub_name [0]:
    Enter length of field pub_name [40]:
    Enter field terminator [none]: ,

    Enter the file storage type of field city [char]:
    Enter prefix length of field city [0]:
    Enter length of field city [20]:
    Enter field terminator [none]: ,

    Enter the file storage type of field state [char]:
    Enter prefix length of field state [0]:
    Enter length of field state [2]:
    Enter field terminator [none]: ,

    Enter the file storage type of field country [char]:
    Enter prefix length of field country [0]:
    Enter length of field country [30]:
    Enter field terminator [none]: \n

    Do you want to save this format information in a file? [Y/n] y
    Host filename: [bcp_fmt] publ_fmt

     Starting copy...

    8 rows copied.
    Network packet size (bytes): 4096
    Clock Time (ms.): total = 150    Avg = 18    (53.33 rows per sec.)

These are the results in the PUBL_OUT output file:

0736,New Moon Books,Boston,MA,USA
0877,Binnet & Hardley,Washington,DC,USA
1389,Algodata Infosystems,Berkeley,CA,USA
1622,Five Lakes Publishing,Chicago,IL,USA
1756,Ramona Publishers,Dallas,TX,USA
9901,GGG&G,München,,Germany
9952,Scootney Books,New York,NY,USA
9999,Lucerne Publishing,Paris,,France

In this example, the user saved a format file called PUBL_FMT in response to the associated prompt. These are the results in the PUBL_FMT file:

6.0
5
1       SQLCHAR       0       4       ","       1       pub_id
2       SQLCHAR       0       40      ","       2       pub_name
3       SQLCHAR       0       20      ","       3       city
4       SQLCHAR       0       2       ","       4       state
5       SQLCHAR       0       30      "\r\n"    5       country

To use the saved format file to copy this data back into SQL Server, type:

bcp pubs..publishers in publ_out /f publ_fmt /Sservername /Usa /Ppassword

Note that the PUBL_FMT format file can be used to copy any data with the same format into SQL Server.

Copying a Database Table to a File in a New Format

By changing the default values of the bcp prompts, you can store data in a new format for use with other software. In most cases, you'll want an ASCII file for other programs. The usual responses to the bcp prompts are as follows:

  • The storage type should be char.
  • The prefix length should be 0.
  • The field length should be the default.
  • The terminator depends on what software you plan to use. For output delimited with commas, use a comma as the terminator for each field. For tabular output, terminate the last field with the newline character (\n) and all other fields with the tab character (\t).

The following example creates output in the computer format called system data format (SDF). Each field has a fixed length with spaces to pad the fields. Adjacent fields in which the data completely fills the first field seem to run together, since there are no field separators on each line of output. Only the final field has a terminator, the newline character(\n). This format can be easily read or produced by other software.

bcp pubs..sales out sal_out /Sserver /Usa /Ppassword

    Enter the file storage type of field stor_id [char]:
    Enter prefix-length of field stor_id [0]:
    Enter length of field stor_id [4]:
    Enter field terminator [none]:

    Enter the file storage type of field ord_num [char]:
    Enter prefix-length of field ord_num [0]:
    Enter length of field ord_num [20]:
    Enter field terminator [none]:

    Enter the file storage type of field date [datetime]: char
    Enter prefix-length of field date [0]:
    Enter length of field date [26]:
    Enter field terminator [none]:

    Enter the file storage type of field qty [smallint]: char
    Enter prefix-length of field qty [0]:
    Enter length of field qty [6]:
    Enter field terminator [none]:

    Enter the file storage type of field payterms [char]:
    Enter prefix-length of field payterms [0]:
    Enter length of field payterms [12]:
    Enter field terminator [none]:

    Enter the file storage type of field title_id [char]:
    Enter prefix-length of field title_id [0]:
    Enter length of field title_id [6]:
    Enter field terminator [none]: \n

    Do you want to save this format information in a file? [Y/n] y
    Host filename: [bcp_fmt] sal_fmt

    Starting copy...

    21 rows copied.
    Network packet size (bytes): 4096
    Clock Time (ms.): total = 210   Avg = 10     (100.00 rows per sec.)

The following output is sent by bcp to the SAL_OUT file:

6380

6871

Sep 14 1994 12:00AM

5

Net 60

BU1032

6380

722a

Sep 13 1994 12:00AM

3

Net 60

PS2091

7066

A2976

May 24 1993 12:00AM

50

Net 30

PC8888

7066

QA7442.3

Sep 13 1994 12:00AM

75

ON invoice

PS2091

7067

D4482

Sep 14 1994 12:00AM

10

Net 60

PS2091

7067

P2121

Jun 15 1992 12:00AM

40

Net 30

TC3218

7067

P2121

Jun 15 1992 12:00AM

20

Net 30

TC4203

7067

P2121

Jun 15 1992 12:00AM

20

Net 30

TC7777

7131

N914008

Sep 14 1994 12:00AM

20

Net 30

PS2091

7131

N914014

Sep 14 1994 12:00AM

25

Net 30

MC3021

7131

P3087a

May 29 1993 12:00AM

20

Net 60

PS1372

7131

P3087a

May 29 1993 12:00AM

25

Net 60

PS2106

7131

P3087a

May 29 1993 12:00AM

15

Net 60

PS3333

7131

P3087a

May 29 1993 12:00AM

25

Net 60

PS7777

7896

QQ2299

Oct 28 1993 12:00AM

15

Net 60

BU7832

7896

TQ456

Dec 12 1993 12:00AM

10

Net 60

MC2222

7896

X999

Feb 21 1993 12:00AM

35

ON invoice

BU2075

8042

423LL922

Sep 14 1994 12:00AM

15

ON invoice

MC3021

8042

423LL930

Sep 14 1994 12:00AM

10

ON invoice

BU1032

8042

P723

Mar 11 1993 12:00AM

25

Net 30

BU1111

8042

QA879.1

May 22 1993 12:00AM

30

Net 30

PC1035


Copying Data from a File to SQL Server

To copy a file to SQL Server, follow these guidelines:

  • When copying data from a file into a table that has no indexes, be sure that the Select Into/Bulk Copy option has been set to true. The SA or database owner can set this option with SQL Enterprise Manager (or the sp_dboption system procedure).
  • After copying data from a file, back up the database with the DUMP DATABASE statement so that the copy and any subsequent changes can be recovered.

The following illustration shows the process to follow to copy data into SQL Server at maximum speed.

To copy data from a file to SQL Server
  1. Use SQL Enterprise Manager (or sp_dboption) to set the Select Into/Bulk Copy option for that database to true.
  2. Drop the indexes on the table. (This can be performed by table owner.)
  3. Be sure that you have select and insert permissions on the table. (The table owner can assign select and insert permissions.)
  4. Perform the copy with bcp. (This can be performed by any user with select and insert permissions.)
  5. Use SQL Enterprise Manager (or sp_dboption) to set the Select Into/Bulk Copy option for that database to false.
  6. Use DUMP DATABASE to back up the newly inserted data. (This can be performed by the SA or the database owner.)
  7. Re-create the indexes. Check to make sure that you have enough space. The distribution statistics for indexes are automatically updated.
  8. Execute stored procedures or queries to check if any of the newly loaded data violates rules or triggers. (This can be performed by the table owner or the stored procedure owner.)

When the transfer is complete, the program reports the number of rows successfully copied and some performance information.


Using a Format File to Selectively Copy Data

Using a bcp format file provides a way to selectively bulk copy data from a file to SQL Server. This allows the user to transfer data into a table when there is a mismatch between the data sent to the table and the columns available for the received data.

Sometimes a user's data file may not match the structure of the SQL Server table into which the data will go. For example, a table contains columns for an employee's ID, name, and department. The input file contains the employee's ID, name, department, and salary. By using a bcp format file, you can bulk copy only the necessary data, without having to delete the unnecessary data from the input file.

The following sections provide examples that demonstrate how to change the format file to simplify loading the data in the input file into the SQL Server table.

Using a Data File with Fewer Columns than the SQL Server Table

This example takes the data in the input file NEW_AUTH.DAT and loads it into the authors table in the pubs database. This is the data in the NEW_AUTH.DAT file:

777-77-7777,Chris,Smith,303 555-1213,Denver,CO,1
888-88-8888,John,Doe,206 555-1214,Seattle,WA,0
999-99-9999,Jane,Door,406 555-1234,Bozeman,MT,1

The structure of the input file differs from that of the authors table in three ways:

  • The first and last names are in reverse order from the order of the columns.
  • The input file does not contain an address field.
  • The input file does not contain a ZIP code field.

To enter this data into the SQL Server table, you must first create a format file for the authors table. To create the format file, type:

bcp pubs..authors out c:\authors.out /Sservername /Usa /Ppassword

The bcp utility displays a series of questions for each column of the authors table. Enter values for the prompts as shown below. Use a comma for the field terminator, and use a newline character (\n) for the field terminator on the contract column. Save this file as AUTHORS.FMT. You should see prompts similar to the following:

Enter the file storage type of field au_id [char]:
Enter prefix-length of field au_id [0]:
Enter length of field au_id [11]:
Enter field terminator [none]: ,

Enter the file storage type of field au_lname [char]:
Enter prefix-length of field au_lname [0]:
Enter length of field au_lname [40]:
Enter field terminator [none]: ,

Enter the file storage type of field au_fname [char]:
Enter prefix-length of field au_fname [0]:
Enter length of field au_fname [20]:
Enter field terminator [none]: ,

Enter the file storage type of field phone [char]:
Enter prefix-length of field phone [0]:
Enter length of field phone [12]:
Enter field terminator [none]: ,

Enter the file storage type of field address [char]:
Enter prefix-length of field address [0]:
Enter length of field address [40]: 0
Enter field terminator [none]:

Enter the file storage type of field city [char]:
Enter prefix-length of field city [0]:
Enter length of field city [20]:
Enter field terminator [none]: ,

Enter the file storage type of field state [char]:
Enter prefix-length of field state [0]:
Enter length of field state [2]:
Enter field terminator [none]: ,

Enter the file storage type of field zip [char]:
Enter prefix-length of field zip [0]:
Enter length of field zip [5]: 0
Enter field terminator [none]:

Enter the file storage type of field contract [bit]: char
Enter prefix-length of field contract [0]:
Enter length of field contract [1]:
Enter field terminator [none]: \n

Do you want to save this format information in a file? [Y/n] y
Host filename [bcp.fmt]: authors.fmt

Starting copy...

23 rows copied.
Network packet size (bytes): 4096
Clock time (ms.): total = 451   Avg = 19   (51.00 rows per sec.)

This creates the AUTHORS.FMT format file, which looks like this:

6.0
9
1

SQLCHAR
0

11

","

1

au_id

2

SQLCHAR
0

40

","

2

au_lname

3

SQLCHAR
0

20

","

3

au_fname

4

SQLCHAR
0

12

","

4

phone

5

SQLCHAR
0

0

""

5

address

6

SQLCHAR
0

20

","

6

city

7

SQLCHAR
0

2

","

7

state

8

SQLCHAR
0

0

""

8

zip

9

SQLCHAR
0

1

"\r\n"

9

contract

For an explanation of each area in the format file, see  Using the bcp Format File, earlier in this chapter.

The format file contains all the information necessary to copy the data from the input file into the SQL Server table. Note that by entering a field length of 0 and no field terminator for the address and zip fields, you have in effect told the format file that those columns do not exist in the input file. However, you still need to edit the format file to show that the au_lname and au_fname columns are reversed in the input file and that no data will be loaded into the address and zip columns of the table. To do this:

  1.
Use a text editor to reverse the server column numbers for the au_lname and au_fname columns.
    2.

  2.
Set the server column numbers for the address and zip columns to 0.
    3.

  3.
Save the modified format file under the same name (AUTHORS.FMT).
    4.

The modified format file should look like this:

6.0
9

1

SQLCHAR

0

11

","

1

au_id

2

SQLCHAR

0

40

","

3

au_lname

3

SQLCHAR

0

20

","

2

au_fname

4

SQLCHAR

0

12

","

4

phone

5

SQLCHAR

0

0

""

0

address

6

SQLCHAR

0

20

","

6

city

7

SQLCHAR

0

2

","

7

state

8

SQLCHAR

0

0

""

0

zip

9

SQLCHAR

0

1

"\r\n"

9

contract

The bcp utility can now use this new format file to copy the data in the input file into the authors table using the following command:

bcp pubs..authors in c:\new_auth.dat /fc:\authors.fmt
/Sservername /Usa /Ppassword

Note  Since the address and zip columns are not present in the input file, those columns contain NULL in the SQL Server table. Therefore, the authors table must allow null values in those columns.

Skipping Over Columns in the Data File

In this example, the data in the input file is slightly different from the first example because it contains all the necessary data for the authors table, including the address and zip fields. The following is the data in the NEW_AUTH.DAT file for this example:

777-77-7777,Chris,Smith,303 555-1213,27 College Ave,Denver,CO,80220,1
888-88-8888,John,Doe,206 555-1214,123 Maple Street,Seattle,WA,95099,0
999-99-9999,Jane,Door,406 555-1234,45 East Main,Bozeman,MT,59715,1

Assume that, although the address and zip fields are present in the input file, they will not be included in the SQL Server table. In addition, the order of the data needs to be reversed for the au_fname and au_lname columns. Perform the steps shown in the previous example to get the format file for the authors table. However, since the input file contains data for the address and zip fields, use a comma for the field terminator for each of them. The format file should look like this:

6.0
9

1

SQLCHAR

0

11

","

1

au_id

2

SQLCHAR

0

40

","

2

au_lname

3

SQLCHAR

0

20

","

3

au_fname

4

SQLCHAR

0

12

","

4

phone

5

SQLCHAR

0

0

""

5

address

6

SQLCHAR

0

20

","

6

city

7

SQLCHAR

0

2

","

7

state

8

SQLCHAR

0

0

""

8

zip

9

SQLCHAR

0

1

"\r\n"

9

contract

Edit the format file to reverse the order of the au_fname and au_lname columns. In addition, set the server column order numbers for the address and zip columns to 0. The modified format file should look like this:

6.0
9

1

SQLCHAR

0

11

","

1

au_id

2

SQLCHAR

0

40

","

3

au_lname

3

SQLCHAR

0

20

","

2

au_fname

4

SQLCHAR

0

12

","

4

phone

5

SQLCHAR

0

0

""

0

address

6

SQLCHAR

0

20

","

6

city

7

SQLCHAR

0

2

","

7

state

8

SQLCHAR

0

0

""

0

zip

9

SQLCHAR

0

1

"\r\n"

9

contract

This format file can now be used to copy in the data in the NEW_AUTH.DAT data file using the same bcp command as the previous example:

bcp pubs..authors in c:\new_auth.dat /fc:\authors.fmt
/Sservername /Usa /Ppassword

Again, since the address and zip fields will not be copied into the authors table, those columns will contain NULL in the SQL Server table.

Using a Data File with More Columns Than the SQL Server Table

In this example, the data in the input file is the same as that in the previous example, except that the input file contains two additional fields: age and salutation. Since the authors table does not have columns for this data to go into, the format file must be changed to allow bcp to read the additional fields from the input file, but not to copy the data into the SQL Server table. This is the data in the input file:

777-77-7777,Chris,Smith,303 555-1213,27 College Ave,Denver,CO,80220,1,28,Ms.
888-88-8888,John,Doe,206 555-1214,123 Maple Street,Seattle,WA,95099,0,35,Mr.
999-99-9999,Jane,Door,406 555-1234,45 East Main,Bozeman,MT,59715,1,33,Mrs.

The same format file from the end of the previous example can be used:

6.0
9

1

SQLCHAR

0

11

","

1

au_id

2

SQLCHAR

0

40

","

3

au_lname

3

SQLCHAR

0

20

","

2

au_fname

4

SQLCHAR

0

12

","

4

phone

5

SQLCHAR

0

0

","

0

address

6

SQLCHAR

0

20

","

6

city

7

SQLCHAR

0

2

","

7

state

8

SQLCHAR

0

0

","

0

zip

9

SQLCHAR

0

1

"\r\n"

9

contract

The format file must be edited to reflect the addition of the new columns. The second line of the format file, which specifies the number of columns, must be changed to 11, since there are 11 fields now in the input file. The field terminator for the contract column must be changed from "\r\n" to ",", since it is no longer the last field in the file. Finally, two new rows are added to the end of the format file to provide the information for the additional fields. The final format file should look like this:

6.0
11

1

SQLCHAR

0

11

","

1

au_id

2

SQLCHAR

0

40

","

3

au_lname

3

SQLCHAR

0

20

","

2

au_fname

4

SQLCHAR

0

12

","

4

phone

5

SQLCHAR

0

0

","

0

address

6

SQLCHAR

0

20

","

6

city

7

SQLCHAR

0

2

","

7

state

8

SQLCHAR

0

0

","

0

zip

9

SQLCHAR

0

1

","

9

contract

10

SQLCHAR

0

0

","

0

age

11

SQLCHAR

0

0

"\r\n"

0

salutation

This format file can now be used to copy in the necessary data from the input file, with bcp ignoring the last two fields in the input file, using the same bcp command as the previous examples:

bcp pubs..authors in c:\new_auth.dat /fc:\authors.fmt
/Sservername /Usa /Ppassword


Common bcp Issues

The following topics discuss issues that you can encounter when using bcp. For more information, choose one of the following topics:

Loading ASCII Files

Native Format and Improperly Defined Tables

Finding Hidden Characters in Data Files

Using Spaces for Delimiters in Data Files

Using Batch Sizes with bcp

Using Default Datatype Sizes

Copying Datetime or Smalldatetime Data

Copying Just the Date of a Datetime Field

Importing Image Data


Loading ASCII Files

Often users try to load an ASCII file in the SQL Server native format. This leads to misinterpretation of the hexadecimal values in the ASCII file. The "unexpected end of file" error message is very common in this instance. The proper way to load the ASCII file is to represent the fields as a character string and let SQL Server do the data conversion.


Native Format and Improperly Defined Tables

Using native format bcp to load data in an improperly defined table can cause the table to be loaded incorrectly. The incorrect loading might appear as an unusual formatting of data in the target table. This would also apply to client tools that use the bcp API in native mode.

Native format bcp is intended for high-speed data transfer between identically defined tables. To achieve the optimum transfer rate, few checks are performed regarding data formatting. The user must ensure the table is correctly defined or else use character format bcp.

Correct table definition includes the correct number of columns, datatype, length, and NULL status.


Finding Hidden Characters in Data Files

Often a hidden character in an ASCII data file can cause problems when trying to use bcp. This problem often results in an "unexpected null found" error message. The hidden character can usually be found at the bottom of the file. Many utilities and text editors display hidden characters. Finding and removing this character should resolve the problem.


Using Spaces for Delimiters in Data Files

Using spaces for delimiters while using bcp does not work. There are two options you can take to correct this problem:

  • Change the delimiter from a space to a nonspace character.
  • Reformat the data file to be of fixed-length columns.


Using Batch Sizes with bcp

The bulk copy program (bcp) accepts as one of its parameters:

/b batchsize

This parameter allows the user to specify the number of rows per batch for the data that will be loaded into a SQL Server table. The use of the /b parameter has a large impact on how the data insertions are logged. When the /b parameter is not used with the bcp utility, all rows from a data file are copied into SQL Server in one batch, and bcp displays the message "1000 rows sent to SQL Server" after every 1000 rows have been copied.

When nonlogged (or "fast") bcp is used, the data insertions are not logged in the transaction log. However, SQL Server still logs extent allocations each time a new extent is allocated to the table. (An extent is a block of eight 2K data pages.)

If the /b parameter is not used, SQL Server treats the entire bcp operation as a single transaction. Thus, if for any reason the bcp is aborted before it finishes, the entire transaction is rolled back, and the destination table will not contain any new rows from the bcp operation.

If the /b parameter is used, each batch of rows is logged as a separate transaction. For example, if a data file has 1000 rows, and a batch size of 100 is used, SQL Server will log the operation as 10 separate transactions. If the bcp operation were to abort while copying in row 750, only the previous 49 rows would be removed, and the destination table would still contain the first 700 rows.

When copying large data files into SQL Server with bcp, it is possible for the transaction log to fill up from the extent allocation logging before the copy is complete. In this situation, you can either enlarge the transaction log or perform the bcp copy by using the /b option and setting the database option Truncate Log on Checkpoint. Setting this option on will instruct SQL Server to truncate the log each time it performs a CHECKPOINT, so the log records for those batches that have been committed will be removed from the log. Because only committed transactions can be truncated from the log, this option will not free up space in the log if the /b option is not used (because the entire operation is logged as a single transaction).

Note When you use nonlogged bcp to import data into a SQL Server database, it is important to back up the database (by using the DUMP DATABASE command) when the bcp copy is complete.


Using Default Datatype Sizes

Using the default size can sometimes lead to the "unexpected end of file" error message. This is most common with the money and datetime datatypes.

The error occurs when only a fraction of the entire date (for example, mm/dd/yy with no time) is used instead of the entire date string. When using the default size option, SQL Server expects to read 25 characters (the length of the date type). To avoid this problem, read in data using delimiters, or create a user-defined fixed-length ASCII file for reading in data.


Copying Datetime or Smalldatetime Data

The bulk copy program (bcp) drops both seconds and milliseconds when bulk copying datetime or smalldatetime data out of SQL Server in character mode. The date is converted in the default date format:

MMM DD YYY HH:MM[AM/PM]

The bcp utility uses the default date format. When bcp is executed in character mode, both datetime and smalldatetime data are converted to the default date format. Thus, seconds and milliseconds are not displayed.

If it is critical to bcp the date datatype information out with both the seconds and milliseconds, one of the following methods can be used:

  • Native mode bcp can be used if the data is to be transferred between various SQL Servers where the tables are identical in structure.
  • Create a view, use the CONVERT() function on the date datatype to save it as a character string, then bulk copy out from the view.


Copying Just the Date of a Datetime Field

It is possible to bulk copy just the date into a datetime field. The storage size will be the same as if you had both the date and time. For a datetime column, this is 4 bytes for the number of days since January 1, 1900, and 4 bytes for the number of milliseconds after midnight on that day. If you select from SQL Server what you have input with bcp, you will see the time "12:00AM" on the end of each date, because the number of milliseconds after midnight is 0 (zero).

To display just the date portion of a DATETIME field, use the style parameter of the CONVERT() function. For example:

select convert(char(12),getdate(),3)


Importing Image Data

You can use bcp to copy a file as image data into Microsoft SQL Server. For example, to load the file TEST.DOC into a table named image run bcp as follows:

bcp pubs..image in test.doc -Usa -P -Ssvr

Answer the prompts bcp presents as follows:

Enter the file storage type of field c1 [image]:
Enter the prefix length of field c1 [4]: 0
Enter length of field c1 [4096]: 5578
Enter the field terminator [none]:

In this example, 5578 is the length of the file. The file will be loaded into column c1.


Generating SQL Scripts

SQL Scripts are descriptions of the statements that are used to create database objects. With SQL Enterprise Manager, you can generate scripts from objects in an existing database. You can then add these objects to a database by running the scripts against that database. In effect, this copies and re-creates database objects. Another reason to generate scripts is to create a record of how a database was created.

You can generate a script for an entire database or for selected objects of that database.

To generate a SQL script
  1. In the Server Manager window, select a server, open its tree (click the "" box), open its Databases folder, and select a database.
  2. From the Object menu, choose Generate SQL Scripts.

    The Generate SQL Scripts dialog box appears.

  3. To generate a script for the entire database, under Scripting Objects, choose All Objects.

    All objects in the database are added to the right-hand box at the bottom of the Generate SQL Scripts dialog box. Optionally, to exclude selected objects, select the objects, and choose Remove.

  4. To generate a script for all objects of a particular type, under Scripting Objects, select the option for that object type.

    For example, to generate a script for all tables in the database, choose the All Tables option.

    The objects are added to the right-hand box at the bottom of the Generate SQL Scripts dialog box. Optionally, to exclude selected objects, select the objects and choose Remove.

  5. To generate a script for a particular object, select the object from the list in the left-hand box at the bottom of the Generate SQL Scripts dialog box, and then choose Add.

    The object moves to the right-hand box. If you make a mistake, select the object from the right-hand box, and then choose Remove.

  6. Under Scripting Options, select the options for the script.
    Object Creation
    When selected, adds object-creation statements to the script. For example, the CREATE TABLE statement.
    Object Drop
    When selected, adds statements that drop objects before creating them. For example, the DROP TABLE statement.
    Table Indexes
    When selected, adds the statements used to create the indexes for a table. Provides the CREATE INDEX statement.
    Table Triggers
    When selected, adds statements used to create triggers for a table. Provides the CREATE TRIGGER statement.
    Table DRI
    When selected, adds statements to create declarative referential integrity statements for a table. Provides the CREATE TABLE statement with the constraint information.
  7. To include security information in the script, select the options under Security.

    Select the options for the user information to be generated with the script. You can generate statements that add all users and groups to the database, that add all logins to SQL Server of the users associated with that database, and/or that add the permissions for the database.

  8. To preview or modify the script before generating it, choose Preview.

    The Object Scripting Preview dialog box appears.

    To modify the script, edit the text in the Object Scripting Preview box, choose the Save As button, and complete the Save As dialog box that appears.

  9. To generate the script, choose Script.

    The Save As dialog box appears.

  10. Select a script file option.
    • To create one script, select Save All Scripts To A Single File. This is the default.
    • To create one script for each object, select Save Scripted Objects To Separate Files. This option is used with source control packages.
  11. Give the script a name ending in the .SQL filename extension, specify the directory, and then choose OK.

Note When a script is run, it creates the database object(s), but it does not include data to a table that it creates. Data can be added, using the INSERT statement or can be copied in from the original table by using bcp or SQL Transfer Manager. When running a script in a non-empty database, the script might not be able to drop and/or create some items correctly (for example, user-defined datatypes) if those items are being used by other database objects.


Transferring Data Between Processor Architectures

You can use SQL Transfer Manager to transfer data from a Microsoft SQL Server database on one processor architecture to a Microsoft SQL Server database on another processor architecture. You can also use character mode bcp.


Transferring Data Between SQL Server Versions

You can use bcp to transfer a native or character format file from SQL Server 4.2 into a SQL Server 6.0 table of the same definition. You can also transfer in the other direction, but if you are bulk copying a table with the new SQL Server 6.0 datatypes into a SQL Server 4.2 table, you must use character format bcp. The destination table would use only SQL Server 4.2 datatypes. Identity column values and the identity property are not transferred.

You can use SQL Transfer Manager to transfer objects and data between SQL Server version 4.2 and SQL Server version 6.0. When moving objects data from SQL Server 4.2 to SQL Server 6.0, some stored procedures or views may contain Transact-SQL statements that are no longer accepted in version 6.0, and some 4.2 object names may now be reserved words in 6.0. In these cases, the transfer will fail for these objects and will not complete correctly for objects that depend on them. For more information, see the compatibility information in the Microsoft SQL Server Transact-SQL Reference.

When using SQL Transfer Manager to transfer objects and data from SQL Server 6.0 to SQL Server 4.2, you cannot include 6.0 specific datatypes in the source objects, and 6.0-specific schema additions such as identity columns and declarative referential integrity will not be included in the transfer.

Note For a list of new SQL Server 6.0 keywords and for other information about language, statement, query, and other compatibility issues between SQL Server 6.0 and SQL Server 4.2 databases, see the compatibility information in the Microsoft SQL Server Transact-SQL Reference.


Chapter 12 Backing Up and Restoring

Backing Up and Restoring

It is important to perform regular backups of your databases and their transaction logs. If you perform regular backups, you will be able to recover from a failure (for example, from a disk failure) by restoring a database from its most recent backup. This chapter shows you how. It is divided into these sections:

  • Basic Backup and Restore Operations is a straightforward presentation of the procedures you use to perform backups, to schedule backups, to restore from those backups, and more.
  • More About Backing Up and Restoring provides a more in-depth discussion and explanation of strategies and techniques used for backing up, restoring, and recovering databases.

Before implementing your backup and restoration strategies, also review the information about database devices, dump devices, databases, transaction logs, and storage management in Part 3, Devices, Databases, and Drives.

Additional useful information can be found in Appendix E, Backup and Recovery Guidelines for Production Environments.


Basic Backup and Restore Operations

Backup and restoration are easy to set up and execute using SQL Enterprise Manager. The information in this section shows you how to back up a database or transaction log, execute a backup immediately, configure a backup for scheduled execution, customize the backup command that is executed, monitor scheduled backup tasks, and restore a database or apply a transaction log from a backup.

For more information choose one of the following topics:

Backup Overview

Before Backing Up

Backing Up a Database or Transaction Log

Executing an Immediate Backup

Scheduling a Backup

Customizing a Backup Command

Setting Backup Task Options

Monitoring, Modifying, or Canceling a Scheduled Backup

Restoring a Database or Applying a Transaction Log

Note This section describes basic operations. For more in-depth information, see More About Backing Up and Restoring, later in this chapter.


Backup Overview

To back up or dump is to create a copy of a database or transaction log on another device (a dump device). Backups are accomplished by using SQL Enterprise Manager or the DUMP statement.

To restore or load is to load a database from a backup of that database and (if applicable) one or more backups of its transaction log. A load overwrites any information in the database with the backed-up information. Loads are accomplished by using SQL Enterprise Manager or the LOAD statement.

With small databases, the transaction log is usually stored on the same database device as the rest of the database. Backing up a database backs up both the database and the transaction log. After that, you can run the DUMP TRANSACTION WITH TRUNCATE_ONLY command to remove committed transactions from the log.

In large databases, the transaction log (the log portion of the database) and the data portion of the database are usually stored on different devices. In these cases, you can back up the transaction log separately. Dumping only the transaction log uses less storage and takes less time than dumping the database, which backs up both the transaction log and the database. Dumps of the transaction log are usually coordinated with database dumps as part of an overall backup procedure.

Typically, transaction log dumps are done more frequently than database dumps. To restore a database, you load the most recent database dump and then load all the transaction log dumps (in order) made since the database dump. The database is restored to its state at the time of the last transaction log dump.

You should maintain regular backups of all databases, including:

  • The master database
  • The msdb database
  • All user databases
  • The distribution database (if the server is configured as a replication distributor)


Before Backing Up

The DBCC statement checks the logical and physical consistency of a database. Regardless of database setup, it is highly recommended that you always run the following DBCC statements just prior to backing up a database.

  • DBCC CHECKDB
  • DBCC CHECKALLOC or NEWALLOC
  • DBCC CHECKCATALOG

It is advised that no other activity be taking place while running these checks, as that can lead to incorrect or misleading results.

Because transactions can occur during or after DBCC is run but before the dump is performed, you may also want to check the database after backup to ensure that the database was consistent at the time it was dumped. If a database or transaction log that contains errors is dumped, those errors will still exist when the data is reloaded. Under some conditions, this can even prevent successful reloading.

For information about using these DBCC statements, see the description of the DBCC statement in the Microsoft SQL Server Transact-SQL Reference.


Backing Up a Database or Transaction Log

You should back up a database after you create it, and then maintain a regular backup schedule to ensure smooth recovery in case of database or media failure. SQL Enterprise Manager allows you to set and maintain a schedule of automatic backups. Scheduling can be accomplished at the same time you define a backup. You can also back up manually at any time.

If a transaction log is on a separate device from its database, you can back up the transaction log separately. You should back up a transaction log more frequently than its database.

The SQL Server dump is a dynamic dump ¾ it can take place while the database is active. The dump captures the state of the data as it is at the moment the statement is executed; no partial transactions are reflected. Any data changes made after the dump begins are not reflected in the dumped database. Performing a dump can slow the system down somewhat, so you may want to run it when the database is not being heavily updated.

You should maintain regular backups of the master database, the msdb (scheduling) database, all user databases, and (if the server is configured as a replication distributor) the distribution database.

To back up a database or a transaction log
  1. From the Server Manager window of SQL Enterprise Manager, select a server.
  2. From the Tools menu, choose Backup/Restore.

    The Database Backup/Restore dialog box appears.

  3. Select the device(s) to back up to.

    In the Dump Devices box, select a device, and then choose Add. To perform a striped dump (a multiple dump device backup), repeat this step for each dump device that will be part of the backup. The added devices move to the Backup Destination list.

    If necessary, you can create a new dump device by choosing New and completing the Create Dump Device dialog box that appears.

    The DISKDUMP device is a special device. Backing up to DISKDUMP sends the data to the NULL device, which dumps data without saving it. You can use the DISKDUMP device name as a bit bucket in conjunction with database or transaction log backups.

    Important You cannot retrieve dumps sent to the NULL (DISKDUMP) device.

    You cannot back up to diskette dump devices when using SQL Enterprise Manager. For information about backing up to diskette dump devices, see the Microsoft SQL Server Transact-SQL Reference. For information about dump devices, see Chapter 5, Managing Devices.

  4. To add a volume name for a device, type up to six characters (letters or numbers) in the Volume box of the Backup Destination list.

    In general, you do not need to provide volume names for dumps. You may provide one if this is the first dump on a device or if Append is not selected. The volume name is in effect for all subsequent dumps appended to the device. Entering a name is optional for subsequent dumps, but if specified it must match the initial volume.

    To view volume and header information for a disk or tape dump device, select the device from the Dump Devices list and then choose the Info button.

  5. From Database list, select the database to back up.
  6. Select either Entire Database or Transaction Log.
    • Entire Database backs up the database and its transaction log.
    • Transaction Log backs up only the transaction log.

      To use this option, the transaction log must be on a separate device from the database. For more information about setting this up, see Chapter 6, Managing Databases.

  7. Select or clear the backup options.
    • Append to Device retains any backups currently on the dump device, and adds the new backup. To overwrite any existing backups on the device with the new backup, clear this option.

      For SQL Server Version 6.0, backups can be appended to any disk or tape dump device, allowing you to keep backups of a database and its transaction logs in one physical location.

      If you are using a tape that contains data in a foreign format (not SQL Server backup files), you must clear this option, or the tape will be rejected.

    • Skip Tape Header specifies that the server will not read the ANSI header on a tape. To tell SQL Server to read any existing ANSI tape labels on the tape(s) you are writing, clear this option.

      For example, if the ANSI label of a tape warns that it has not expired or that you don't have permission to write to it, selecting this option causes SQL Server to ignore the warning. Or if the tape you are writing to is new (and therefore has no ANSI label), SQL Server writes a new label on the first try. Selecting this option prevents unnecessary retries as SQL Server tries to find a label.

      This allows you to choose between the security of paying attention to ANSI labels or the convenience of ignoring them. In either case, SQL Server still writes the labels.

      Setting this option for a particular backup overrides the setting defined for the tape dump device when it was created.

    • Unload Tape at End automatically rewinds and unloads the tape when a backup to a tape device completes.

      If you will be performing multiple dumps to a single tape, clear this option. If this is a single backup or the last backup of several to a tape, select this option.

    • Expires on sets the backup to expire on a specific date. If you select this option, you must also set the expiration date in the adjacent box.

      An existing dump cannot be overwritten until it expires. However, when Append to Device is selected, this option is informational only.

    • Expires after sets the backup to expire after an elapsed number of days. If you select this option, you must also type the number of days in the adjacent box.

      An existing dump cannot be overwritten until it expires. However, when Append to Device is selected, this option is informational only.

    • No expiration date specifies that the backup has no expiration date and can be overwritten at any time. This is the default.
  8. Either execute the backup or schedule it for execution.
    • To immediately execute the backup, choose the Backup Now button. For more information, see Executing an Immediate Backup, next.
    • To set up scheduled execution, choose the Schedule button and complete the Schedule Backup dialog box that appears. For more information see Scheduling a Backup, later in this chapter.

You cannot back up a transaction log separately after enabling the Select Into / Bulk Copy database option and making unlogged changes to the database with SELECT INTO or a bulk copy operation. Under these conditions, do a database backup instead.

For more information about backing up databases, see More About Backing Up and Restoring, later in this chapter. You can also back up a database or transaction log using the DUMP statement. For information, see the Microsoft SQL Server Transact-SQL Reference.


Executing an Immediate Backup

You can perform a backup as soon as you define it in the Database Backup/Restore window. There are two ways to execute an immediate backup:

  • As a foreground task that occupies SQL Enterprise Manager until the backup completes.
  • As a background task that allows SQL Enterprise Manager to remain available to you.
To execute a backup immediately, as a foreground task
  1. Define the backup as described in Backing Up a Database or Transaction Log, earlier in this chapter.
  2. From the Database Backup/Restore window, choose the Backup Now button.

    The backup executes. The cursor hourglass is displayed, and SQL Enterprise Manager is unavailable until the backup completes.

To execute a backup immediately, as a background task
  1. Define the backup as described in Backing Up a Database or Transaction Log, earlier in this chapter.
  2. From the Database Backup/Restore window, choose the Schedule button.

    The Schedule Backup dialog box appears.

  3. Select the option for Immediately.
  4. Choose the OK button.

    The backup executes, the Database Backup/Restore window returns, and SQL Enterprise Manager is immediately available.


Scheduling a Backup

To ensure that your databases and logs are regularly backed up, you can use SQL Enterprise Manager to schedule backups. Scheduled backups can be set to occur one time or on a recurring basis. Recurring backups can be set to occur hourly, daily, weekly, or monthly.

To schedule a backup
  1. Define the backup as described in Backing Up a Database or Transaction Log, earlier in this chapter.
  2. From the Database Backup/Restore window, choose the Schedule button.

    The Schedule Backup dialog box appears.

  3. If appropriate, change the task name and/or the SQL command.
    • The task name is generated automatically by SQL Enterprise Manager. The name defaults to Backup ¾ databasename. You can change it to another unique name.
    • The SQL command is the Transact-SQL text of the backup command. You can modify the command by typing valid DUMP statement syntax. For more information, see Customizing a Backup Command, later in this chapter.
  4. Set the schedule.
    • To execute the backup immediately, choose Immediately. (The backup will run when you choose the OK button.)
    • To schedule the backup to run once, choose One Time, set a date in the On Date box, and set a time in the At Time box.
    • To schedule the backup to run at regular intervals, select recurring, choose the Change button, and complete the Task Schedule dialog box that appears. For more information, see the procedure that follows.
  5. Choose OK.
    • If the option is set for Immediately, the backup executes.
    • If the option is set for One Time or Recurring, the scheduled backup task is created.
To set a recurring backup schedule
  1. Open the Schedule Backup dialog box as described in the previous procedure, select the Recurring option, and choose the Change button.

    The Task Schedule dialog box appears.

  2. Set a frequency.
    • Daily

      If you select the Daily option, then the Daily frame appears in the dialog box. Enter the number of days in the recurrence cycle. The default is Every 1 Day(s), indicating that the recurring task will be executed each day.

      For example, if you enter 3, the recurring task is executed every third day.

    • Weekly

      If you select the Weekly option, then the Weekly frame appears in the dialog box. Enter the number of weeks in the recurrence cycle, and select the day(s). The default is Every 1 Week(s), on Sunday.

      For example, if you enter 2 and select Friday, the backup is run on Friday of every second week.

    • Monthly

      If you select the Monthly option, then the Monthly frame appears in the dialog box. Complete the choices in this frame.

      For example, if you enter Day 1 of Every 1 Month(s), the backup is run on the first day of every month.

  3. Under Daily Frequency, specify the frequency with which the task will occur.

    On days that the backup runs, the time(s) it runs will run based on this setting. This can be either once a day at a specified time, or repeated at a specified interval within a specified range of hours.

  4. Under Duration, set a start date and an end date.
    • Start Date is the first day on which the backup will be run.
    • End Date is the last day on which the backup will be run. (This option does not apply if No End Date is selected.)
    • No End Date sets an unlimited duration.
  5. Choose OK.

    The recurring schedule is set. The Schedule Backup dialog box returns.

You can also schedule a backup from the Task Scheduling window. For more information, see Chapter 16, Scheduling Tasks. Also see Monitoring, Managing or Canceling a Scheduled Backup, later in this chapter.


Customizing a Backup Command

You can customize the backup command (the DUMP statement) that is built by SQL Enterprise Manager when you define a backup in the Database Backup/Restore window. To do this, you open the Schedule Backup dialog box.

To customize the backup command
  1. Define the backup as described in Backing Up a Database or Transaction Log, earlier in this chapter.
  2. From the Database Backup/Restore window, choose the Schedule button.

    The Schedule Backup dialog box appears.

  3. As appropriate, change the text of the DUMP statement in the SQL Command box.

    For information about the syntax that can be used in the SQL Command box, see the discussion of the Dump Statement in the Microsoft SQL Server Transact-SQL Reference.

  4. Choose OK.

You modify the text in the SQL Command box by typing valid DUMP statement syntax. For example, if you are backing up the transaction log of the inventory database to the TAPE03 device, SQL Enterprise could have built this command for you:

DUMP TRANSACTION inventory TO tape03 WITH UNLOAD, NOINIT, SKIP

If you need to truncate the log (remove the inactive part of the log without making a backup copy of it), you could change the command to this:

DUMP TRANSACTION inventory WITH TRUNCATE_ONLY

For more information about truncating logs, see More About Backing Up and Restoring, later in this chapter.


Setting Backup Task Options

Scheduling a backup creates a backup task. While scheduling the backup, you can set task options that will:

  • Send an e-mail notification to an operator when the backup fails or succeeds.
  • Write an entry to the Windows NT Application log when the backup fails or succeeds.
  • Specify the number of retry attempts when a backup fails, and the delay between each retry.
To set the backup task options
  1. Define the backup as described in Backing Up a Database or Transaction Log, earlier in this chapter.
  2. From the Database Backup/Restore window, choose the Schedule button.

    The Schedule Backup dialog box appears.

  3. Choose the Options button.

    The Task Options dialog box appears.

  4. To notify an operator by e-mail of the status of the backup task execution, select a name from the list in the Operator box, and then select the e-mail On Success and/or On Failure check boxes.

    If necessary, you can add a new operator by selecting <New Operator> in the Operator box and completing the New Operator dialog box that appears. For information about creating new operators, see Chapter 17, Managing Alerts.

  5. To record information in the Windows NT Event log about the backup task execution, select the NT Event Log On Success and/or the On Failure check boxes.
  6. To specify the number of retry attempts for a failed task, type a number between 0 and 256 in the Retry Attempts box, and another number¾representing the number of minutes to wait before retrying a failed task¾in the Retry Delay box.

    The default for both values is 0.

  7. Choose OK.

    The options are set.


Monitoring, Modifying, or Canceling a Scheduled Backup

You can schedule a backup for one-time or recurring execution at the time you define it in the Database Backup/Restore window. SQL Enterprise Manager then creates a scheduled backup task.

However, once you do this, the scheduled backup cannot be monitored, modified, or canceled from the Database Backup/Restore window. You must use the Task Scheduling window.

When using the Task scheduling window, be aware that all tasks defined on the server ¾ not just backup tasks ¾ are displayed. By default, the name of a backup task is generated by SQL Enterprise Manager using the form
BACKUP - databasename. However, this name could have been changed from the default by the user who scheduled the backup. Also, a backup task has a type of TSQL, which indicates that the task is a scheduled execution of a Transact-SQL statement.

To open the Task Scheduling window
  1. From the Server Manager window, select a server.
  2. Under the selected server, double-click the Executive icon.

    Or from the toolbar, choose the Task Scheduling button.

    The Task Scheduling window appears.

From the Task Scheduling window you can view a list of all scheduled tasks, plus a list of tasks that are currently running. Note that all scheduled or running tasks defined on that server are displayed (not just the backup tasks).

To display a list of tasks
  1. To view a list of tasks defined for the server, select the Task List tab.

  2. To view a list of the tasks that are currently running or are waiting for execution, choose the Running Tasks tab.

  3. To update either tab with current information, choose the Refresh button.

For a selected task, you can view the task history, which provides information about the last run date of a task, the time and duration of the last run, the status of that run, and whether a user was sent e-mail by SQL Executive as a result of the task running. You can also view any messages sent by SQL Executive.

To view the history of a backup task
  1. From the Task Scheduling window, select the backup task.
  2. From the Task Scheduling toolbar, choose the Task History button.

    The Task History dialog box appears.

If appropriate, you can edit a scheduled backup task. You can change the task name, the task type, the database the task is run against, the command that is run, the task schedule, and the task options. You can suspend a scheduled backup task without canceling the task, or you can reenable a suspended task.

To modify a backup task
  1. From the Task List of the Task Scheduling window, select the backup task.
  2. From the Task Scheduling toolbar, choose the Edit Task button.

    The Edit Task dialog box appears.

  3. To suspend the task, clear the Enabled check box. Or to reenable a suspended task, select the Enabled check box.
  4. To rename the task, edit the text in the Name box.
  5. To change the task type, select the new type from the Type box.

    Backup tasks use a type of TSQL.

  6. To change the database the task is run against, select the new database from the Database box.
  7. To change the SQL command that is executed by the scheduled task, in the SQL Command box, edit the text of the DUMP statement.

    For information about the syntax that can be used in the SQL Command box, see the discussion of the Dump Statement in the Microsoft SQL Server Transact-SQL Reference.

  8. To change the backup schedule, select the appropriate options in the Schedule frame. To change a recurring schedule, choose the Change button, and complete the Task Schedule dialog box that appears.

    For information about completing this dialog box, see Scheduling a Backup.

  9. To change the backup task options, choose the Options button, and complete the Task Options dialog box that appears.

    For information about completing this dialog box, see Setting Backup Task Options.

  10. Choose Modify.

If appropriate, you can immediately run a scheduled backup task.

To immediately run a backup task
  1. From the Task List of the Task Scheduling window, select the backup task.
  2. From the Task Scheduling toolbar, choose the Run Task button.

If you no longer need to back up a database or a transaction log on a scheduled basis, you can cancel the scheduled backup.

To cancel a backup task
  1. From the Task List of the Task Scheduling window, select the backup task.
  2. From the Task Scheduling toolbar, choose the Delete Task button.

    A confirmation dialog box appears.

  3. Choose Yes.

    The task is deleted.

For more information about monitoring and managing scheduled tasks, see Chapter 16, Scheduling Tasks.


Restoring a Database or Applying a Transaction Log

If the device that a database resides on fails and the database is damaged, you can restore the database by reloading the most recent database backup and the succeeding transaction log backups. Or if you find that you have some corrupt data on the database, you can reload a database backup over the old database.

When a database is restored from a backup, that database must not be in use. Any data in the specified database is replaced by the loaded data.

If you are reloading a database because of media failure, you must drop the damaged database by using DBCC or the sp_dbremove system stored procedure, re-create the database, and then restore the database from a backup.

Loading a transaction log results in re-execution of the changes it contains and in rolling back any transactions that were uncommitted when the transaction log was backed up.

Backups of the transaction log must be loaded in the sequence in which they were made. SQL Server checks the time stamps on each dumped database and each dumped transaction log to see that the sequence is correct. When the entire sequence of transaction log dumps has been loaded, the database is restored to its state at the time of the last transaction log dump (minus active transactions). This recovers as much of a database as possible in case of system failure.

Note Restoring the master database is a special case. For information, see Restoring the master Database, later in this chapter.

You can also dump a database and load that dump into another database. However, the new database must be at least as large as the dumped database that is being loaded. (Segment mappings must also be the same. For more information, see More About Backing Up and Restoring, later in this chapter.)

Note If the msdb database is to be restored from a backup, the SQLExecutive service must be stopped before the restore begins and then restarted after the restore is complete. If this is not done, then SQL Executive will not function properly.

To restore a database or apply a transaction log
  1. From the Server Manager window, select a server.
  2. From the Tools menu, choose Backup/Restore.

    The Database Backup/Restore dialog box appears.

  3. Select the Restore tab.

  4. To display information about the backups that exist on a dump device, select the device's "" box.

    A list of backups on that dump device appears. This information includes the number of the backup, the database name, the date the backup was created, and the size of the backup. An icon indicates whether the backup was of a transaction log or was a complete database dump.

  5. For volume or header information about the backups on a disk or tape dump device, select the device from the Dump Devices list, and choose the Info button.

    The Header Info Dialog box appears. For information about this dialog box, see Viewing Volume and Header Information, later in this chapter.

  6. To select the device that will be restored from, select a device from the Dump Devices list, and then choose Add. The added device moves to the Restore Locations list.

    Repeat this step for each device to restore from. If you have dumped the information to one or more disk devices, you must restore the information from all those devices. If a dump was made entirely to tape dump devices, you can restore from fewer tape dump devices than were originally dumped to, as long as all tapes from that dump are provided.

    If necessary, you can add a dump device (for example, to restore from a network path) by choosing New and completing the Create Dump Device dialog box that appears.

    You cannot restore from diskette dump devices when using SQL Enterprise Manager. For information about restoring from diskette dump devices, see the Microsoft SQL Server Transact-SQL Reference. For more information about dump devices, see Chapter 5, Managing Devices.

  7. To specify a volume name for a device, type up to six characters (letters or numbers) in the Volume box of the Backup Destination list. A volume name is optional, but if you enter one, it must match the volume name on the device.

    To determine the volume name, select the device from the Dump Devices list and then choose the Info button.

  8. From the Database list, select the database to restore.
  9. Select either Load Database or Apply Transaction Log.
    • Load Database restores the entire database.
    • Apply Transaction Log restores the transaction log information, reexecutes the changes it contains, and rolls back any transactions that were uncommitted when the transaction log was backed up.
  10. Select or clear the restore options.
    • Skip Tape Header specifies that the server will not read the ANSI header on the tape.
    • Unload Tape at End automatically rewinds and unloads the tape when a restore from a tape device completes.
    • File Number specifies the file number of the dump to restore for dumps containing multiple files.
  11. Choose the Restore button.

You can also restore a database or apply a transaction log by using the LOAD statement. For information, see the Microsoft SQL Server Transact-SQL Reference.

Note If you have loaded a dump into a new database that was created using the FOR LOAD option, after completing the load(s) you must clear the database option DBO Use Only by using SQL Enterprise Manager or sp_dboption. Until you do this, users other than DBO may not access the database.

For more information about restoring databases, see More About Backing Up and Restoring, later in this chapter.


More About Backing Up and Restoring

The information earlier in this chapter provided a straightforward look at the procedures you use to perform backups, to schedule backups, to restore from those backups, and so on. The information that follows offers you a more in-depth discussion and explanation of strategies and techniques used for backing up, restoring, and recovering databases and why you do so.

For more information, choose one of the following topics:

About Automatic Recovery

About Transaction Logs

About CHECKPOINT

About Dumps

About Loads

How to Recover from Media Failure


About Automatic Recovery

Microsoft SQL Server provides two different types of recovery:

  • Automatic recovery occurs every time SQL Server is restarted. This type of recovery protects your database in the event of system failures.
  • User-initiated means you back up the database and its log at regular intervals and then restore the database and its log when necessary. (You can perform the backups, or scheduled them to occur on a one-time or recurring basis.)

    Regular backups provide the means of recovering data in case of media failure (as do the disk storage methods¾for example, hardware-based RAID or Windows NT-based mirroring¾discussed in Chapter 7, Managing Drives.)

Whenever SQL Server is restarted, recovery is performed automatically on each database. This does the following:

  • Rolls back uncommitted transactions¾those that were ongoing at the time SQL Server was shut down or when the system failed.
  • Checks the transactions that had been committed between the last checkpoint and the failure, and rolls them forward.

    (In each database, the automatic recovery mechanism looks at the transaction log. If the log has committed transactions not yet written out to the database, it performs those transactions again. This action is known as rolling forward.)

Automatic recovery begins with the master database, goes on to model, clears out the tempdb temporary database, recovers msdb, recovers pubs, recovers distribution (if the server is configured as a replication distributor), and, finally, recovers user databases. Users can log in to SQL Server as soon as the system databases have been recovered, but they cannot access a user database while recovery is in progress on it.

Two configuration options are relevant to automatic recovery:

  • The recovery flags option, which determines what information SQL Server displays during recovery.
  • The recovery interval option, which controls the maximum time required to recover a database by setting the interval at which SQL Server decides whether to run an automatic checkpoint.

These two options are set by using SQL Enterprise Manager or sp_configure. For more information, see Chapter 3, Configuring Servers.


About Transaction Logs

Transaction logs are areas reserved by SQL Server to record changes that are made to a database. Each database has its own transaction log. Every change made to a database is automatically recorded in its transaction log.

Transaction logs are used by SQL Server during automatic recovery. They should not be queried with Transact-SQL statements.

The transaction log records data modification requests (INSERT, UPDATE, or DELETE statements) as they are executed. When a transaction begins, a begin transaction event is recorded in the log. This event is used during automatic recovery to determine the starting point of a transaction.

As each data modification statement is received, it is recorded in the log. The change is always recorded in the log before that change is made in the database itself. This type of log is called a write-ahead log.

The transaction log is shared by all users of the database. Multiple changes are frequently recorded each time a log page is written to the database device. This greatly improves I/O efficiency.

Caution A database's transaction log is contained in its syslogs system table. Do not try to access the syslogs table. It is for the internal use of SQL Server only.


About CHECKPOINT

The checkpoint mechanism is an automatic means for guaranteeing that completed transactions are regularly written from SQL Server's own disk cache to the database device. A checkpoint writes all dirty pages¾cached pages that have been modified since the last checkpoint¾to the database device.

There are two types of checkpoints:

  • Checkpoints that are executed automatically by SQL Server.
  • Checkpoints that are forced by database owners or the SA with the CHECKPOINT statement.

Forcing dirty pages onto the database device means that all completed transactions are written out. By calling all completed transactions to be written out, the checkpoint shortens the time it takes to recover, since the database pages are current and there are no transactions that need to be rolled forward. A typical checkpoint takes only a second or two.

The automatic checkpoint interval is calculated by SQL Server on the basis of system activity and the recovery interval configuration option, which specifies the maximum acceptable recovery time. The checkpoint (actually, the CHECKPOINT process) also performs a few other tasks, including truncating the log if the database option has been set.

Database owners can force a checkpoint at any time by executing the CHECKPOINT statement. Permission to execute the CHECKPOINT statement defaults to the database owner and cannot be transferred to other users.

The CHECKPOINT statement applies to the current database. Like the automatic checkpoint, it forces all dirty pages in the database to be written to disk. The CHECKPOINT statement is used in the following ways:

  • As a precautionary measure in special circumstances¾for example, just before a planned restart so that the SQL Server recovery mechanisms won't have anything to recover.
  • To cause a change in database options to take effect after the database options have been reset.
  • To make a ROLLBACK TRANSACTION statement take effect when canceling a user-defined transaction in which a database option was changed.

For more information about CHECKPOINT, see the Microsoft SQL Server Transact-SQL Reference.


About Dumps

A backup is also referred to as a dump. Backing up a database creates a copy of its tables, data, and user-defined objects. In case of media failure, you can recover your databases if you have been making regular backups of your databases and their transaction logs.

The basic operations used to back up a database were presented in Basic Backup and Restore Operations, earlier in this chapter. The following topics provided additional information about backing up.

For more information choose one of the following topics:

DUMP Statement Summary

About Database Dumps

About Transaction Log Dumps

When to Back Up

Interactions Between Database and Transaction Log Dumps

Causes of the Transaction Log Filling Up

Backing Up the master Database

Backing Up the msdb Database

Backing Up the distribution Database

About Disk Dump Devices

About Tape Dump Devices

About Diskette Dump Devices

Backing Up to a Novell File Server


DUMP Statement Summary

You can dump a database or a transaction log by using either SQL Enterprise Manager or the DUMP statement. However, some operations can only be performed using the DUMP statement. Following is a summary of that statement.

Syntax

Dumping a database:

DUMP DATABASE {dbname | @dbname_var}
TO dump_device [, dump_device2 [..., dump_device32]]
[WITH options
[[,] STATS [ = percentage]]]

Dumping a transaction log:

DUMP TRANSACTION {dbname | @dbname_var}
TO dump_device [, dump_device2 [..., dump_device32]]
[WITH {TRUNCATE_ONLY | NO_LOG | NO_TRUNCATE}
{options}]

where

dump_device =
{ dump_device_name | @dump_device_namevar}
| {DISK | TAPE | FLOPPY | PIPE} =
{'temp_dump_device' | @temp_dump_device_var}}
[VOLUME = {volid | @volid_var}]
options =
[[,] {UNLOAD | NOUNLOAD}]
[[,] {INIT | NOINIT}]
[[,] {SKIP | NOSKIP}]
[[,] {{EXPIREDATE = {date | @date_var}}
| {RETAINDAYS = {days | @days_var}}]

For more information about the DUMP statement, including explanations of each parameter and option, see the discussion of the DUMP Statement in the Microsoft SQL Server Transact-SQL Reference.


About Database Dumps

You should back up a database immediately after you create it. After that, you should continue to back it up on a regular schedule.

Databases and transaction logs are backed up onto dump devices. A dump device can be a disk file or a tape drive (or for compatibility with earlier releases a diskette). You can back up a database to one device or multiple devices. You can back up multiple databases or transaction logs to a common device or separate devices.

You should maintain regular backups of all databases, including:

  • The master database
  • The msdb database
  • All user databases
  • The distribution database (if the server is configured as a replication distributor)

If you store the transaction log on a different disk device from its database, you should back the transaction log up more frequently to record changes made since the last database backup. For example, you might back up a heavily used database once a week but back up its transaction log daily (thus capturing changes made since the last database dump). For information about backing up the transaction log, see About Transaction Log Dumps, later in this chapter.

In case of media failure, you can recover your databases if you have been making regular backups (dumps) of your databases and their transaction logs. This depends completely on the regular use of database and transaction log dumps.

Backup responsibility is usually assigned to either the SA or database owner. However, permission to dump a database or a transaction log can be transferred by the database owner to other users. In any case, the user responsible should set up a regular backup schedule. (SQL Enterprise Manager provides a scheduling interface that allows you to automate this.)

There is no best schedule for backing up databases and transaction logs, but the frequency of your backups determines the largest amount of work that could be lost if a media failure should occur. For an installation with large and active databases, daily backups of the transaction log and weekly backups of the database are typical.

You can back up a database or a transaction log while the database is active. This type of backup is known as a dynamic dump. The dynamic dump makes backups convenient and continuous operation possible. However, because the dynamic dump slows SQL Server somewhat, it is best to execute it when the database is not being heavily updated.

The DUMP DATABASE statement executes a checkpoint internally. This forces all completed transactions to be written out. It then makes an exact image of the database, capturing it as it was when the DUMP statement was executed.

However, transactions that aren't committed at the start of the dump don't appear in the database should it be subsequently loaded. Any changes made after the dump begins are not reflected in the image. Only pages that are used are backed up. This includes both data and log pages.

Note The files created by a backup can only be used by a load. To copy data for use by applications other than SQL Server, use bcp, SQL Transfer Manager, or a similar utility, not the DUMP statement.

While the dump is in progress, a change to a data or index page that has already been backed up takes place immediately and does not change the dumped image. If an update is requested on a page that has not yet been backed up, the system immediately dumps that page and then makes the change. In other words, when users write a page during a dump, they must wait for the dump to write the page first.

Note It is highly recommended that you always run DBCC CHECKDB, DBCC CHECKALLOC or NEWALLOC, and DBCC CHECKCATALOG on a database either just before or just after dumping it. For information see Before Backing Up, earlier in this chapter.

Each server is installed with a specified character set and sort order. When you dump a database, the backup has the same character set and sort order as the server. You cannot load a database with one character set and sort order onto a server that has a different character set and sort order. For more information about character sets and sort orders, see Microsoft SQL Server Setup. For information about changing a character set or sort order, see Chapter 3, Configuring Servers.


About Transaction Log Dumps

The SA is responsible for maintaining the transaction log, which includes these steps:

  • Placing the transaction log onto a separate database device from its database. (This is recommended for all user databases.)
  • Monitoring the transaction log with the sp_spaceused and sp_helpdb system procedures, or the DBCC SQLPERF(LOGSPACE) statement.
  • Keeping the transaction log at a reasonable size (when the log is in a separate database device) by regularly using the DUMP TRANSACTION statement.

A transaction log can be backed up separately from the database if it is stored on a separate database device. If it is, then it is important to back up the transaction log frequently. A transaction log dump, like a database dump, can take place while the database is active.

Typically, transaction logs are backed up more often than databases. A transaction log might be backed up once a day, and a database might be backed up once a week. Backing up a transaction log takes less time and uses less storage space than backing up a database. (Do not back up a transaction log unless the database has already been backed up at least once.)

It takes longer to recover a database when you restore the database and all transaction logs sequentially than it does when you restore only the database. Finding the correct strategy depends on your environment. The time required to perform backups must be considered in relation to the time required to restore. (Of course, you will back up more often than you will restore.)

You back up a transaction log by using either SQL Enterprise Manager or the DUMP TRANSACTION statement. The DUMP TRANSACTION statement has several options, including these:

TRUNCATE_ONLY
Removes the inactive part of the log without making a backup copy of it. This frees space used by the transaction log. Use this option only if you do not want to keep transaction logs for recovery.

The DUMP DATABASE statement backs up the log but does not remove the inactive portion of it. If you use TRUNCATE_ONLY and do not have a backup created by DUMP DATABASE, the changes that had been recorded in the log cannot be recovered. In addition, future transaction log dumps cannot be used for recovery until a DUMP DATABASE statement is issued.

Since the TRUNCATE_ONLY option does not perform a dump, you can use any or no dump device name.

You cannot use both TRUNCATE_ONLY and NO_LOG in the same statement.

NO_LOG
Used when you have run out of space in the transaction log and you cannot execute DUMP TRANSACTION WITH TRUNCATE_ONLY to retrieve some space from the log. Like TRUNCATE_ONLY, NO_LOG removes the inactive part of the log without making a backup copy of it. In addition, NO_LOG saves space by not recording this procedure in the transaction log.

After the transaction log has been dumped using NO_LOG, the changes that had been recorded in the log cannot be recovered. You should immediately execute DUMP DATABASE.

You cannot use both TRUNCATE_ONLY and NO_LOG in the same statement.

NO_TRUNCATE
Saves the complete log (everything that has happened since the last DUMP TRANSACTION) even if the database is inaccessible. Unlike the TRUNCATE_ONLY and NO_LOG options, the NO_TRUNCATE option does not purge the log of committed transactions.

If the database and the log are on separate devices, and if you lose the database device, at that point you can still dump the current contents of the log. After the failure condition is resolved (for example, after hardware is repaired) this allows you to recover up to the exact time of the failure

If you always dump the database (which backs up the database and the transaction log) and never dump the transaction log, the transaction log will never be cleared out and may run out of space. You can clear the log by using DUMP TRANSACTION and the WITH TRUNCATE_ONLY clause immediately after you dump the database.

Two database options, Select Into/Bulk Copy and Truncate Log on Checkpoint, affect transaction log dumps. By default, these options are set off in newly created databases (although the Truncate Log On Checkpoint option is set on for the master and msdb databases).

If Truncate Log On Checkpoint is set on, you are not allowed to dump the log because changes are not recoverable. You can dump the log when Select Into/Bulk Copy is set on, provided that you have not performed any nonlogged operations (SELECT INTO or fast bulk copy). If nonlogged operations have taken place since the last database dump, or if Truncate Log On Checkpoint is set on, the DUMP TRANSACTION statement produces an error message instructing you to use DUMP DATABASE instead. You will also get an error message if you use DUMP TRANSACTION but the transaction log is not on a separate device. For information about setting database options, see Chapter 6, Managing Databases.

You can use a DBCC statement, DBCC SQLPERF(LOGSPACE), to check the space in your transaction log. In addition, you can use this DBCC statement in conjunction with the Windows NT Performance Monitor to set an alert for when the transaction log is full. For more information about setting an alert from the Windows NT Performance Monitor, see your Windows NT documentation.

Truncating the Transaction Log

Truncating a transaction log removes the inactive portion of the log. You usually truncate a transaction log after you have backed up an entire database (because using DUMP DATABASE backs up the database and the transaction log but does not remove the inactive portion of the transaction log).

The following options can be used to keep transaction logs as small as possible. All three truncate the log without making a backup copy.

  • The DUMP TRANSACTION statement with the WITH TRUNCATE_ONLY clause
  • The DUMP TRANSACTION statement with the WITH NO_LOG clause
  • Setting the database option for Truncate Log On Checkpoint

    This is set by using SQL Enterprise Manager or sp_dboption, and it means that you can recover the database only as it was at the last database backup. It is usually better to have a background task regularly back up the transaction log.

Caution After the transaction log has been dumped by using the WITH TRUNCATE_ONLY or WITH NO_LOG clause, the changes that had been recorded in the log cannot be recovered. You should use the DUMP DATABASE statement after dumping a transaction log with these options. If the log has been dumped by using WITH NO_LOG, you should immediately execute DUMP DATABASE.

You can use the null device name DISKDUMP with either of the DUMP TRANSACTION statements. However, since the data is written to the null device, you cannot recover the transaction log dumps.


When to Back Up

You should back up databases and transaction logs frequently, and you should save the backups.

The frequency of your backups and the amount of time that you should save them depend on your database application. As an example, the following is a typical schedule:

When to perform the backup | What to back up | Minimum time to keep backup
Every day | Transaction log | Two weeks
Every week | Database and transaction log | Two months

In addition to routine backups, it is important to back up a database:

  • After initially creating the database.
  • After performing a nonlogged operation.
  • After creating an index.

The reasons for backing up a database during these times are summarized in the following sections.

After Creating a Database and Regularly Thereafter

Each database should be backed up just after it is created, and on a fixed schedule thereafter. For example, if you create a database on Monday and wait until Friday afternoon to back it up, you risk losing a whole week's work if there is a media failure on Friday at noon.

Transaction log backups made between the creation of the database and before the first database backup cannot be used, since you must load the transaction log after you load the database.

After Performing a Nonlogged Operation

In addition to backing up each database on a fixed schedule, you must back up a database any time you perform an operation that is not logged. For example, back up a database:

  • Every time you are forced to execute DUMP TRANSACTION WITH NO_LOG or WITH TRUNCATE_ONLY (because you have run out of disk space for the transaction log).
  • Every time you use non-logged WRITETEXT or UPDATETEXT, or SELECT INTO on a permanent table, and fast bulk copy (because SQL Server does not log the data insertions made by these statements, there would be no way to recover them in case of media failure).

After Creating an Index

You should back up the database each time you create an index. The pages that are written when a new index is created are not recorded in the log; instead, SQL Server relies on LOAD TRANSACTION to re-create the index in case of media failure. This does not mean that CREATE INDEX is unrecoverable but that SQL Server takes just as long to recover the index as to create it in the first place. Since you use LOAD TRANSACTION after a media failure, it is better to have backed up the database so that you do not have to wait for the index to be rebuilt.


Interactions Between Database and Transaction Log Dumps

You should not back up a transaction log unless at least one previous backup of the database has been made. The following illustration shows the interaction between backups of a database and backups of its transaction log.

Based on this illustration, if a media failure occurs at 5:01 p.m. on Tuesday, all you would need to do (assuming that the media failure was not due to a hardware problem) is load dump 5, which is a database dump that was made at 5:00 p.m. The only work lost would be whatever had been done in the minute between the database backup and the media failure.

If the media failure occurred at 4 p.m. on Tuesday, you would need to load dump 1, the database dump that was made at 5 p.m. on Friday. Then you would need to load dumps 2, 3, and 4 (the transaction log dumps made since the last complete database backup).

After all the transaction log dumps are loaded, the system is in the exact state it was in on Tuesday at 10 a.m., resulting in the loss of Tuesday's work, showing the need for frequent transaction log dumps.

In this example, the DUMP TRANSACTION statement and the WITH NO_TRUNCATE clause could have been used. In this case, successfully using the WITH NO_TRUNCATE clause is based on the assumption that the transaction log is on a separate physical drive from the database affected by the media failure. Recovery from a media failure that occurred at 4:00 p.m. on Tuesday could be done that would avoid loss of Tuesday's work.

To do this, you would load the database dump that was made at 5 p.m. on Friday and then load dumps 2, 3, 4, and the last transaction log dump made with the WITH NO_TRUNCATE clause.


Causes of the Transaction Log Filling Up

The SQL Server transaction log can become full, preventing further update, delete, or insert activity in the database, including checkpoint. This is usually seen as error 1105:

Can't allocate space for object syslogs in database dbname because the logsegment is full. If you ran out of space in syslogs, dump the transaction log. Otherwise use ALTER DATABASE or sp_extendsegment to increase the size of the segment.

This can happen on any database, including master or tempdb.

The space requirements for logging can be considerable. For example, in most cases the before and after images of each updated data row must be recorded, plus that of any affected index rows. Since a certain fixed amount of transaction record overhead must be recorded for each logged row, the ratio of updated data to log space consumption will vary depending on the row width. For a narrow row, the amount of log space consumed for a particular update, delete, or insert could be ten times the data space consumed. For wider rows, the amount of log space consumed will be proportionately less. Log space consumption is an unavoidable consequence of providing transactional integrity. The administrator must provide sufficient log space for the particular installation.

The amount of log space required can vary depending on many factors and is very difficult to accurately predict beforehand. While general rule-of-thumb figures, such as 10 to 25 percent of the database size, are sometimes mentioned as a starting point for sizing the log, in actuality this varies widely. Successful SQL Server installations often do some simple empirical tests to roughly assess the log space requirements for their particular data and applications and then size their log based on this. Attempting to size the log based solely on calculations and without tests is difficult and often inaccurate.

Several difficult-to-predict factors can account for variation in log space consumption. One example is the query optimizer. For a given SQL data modification statement, the access plan can vary over time depending on statistical distribution of the data. Different access plans can consume different amounts of log space. Another example is inevitable internal database fragmentation, which can affect the number of page splits performed. There is nothing that can be done or should be done to examine or affect this process, since SQL Server automatically manages data for the user.

An example of a simple test would be to do DBCC CHECKTABLE(SYSLOGS), which returns the number of 2048-byte data pages in the log, both before and after executing a representative sample of your data modification queries. This can give an approximate idea of the log space requirement for these types of queries. It is usually best to err on the side of excess when providing either log or data disk space for relational databases such as SQL Server.

Even with the Truncate Log On Checkpoint option enabled, a number of factors can cause log space exhaustion. These are as follows:

  1. A large atomic transaction, especially a bulk update, insert, or delete.

    Each single SQL statement is considered an atomic unit that must be applied or not applied in its entirety. For this reason, all row alterations must be logged, and the transaction cannot be truncated over its duration. For example, if a large bulk INSERT was issued that had a running time of five minutes, the log consumed by this transaction cannot be truncated for this period. The Database Administrator must provide sufficient log space for the largest bulk operation expected or must perform the bulk operation in smaller groups.

  2. An uncommitted transaction.

    The log can only be truncated prior to the oldest uncommitted transaction. There are several possible causes of an uncommitted transaction, most of which are application errors. Some of these are:

    • A bulk transaction.

      As considered previously, for the duration of a large bulk transaction, the log records generated by it cannot be truncated. However, such a transaction also precludes log truncation of other shorter transactions that do commit, over the same period.

      For example, say the Database Administrator has sized the log such that it is sufficient for the largest envisioned bulk transaction. Yet while this transaction runs, other shorter data modification statements may also be consuming log space. This log space cannot be truncated, since the large bulk transaction started first and hence becomes the oldest uncommitted transaction. The administrator must be aware of the concurrency and log impact of a large bulk transaction, and size the log appropriately.

    • A poorly designed application that allows for user input or other lengthy activity within a user-defined transaction.

      For example after issuing a BEGIN TRANSACTION, an application might prompt the user for input, which could take a long time depending on user behavior. Until the user responds and the application issues a commit, log truncation will not be possible.

    • An application error in which a transaction is not committed.

      A common cause of this is incorrect handling of the DB-Library call dbcancel() (or ODBC SQLCancel() ) within a user-defined transaction. When a query is canceled with dbcancel() (or ODBC SQLCancel() ), the currently executing SQL statement is aborted and rolled back, but the outer transaction is not. The application must be aware of this and issue the necessary ROLLBACK TRANSACTION or COMMIT TRANSACTION statement to close the transaction. Failure to do so can often result in error 3902:

      The commit transaction has no corresponding BEGIN TRANSACTION.

      It may be useful for the application to send a SELECT @@TRANCOUNT to determine what transaction nesting level exists. However, the application should not blindly do this and then issue COMMIT/ROLLBACK to achieve @@TRANCOUNT=0. This is because if @@TRANCOUNT is ever different from what the application expects, this indicates the application has lost track of the transaction nesting level, which is an application design error. Issuing COMMIT/ROLLBACK at this point could result in applying or aborting unintended transactions, since the application does not know which transactions resulted in the unintended transaction level. Instead, the programmer should debug the application and any stored procedures involved to determine the cause of the unintended transaction level.

      You can use DBCC OPENTRAN() to obtain useful information. For more information see the Microsoft SQL Server Transact-SQL Reference.

    • Transaction not committed due to blocking.

      In a multiuser environment, it is possible for an open transaction to become blocked on locks held by another process. In this case, the transaction will nevertheless remain open, preventing log truncation. To detect this, the programmer or database administrator will need to use sp_who, sp_lock, the Current Activity window of SQL Enterprise Manager, or other tools to analyze the concurrency environment. In most cases, blocking problems can be reduced or eliminated through proper query, index, and database design.

    • Failed attempt to cancel a data modification query.

      If the client application issues a dbcancel() (or ODBC SQLCancel() )and the query is not canceled due to either a network problem or a SQL Server problem, the query will continue to run and the transaction will remain open. If you suspect a problem here, use sp_who to see if the query is canceled. If attempting cancel from a TCP/IP sockets client, try the test from a named pipes client, or run the client application on the server machine using local pipes. This will help discern whether a network problem or a SQL Server problem is preventing the cancel.

      If you suspect a problem you can also use SQL Enterprise Manager or the KILL statement to terminate the user process. You also may sometimes be able to correct this problem by rebooting the client computer and re-establishing the connection to SQL Server.

  3. Checkpoint handler truncation bandwidth exceeded.

    Although the log is truncated every 60 seconds, the rate at which this truncation takes place is finite. This scenario is uncommon, and the other possible causes of log overflow should be considered and ruled out before inspecting this possibility. However, it is possible to exceed the maximum truncation rate if many clients are simultaneously issuing large updates. (This is similar to a funnel, which can only drain fluid at a certain rate and can be overfilled even while draining.) In this scenario, the application can be restructured to reduce the number of rows being updated, which should always be a primary design goal for any relational database.

    If this is not feasible, the system can be reconfigured for increased disk I/O bandwidth though striping, additional controllers, and so on. (For more information, see Chapter 7, Managing Drives.) It is common in this case to see the checkpoint handler process spend increasing amounts of time in the DUMP TRANSACTION state as it attempts to keep up with log truncation. Once the truncation threshold is exceeded (as described in the following text), you may not see the checkpoint handler ever attempt truncation in that database until the log is cleared.

  4. Truncation threshold exceeded.

    The checkpoint handler essentially does a DUMP TRANSACTION WITH TRUNCATE_ONLY. Just as if this was issued manually, it will not always succeed if the log is already full to a certain point. For example, a burst of update activity could fill the log to (for example) 95% between visits by the checkpoint handler. When the checkpoint handler attempts truncation, although the log is not completely full, it may be too full to allow truncation. This is because the truncation of the log must itself be logged. The only solution in this case is to use DUMP TRANSACTION WITH NO_LOG to manually truncate the log.

    Using the NO_LOG option is not recommended except when absolutely necessary, since it is a nonlogged operation during which system failure could introduce database errors.

  5. Interactions between any of the previously described conditions.

    For example, under normal conditions in an update-intensive environment, the checkpoint handler truncation rate may keep the log from filling up. If a temporarily open transaction caused by any of the previously described conditions (such as lock contention) causes the log to fill to, say, 50%, there will be much less headroom for handling other update situations. This makes it much more likely to reach the truncation threshold, at which point automatic truncation will not be possible.

    Transactions in tempdb are logged like any other database. Since Truncate Log On Checkpoint is on in tempdb, in most cases the log will be truncated and not overflow. However any of the previously described circumstances can cause the tempdb log to fill up.

    Usually, tempdb is configured for mixed log and data (sysusages.segmap=7), so data and log operations will contend for the same available space. Certain Transact-SQL constructs such as GROUP BY, ORDER BY DESC, and so on will automatically require tempdb for work space. This will also cause an implicit BEGIN TRANSACTION record in tempdb for the work space. This tempdb transaction will continue for the duration of the transaction in the user database, which can defer tempdb log truncation for this period. If the transaction in the user database is halted for any reason, including a blocking lock, or the application not processing dbnextrow() to completion, the transaction in tempdb will likewise be left open, preventing tempdb log truncation. The programmer must debug the application and/or resolve the concurrency issues that caused this.

  6. Transactions marked for publication but not read by the log reader.

    For information, see Part 6, Replication.

The following discusses log truncation behavior at SQL Server startup on the basis of whether Truncate Log On Checkpoint is set on.

  • If Truncate Log On Checkpoint is set on and the log is found to be full at startup time, it will be automatically dumped with NO_LOG.
  • Truncate Log On Checkpoint is the default in master because its log cannot be put on a separate device, so it can never be loaded. The only viable option is to discard the log when it gets full.
  • If Truncate Log On Checkpoint is not set and the log is found to be full at startup time, recovery completes, but the final checkpoint is not written. An administrator can get into the database and dump the log with NO_TRUNCATE to save the data and then dump with NO_LOG to purge it (or just purge it).


Backing Up the master Database

The master database is backed up in the same way as user databases and should be dumped regularly and frequently. It is important to make backups of master after any statement or system procedure that records information in it is used.

For example, back up master after these statements and/or stored procedures are used:

ALTER DATABASE | sp_addserver
CREATE DATABASE | sp_addumpdevice
DISK INIT | sp_configure
DISK MIRROR | sp_dropdevice
DISK UNMIRROR | sp_droplogin
DISK REMIRROR | sp_dropsegment
DISK RESIZE | sp_dropserver
various DBCC options such as SHRINKDB | sp_dropremotelogin
sp_addlogin | sp_extendsegment
sp_addremotelogin | sp_logdevice
sp_addsegment |

The master database backups are used as part of the recovery procedure when a failure that affects the master database occurs. If the master database is damaged, a special procedure must be used to recover it. For information, see Restoring the master Database, in this chapter.

Because master cannot be separated from its transaction log, you cannot separately back up the transaction log for master.

Note The master database contains the system catalog, which is the most important information about your SQL Server configuration. When dumping the master database, it is also advisable to make hard copies (using the SELECT * statement) of the sysdatabases, sysusages, and syslogins system tables. This information is useful in recovery procedures following DISK REINIT and DISK REFIT.


Backing Up the msdb Database

The msdb database supports SQL Executive and provides a storage area for scheduling information. The msdb database is backed up in the same way as user databases and should be dumped regularly and frequently.

It is important to make backups of msdb regularly. This database is modified by such things as the tasks that you schedule from the Task Scheduling window, the automatic backups you schedule from the Database Backup/Restore window, and all replication tasks (which are automatically created as necessary, if the server is configured as a replication distributor).

Because the setup program installs msdb and its transaction log on separate devices, you can perform both database and transaction log dumps for msdb.


Backing Up the distribution Database

When a server has been configured to participate in replication either as a remote distribution server or as a combined publisher/distributor, it will have a database dedicated to replication distribution activities. The default name for this database is distribution, although the user setting up replication can change that name.

The distribution database is backed up in the same way as user databases, and it should be dumped regularly and frequently. The distribution database should have its transaction log on a separate device, so you usually can perform both database and transaction log dumps.

For more information about the distribution database see Part 6, Replication.


About Disk Dump Devices

Disk dump devices are files on hard disks or other disk storage media. Disk devices can be defined on a server's local disk or on a disk on a shared network resource. Dumping to a file on the same physical device as the database is not usually recommended; if the disk device containing that file crashes, there is no way to recover the database.

For more information about disk dump devices, see Chapter 5, Managing Devices.


About Tape Dump Devices

Tape dump devices are tape drives supported by Windows NT. To dump to a tape, the tape dump device must be located on the computer on which SQL Server is running.

You can add multiple dumps to a single tape, adding each dump to the tape after the last dump. Or, you can overwrite the existing information on a tape with the new dump.

Information about a tape dump is recorded on the tape label. This information includes up to 17 characters of the database name, the time and date of the dump, and the type of dump (database or log). This is called volume and header information and can be viewed using SQL Enterprise Manager or the LOAD HEADERONLY statement. For information, see Viewing Volume and Header Information, later in this chapter.

For information about installing a tape drive, see the documentation for Microsoft Windows NT. For more information about setting up your tape dump device, see Chapter 5, Managing Devices. Also see the Microsoft SQL Server Transact-SQL Reference.


About Diskette Dump Devices

For compatibility with earlier releases, diskettes (floppy disks) can be used to receive dumps. (However, if you need to do this, it is recommended you consider dumping to a disk dump device and then copying the dump to diskette or other external storage media.)

SQL Enterprise Manager cannot be used to initiate a diskette dump, because the console command-line utility must be used to prompt the user and then wait for responses.

Diskette dump devices must be located on the computer where SQL Server is running. By default, when SQL Server is installed, two diskette dump devices are created: DISKETTEDUMPA and DISKETTEDUMPB.

You cannot simultaneously dump multiple databases to the same diskette, but you can execute more than one dump or load at the same time to two diskette dump devices, as long as the diskette dump devices have different controller numbers. You can execute sp_helpdevice to find diskette dump device controller numbers.

A database backup can span many diskettes. When you back up to diskettes, the console utility prompts you to insert new diskettes if necessary. If you are using isql, you must execute the DUMP DATABASE statement and then switch to a different screen session and start the console utility.

To start the console utility
  1. Type:

    console [/S servername] [/P pipename]

    where

    /S
    Is required if you are executing console from a remote computer. However, the diskette drive must reside on the computer running SQL Server.
    /P pipename
    Specifies the pipe that the server started with.
  2. Follow the prompts issued by the console utility, which tell you when to insert diskettes.

The following example shows you how to use isql to back up the pubs database to the DISKETTEDUMPA dump device.

To dump the pubs database to the DISKETTEDUMPA dump device
  1. From isql, type:
    dump database pubs
to diskettedumpa
  2. Switch to a different operating-system screen session and start the console utility:
    console
  3. Watch for prompts to add and remove diskettes.


Backing Up to a Novell File Server

Dump devices can be located on Novell file servers. The capability to define dump devices located on Novell file servers takes advantage of the Windows NT Workstation Client and Gateway Services for NetWare available from Microsoft.

Defining database dump devices with Microsoft SQL Server without setting up a Gateway Share is simple and does not require special mapping on the Novell file server, nor does it require that there be a shared device defined in File Manager.

It is important that the Client and Gateway Services for NetWare be appropriately set up so that files can be copied from the Novell file server to Windows NT without error. Routing and frame type issues must be resolved prior to implementing this procedure.

To set up the Client and Gateway Services, an NTGATEWAY group must already exist on the Novell file server. There are two ways to do this.

Guest Validation by the Novell File Server

The first method depends on GUEST validation by the Novell file server. Begin the Windows NT setup by assigning the LocalSystem account to the SQL Server (MSSQLServer) service. Use the Services application in the Control Panel to do this. For instructions, see your documentation for Windows NT.

When SQL Server starts, it will log in as a LocalSystem account on Windows NT, which means that the Novell file server will have no knowledge of this Windows NT user ID.

On the Novell file server, add the GUEST account to the NTGATEWAY Group and be sure that it has complete Trustee rights to the directory where the SQL Server database dump will be written. When SQL Server attempts to dump the database to this directory, the Novell file server will validate the login and use the GUEST account with NTGATEWAY as the user group.

Running SQL Server Under a Valid User Account

The second way to set up the Client and Gateway Services is to start the SQL Server service with a user account that is valid on the Novell file server and on Windows NT. This user must have appropriate access to stop and start Windows NT services. The user ID and password on Windows NT must exactly match the user ID and password on the Novell file server. In addition, the user account must also be a member of the NTGATEWAY Group and have complete Trustee rights to the directory where the SQL Server database dump will be written.

Unlike setting up a local disk dump device, a UNC path to a Novell file server consists of the file server name, volume, directory, and file.

For example, to define a database dump device on the Novell file server WHISTLE/SYS:USERS/TEST, the following would be entered as the physical filename:

Logical Name: pubsdump
Physical Name: \\WHISTLE\SYS\USERS\TEST\PUBS.DMP

Once the dump device has been defined, verify that the process works by dumping a database with a valid SQL Server login ID.

Note When a server is configured to run the SQL Server service under a user account in order to perform backups to dump devices located on a Novell file server, that server cannot act as a SQLMail client. SQLMail functionality requires that the SQL Server service (MSSQLServer) be configured to run under the computer's LocalSystem account. For more information see Chapter 18, Setting Up Mail.


About Loads

A load is the act of restoring a database from a backup. There are a number of reasons you may need to do this. For example, if the device that a database resides on fails and the database is damaged, you can restore the database by reloading the most recent database dump and the successive log dumps. (If you are restoring a database because of media failure, you must drop and re-create the damaged database before you restore from the backup.)

The basic operations used to restore a database were presented in Basic Backup and Restore Operations, earlier in this chapter. The following topics provided additional information about restoring.

For more information choose one of the following topics:

LOAD Statement Summary

About Database Loads

About Transaction Log Loads

Viewing Volume and Header Information

Loading from Different Processor Architectures

Loading a Version 4.2 Database Dump

Loading an OS/2-based Database Dump

Loading from a Diskette Dump Device

Moving a Database


LOAD Statement Summary

You can load a database or apply a transaction log by using either SQL Enterprise Manager or the LOAD statement. However, some operations can be performed only by using the LOAD statement. This is the syntax for the LOAD statement.

Syntax

Loading a database:

LOAD DATABASE {dbname | @@dbname_var}
FROM dump_device [, dump_device2 [..., dump_device32]]
[WITH options
[[,] STATS [ = percentage]]]

Loading a transaction log:

LOAD TRANSACTION {dbname | @@dbname_var}
FROM dump_device [, dump_device2 [..., dump_device32]]
[WITH options]

Loading header information:

LOAD HEADERONLY
FROM dump_device

where

dump_device =
{ dump_device_name | @@dump_device_namevar}
| {DISK | TAPE | FLOPPY | PIPE} =
{'temp_dump_device' | @@temp_dump_device_var}}
[VOLUME = {volid | @@volid_var}]
options =
[[,] {UNLOAD | NOUNLOAD}]
[[,] {SKIP | NOSKIP}]
[[,] {FILE = fileno}]

For more information¾including explanations of each parameter and option¾see the discussion of the LOAD Statement in the Microsoft SQL Server Transact-SQL Reference.


About Database Loads

When SQL Server loads a database, it rolls back any uncommitted transactions that were active at the moment the dump began. When the load is complete, the database is in the same state it was in when the DUMP statement was executed, minus any transactions that were active at that point.

Once the data from the dump has been reloaded, SQL Server reinitializes any remaining unused pages. For example, if a 100-MB database contains only 5 MB of data, all 100 MB of space is still rewritten. A database load command takes at least as long as the CREATE DATABASE statement that created the database.

Loading a database locks it so that it cannot be modified while recovery is in progress. Users can, however, access and modify other databases on SQL Server during this time.

If a failure occurs while a database is being loaded, SQL Server notifies the SA but does not recover the partially loaded database. The database load must be restarted.

The destination database must have at least as much storage space as was allocated to the dumped database. The actual amount of data in the dumped database is irrelevant. To get information about allocated storage space, use SQL Enterprise Manager or the DBCC CHECKALLOC statement.

After a media failure, restart SQL Server in the usual way. If SQL Server cannot access (USE) a database, it marks the database as suspect, locks it, and displays a warning message. A damaged database must be dropped, which can be done using SQL Enterprise Manager, the DROP DATABASE statement, DBCC DBREPAIR (db_name, DROPDB), or sp_dbremove.

After the database is dropped, it must be re-created. After it is re-created, the SA or database owner can load the most recent database dump (plus any transaction log dumps) using SQL Enterprise Manager or the LOAD DATABASE statement. (The master database is restored using a special procedure. For information, see Restoring the master Database, later in this chapter.)

To learn how to load databases, see Restoring a Database or Applying a Transaction Log, earlier in this chapter.


About Transaction Log Loads

Once you've restored a database, you can load the transaction log dump(s) that were accomplished after that database dump. Loading transaction logs allows you to recover as much of a database as possible in case of system failure.

Backups of the transaction log must be loaded in the sequence in which they were made. SQL Server checks the timestamps on each dumped database and each dumped transaction log to see that the sequence is correct.

Loading a transaction log is also referred to as applying a transaction log. Loading a transaction log results in re-execution of the changes it contains and in rolling back any transactions that were uncommitted when the transaction log was backed up.

When the entire sequence of transaction log dumps has been loaded, the database is restored to its state at the time of the last transaction log dump, minus active transactions. (The exception to this is the DUMP TRANSACTION statement itself, which was active at that point. It is not rolled back; it is completed by the next LOAD TRANSACTION statement.)

To learn how to load transaction logs, see Restoring a Database or Applying a Transaction Log, earlier in this chapter.


Viewing Volume and Header Information

Using SQL Enterprise Manager or the LOAD HEADERONLY statement, you can retrieve all the volume-specific and dump header - specific information for all dumps on a specific disk or tape dump device.

For each dump on a given disk or tape dump device, the header information is sent by the server as a row in a table with the following columns:

Option | Datatype | Possible information
Dump Type | smallint | Database(1) or Transaction(2)
Database | varchar(30) | Database name
Striped | smallint | Striped dump(1), non-striped dump(0)
Compressed | smallint | Compressed(1), uncompressed(0)
Sequence | varchar(6) | Position of the dump in the volume
Volume | varchar(6) | Volume ID
Device Type | smallint | Disk(2), Floppy(3), Tape(5) or Pipe(6)
Table | varchar(30) | Reserved for future use
Dump Size | varchar(15) | Size of dump, in pages
Stripe Set | varchar(2) | Number of devices in the stripeset
Stripe Set Name | varchar(30) | Stripeset ID, for future use
Current Sequence | char(13) | Current/old sequence number
New Sequence | char(13) | New sequence number
Creation Date | char(15) | Creation date (Shortmonth DD, YY)
Creation Time | char(15) | Creation time (HH:MM)
Expire Date | char(15) | Expiration date for the volume (Shortmonth DD, YY)

Note For any dump, only the appropriate columns will contain a value. All other columns will be NULL.

In SQL Enterprise Manager, volume and header information can be displayed by using the Info button in the Database Backup/Restore dialog box. For information on accessing volume and header information, see Backing Up a Database or Transaction Log, earlier in this chapter.


Loading from Different Processor Architectures

It is not possible to dump a database in one processor architecture and load it in another. If the dump being loaded is from SQL Server 6.0, an attempt to load to another processor architecture will return an error. An attempt to load a dump from an earlier SQL Server release to another processor architecture may not return an error. Even if the operation appears to succeed, serious problems will subsequently result. (Also, you cannot run the setup program to perform an upgrade from a database environment that existed on a different computer.)

For example, you cannot dump a database from an Alpha AXP-based computer and load it into an Intel-based computer. Nor should you copy MASTER.DAT from an Intel-based computer to a MIPS- or Alpha AXP-based computer and run setup to upgrade it.

However, you can use SQL Transfer Manager to simply transfer data from one architecture to another. For information, see Chapter 11, Exporting and Importing Data.


Loading a Version 4.2 Database Dump

User database dumps from SQL Server 4.2 can be loaded into SQL Server 6.0, as long as the same sort order is used by both SQL Servers. The user database dump must be a full database dump, not a transaction log dump, and the dump must occur when there is no update activity taking place in the database. For this reason, it is recommended that the dump occur when SQL Server is started in single-user mode. After the database is successfully loaded, the database will be upgraded.

This capability is one-way only; you cannot dump a SQL Server 6.0 database and load it into a SQL Server 4.2 server. Nor can you load a SQL Server 4.2 master database dump into a SQL Server 6.0 database.

When loading a SQL Server 4.2 user database onto a SQL Server 6.0 server, all necessary comments must exist in the syscomments table. SQL Server cannot upgrade all objects from SQL Server 4.2x databases to SQL Server 6.0 if you have deleted data from the text column in the syscomments table.

Also, you may encounter conflicts with the new SQL Server 6.0 keywords. If conflicts arise after loading the database, you can change the conflicting table or object name and alter the applications that access those objects so that they use the new names. For a list of the new keywords and other reserved words, see the Microsoft SQL Server Transact-SQL Reference. Also see Microsoft SQL Server Setup for information about upgrading a server from version 4.2 to version 6.0.

Note For information about keywords, reserved words, language, statement, query and other compatibility issues between SQL Server 6.0 and SQL Server 4.2 databases, see the compatibility information provided in the Microsoft SQL Server Transact-SQL Reference.


Loading an OS/2-based Database Dump

It is possible to do a full database dump from an OS/2-based version 4.2x Microsoft SQL Server and load it onto a Windows NT-based SQL Server, or vice versa, as long as the same sort order is running on both SQL Servers. The dump can be to a disk dump device, a diskette dump device, or a tape drive that is supported by Windows NT.

The dump must be a full database dump, not a log dump, and the dump must occur when there is no update activity taking place in the database. For this reason, it is recommended that the dump occur when SQL Server is started in single-user mode.

Note When you load a database dump taken from a Windows NT-based SQL Server onto an OS/2-based SQL Server, DBCC CHECKALLOC on that database will report some errors. If DBCC CHECKALLOC reports error message 2540 in syslogs, and there are 14 or less of these messages (meaning 14 or less pages affected, or up to 7 of the 8 pages on the first and last extent of the log), the messages can be safely ignored. These messages report uninitialized pages that the Windows NT - based SQL Server didn't use and that the OS/2-based SQL Server doesn't need. To correct these errors, issue DBCC FIX_AL (dbname). In order to execute this command, the database being fixed must be in single-user mode. The command should be executed from a database other than the database being fixed.

If other error messages are reported by DBCC CHECKDB or DBCC CHECKALLOC, do not ignore them, as they indicate a real problem.


Loading from a Diskette Dump Device

You can execute the LOAD statement to restore from a diskette, but the console command-line utility must be used to prompt the user and then wait for responses. If console is not running or if the user does not answer its questions, the load cannot proceed.

For information about running console and loading from a diskette dump device, see the Microsoft SQL Server Transact-SQL Reference.


Moving a Database

You can use SQL Enterprise Manager or the LOAD DATABASE statement to move a database to another device, or to another server as long as the same character set and sort order are used on both servers. (If the character sets and sort orders differ, use SQL Transfer Manager instead.)

The recipient database must be as large as, or larger than, the database to be loaded. If the recipient database is too small, SQL Server displays an error message that gives the required size.

If a database will be loaded into a newly created database, use the FOR LOAD option when creating the new database. This specifies that the data pages will not be zero-initialized because the only operations allowed against that database are ALTER DATABASE FOR LOAD or LOAD DATABASE. Users cannot access the database until after a successful load. Any unused data pages will be initialized by the database load.

Note When you create a database with the FOR LOAD option, after completing the load(s) you must clear the database option DBO Use Only by using SQL Enterprise Manager or sp_dboption. Until you do this, users other than the DBO may not access the database.

To move a database to another database device
  1. Create the new device using SQL Enterprise Manager or the DISK INIT statement.

    Or, use SQL Enterprise Manager to make sure the database device exists, or sp_helpdevice to make sure the database device is listed in sysdevices.

  2. Use SQL Enterprise Manager or the CREATE DATABASE statement to create the new database on the new database device.
    • The new database name must be unique.
    • Use the FOR LOAD option.
    • Do not place the transaction log on a separate device.
    • The new database must be equal in size or larger than the database that will be loaded.
  3. Dump the old database using SQL Enterprise Manager or the DUMP DATABASE statement.
  4. Load the dump into the new database using SQL Enterprise Manager or the LOAD DATABASE statement.
  5. Clear the DBO Use Only option for the new database using SQL Enterprise Manager or sp_dboption.
  6. If appropriate, move the transaction log to a separate device. Use SQL Enterprise Manager or the ALTER DATABASE statement, and then the sp_logdevice system procedure.

    For information about moving the transaction log, see Chapter 6, Managing Databases.

  7. Drop the old database using SQL Enterprise Manager, the DROP DATABASE statement, or sp_dbremove.
To move a database to another server
  1. Follow the same procedure as for moving a database to another database device.
  2. If the syslogins table on the new server is different from the syslogins table on the old server, the ownership of databases and database objects will be incorrect. Use aliases to map owners to their objects on the new SQL Server.

If the dumped database uses segments to store particular tables or indexes, the new database must include devices of the same size and page order for these segments and their related data in order for the LOAD statement to work correctly. Execute the sp_helpdb system stored procedure with the database name to see the size and fragments. Select from the sysusages system table to determine the order of the device fragments. Then re-execute the CREATE DATABASE statement and the ALTER DATABASE statement to re-establish the fragments.

The device fragments that the new database uses for data and for the log must appear in the same order and have the same amount of space as the fragments in the original database. For example, if the original database had 10 MB of data (on any number of fragments), followed by 3 MB of log, followed by 6 MB more of space for data, the new database must have the same order by space and usage: 10 MB for data, 3 for log, and 6 (or more) for data. In this case, the total size of the destination database must be at least as large and have at least as many fragments (assigned in the same order and have the same uses) as the load.


How to Recover from Media Failure

To recover user databases from media failure, find necessary information about lost devices and databases, re-create the lost devices in order, re-create the affected databases, and then restore those databases from backups. Anything done after the backups were created must be reapplied.

The procedure for restoring the master database is different. For details, see Restoring the master Database, later in this chapter.


Finding Information About Lost Devices and Databases

If the size of the original devices are not known, they can be derived from the sysdevices, sysdatabases, and sysusages tables in the master database.

The size and device assignment of databases can be derived from the sysdevices, sysusages, and sysdatabases tables. Each chunk of disk space assigned to a database is represented by a row in the sysusages table. The size of each chunk is in the row. The dbid of the database to which the chunk is assigned is also in the row, and the corresponding database name can be obtained from sysdatabases. The device containing the chunk of disk space can be deduced by noticing which low/high range in sysdevices contains the starting virtual address (vstart) specified in the sysusages table.

To determine whether a device is a log device, look at the value of segmap in sysusages: 7 indicates log and data, 4 indicates log only, and 3 indicates data only. Anything else is a user-defined segment.

Before re-creating devices, gather information about all affected databases. (This information must be gathered before re-creating lost devices and databases, since as part of those procedures you drop affected devices and databases, and at that point this information is lost).

To find information about lost databases
  1. Use the following query to examine the device allocations and uses for the damaged database. You will have to assign the same blocks of space, for the same purposes. This query shows the uses and sizes of the devices allocated to mydb:
    select segmap, size from sysusages
    where dbid =
        (select dbid from sysdatabases
            where name = "mydb")
  2. Examine the output of the query. Each row with 3 in the segmap column represents a data allocation; each row with 4 in the column represents a log allocation. The size column indicates the number of 2K blocks of data. Note the order, use, and size of this information. For example:
    segmap       size
-----------  ----------
          3       10240
          3        5120
          4        5120
          3        1024
          4        2048

    This translates into these sizes and uses, in megabytes:

    Data -- 20
Data -- 10
Log  -- 10
Data -- 2
Log  -- 4

    Note A 7 in the segmap column indicates that the data and log are on the same device, and you can recover only up to the point of the most recent database backup. If the transaction log and database are on the same device, you can perform a DUMP DATABASE, not a DUMP TRANSACTION statement.

  3. Save this information. You will need it when you re-create lost databases.


Re-creating Lost Devices

To re-create lost devices
  1. Start SQL Server in single-user mode. Type:

    where

    /c
    Starts SQL Server independent of the Windows NT Service Control Manager.
    /d master_device_ path
    Specifies a physical name for the MASTER database device. For example:
    /dc:\sql60\data\master.dat
    /m
    Specifies single-user mode.

    sqlservr /c /d master_device /m

    where

    /c
    Starts SQL Server independent of the Windows NT Service Control Manager.
    /d master_device_ path
    Specifies a physical name for the MASTER database device. For example:
    /dc:\sql60\data\master.dat
    /m
    Specifies single-user mode.
  2. Query and save information from the sysusages and sysdevices tables, so that you can later re-create the devices and databases with the proper sizes. Follow the instructions in, "Finding Information About Lost Devices and Databases." Finding Information About Lost Devices and Databases.
  3. Drop each database that has space allocated on a lost device by using the DBCC DBREPAIR statement. Type:

    DBCC DBREPAIR(database_name, DROPDB)

    where database_name specifies which database to drop.

    You can also drop databases using the sp_dbremove system procedure.

  4. Drop lost devices using the sp_dropdevice system procedure.
  5. Execute CHECKPOINT, shut down SQL Server, and then start it in normal mode.
  6. Re-create lost devices by executing the DISK INIT statement using the size of the original devices (as determined following the instructions in Finding Information About Lost Devices and Databases.

For information about using DISK INIT, DBCC DBREPAIR, sp_dbremove, and sp_dropdevice, see the Microsoft SQL Server Transact-SQL Reference.


Re-creating and Reloading Lost Databases

You restore a database by re-creating the database and then reloading the most recent database dump and the succeeding transaction log dumps.

To re-create and reload an affected database
  1. If the transaction log of the damaged or inaccessible user database is on an undamaged device, use DUMP TRANSACTION with the NO_TRUNCATE clause to dump it.
  2. Examine the device allocations and uses for the damaged database by reviewing the information you gathered in Finding Information About Lost Devices and Databases, earlier in this chapter.

    You will have to assign the same blocks of space, for the same purposes. Examine the query output. Each row with 3 in the segmap column represents a data allocation; each row with 4 in the column represents a log allocation. The size column indicates the number of 2K blocks of data. Note the order, use, and size of this information. For example:

    segmap       size
-----------  ----------
          3       10240
          3        5120
          4        5120
          3        1024
          4        2048

    This translates into these sizes and uses, in megabytes:

    Data -- 20
Data -- 10
Log  -- 10
Data -- 2
Log  -- 4

    Note A 7 in the segmap column indicates that the data and log are on the same device, and you can recover only up to the point of the most recent database backup. If the transaction log and database are on the same device, you can perform a DUMP DATABASE, not a DUMP TRANSACTION statement. (You should perform step 4 using the LOG ON option with CREATE DATABASE. Instead, be sure that you allocate sufficient space.)

  3. Use the DROP DATABASE statement to drop the database from the failed device. If the system reports errors, use the DROPDB clause of the DBCC DBREPAIR statement, or use the sp_dbremove system procedure.
  4. Re-create the database, using the CREATE DATABASE statement to duplicate all the rows from the old sysusages table up to and including the first log device. For example:
    CREATE DATABASE mydb on datadev1 = 20, datadev2 = 10
    log on logdev1 = 10
  5. If you need more space, use the ALTER DATABASE command to re-create the rest of the entries. For example, to allocate more space on DATADEV1:
    alter database on datadev1 = 2

    To allocate space on another device:

    alter database on datadev3 = 2

    When you allocate space on existing devices, the device is automatically assigned the same usage: data or log. When you allocate space on a device that's not already in use by the database, it's always allocated as a data device. For example, to re-create the final allocation on LOGDEV1, which is already in use by the database, type:

    alter database mydb on logdev1 = 4

    LOGDEV1 is automatically entered into sysusages as a log device.

    To allocate log space on a device that is not already in use by the database, follow the ALTER DATABASE command with the sp_logdevice procedure, like this:

    alter database mydb on logdev2 = 4
sp_logdevice mydb, logdev2
  6. Reload the database using LOAD DATABASE, and then load previously dumped logs and the newly dumped current log using LOAD TRANSACTION.

For information about using ALTER DATABASE, CREATE DATABASE, DBCC DBREPAIR, DISK INIT, DROP DATABASE, LOAD DATABASE, LOAD TRANSACTION, sp_dbremove, and sp_dropdevice, see the Microsoft SQL Server Transact-SQL Reference.


Restoring the master Database

A damaged master database makes itself known either with an inability to start SQL Server, by segmentation faults or input/output errors, and/or in a report from DBCC. Damage can be caused by a media failure in the area in which master is stored.

The procedure used to recover a damaged master database is different from the procedure used to recover user databases. If the master database becomes unusable, it must be restored from a previous dump. All changes made to the master database after the last dump are lost when the dump is reloaded and therefore must be reapplied.

It is strongly recommended that the master database be backed up each time it is changed. This is best accomplished by prohibiting the creation of user-defined objects in master and by being aware of the statements and system procedures¾and the equivalent actions in SQL Enterprise Manager¾that modify it.

The most common statements and system procedures that modify master are:

  • DISK INIT
  • CREATE DATABASE
  • ALTER DATABASE
  • DISK MIRROR
  • DISK UNMIRROR
  • DISK REMIRROR
  • sp_dropremotelogin
  • sp_addumpdevice
  • sp_dropdevice
  • sp_addlogin
  • sp_droplogin
  • sp_addserver
  • sp_dropserver
  • sp_addremotelogin

If a user database is created, expanded, or shrunk after the most recent dump of the master database, and if it becomes necessary to reload the master database, then that user database and all data in will be lost. Because of this, always dump the master database after creating, expanding, or shrinking user databases.

These are the steps required to recover a damaged master database:

To recover a damaged master database
  1. Use the SQL Setup program to rebuild the master database.

    You must rebuild using the same character set and sort order as the master database dump that will be reloaded.

  2. Add a dump device (unless the dump will be reloaded from diskettes).
  3. Restart SQL Server in single-user mode.
  4. Restore the master database from the most recent dump.
  5. Apply to the master database any changes that were not included in the most recent dump.
  6. Restore the msdb database.

These steps are explained in the sections that follow.

Rebuild the master Database

Use the SQL Setup program to rebuild the master database.

To rebuild the master database
  1. From the Microsoft SQL Server 6.0 program group, double-click the SQL Setup icon.

    Or from the distribution media, from the directory containing the software compatible with your hardware platform's processor architecture, run SETUP.EXE.

  2. Respond to the on-screen instructions until the Options dialog box appears.
  3. Select the Rebuild Master Database option, and then choose the Continue button.

    A confirmation dialog box appears.

  4. Choose Resume.

    The Rebuild Options dialog box appears.

  5. To specify the character set, choose the Sets button and complete the Select Character Set dialog box that appears.

    If you will be using the default character set (ISO 8859-1), skip this step.

    Important You must use the same character set and sort order that were previously used for this master database.

  6. To specify the sort order, choose the Orders button and complete the Select Sort Order dialog box that appears.

    If you will be using the default sort order (dictionary order, case-insensitive), skip this step.

  7. In the Rebuild Options dialog box, choose Continue.

    The SQL Server Installation Path dialog box appears.

  8. If it is not correctly displayed in the SQL Server Installation Path dialog box, enter the location of the existing SQL Server installation, and then choose Continue.

    The Rebuild Master Device dialog box appears.

  9. If it is not correctly displayed in the Rebuild Master Device dialog box, enter the location and name of the existing MASTER device. Also enter a MASTER device size, and then choose Continue.

    The setup program rebuilds the master database.

  10. When rebuilding is complete and the completion dialog box appears, choose the Exit button.

The files MASTER.DA@ and MASTER.AL@ are stored in the \SQL60\INSTALL directory. When rebuilding the master database (or when installing SQL Server), one of these two files is used by the setup program. When the default sort order and character set are selected, MASTER.DA@ is expanded and copied onto the server, replacing MASTER.DAT. When an alternate character set and/or sort order is selected, MASTER.AL@ is expanded, copied onto the server, and several SQL scripts are run.

Although they were part of earlier releases, SQL Server 6.0 does not need (nor does it provide) a bldmastr utility or an INSTMSTR.SQL script.

Add the Dump Device

If the backup of master was made to a disk dump device or a tape dump device, you must add that dump device before performing the load. (This is not necessary if you will be loading from a diskette dump device.) Use SQL Enterprise Manager or the sp_addumpdevice system procedure to add the dump device. The following procedure assumes that you are using SQL Enterprise Manager.

To add the dump device
  1. Start SQL Server normally and start SQL Enterprise Manager.
  2. From the Server Manager window select a server, from the Tools menu choose Backup/Restore, and then from the Database Backup/Restore dialog box that appears, choose the New button.

    The Create Dump Device window appears.

  3. In the Device Name box, type the logical name of the dump device that contains the most recent master database backup. For example:
    Tape0
  4. In the Device Path box, type the physical name for that dump device.

    This is the path and filename of the operating-system file that contains the backup. For example:

    \\.\TAPE0

    If you do not remember the path, you can choose the Locate button and select a dump device file from the directory tree that is displayed. For more information about physical names see About Dump Devices, in Chapter 5, "Managing Devices."

  5. Select a device type:
    • Disk specifies a dump device file on a hard disk (or other disk media).
    • Tape specifies a dump device for a tape drive.
  6. If you selected Tape in step 4, also select or clear the Skip Headers check box.

    This option indicates whether ANSI tape labels are read or ignored.

  7. Choose the Add button.

    The dump device is added.

For information about adding a device using the sp_addumpdevice system procedure, see the Microsoft SQL Server Transact-SQL Reference.

Restart SQL Server in Single-user Mode

Before you can reload the master database, you must start SQL Server in single-user mode.

To start SQL Server in single-user mode
  1. If it is already running, stop the server.
  2. From a command prompt, type:

    sqlservr /c /d master_device /m

    where

    /c
    Starts SQL Server independent of the Windows NT Service Control Manager.
    /d master_device_ path
    Specifies a physical name for the MASTER database device. For example:
    /dc:\sql60\data\master.dat
    /m
    Specifies single-user mode.

For example:

sqlservr /c /dc:\sql60\data\master.dat /m

Restore the master Database from the Most Recent Backup

Reload the most recent dump of the master database using SQL Enterprise Manager or the LOAD DATABASE statement.

When using SQL Enterprise Manager, in the Server Manager window the server status may appear red since the server was started independent of the Windows NT Service Control Manager. However, you can ignore this status. You will be able to connect and then restore the master database from the Database Backup/Restore window.

You can also restore the master database using the LOAD statement from isql (or another query interface).

To restore the master database using the LOAD statement
  • Type:

    LOAD DATABASE dbname
    FROM dump_device [, dump_device2 [..., dump_device32]]

    where

    dbname
    Is the database name (in this case, master).
    dump_device
    Is the logical name of the dump device.

For example:

LOAD DATABASE master FROM tape0

Important When the load of master is complete, the server automatically shuts itself down. An error message appears, stating that the server connection has been broken. You can then restart the server normally.

Additional options can be used with the LOAD DATABASE statement. For information, see the Microsoft SQL Server Transact-SQL Reference.

Apply Changes to the master Database

If there have been no changes to the master database since the last dump, then you are done. Restart the server normally (in multiuser mode).

If login IDs or devices have been added to or dropped from the master database since the last dump, those changes must be reapplied. Restart the server and reapply the changes manually or from saved batch files.

If databases have been created, expanded, or shrunk since the last dump of master, those databases must be re-created and all the data contained in them must be reentered. This can be done manually, from saved batch files, or by reloading dumps of those databases after they have been re-created.

If you have made many changes and have no recent dump, it is possible that by reloading master in some cases you can regain data in user databases that has been lost. This technique requires the use of DISK REINIT and DISK REFIT and can involve manual modifications to the master database tables.

Use DISK REINIT to re-create rows in sysdevices for all database devices that have been added after the most recent dump. DISK REINIT updates sysdevices just as DISK INIT does, but it does not format the physical disk file, so existing data is preserved.

Use DISK REFIT to re-create rows in sysusages and sysdatabases for all CREATE and ALTER DATABASE statements that were performed after the most recent dump. DISK REFIT scans the physical file associated with each space that is allocated to databases. It also adds the corresponding sysdatabases entries. Some of the information is not reconstructed perfectly. For example, the original virtual device number is not assigned, because it is not known. Instead, virtual device numbers are assigned sequentially. The database owner is not extracted while scanning the physical files; ownership is set to the system administrator. It is also not possible to determine how many sysusages entries originally existed. DISK REFIT inserts a separate entry for each different segment type.

When this is done, correct the entries made by DISK REFIT to sysdatabases and sysusages (if desired) and also add to syslogins any login IDs that were not retained. Then shut down and restart SQL Server.

Caution Capturing the latest changes made to a database by using DISK REFIT and DISK REINIT to re-create the master database is possible, but it is preferable to keep the master database current by dumping it after creating or altering databases. Using DISK REFIT and DISK REINIT is a complicated process that can result in data loss because many of the changes made to a database often must be reconstructed manually in the master database. If you feel this technique is necessary, contact your primary support provider before beginning the recovery process.

After all the changes since the last dump of master have been applied, restart the server normally (in multiuser mode).

Restore the msdb Database

The msdb database supports SQL Executive and provides a storage area for scheduling information. The schedules that you implement using SQL Enterprise Manager are maintained in the msdb database. This includes such things as the tasks that you schedule from the Task Scheduling window, the automatic backups you schedule from the Database Backup/Restore window, and all replication tasks (which are automatically created by the system if the server is configured as a replication distributor).

During installation of a server, the setup program automatically creates two devices (of 2 MB and 1 MB) on the same disk drive as the master database, and then places the msdb database on the 2 MB device (MSDBDATA) and its transaction log on the 1 MB device (MSDBLOG). Scheduling information is then stored in this database.

During a rebuild of the master database, the setup program drops and re-creates the msdb database, which results in a loss of all scheduling information. Therefore, after the master database has been restored, you must perform these steps to restore msdb:

To restore msdb
  1. If necessary, expand the MSDBDATA device, and then allocate the expanded space to the msdb database.

    The msdb database must have as much or more space allocated to it as was allocated to it before the master database was rebuilt.

  2. Restore the msdb database from the most recent database backup.
  3. Apply all transaction log dumps that were performed after that database dump.
  4. Re-create any scheduled tasks that were implemented after the last transaction log dump.

In general, the msdb database can be treated as a user database, as described in Re-creating and Reloading Lost Databases.


Part 6 Replication

Replication

Replication, which is provided as an integral element of Microsoft SQL Server 6.0, allows you to automatically distribute read-only copies of transactional data from a single source server to one or more destination servers at one or more remote locations. Data can be replicated continuously or at specified intervals. It can be replicated in its entirety or as filtered subsets. Each destination server can receive some or all of the replicated data. Any number of source and destination servers can exist in an enterprise, and servers can perform both source and destination roles.

With replication, you can keep multiple copies of a table up to date, keep multiple databases closely synchronized, intermittently update data on multiple databases, and resynchronize data following a system outage or failure.

Here are a few of the many ways you might use replication:

  • To maintain several decision-support servers, removing the report generation and ad-hoc query impact from the source server
  • To distribute and update read-only copies of changes from a master price list on a source server to several regional servers supporting field offices
  • To distribute location-specific data from a centralized master table
  • To support order processing during a communications outage

You can easily configure, manage, and monitor replication using the new SQL Enterprise Manager enterprise administration tool, which offers convenient, centralized server management via a graphical interface.

The chapters in this part present the information you'll need to establish and maintain data replication between the servers of your enterprise.

Chapter 13, Replication Concepts, introduces SQL Server 6.0 replication. This chapter describes what replication is and what it can do for you, discusses the elements that make up replication, and describes how replication works. It also provides a replication glossary that defines many replication-related terms.

Chapter 14, Setting Up Replication, explains how to set up replication between servers. This chapter tells you what information to gather and what prerequisites to satisfy before setting up replication; how to set up servers, databases, and tables to send and receive replicated data; and how to stop replication. Also provided are a number of replication setup examples.

Chapter 15, Advanced Replication, explains how to monitor and maintain replication and how to recover from replication error conditions. It shows you how to set up several advanced replication examples. The tables, stored procedures, and scripts used by replication are discussed. Also, it describes how to set up replication manually, without the use of SQL Enterprise Manager.


Chapter 13 Replication Concepts

Replication Concepts

Replication¾provided as an integral element of Microsoft SQL Server 6.0¾allows you to automatically distribute copies of transactional data from a single source server to one or more destination servers at one or more remote locations.

This chapter provides an orientation to SQL Server 6.0 replication, describing its essential features, components, and capabilities. It also provides a replication glossary that defines many replication-related terms.

For information, choose one of the following topics.

Replication Overview

The Publishing/Subscribing Metaphor

Replication Components

Replication Is Log-Based

Server Roles in Replication

Data Distribution Options

Synchronization

Push and Pull Subscriptions

Graphical Administration

Replication Security

Replication and SQL Executive

Replication and ODBC

Replication Scenarios

Frequently Asked Questions

Replication Terminology


Replication Overview

Replication is the duplication of table schema and data from a source database to a destination database. There are two basic replication models, tight consistency and loose consistency.

Tight consistency is a replication model that guarantees that all copies will be constantly identical to the original. It requires a high-speed LAN, reduces database availability, and is a less scalable model than one based on loose consistency. This is implemented today through the use of two-phase commit. (For information on implementing two-phase commit for SQL Server 6.0, see Microsoft SQL Server Programming DB-Library for C.)

Loose consistency is a replication model that allows a time lag between the moment when original data is altered and when the replicated copies of that data are updated. It does not guarantee that all copies will be constantly identical to the original. An advantage of loose consistency is that it supports LANs, WANs, fast and slow communication links, and intermittently connected databases. It allows better database availability and is much more scalable than a tight consistency model. SQL Server 6.0 replication is based on a loose consistency model.

SQL Server 6.0 replication has these fundamental characteristics:

  • It is transaction log-based. That is, transactions marked for replication are read from the transaction log of the source database and applied to the destination databases.
  • It uses terminology based on a publishing/subscribing metaphor.
  • It employs servers in three different roles: publication, distribution, and subscription.
  • It uses a dedicated SQL Server database as a reliable queue for replicated data.
  • It offers great flexibility in selecting the particular data that will be replicated to each destination database.
  • It provides easy, graphical tools for set up and administration.
  • It enhances security by limiting which users can set up and administer replication and which destination servers can receive (or even see) tables available for replication.

See the topics that follow for more information about each of these features.


The Publishing/Subscribing Metaphor

SQL Server 6.0 replication terminology is based on a publishing/subscribing metaphor:

  • When data is made available for replication, it is published. The server that contains the source database and makes the data available for replication is called the publication server or publisher.
  • An article is the basic unit of replication. It contains data originating from a single table that has been marked for replication. Each article must belong to a publication.
  • A publication is a collection of articles. One or more articles can belong to a publication. One or more publications can be created from each user database on a publication server.

    Note that all articles within a publication are guaranteed to be initially synchronized as a single logical unit. This helps to maintain integrity relationships originating from the underlying tables.

  • When a server requests a publication, it becomes a subscription server or subscriber. A subscriber can subscribe to some or all available publications and to some or all articles within a publication.

Replicated data moves in only one direction ¾ from the publication server to the subscription servers. You will usually treat replicated data residing in destination tables on subscription servers as read-only. (Note that this means the data should be treated as read-only for the users of the subscription databases. Do not set the Read Only database option, or that subscription database will be unable to receive replicated data.)

This is not so limiting as it might at first sound, since each server can act as both subscriber and a publisher and secondary copies of data can be locally processed on the subscriber. For examples of publishing subscribers and of secondary processing of data, see Chapter 15, Advanced Replication.


Replication Components

The log reader process, the synchronization process, the distribution database, and the distribution process are the main components of replication.

The log reader process moves transactions marked for replication from the publication server transaction log into the distribution database, where the transactions wait for distribution to subscription servers.

The synchronization process prepares initial synchronization files containing schema and data of published tables, stores the files in the SQL Server working directory on the distribution server, and records synchronization jobs in the distribution database. Synchronization affects new subscribers only.

The distribution database is a store-and-forward database that holds all transactions waiting to be distributed to subscription servers. The distribution database receives transactions sent to it from the publication server by the log reader process and holds them until the distribution process moves them to the subscription servers. The distribution database is used only by replication and does not contain any user tables.

The distribution process moves to subscription servers the transactions and initial synchronization jobs held in the distribution database tables. They are applied at the subscribers to the destination tables in the destination databases.

All three processes (log reader, synchronization, and distribution) exist on the server that performs distribution, are subsystems of SQL Executive, and are not started or directly administered by users.

The following illustration provides a functional overview of the replication components.

Note To best depict functionality, the illustration shows the publication and distribution servers as separate computers. However, any SQL Server 6.0 server can perform both roles. The publication and distribution servers are typically the same physical machine. However, when appropriate, two separate servers can perform those roles. For more information, see Server Roles in Replication, later in this chapter.

SQL Server replication components are implemented by using a modular design. Because of this, if you are running high-activity production systems, you will be able to install components of replication on separate computers, balancing workload and helping to minimize SQL Server replication's impact on the production server's performance.

In a typical replication situation, the log reader process, the synchronization process, the distribution process, and the distribution database are installed on the publication server. However, these components can be installed on a separate server, which in some configurations can improve performance.


Replication Is Log-Based

After servers have been configured for replication and the source and destination data tables have been synchronized, a replication process (the log reader) monitors the transaction log of each database set up for replication. When a transaction occurs on a published table, it is marked for replication. When the log reader finds transactions marked for replication, it applies them to the distribution database. The transactions are held in the distribution database until they can be distributed to the appropriate destination servers and applied to the destination databases.

Only committed transactions are sent to destination servers. Replicated changes to a table are guaranteed to be sent to the destination servers in the order in which they are committed. This ensures the subscribers receive transactions in the same order in which they were applied at the publisher. Because this is a log-based solution, maximum concurrent access to data is maintained. Replication does not exclude user access to destination tables during the associated inserts, deletes, and updates.

During normal operation, transactions marked for replication are preserved in a publication database's transaction log until they have been moved into the distribution database by the log reader. After this occurs, the transaction log of the publication database can be truncated using normal procedures. Records still waiting to be replicated are not truncated. (The transaction log on the publisher can be dumped without interfering with replication, since only transactions not marked for replication are purged.)


Server Roles in Replication

Servers can have three roles in SQL Server replication. All SQL Server 6.0 servers are capable of performing all of these roles.

  • Publication server. A server that has made data available for replication. A publication server maintains publication databases, makes published data from those databases available for replication, and sends copies of all changes to the published data to the distribution server. Also referred to as a publisher.
  • Distribution server. The server containing the distribution database. The distribution server receives all changes to published data, stores the changes in its distribution database, and, when appropriate (depending on scheduling and other variables), transmits them to subscription servers. The distribution server can be the same computer that is acting as the publication server, or a different computer. Also referred to as a distributor.
  • Subscription server. A server that maintains destination databases, which receive and maintain copies of published data. Also referred to as a subscriber.

In most cases, the first two roles are combined in one computer; the publication server also acts as the distribution server, as shown in this illustration:

Note that the publishing and subscribing roles are not exclusive: servers can simultaneously perform both. For example, suppose Server A publishes Publication 1, and Server B publishes Publication 2. In this case, Server A could act both as a publication server (of Publication 1) and a subscription server (to Publication 2).

As an option, the distribution server can be installed on a separate computer, as shown in the following illustration. This might be an appropriate configuration when high loads are present, such as when a busy on-line transaction processing (OLTP) server is configured as a publication server. Using a separate distribution server reduces local processing and disk usage on the publication server, although it somewhat increases overall network traffic.

Note that using a separate distribution server requires separate SQL Server installations (two licenses), one for the publication server and one for the distribution server.


Data Distribution Options

SQL Server replication offers great flexibility in determining exactly what sets of replicated data each subscriber receives:

  • Selective subscription to publications. A subscription server can subscribe to none, some, or all of the publications offered by the publication servers of your enterprise.
  • Selective subscription to articles. A subscription server can subscribe to some or all of the articles within a publication.
  • Secure publications. Each publication has a security status of unrestricted (the default) or restricted. A publication marked as unrestricted is visible to and can be subscribed to by any registered subscription server. A publication marked as restricted is visible to and can be subscribed to by only those subscription servers that have been granted access.
  • Publication of vertically partitioned tables. You can create an article that replicates only selected columns of the base table. Subscription servers receive only that vertically partitioned subset of the data. Note that the replicated columns must include the primary key column(s). The following illustration shows the replication of a vertically partitioned table.

  • Publication of horizontally partitioned tables. You can create an article that replicates only selected rows of the base table. Subscription servers receive only that horizontally partitioned subset of the data. The following illustration shows the replication of a horizontally partitioned table.

  • And of course, an article can be simultaneously partitioned both vertically and horizontally, as depicted in the following illustration.


Synchronization

Before a new subscriber can receive replicated transactions from a publication, the publication and destination tables must contain the same schema and data. The process that accomplishes this is called initial synchronization.

For information, choose one of the following topics:

Synchronization Overview

Automatic Synchronization

Manual Synchronization

No Synchronization

Snapshot Only


Synchronization Overview

Initial synchronization ensures that the table schema and the table data in the publication and destination databases are made identical. Replication ensures that updates are applied to a subscriber only after the subscriber is synchronized. Initial synchronization affects new subscribers only.

When a publication is first created a copy of the table schema is written to a file for transfer. If an index is requested, the index is created as part of this schema. When synchronization begins, a "snapshot" is taken of the table data of the published article, and that snapshot is also written to a file. If an index is requested, the index is created as part of the schema. The table schema is written to an .SCH file, and the table data is written to a .TMP file. These files are stored in the working directory of the distribution database (by default, \SQL60\REPLDATA). The .SCH and .TMP files are a synchronization set that represent a snapshot in time of that article. There is a synchronization set for each article within a publication.

After the synchronization set is created, subsequent inserts, updates, deletes, or modifications to the published data are captured but will be replicated to each subscriber only after its initial synchronization is complete. Thus, SQL Server ensures that updates are applied to a subscriber only after the subscriber has a current snapshot of the table schema and data.

When synchronization sets are distributed and applied to subscribers, only those subscribers waiting for initial synchronization are affected. Other subscribers to that publication or article¾those that are already synchronized and have been receiving inserts, updates, deletes, or modifications to the published data¾are unaffected.

Initial synchronization can be accomplished automatically or manually (as described in the topics that follow). Synchronization of all new subscribers can be scheduled to occur either frequently (every few minutes) or on a specified day at a specified time.

All components of a publication¾all the articles¾are synchronized simultaneously, preserving referential integrity between the underlying tables.


Automatic Synchronization

Automatic synchronization is accomplished by SQL Server. A snapshot is taken of the table schema and data of the published article, and that snapshot is written to files for transfer.

The synchronization process also creates a synchronization job and places it in the distribution database. When distributed, this job applies the files in the synchronization set to all subscription databases that are waiting for synchronization. The job to copy the table schema and data is transferred to the waiting subscribers as with any other replication job, via the distribution database. No operator intervention is required.

Automatic synchronization occurs on a scheduled basis. Since automatic synchronization of databases or even individual tables requires a fairly high amount of system overhead, a benefit of scheduling automatic synchronization for less frequent intervals is that it allows the synchronization snapshot to be scheduled for a period of low activity on the publication server.

When a scheduled initial synchronization time arrives, synchronization occurs only for those subscribers that have requested synchronization since the last sync event occurred (not for all subscribers to that publication). This minimizes the impact on the publication server.

Important A scheduled synchronization is based on the date and time at the distribution server (not the date and time at the subscription servers).


Manual Synchronization

Manual synchronization is carried out by the user. As with automatic synchronization, the publication server produces files containing a snapshot of the table schema and data from the published table, but with manual synchronization, it is applied to the subscriber by a user, from tape or other storage medium. After manual synchronization is accomplished, the user must inform SQL Server that the synchronization is complete.

The user can obtain the table schema script (an .SCH file) and the table data file (a .TMP file) for each synchronization job from the working directory of the distribution database (by default, \SQL60\REPLDATA). See Chapter 14, Setting Up Replication, to learn how to determine the filenames for a particular synchronization job.

Manual synchronization is particularly useful when the publication and subscription servers are connected by a slow, expensive, or low-quality network connection, and when a table being published is very large.

For example, if a publication server in Boston is connected over an expensive communications link to a subscription server in Stockholm, a manual synchronization could be accomplished by physically sending a tape containing the .SCH and .TMP file to Stockholm. The table schema script and the table data file could be manually applied to the database, and then SQL Server could be informed that the manual synchronization is complete. This avoids sending the files over the communications link.

Manual synchronization events can affect all the replicated data being sent to a subscriber's database. When a manual synchronization event is set up, a placeholder is put in the distribution database. All transactions in the distribution database continue to be sent to the destination database until that placeholder is encountered; at that point, distribution to that destination database stops, even for other publications and articles in that destination database that are not waiting for a manual synchronization. Replication to the entire database is paused until the manual synchronization is carried out and SQL Server is informed that the synchronization is complete.


No Synchronization

As an option, when setting up a subscription, you can specify that SQL Server will not synchronize the published articles with the destination tables. SQL Server assumes that they are already synchronized, and inserts, updates, deletes, or modifications to the published data are replicated to each subscriber as soon as the subscription are established.

In this case, it is the responsibility of the user setting up replication to ensure that the table schema and data are identical for the published article and the destination table. The advantage of this option is that it allows changes to replicated data to be immediately distributed to subscribers, without incurring the system overhead associated with synchronization. It is intended for advanced users who will be implementing a custom replication solution.


Snapshot Only

When setting up a subscription, you can specify that SQL Server will synchronize the published articles with the destination tables, and that the synchronization will repeat at defined intervals. Inserts, updates, deletes, or modifications to the published data will not be provided to the subscribers. This is called a Scheduled Table Refresh. In effect, it is a repeating automatic synchronization, with replication of subsequent transactions turned off.

For example, a scheduled table refresh could be useful if you need to completely refresh the data on a particular subscriber once a day, once a week, or once a month.


Push and Pull Subscriptions

For a subscription server to receive published data, it must subscribe to one or more articles or publications. This can be accomplished by performing either a push subscription or a pull subscription. The type of subscription is determined by the administrative focus, that is, on whether you are administering the publication server or the subscription server.

For more information, choose one of the following topics.

Push Subscriptions

Pull Subscriptions


Push Subscriptions

A push subscription is carried out when administrative focus is set on the publication server. As part of the process of creating or managing a publication, subscriptions are created by "pushing" out a publication or an article to one or more subscription servers.

One advantage of using push subscriptions is that they simplify and centralize subscription administration. The act of publishing is combined with the act of subscribing, and one person can perform both in the same administrative session. The need to separately administer each subscriber is eliminated. Another advantage is that for each publication, many subscribers can be set up at once.


Pull Subscriptions

A pull subscription is carried out when administrative focus is set on the subscription server. A subscription is created by "pulling" in a publication or an article from a publication server.

One advantage of using pull subscriptions is that they provide a degree of replication autonomy for a subscription server. The SA or DBO of the subscription server can decide which publications will be received. The subscriber avoids receiving unwanted data from a publication server. Another advantage is that for each subscription server, subscriptions from many publication servers can be set up during one administrative session.

With pull subscriptions, the act of publishing is separate from the act of subscribing, and the user administering the subscription server need not be the same person who administers the publication server.

For more information about push and pull subscriptions, see Chapter 14, Setting Up Replication.


Graphical Administration

SQL Enterprise Manager allows SQL Server administrators and database owners to manage SQL Server via a powerful yet easy-to-use interface. SQL Server replication particularly benefits from SQL Enterprise Manager. From a single server or workstation that has the SQL Server 6.0 utilities installed, you can use SQL Enterprise Manager to reach across your enterprise and set up a complete replication environment spanning as many servers as necessary. Replication can be completely set up and managed by using SQL Enterprise Manager.

Many of the procedures and examples in Chapter 14, "Setting Up Replication," and Chapter 15, "Advanced Replication," include instructions on how to use SQL Enterprise Manager to easily perform replication tasks. For more information about using SQL Enterprise Manager for tasks other than replication, see Chapter 2, Introducing the SQL Distributed Framework, or see the online Help for SQL Enterprise Manager.

As an option, you can also use manual procedures to set up replication. For more information, see Chapter 15, Advanced Replication.


Replication Security

SQL Server replication expands the security available from Windows NT and SQL Server 6.0 by limiting which users can set up and administer replication and which subscription servers can subscribe to (or even see) certain publications.

For more information, choose one of the following topics:

User-level Security

Publication-level Security


User-level Security

Replication permits SAs, database owners (DBOs), and others (public) to perform these replication tasks:

Replication task | SA | DBO | Public
Install a distribution database | X |  |
Configure a publication server | X |  |
View publication servers | X | X | X
Manage publications | X | X* |
View publications | X | X | X
Manage subscriptions | X | X* |
View subscription servers | X | X | X
Configure a database for publishing | X |  |
* Must be set up by the SA. For information, see Chapter 14, "Setting Up Replication."


Publication-level Security

On a publication-by-publication basis, you can control the access that subscription servers have to a publication by marking the publication as either unrestricted or restricted.

A publication marked as unrestricted is visible to and can be subscribed to by any subscription server known to the publication server.

A publication marked as restricted is visible to only those subscription servers authorized for access. Servers not authorized for access cannot subscribe to the publication; they cannot even see it. As a result, users setting up subscriptions at servers not authorized for access will not even know of a restricted publication. At those servers, it will not appear in any list.


Replication and SQL Executive

SQL Executive has a scheduling engine that controls scheduled replication tasks and is used to implement replicated data transfer. This scheduling engine has three subsystems: the log reader process, the distribution process, and the synchronization process. Together they provide the functionality that, administered through SQL Enterprise Manager, allows you to set the frequency of each replication task. For example, you could set up replication so that the publisher's log is continuously read, transactions are distributed to subscribers every ten minutes, and initial synchronization events occur every night at midnight. For more information on these processes, see Replication Components, earlier in this chapter.

SQL Executive maintains a task list, a task queue, and a task history that can be useful for troubleshooting replication. These can be viewed and managed by using SQL Enterprise Manager. For information on monitoring scheduled tasks, see Chapter 16, Scheduling Tasks.

Events in the task history can also be written to the Windows NT application log¾if the task is set to use Windows NT logging¾and can be viewed by using Event Viewer. For information on using Event Viewer, see your documentation for Windows NT.

SQL Executive also has an alerts engine that provides an easy way to set alerts on replication events. When the event occurs, SQL Executive responds automatically, either by executing a task that you have defined or by sending an email and/or a pager message to an operator you have specified. For information on setting up alerts for replication, see Chapter 17, Managing Alerts.


Replication and ODBC

A distribution server connects to all subscription servers as an Open Database Connectivity (ODBC) client. Replication requires that the ODBC 32-bit driver be installed on all distribution servers. The SQL Server 6.0 setup program automatically installs the necessary driver on Windows NT-based computers. You do not need to preconfigure ODBC Data Sources for SQL Server 6.0 subscription servers, because the distribution process will simply use the subscriber's network name to establish the connection.

By default, regardless of the security mode the servers are set for, a distribution server connects to a subscription server using a trusted connection. To support this connection, the SQL Client Configuration Utility on a distribution server (either a combined publisher/distributor or a remote distributor) must be set to use Named Pipes or Multi-Protocol as the default network.


Replication Scenarios

Following are scenarios depicting a few of the many possible replication configurations. These are provided to help orient you to the capabilities of SQL Server 6.0 replication. You are not limited to these configurations¾many others are possible.

For information choose one of the following topics:

Central Publisher

Central Publisher Using a Remote Distributor

Publishing Subscriber

Central Subscriber

Multiple Publishers of One Table

Downloaded Data

For additional examples and more detailed information¾including a summary of setup instructions¾see the examples provided in Chapter 14, Setting Up Replication, and Chapter 15, Advanced Replication.


Central Publisher

The basic replication scenario is a central publisher replicating data to any number of subscribers. The publication server is the primary owner of the replicated data, and the subscription server will usually treat this as read-only data. (Note that this means the data should be treated as read-only for the users of the subscription databases. Do not set the Read Only database option, or that subscription database will be unable to receive replicated data.) In this scenario, the publication server also acts as the distribution server.

This scenario might be used, for example, to distribute master data, lists, or reports from a central server to any number of subscription servers.

For information about implementing this scenario, see Chapter 14, Setting Up Replication.


Central Publisher Using a Remote Distributor

This scenario is similar to the central publisher scenario, except that separate computers perform the publication and distribution tasks. This is useful when the publication server¾for example, a heavily used online transaction processing (OLTP) server¾should be freed from the distribution role because of performance and storage space considerations. The publication server must be connected to the distribution server by a reliable, high-speed communications link.

For information about implementing this scenario, see Chapter 14, Setting Up Replication.


Publishing Subscriber

This scenario uses two servers to publish the same data. The publication server sends data to a subscription server, which then republishes the data to any number of subscribers. This is useful when a publication server must send data to subscribers over a slow or expensive communications link. If there are a number of subscribers on the far side of that link, using a publishing subscriber shifts the bulk of the distribution load to that side of the link.

Note that in this illustration, both the publication server and the publishing subscriber are acting as their own local distribution servers. If each was set up to use a remote distribution server, each distribution server would need to be on the same side of the slow or expensive communications link as its publication server. Publication servers must be connected to remote distribution servers by reliable, high-speed communications links.

For information about implementing this scenario, see Chapter 15, Advanced Replication.


Central Subscriber

In this scenario, a number of publication servers replicate information into a common destination table. The destination table is horizontally partitioned and contains a location-specific column as part of the primary key. Each publication server replicates rows containing location-specific data.

This replication configuration might be useful, for example, for rolling up inventory data from a number of servers at local warehouses into a central subscriber at corporate headquarters. It could also be used to roll up information from autonomous business divisions within a company, or to consolidate order processing from dispersed locations.


Multiple Publishers of One Table

This scenario shows a single table that is maintained on three servers. The table is horizontally partitioned, and each server is the publisher of the data in particular rows and the subscriber to data in the remaining rows. Each server controls its own data and has a view of the other data. Stored procedures can be used to allow updates to locally owned data only.

This replication configuration might be useful, for example, for maintaining common information at regionally dispersed centers, such as warehouses or divisional offices. It could also support regional order processing.


Downloaded Data

In this example, data is downloaded from a legacy database on a mainframe computer into a SQL Server 6.0 database on a server and is replicated to any number of subscription servers. This might be used, for example, in a large retail environment where sales and inventory information is entered at point-of-sale terminals and maintained on the mainframe but data is analyzed and management reports are created on the server and distributed to regional offices using SQL Server replication.

For information about implementing this scenario, see Chapter 15, Advanced Replication.


Frequently Asked Questions

Here are answers to some frequently asked questions about replication.

Who can receive replicated data?

Only SQL Server 6.0 servers can participate in replication. SQL Server 6.0 servers can publish, distribute, and subscribe to replicated data. However, replication is designed to support¾in the future¾other types of ODBC-enabled subscribers.

What is not replicated?

Not replicated are system tables and changes to the schema of a published table.

When the identity property has been applied to a column, data from that column can be replicated, but the identity property cannot. The identity property will not be applied to that column on subscription servers. For information about the identity property, see the Microsoft SQL Server Transact-SQL Reference.

All datatypes are replicated, with these exceptions:

  • A timestamp column becomes a binary(8) column.
  • When using transaction-based replication, data in a text or image column is passed as NULL.

    Note Text and image columns can be replicated via the table refresh mechanism. See "How are text and image columns handled?" next in this chapter.

Also, when setting up a publication, you can choose to pass user-defined datatypes or convert them to their base datatypes.

How are text and image columns handled?

Transaction-based replication of text and image columns is not supported. However, scheduled table refresh of text and image columns is supported.

For example, you could publish an article that contains text and image columns and do a table refresh of the subscribers at a defined interval (for example, every hour). You could then join the text and image destination table with a transaction log-based destination table. To ensure proper consistency, you would probably need to publish a timestamp column.

For information about publishing a table by using the Scheduled Table Refresh option, see Chapter 14, Setting Up Replication.

How many times can a subscriber subscribe to an article?

SQL Server replication permits each subscription server to subscribe only once to a particular article. Note that if a subscriber subscribes at the publication level, it is automatically subscribed to each article in that publication.

However, it is possible for a subscription server to use multiple copies of replicated data, since secondary copies of data can be locally processed on the subscription server.

For example, if database_1 subscribes to table_a, then database_2 on the same server cannot subscribe to the same article. However, you could, for example, create a trigger on the destination table_a in database_1 that does an insert, update, or delete into a table in database_2 every time destination table_a is updated. Or you could create a cross-database view using the replicated data.

Where can replicated data be modified?

In most cases, data will be modified only on the publication server. It is recommended that you maintain all replicated data residing in destination tables on subscription servers as read-only. (This means the data should be treated as read-only for the users of the subscription databases. Do not set the Read Only database option, or that subscription database will be unable to receive replicated data.)

This is not as limiting as it might at first sound, since each server can act as both subscriber and publisher and since secondary copies of data can be locally processed on the subscriber. For examples of publishing subscribers and of secondary processing of data, see Chapter 15, Advanced Replication.

Can one distribution server support multiple publication servers?

Yes. It possible to have one server distributing from a number of publication servers to a number of subscription servers. However, this increases the hardware requirements for the distribution server. In such a configuration, the distribution server will require additional memory and available disk space. A multiprocessor machine would be beneficial in this environment because it would take full advantage of the multithreaded architecture of the replication processes.

Is this a hot backup system?

The replication capability of SQL Server 6.0 is not specifically designed to accomplish hot backups, and it does not allow the subscriber to be automatically updated on changes that affect system tables (such as schema changes or permission changes).


Replication Terminology

To help you understand the information presented in this chapter, here are some replication-related definitions. This is a brief list of definitions and is not intended to serve as a comprehensive SQL Server glossary. It is provided as a quick reference, to help you understand some of the replication elements that are discussed throughout this chapter. You may find it useful to refer to this list of replication definitions as you read through this chapter; Chapter 14, "Setting Up Replication"; and Chapter 15, "Advanced Replication."

article
The basic unit of replication. An article contains data originating from a table that has been marked for replication. One or more articles are grouped within a publication.
automatic synchronization
Synchronization that is accomplished automatically by SQL Server. A snapshot is taken of the table data, and along with the table schemas that snapshot is written to files for transfer. The job to copy the table schema and data is transferred, as is any other replication job, via the distribution database. No operator intervention is required.
destination database
The subscribing database. The database that receives tables and data replicated from a publication database.
destination server
See subscription server.
destination table
The subscribing table, created as a replicated image of a published table. A destination table in a destination database is synchronized with and contains data derived from the published table in a publication database.
distribute
To move transactions from the distribution database tables to subscription servers, where they are applied to the destination tables in the destination databases.
distribution database
A store-and-forward database that holds all transactions that are waiting to be distributed to subscription servers. The distribution database receives transactions sent to it from the publication server by the log reader process and holds them until the distribution process moves them to the subscription servers.
distribution process
Moves transactions from the distribution database tables to subscription servers, where they are applied to the destination tables in the destination databases. The distribution process is a subsystem of the scheduling engine in SQL Executive.
distribution server
The server containing the distribution database. The distribution server receives all changes to published data, stores the changes in its distribution database, and, when appropriate (depending on scheduling and other variables), transmits them to subscription servers. The distribution server can be the same computer that is acting as the publication server, or a different computer. Also referred to as a distributor. See also local distribution server, remote distribution server.
distributor
See distribution server.
filtering
The method by which only selected rows or only selected columns of a table are designated for replication; the method by which partitioning is accomplished. See also partitioning.
horizontal filtering
See horizontal partitioning.
horizontal partitioning
Creating an article that replicates only selected rows from the base table. Subscription servers receive only that horizontally partitioned subset of data.
initial synchronization
See synchronization.
latency
The amount of time that elapses between a transaction being logged on the publication server and being successfully delivered to the destination database on the subscription server.

Latency consists of two components: duration in the transaction log, and duration in the distribution database.

local distribution server
When a publication server also acts as its own distribution server, it is sometimes called a local distribution server. In this case, the publication database and the distribution database reside on the same computer. Compare with remote distribution server.
log reader process
Moves transactions from the publication server transaction log into the distribution database. The log reader process is a subsystem of the scheduling engine in SQL Executive.
loose consistency
A replication model that allows a time lag between the moment original data is altered and the replicated copies of that data are updated¾it does not guarantee that all copies will be constantly identical to the original. An advantage of loose consistency is that it supports LANs, WANs, fast and slow communication links, and intermittently connected databases. It also allows better database availability and scales much better in its implementation as compared to tight consistency. SQL Server 6.0 replication is based on a loose consistency model.
manual synchronization
Synchronization that is accomplished by a user. As with automatic synchronization, the publication server produces files containing the schema and a snapshot of the data from the published table, but with manual synchronization, it is applied to the subscriber manually, using tape or an other medium. After a manual synchronization is accomplished, the user must inform SQL Server that the synchronization is complete. The user can obtain the table schema script (an .SCH file) and the table data file (a .TMP file) for each synchronization job from the working directory of the distribution database, which is set by default to \SQL60\REPLDATA.
no synchronization
A replication option sometimes used when a destination database subscribes to a publication. Synchronization is not accomplished by SQL Server. It is the responsibility of the user setting up replication to ensure that the table schema and data are identical for the published article and the destination table. This option allows changes to replicated data to be immediately distributed to subscribers, without delay for synchronization. See also automatic synchronization, manual synchronization.
partitioning
Creating an article that replicates only selected information from the base table. Subscription servers receive only that subset of data from the source table. Note that the replicated columns must include the primary key column(s). Sometimes referred to as filtering. See also horizontal partitioning, vertical partitioning.
publication
The term for a group of tables that have been made available for replication as a unit. A publication can contain one or more published tables¾articles¾from one user database. Each user database can have one or more publications.
publication database
A database that is the source of replicated data. A database containing tables that have been made available for replication.
publication server
A server that has made data available for replication. A publication server maintains publication databases, makes published data from those databases available for replication, and sends copies of all changes to the published data to the distribution server. Also referred to as a publisher.
publish
Make data available for replication.
publisher
See publication server.
pull subscription
A subscription performed while administrative focus is set on the subscription server. A subscription is created by "pulling" in a publication or an article from a publication server.

One advantage of a pull subscription is that it provides a degree of replication autonomy for a subscription server. The SA or DBO of the subscription server decides which publications will be received. In this way, the subscriber avoids receiving unwanted data from a publication server. Another advantage is that for each subscription server, subscriptions from many publication servers can be set up during one administrative session.

With a pull subscription, the act of publishing is separate from the act of subscribing, and the user administering the subscription server need not be the same person who administers the publication server. See also push subscription.

push subscription
A subscription performed while administrative focus is set on the publication server. As part of the process of creating or managing a publication, subscriptions are created by "pushing" out an article to one or more subscription servers.

One advantage of a push subscription is that it simplifies and centralizes subscription administration. The act of publishing is combined with the act of subscribing, and one person can perform both in the same administrative session. The need to separately administer each subscriber is eliminated. Another advantage is that for each article, many subscribers can be set up at once.

remote distribution server
When a publication server does not act as its own distribution server but instead is configured to send transactions that are marked for replication to a distribution database on another computer, then that other computer is called a remote distribution server. In this case, the publication database and the distribution database reside on separate computers. Compare with local distribution server.
replication
Duplication of table schema and data from a source database to a destination database, usually (but not necessarily) on separate servers.
restricted publication
A security status. A publication marked restricted is displayed to and can be subscribed to only those servers that have been granted access. See also unrestricted publication.
retention
The period of time that a transaction is maintained in the distribution database after it has been successfully delivered to the destination database on the subscription server.
schema script
See table schema script.
source database
See publication database.
subscribe
Agreeing to receive a publication or an article. A destination database on a subscription server subscribes to replicated data from a publication database on a publication server.
subscriber
See subscription server.
subscription database
See destination database.
subscription server
A subscription server maintains destination databases, which receive and maintain copies of published data. Also referred to as a subscriber.
synchronization
Before a subscription server can receive replicated transactions from an article or a publication, the publication and destination tables must contain the same schema and data. The process that accomplishes this normally occurs once and is called synchronization. Synchronization ensures that the table schema and the table data in the publication and destination databases are made identical.

SQL Server 6.0 replication ensures that updates are applied to a subscriber only after the subscriber is synchronized (has a current snapshot of the table schema and data). Synchronization affects new subscribers only.

synchronization process
Creates synchronization files containing data from published tables and applies these files, along with table schema files, to destination database tables. The synchronization process is a subsystem of the scheduling engine in SQL Executive.
synchronize
See synchronization.
table creation script
See table schema script.
table data file
A file containing a snapshot of the data of a published table, and used during synchronization as the source of data inserted into the destination table. The data snapshot is written to a file ending in the .TMP filename extension. The file is stored in the working directory of the distribution database, which is set by default to \SQL60\REPLDATA. See also table schema script.
table schema script
A script containing the schema of a published table, and used during synchronization to create the destination table. The schema script is written to a file ending in the .SCH filename extension. The file is stored in the working directory of the distribution database, which is set by default to \SQL60\REPLDATA. See also table data file.
tight consistency
A replication model that guarantees that all copies will be constantly identical to the original. It is usually implemented using two-phase commit, and it requires a high-speed LAN. It also reduces database availability and is less scalable in its implementation as compared to loose consistency.
unrestricted publication
A security status. A publication marked unrestricted (the default) is displayed to and can be subscribed to by any registered subscription server. See also restricted publication.
vertical filtering
See vertical partitioning.
vertical partitioning
Creating an article that replicates only selected columns from the base table. Subscription servers receive only that vertically partitioned subset of data. Note that the replicated columns must include the primary key column(s).


Chapter 14 Setting Up Replication

Setting Up Replication

To establish replication between servers of your enterprise, you set each server's distribution, publication, and subscription options, publish data from publication servers, and subscribe to published data from subscription servers. This chapter explains how to perform these tasks. It also discusses planning and prerequisites and explains how to stop replication.

The procedures presented in this chapter assume you will be using SQL Enterprise Manager to perform replication administration tasks. If you need to set up replication manually, see the instructions in Chapter 15, Advanced Replication. For background and conceptual information about replication, see Chapter 13, Replication Concepts.

For information, choose one of the following topics.

Before You Set Up Replication

Configuring Servers for Replication

Publishing

Subscribing

Stopping Replication

Replication Tips

Replication Examples


Before You Set Up Replication

Before you set up replication, review the following information.

Satisfy server hardware requirements

There are no special memory or other hardware requirements for subscription servers, nor for publication servers that are configured to use a remote distribution server.

However, if a server will act as either a distribution server or a combined publication/distribution server, it must have at least 32 MB of memory installed, with at least 16 MB assigned to SQL Server. Use SQL Enterprise Manager or sp_configure to assign memory to SQL Server. For information about assigning memory, see Chapter 3, Configuring Servers.

If a distribution server will be set up to perform distribution for more than one publication server, the distribution server will require additional memory and available disk space. A multiprocessor machine is beneficial in this environment because it takes full advantage of the multithreaded architecture of the distribution processes.

All other hardware and software requirements are identical to those for any SQL Server installation. For SQL Server hardware and software requirements, see Microsoft SQL Server Setup.

Use one character set

Publication, distribution, and subscription servers that participate together in replication should be configured to use the same character set.

If you would like query results on replicated data to remain consistent between the publication and subscription servers, it is recommended that servers that participate together in replication to use the same sort order. (However, this is not required.)

Set the server logon security mode

Replication can be implemented on servers that have been configured to use any of SQL Server's login security modes. For information about the login security mode, see Chapter 8, "Security Concepts."

By default, regardless of the security mode the servers are set for, a distribution server connects to a subscription server using a trusted connection (forced integrated security). This means that the SQL Client Configuration Utility on the distribution server (a combined publisher/distributor or a remote distributor) must be set to use Named Pipes or Multi-Protocol as the default network.

This also means that when servers participate in replication but reside within separate Windows NT Server domains, trust relationships must be established between those domains. For information on establishing trust relationships, see your manuals for Windows NT Server.

Create publication and destination databases

It is not required, but it is a good idea to create the databases that will be published and the databases that will subscribe to published data before configuring servers to participate in replication. This allows you to mark those databases as authorized to publish or subscribe at the time that you configure the server replication options.

Allow adequate transaction log space for publication databases

For each database that will be published, make sure that the transaction log has ample space allocated to it.

The transaction log of a published database may require more space than the log of an identical database that is not set up to be published. If the distribution database is unavailable for any reason, or if the replication log reader is not running, the transaction log of a publication database will continue to grow and cannot be truncated past the oldest published transaction that has not been passed into the distribution database (unless replication is turned off completely for that database).

Add declared primary keys to tables that will be published

Primary key support requires that all published tables contain a declared primary key. Existing tables can be prepared for publishing by adding a declared primary key using the Manage Tables functionality of SQL Enterprise Manager, or the following ALTER TABLE syntax.

ALTER TABLE [database.[owner.]]table_name
ADD CONSTRAINT constraint_name
PRIMARY KEY [CLUSTERED | NONCLUSTERED]
(column_name [{, column_name}...])
[WITH FILLFACTOR = fillfactor]

For more information about adding a declared primary key using SQL Enterprise Manager, see the Microsoft SQL Server Database Developer's Companion. For more information on ALTER TABLE, see the Microsoft SQL Server Transact-SQL Reference.


Configuring Servers for Replication

Before a server can participate in replication as a publisher, you must install or select a distribution database and also set the server's publication options. Before a server can participate in replication as a distributor, you must install a distribution database. Before a server can participate in replication as a subscriber, you must set the server's subscription options.

For information, choose one of the following topics.

Installing or Selecting a Distribution Database

Setting Publication Options

Setting Subscription Options

Using the Replication Topology Window

Setting Up DBOs to Manage Publications and Subscriptions


Installing or Selecting a Distribution Database

If a server will participate in replication as a publisher, before any other replication options are set, you must define whether that publication server will act as its own distribution server or will use a remote distribution server. If it will act as its own distribution server, a distribution database must be installed.

If a server will act as a remote distribution server for other publication servers, it must have a distribution database installed. This must be set up before any dependent publication servers are set up.

Note If a server will act as either a distribution server or a combined publication/distribution server, it must have at least 32 MB of memory installed, with at least 16 MB assigned to SQL Server. Use SQL Enterprise Manager or sp_configure to assign memory to SQL Server. For more information, see Chapter 3, Configuring Servers.

To install or select a distribution database
  1. From the Server Manager window, select a server.
  2. From the Server menu, choose Replication Configuration, and then from the drop-down menu that appears, choose Install Publishing.

    The Install Replication Publishing dialog box appears.

  3. To configure this server to act as the distributor of its own publications, or to prepare it to act as a remote distribution server for other publication servers:
    • Choose the Local option.
    • In the Database Name box, type a name for the distribution database. The default name is distribution.
    • In the Data Device box, select a device for the distribution database, and type a size in the Size (MB) box. If the device does not already exist, add it by choosing <new> from the Data Device box and completing the New Device dialog box that appears.
    • In the Log Device box, select a device for the distribution database transaction log, and type a size in the Size (MB) box. If the device does not already exist, add it by choosing <new> from the Log Device box and completing the New Device dialog box that appears.

    Note Replication of published data requires extensive use of the distribution database. A minimum size of 30 MB for the data device and 15 MB for the log device is recommended for initial implementation. These sizes can be expanded as required.

  4. To configure this server to use a remote distribution server, select the Remote option, and then select a server from the list.

    The selected server will maintain the distribution database and will run the log reader, synchronization, and distribution processes for this publication server.

  5. Choose OK.

    Important Before you choose the OK button, make certain the distribution database options are set appropriately. Once a distribution database is selected, a significant reconfiguration is required to change to a different distribution database. For information about changing the distribution database, see Chapter 15, Advanced Replication.

    After you choose OK, a dialog box asks whether you will configure publication options for this server at this time.

  6. Choose Yes.

    The Replication-Publishing dialog box appears. For information on completing this dialog box and setting the publication options, see Setting Publication Options.


Setting Publication Options

The server publication options determine the servers that are authorized to subscribe to this server's publications, the schedule by which replication will be performed for each subscription server, which of this server's databases are authorized to publish data, and the directory used as the distribution working directory. For a server that will act as a remote distribution server, the server publication options also determine which publication servers are authorized to use it as a remote distribution server.

To set a server's publication options
  1. In the previous topic, Installing or Selecting a Distribution Database, if you chose the Yes button in step 6, then the Replication-Publishing dialog box is already displayed.

    If not, then from the Server Manager window, select a server; from the Server menu, choose Replication Configuration; and from the drop-down menu that appears, choose Publishing.

    The Replication-Publishing dialog box appears.

  2. Define the servers that will be permitted to subscribe to this server's publications by selecting them in the Enable Publishing to These Servers list.

    If a server is not registered with SQL Enterprise Manager or is not set as a remote server to this server, it will not be listed. To register a server, choose the New Server button and complete the Register Server dialog box that appears.

  3. To set a subscription server's distribution schedule to a setting other than the default (continuous replication), select the Distribution Schedule cell for that server, choose the Distribution Options button, and complete the Distribution Options dialog box that appears.

    The Distribution Options dialog box contains these elements:

    • Commit Every <x> Transactions to Subscriber specifies the maximum number of transactions that will be sent to the subscription server as a single unit. If the number of transactions marked for replication exceeds this number, several units will be sent. (Note that tuning this number can improve your distribution throughput.)
    • Distribution Schedule displays the distribution schedule (the interval at which transactions will be replicated to the subscription server).
    • Change opens the Task Scheduling dialog box, where you can change the distribution schedule for the subscription server.
    • Retention Period After Distribution (hours) determines how long transaction information is retained in the distribution database after it is applied to the subscriber.
  4. Under Publishing Databases, select the databases that will be allowed to publish data.

    If you have not yet created all the databases to be published, go ahead and complete the publication options now. You can later create the necessary databases and then return and edit the publication options to authorize the new databases for publication.

  5. To change the distribution working directory, type a new Universal Naming Convention (UNC) path in the Working Directory box.

    This directory is used to store the schema scripts and data synchronization files. The default is \\servername\C$\SQL60\REPLDATA, where servername is the name of the distribution server.

    A UNC path takes the form \\servername\sharename\directory.

  6. If this server will act as remote distribution server for other publication servers:
    • Choose the Distribution Publishers button. The Replication-Distribution dialog box appears.

    • In the Replication - Distribution dialog box, select the servers that will be permitted to use this server as their remote distribution server.

      If a server is not registered with SQL Enterprise Manager or is not set as a remote server to this server, it will not be listed. To register a server, choose the New Server button, and complete the Register Server dialog box that appears.

    • Choose OK.
  7. Choose OK.


Setting Subscription Options

The server subscription options determine the publication servers that are permitted to replicate to this server, and the destination databases on this server that are permitted to subscribe to publications.

To set server subscription options
  1. In the Server Manager window, select a server.
  2. From the Server menu, choose Replication Configuration, and then from the drop-down menu that appears, choose Subscribing.

    The Replication-Subscribing dialog box appears.

  3. Define the publication servers that will be permitted to replicate to this server by selecting them in the Enable Subscribing from These Servers list.

    If a server is not registered with SQL Enterprise Manager or is not set as a remote server to this server, it will not be listed. To register a server, choose the New Server button and complete the Register Server dialog box that appears.

  4. Under Subscribing Databases, select the databases that will be allowed to subscribe to publications.

    If you have not yet created the destination databases on this server, go ahead and complete the subscription options now. You can later create the necessary databases and then return and edit the subscription options to authorize the new databases to subscribe to publications.

  5. Choose OK.


Using the Replication Topology Window

The Replication Topology window provides a convenient way to view the replication relationships of a server, to add subscription servers, and to open the replication management dialog boxes that are provided by SQL Enterprise Manager.

To use the Replication Topology window
  1. From the Server Manager window, select a server.
  2. From the toolbar, select the Replication Topology button. Or from the Server menu, choose Replication Configuration, and then from the drop-down menu that appears, choose Topology.

    The Replication Topology window appears, with the selected server in the center. Other servers with which it has replication or remote server relationships are depicted in the window, connected to it by links.

  3. To change the perspective, choose the Zoom Out or Zoom In buttons.
    • Choose Zoom In to increase the magnification. Servers and other elements of the topology are enlarged, but the area that can be viewed without scrolling is reduced.

    • Choose Zoom Out to reduce the magnification. Servers and other elements of the topology are reduced, but the area that can be viewed without scrolling is enlarged.

  4. To rearrange the location of servers in the topology illustration, click and drag them to the desired locations in the window.
  5. To add a server, select a server from the Server Manager window, and then drag and drop it into the Replication Topology window.

    If you have SA privileges on both new servers, the new server is automatically configured as a subscription server to the central server. This sets up the two servers as remote servers for each other and adds the appropriate remote logins required to support replication.

  6. To manage replication for any of the depicted servers, use the right mouse button to click on the server, and then select from the commands on the drop-down menu that appears.
    • Choose Replication Configuration to install or select a distribution database, or to set server publication and subscription options. It is the equivalent of the same command on the Server menu.
    • Choose Publications to publish data. It is the equivalent of the Manage Replication/Publications command from the Manage menu, or the Manage Publications button on the toolbar. This command is unavailable if this server's publication options are not set up to allow publishing.
    • Choose Subscriptions to subscribe to published data. It is the equivalent of the Manage Replication/Subscriptions command from the Manage menu, or the Manage Subscriptions button on the toolbar. This command is unavailable if this server's subscription options are not set up to allow subscribing.


Setting Up DBOs to Manage Publications and Subscriptions

When you set up publication, distribution, and subscription servers for replication, permissions are automatically set that allow the SAs to manage publications and subscriptions. However, before the DBOs of the publication and subscription databases can manage publications or subscriptions, the proper permissions must be set up.

Permissions are set up by creating some necessary SQL Server login IDs, database users, and remote login mappings. Permissions are set up separately for the DBOs of publication and subscription databases. There are two ways to set up permissions for the DBO of a publication database, depending on whether that publication server uses a remote distribution server or acts as its own combined publisher/distributor.

A DBO on a Combined Publisher/Distributor

When a publication server is configured to act as a combined publisher/distributor, to allow the DBO of a publication database to manage publications, you must:

  1. Add a database user to the publisher's msdb database for the login ID of the user who is DBO in the publication database.
  2. Add a database user to the publisher's distribution database for the login ID of the user who is DBO in the publication database.

If several users in the publication database are aliased to DBO, this must be repeated for each aliased user. Or, all users could be aliased to one user in the msdb database, and to one user in the distribution database.

Database users are set up using SQL Enterprise Manager or the sp_adduser system stored procedure. For detailed information about setting up database users, see Chapter 9, Managing Security.

A DBO on a Publication Server that Uses a Remote Distributor

When a publication server is configured to use a remote distribution server, to allow the DBO of a publication database to manage publications, you must:

  1. On the distribution server, add a login ID for the user from the publication server (the user who is the DBO of the publication database). If that user already has a login ID on the remote distribution server, skip this step.

    Add the login ID using SQL Enterprise Manager or sp_addlogin.

  2. On the distribution server, to the msdb database, add a database user for the login ID that was added in step 1.

    Add the database user using SQL Enterprise Manager or sp_adduser.

  3. On the distribution server, to the distribution database, add a database user for the login ID that was added in step 1.
  4. On the distribution server, map the login ID from the publication server to the login ID on the remote distributor.

    Map the login IDs using sp_addremotelogin. For example, if the publication server is named AIREDALE, the login ID on the distribution server is peggysue, and the login ID of the DBO of the publication database is peggy, you would type:

    sp_addremotelogin AIREDALE, 'peggysue', 'peggy'
  5. On the distribution server, set the trusted remote login option to use integrated security.

    Set the remote login option using sp_remoteoption. For the above example, you would type:

    sp_remoteoption AIREDALE, 'peggysue', 'peggy', 'trusted', true

If several users in the publication database are aliased to DBO, this must be repeated for each aliased user. In this case, instead of creating a database user for each one, you could alias all the users to one user in the msdb database, and to one user in the distribution database.

For detailed information about setting up database users, see Chapter 9, Managing Security. For information about setting up remote logins, see Chapter 10, Remote Servers and Users.

A DBO on a Subscription Server

To allow the DBO of a destination database to manage subscriptions, you must use sp_addremotelogin to map the login ID of the DBO on the subscriber to the repl_subscriber login ID on the publisher. This mapping is performed on the publication server. To use integrated security, the trusted remote login option must then be set using sp_remoteoption.

This must be repeated for each publication server that the destination database will subscribe from. If several users in that destination database are aliased to DBO, this must be repeated once for each aliased user.

To set up permissions allowing the DBO of a destination database on a subscription server to subscribe to the publications from a publication server
  • On the publication server, type

    sp_addremotelogin remoteserver, 'repl_subscriber', 'loginID'

    where

    remoteserver
    Is the name of the subscription server. (From the perspective of the publication server that is being administered, the subscriber is a remote server.)
    repl_subscriber
    Is the login ID on the local server. (In this case, it is the special repl_subscriber login ID on the publication server.)
    loginID
    Is the login ID on the subscriber. (The login ID of the user who is DBO of the destination database.)

    For example:

    sp_addremotelogin TERRIER, 'repl_subscriber', 'delaney'

Then type:

sp_remoteoption remoteserver, 'repl_subscriber', 'loginID', 'trusted', 'true'

For example:

sp_remoteoption TERRIER, 'repl_subscriber', 'delaney', 'trusted', 'true'

For more information about setting up remote logins, see Chapter 10, Remote Servers and Users.


Publishing

Data is published by creating a publication, selecting the tables to be included in the publication, and making the publication available to subscription servers. A table included in a publication is called an article. An article can be the entire table, or a subset of columns and/or rows from the table.

The topics that follow explain how to create and modify publications and articles.

For more information choose one of the following topics:

Creating Publications

Defining Articles

Modifying Publications and Articles


Creating Publications

One or more publications can be created from each user database on a publication server. Publications cannot span databases: each publication can contain articles from only one database.

Before you create publications, you must set the server replication options as described in Configuring Servers for Replication, earlier in this chapter.

To create a new publication
  1. From the Server Manager window, select a publication server.
  2. From the toolbar, choose the Manage Publications button. Or from the Manage menu, choose Replication, and then from the drop-down menu that appears, choose Publications.

    The Manage Publications dialog box appears.

  3. Select a database, and then choose the New button.

    The Edit Publications dialog box appears.

  4. In the Publication Title box, type a name for the new publication.

    A publication name must be unique for this database and conform to the rules for identifiers.

  5. In the Description box, type a description of this publication.

    A description can be up to 255 characters.

  6. Select a replication frequency.

    Replication frequency determines the basic method that will be used to replicate this publication.

    • Transaction based specifies that each transaction marked for replication will be read from the transaction log of the source database and applied to the destination databases.
    • Scheduled table refresh specifies that at scheduled intervals all articles in the publication will be refreshed. Each time refresh occurs, all data (and, optionally, the table schemas) will be applied to all destination tables. No data changes are sent between the scheduled refresh intervals. Transaction-based replication does not occur.
  7. To specify the tables that will be published, select the Articles tab, select one or more tables from the Database Tables list, and choose the Add button.

    The tables are added to the Articles in Publication list.

  8. To customize an individual table, select the Articles tab, select an article from the Articles in Publication list, choose the Edit button, and complete the Manage Articles dialog box that appears.

    You have a number of options for customizing an article. For each article, you can set the article name, article description, and destination name; exclude rows and columns from those published (horizontal and vertical partitioning); customize the synchronization schema script; and customize the data replication mechanism. For more information, see Defining Articles, later in this chapter.

  9. When the article is defined, from the Manage Articles dialog box, choose OK.

    The Edit Publications dialog box returns.

  10. To define the initial synchronization method and schedule, choose the Synchronization tab, and complete the Synchronization options.

    Initial synchronization determines the method by which the output data files are created for synchronization of the destination database. (This applies for both automatic and manual synchronization.) This can be bcp, native format (the default); or bcp, character format.

    The schedule determines how frequently automatic synchronization will be performed for new subscriptions. Since automatic synchronization of databases or even individual tables requires a fairly high amount of system overhead, using automatic synchronization on a scheduled basis allows you to set an interval between the time a server subscribes to a publication and is synchronized to that publication. This allows synchronization to be scheduled for a low-activity period on the publication and subscription servers.

  11. To restrict replication to only selected servers, select the Security tab, choose the Restricted option, and from the list of servers, select those servers that are authorized to access this publication.

    A publication marked unrestricted is visible to and can be subscribed to by any subscription server. A publication marked restricted is visible only to those subscription servers that have been marked for access.

  12. When the publication is defined, choose the Add button.

    The Manage Publications dialog box returns. The new publication and its articles are listed under the published database.

    Note that restricted publications have a key added to their icons.

  13. To create additional publications, repeat steps 3 through 12.
  14. When you finish creating publications, choose the Close button.


Defining Articles

A published table is called an article. You have a number of options for controlling the way a table is published. An article can be the entire table or a subset of columns and/or rows from the table.

For each article, you can set the article name, article description, and destination table name; exclude rows and columns from those published (horizontal and vertical partitioning); customize the synchronization schema script; and customize the data replication mechanism. You accomplish these tasks by using the Manage Article dialog box.

To define an article
  1. While creating a publication, from the Edit Publications dialog box, select the Article tab; from the Articles in Publication list, select an article; and then choose the Edit button.

    For information about how to access the Edit Publications dialog box, see Creating Publications, earlier in this chapter.

    The Manage Article dialog box appears.

  2. To change the default name supplied for the article, type a new name in the Name box.
  3. To provide a description of this article, type it in the Description box.

    A description can be up to 255 characters.

  4. To change the default name supplied for the destination table, type a table name in the Destination Table box.
  5. To partition the article vertically or horizontally, select the Filters tab.
  6. To partition the article vertically¾so that only selected columns are replicated¾select the Replicate option box for each column to be replicated. Clear the Replicate option box for each column that will not be replicated.

    If you do not modify the default settings, all columns are replicated. You must replicate the primary key column.

  7. To partition the article horizontally¾so that only selected rows are replicated¾type a WHERE clause in the Restriction Clause box.

    For example, if you have published the authors table from the pubs database and are editing the authors article, you could replicate only those rows containing authors from California by typing:

    state = 'CA'
  8. To customize the data replication mechanism or the synchronization schema script, select the Scripts tab.

  9. Define the data replication mechanism.

    Usually, you will not change this from the default. The data replication mechanism determines the action SQL Server takes when the log reader process encounters transactions (INSERT, UPDATE, or DELETE) that are marked for replication in the transaction log of the publication database.

    • To use the default, do not change the selected options for the INSERT Command, UPDATE Command, and DELETE Command.

      When the log reader process encounters a transaction of one of these types (INSERT, UPDATE, or DELETE) that is marked for replication in the transaction log of the publication database, the SQL statement will be reconstructed and applied to the destination database. This is the default data replication mechanism used by SQL Server replication.

    • To specify custom processing for one or more of the command types (INSERT, UPDATE, or DELETE), choose the Custom option, and then enter a custom command in the Custom box. There are two possible custom commands.

      If you enter NONE, transactions of that type will not be replicated. For example, if for DELETE you choose the Custom option, and type NONE, then DELETE commands will not be replicated.

      If you enter CALL stored_procedure_name (for example, if you type CALL MYPROC), when the log reader encounters a command of that type (INSERT, DELETE, or UPDATE) in a transaction marked for replication, it will pass column parameters from that transaction to the referenced stored procedure. The referenced stored procedure must exist in the destination database of each subscriber.

      For information about creating your own stored procedures to be called when INSERT, DELETE, or UPDATE statements are encountered by the log reader, see Chapter 15, Advanced Replication.

  10. To allow SQL Server to automatically create the initial table synchronization schema script for you, leave the Creation Script box blank.

    When you edit a new article, this box is empty. When you edit an existing article, this box contains the full path to the schema script in the distribution working directory. For example:

    \\TERRIER\C$\SQL60\REPLDATA\terrier_sales_receipts_charges.sch

    Schema scripts are automatically generated when a publication is created or modified (by choosing the Add or Modify button from the Edit Publications dialog box).

  11. To edit an existing schema creation script, choose Edit, edit the creation script in the Creation Script dialog box that appears, and then choose OK.

    The Manage Article dialog box returns.

  12. To generate a schema script now, choose the Generate button and complete the Auto-Generate Sync Scripts dialog box that appears.

    • Select Do Nothing when you do not want to drop, truncate, or delete rows from the destination table before synchronization is applied.
    • Select DROP Table First to drop the existing table before synchronization is applied.
    • Select Truncate Table Only to remove all rows but leave the table structure in place before synchronization is applied.
    • Select Delete Data using Restriction Clause to remove only the target rows (as defined by the restriction clause) before synchronization is applied.
    • Select Transfer Clustered Index to create in the destination table the same clustered index that exists for the published table.
    • Select Transfer non-Clustered Index to create in the destination table the same non-clustered indexes that exist for the published table.
    • Select Convert UDDT to base datatype to convert user-defined datatypes from the published table to base datatypes in the destination table.
    • Select Include DRI-PK to copy the declared primary key to the destination table.

    When the options are set, choose Auto-Generate. The initial table synchronization schema script is created. The Manage Article dialog box returns.

  13. To use a schema creation script that you have prepared manually, place that schema script in the distribution working directory, and then enter the full path and filename in the Creation Script box. For example:
    \\TERRIER\C$\SQL60\REPLDATA\terrier_sales_receipts_myschema.sch

    Note that you enter the full UNC path even if this is a combined publisher/distributor using its own local distribution working directory. Use the administrative share name (ending in "$") for the drive, rather than the drive letter.

  14. To specify custom filtering, select the Advanced button and complete the Manage Article-Advanced dialog box that appears.

    • To specify a custom filter stored procedure, select a stored procedure from the list in the Filter Stored Procedure box.

      This is a filter stored procedure that you have previously created in the publication database. This stored procedure must take the form:

      IF sql_statement RETURN 1, ELSE RETURN 0

      where sql_statement is a Transact-SQL statement that accomplishes filtering. For example:

      IF exists (select * from authors where city = 'Oakland')
   return 1
else
   return 0

      Because the filter is executed against every log record for the replicated table, the filter should be as simple as possible. This will minimize overhead.

      Any reference to the table will represent only a single log record value.

    • To set the synchronization object to an object other than the default, select the object from the list in the Synchronization Object box. If you are setting up custom filtering, this will be a view you have created in the publication database.

      The Synchronization Object is the database object that is used as the source of the data for the initial synchronization of the destination table. In most cases, this is handled automatically by SQL Server and you do not need to change from the default. By default, the synchronization object is the article's base table. If the article has been horizontally and/or vertically partitioned, SQL Server automatically creates a view of the partitioned table, and by default that view becomes the synchronization object.

      The Synchronization Object list includes all the tables and views in the publication database.

    When the options are set, choose OK. The Manage Article dialog box returns.

  15. When the advanced article is defined, from the Manage Article dialog box, choose OK.

    The Edit Publications dialog box returns.

If you create an auto-generated script that does not support the creation of indexes, then the synchronization task will use fast bcp as the initial synchronization method if the Select Into/Bulk Copy option is set in the destination database.


Modifying Publications and Articles

You modify an existing publication or article in a manner similar to the way you create a new publication or article. However, you cannot modify a publication or article that has an existing subscription. Before modifying a publication or an article, you must drop all subscriptions. After modifying a publication or article, resubscribe all appropriate subscribers.

To modify a publication and/or its articles
  1. From the Server Manager window, select a publication server.
  2. From the toolbar, choose the Manage Publications button.

    The Manage Publications dialog box appears.

  3. Choose a database's "" box to display its publications. Select a publication from the list, and then choose the Change button.

    The Edit Publications dialog box appears.

    Modify the publication as necessary. For detailed information about the information you can change for a publication, see Creating Publications, earlier in this chapter.

  4. To modify an article, in the Edit Publications dialog box, select the Articles tab, select an article from the Articles in Publication list, choose the Edit button, and complete the Manage Articles dialog box that appears.

    For detailed information about the information you can change for an article, see Defining Articles, earlier in this chapter.


Subscribing

To subscribe means to agree to receive a publication or an article. A destination database on a subscription server subscribes to replicated data from a publication database on a publication server.

When setting up a subscription, you have the option of performing either a pull subscription or a push subscription. The type of subscription is determined by the administrative focus, that is, on whether you are administering the publication server or the subscription server.

A pull subscription is carried out while a subscription server is being administered. A subscription is created by "pulling" in a publication or an article from a publication server. A push subscription is carried out while a publication server is being administered. As part of the process of creating or managing a publication, subscriptions are created by "pushing" out a publication or an article to one or more subscription servers.

After a subscription is set up, the publication and destination tables must be initially synchronized. Synchronization makes the table schema and the table data in the destination database identical to that in the publication database. SQL Server prevents updates from being replicated to a destination database until the new subscription has been synchronized.

In many cases, when you set up a subscription, you will specify automatic synchronization, which is accomplished automatically by SQL Server and requires no user intervention. However, if a subscription is set up specifying manual synchronization, a user must first perform the synchronization and then inform SQL Server that the manual synchronization is completed. Only after SQL Server is informed of this manual synchronization are updates allowed to be applied to the destination database.

For more information, choose one of the following topics.

Setting Up Pull Subscriptions

Setting Up Push Subscriptions

Acknowledging a Manual Synchronization


Setting Up Pull Subscriptions

A pull subscription is carried out while a subscription server is being administered. A subscription is created by "pulling" in a publication or an article from a publication server.

With pull subscription, the act of publishing is separate from the act of subscribing, and the user administering the subscription server need not be the same person who administers the publication server.

One advantage of using pull subscriptions is that the SA or DBO of the subscription server decides which publications will be received. Another advantage of a pull subscription is that for each subscription server, subscriptions from many publication servers can be set up during one administrative session.

Before subscribing to publications or articles, create the necessary destination databases on the subscription server, and authorize those databases to subscribe to publications. For information on creating databases, see Chapter 6, Managing Databases. For information on authorizing databases to subscribe to publications, see Configuring Servers for Replication, earlier in this chapter.

To set up a pull subscription
  1. From the Server Manager window, select the subscription server.
  2. From the toolbar, choose the Manage Subscriptions button. Or from the Manage menu, choose Replication, and then from the drop-down menu that appears, choose Subscriptions.

    The Manage Subscriptions dialog box appears, displaying a list of the servers that have been authorized to publish to this subscription server.

  3. Open the published database tree for a publication server (choose the "" box next to the server name), and then from the displayed list of published databases, open the publications list for the database (choose the "" box next to the database).

    A list of that database's publications appears.

  4. Select a publication. Or open the article tree for the publication (choose the "" box next to the publication name), and then select an article.

    This is the publication or article that will be subscribed to. If you select a publication, all articles in the publication will be included in the subscription.

  5. Choose Subscribe.

    The Subscription Options dialog box appears.

  6. From the list in the Destination Database box, select a database.

    This is a database on the subscription server that will receive the replicated tables and data.

  7. Under Sync Method, select a synchronization option.
    • Select Data Synchronization Automatically Applied when you want SQL Server to automatically synchronize the schema and data of the destination tables with the published tables. This is the default synchronization method.
    • Select Data Synchronization Manually Applied by Operator when synchronization will be carried out by a user. The user must obtain schema and data files from the distribution server, manually synchronize the schema and data of the destination tables with the published tables, and then inform SQL Server that the synchronization is complete.

      Selecting manual synchronization can affect all the replicated data being sent to a destination database, since when the synchronization job becomes the next job in the distribution database queue, replication to the entire subscription database is paused until the manual synchronization is carried out and SQL Server is informed that the synchronization is complete. For more information about manual synchronization, see Acknowledging a Manual Synchronization, later in this chapter. Also see Chapter 13, Replication Concepts.

    • Select No Data Synchronization when you want SQL Server to immediately begin sending modifications to published data to the destination database. SQL Server assumes that the publication and destination tables are already synchronized. This option is intended for advanced users who will be implementing a custom replication solution.
  8. To view information about the publication, choose the More Info button.

    The Publication Info dialog box appears.

  9. Choose OK.

    The subscription is added. The Manage Subscriptions dialog box returns.


Setting Up Push Subscriptions

A push subscription is carried out while a publication server is being administered. As part of the process of creating or managing a publication, subscriptions are created by "pushing" out an article to one or more subscription servers. A push subscription is possible only after a user with SA privileges on the subscription server has enabled this publication server (in the Replication Subscribing dialog box, as described in Setting Subscription Options, earlier in this chapter).

One advantage of using push subscriptions is that they simplify and centralize subscription administration. The act of publishing is combined with the act of subscribing, and one person can perform both in the same administrative session. The need to separately administer each subscriber is eliminated. Another advantage is that for each article, many subscribers can be set up at once.

However, push subscriptions can only be accomplished at the article level. (Pull subscriptions, on the other hand, can be accomplished at both the publication and article levels.)

Before subscribing articles, create the necessary destination databases on the subscription server, and authorize those databases to subscribe to publications. For information on creating databases, see Chapter 6, Managing Databases. For information on authorizing databases to subscribe to publications, see Configuring Servers for Replication, earlier in this chapter.

You set up a push subscription while creating or editing publications on a publication server.

To set up a push subscription
  1. Create or edit the publication as described in Creating Publications, earlier in this chapter.
  2. While creating or editing the publication, in the Edit Publications dialog box, select an article from the Articles in Publication list, and choose Edit.

    The Manage Article dialog box appears.

  3. Choose Subscribers.

    The Publication Subscribers dialog box appears, listing the servers that are authorized to subscribe to publications of this publication server.

  4. From Subscription Servers list, select a server, and choose Subscribe.

    The Subscription Options dialog box appears.

  5. From the list in the Destination Database box, select a database.

    This is a database on the subscription server that will receive the replicated tables and data.

  6. Under Sync Method, select a synchronization option.
    • Select Data Synchronization Automatically Applied when you want SQL Server to automatically synchronize the schema and data of the destination table with the published table. This is the default synchronization method.
    • Select Data Synchronization Manually Applied by Operator when synchronization will be carried out by a user. The user must obtain schema and data files from the distribution server, manually synchronize the schema and data of the destination table with the published table, and then inform SQL Server that the synchronization is complete.

      Selecting manual synchronization can affect all the replicated data being sent to a destination database, since when the synchronization job becomes the next job in the distribution database queue, replication to the entire subscription database is paused until the manual synchronization is carried out and SQL Server is informed that the synchronization is complete. For more information about manual synchronization, see Acknowledging a Manual Synchronization, later in this chapter. Also see Chapter 13, Replication Concepts.

    • Select No Data Synchronization when you want SQL Server to immediately begin sending modifications to published data to the destination database. SQL Server assumes that the publication and destination tables are already synchronized. This option is intended for advanced users who will be implementing a custom replication solution.
  7. Choose OK.

    The subscription is added. The Publication Subscribers dialog box returns.

  8. To subscribe to another server, repeat steps 4 through 7.
  9. When you are done subscribing servers, from the Publication Subscribers dialog box, choose OK, and then complete the creation or editing of the publication or article.

For more information on creating or editing publications and articles, see Publishing, earlier in this chapter.


Acknowledging a Manual Synchronization

Before a subscription server can receive replicated transactions from an article or a publication, the publication and destination tables must contain the same schema and data. The process of accomplishing this is called initial synchronization. Synchronization ensures that the table schema and the table data in the publication and destination databases are made identical. Synchronization affects new subscribers only.

Replication allows updates to be applied to a subscriber only after the subscriber is synchronized (has a current snapshot of the table schema and data).

If you choose the automatic synchronization option for a subscription, synchronization will occur automatically, and you do not need to take any special action. However, if you choose the manual synchronization option for a subscription, before replication can begin for that subscription, you must manually synchronize the published tables on the publication server with the destination tables in the destination database on the subscription server.

Manual synchronization might be accomplished, for example, by loading files from a tape that has been mailed to a remote server location. Manual synchronization is particularly useful when the publication and subscription servers are connected by a slow, expensive, or low-quality network connection or when a table being published is very large.

SQL Server automatically creates synchronization files and places them in the publication server's distribution working directory. There are two files for each synchronization job for each published article: a schema script (an .SCH file) and a data file (a .TMP file).

You can determine the name and location of the schema synchronization file for an article by opening the Manage Article dialog box for that article, choosing the Scripts tab, and reading the entry in the Creation Script box. This box contains the full path to the schema script in the distribution working directory. For information about accessing the Manage Article dialog box, see Publishing, earlier in this chapter.

For example, suppose the server TERRIER is a combined publisher/distributor; has its distribution working directory set to C:\SQL60\REPLDATA; and has a publication database named sales, a publication named receipts, and a published table named charges. Then the following could be displayed for the article in the Creation Script box of the Manage Article dialog box:

\\TERRIER\C$\SQL60\REPLDATA\terrier_sales_receipts_charges.sch

To determine the name of the synchronization data file, you can view the task history for the sync task. This history gives the exact .TMP filename created. (Also, when a destination database is waiting on a manual synchronization, the full name and path of the .TMP file will be contained in the description column of the MSlast_job_info table in the destination database of the subscriber. The article and publication names are also contained in that table.) For information on viewing task history, see Chapter 16, Scheduling Tasks.

After you have created a table on the destination server with the schema from the creation script and have populated it with the data from the data file, you must inform SQL Server that the manual synchronization is complete.

Note that when a destination database is waiting on a manual synchronization, it cannot receive any updates to any of the other publications it is subscribed to (not just the publication that is waiting for a manual synchronization).

To acknowledge completion of a manual synchronization
  1. From the Server Manager window, select the subscription server, and then from the toolbar, choose the Manage Subscriptions button.

    The Manage Subscriptions dialog box appears.

  2. Open the published database tree for a publication server (choose the server's "" box), and then select a database and open its publication tree (choose the publication's "" box).

    A list of that database's publications appears.

  3. Select a publication, open the article tree for a publication (choose the publication's "" box), and then select an article.
  4. Choose Sync Completed.

    A confirmation dialog box appears. If the distribution process is waiting for the manual synchronization of this article, the Sync Completed button is enabled. If not, it is dimmed.

  5. Choose Yes.

    SQL Server has been informed that the subscription server's destination database is synchronized with the publication or article(s). The replication processes are now allowed to send replication transactions (changes to data in the synchronized articles) to the destination database.

For more information about manual synchronization, see Chapter 13, Replication Concepts.


Stopping Replication

After replication has been implemented, there are several ways you can stop data from being replicated. The methods you use depend on whether you will be stopping replication from a subscription server, a publication server, or a distribution server.

For information, choose one of the following topics.

Stopping Replication from a Subscriber

Stopping Replication from a Publisher

Stopping Replication from a Distributor


Stopping Replication from a Subscriber

While administering a subscription server, you can cancel subscriptions to selected publications or articles.

To cancel subscriptions
  1. From the Server Manager window, select a subscription server, and then from the toolbar, select the Manage Subscriptions button.

    The Manage Subscriptions dialog box appears, listing publication servers that are authorized to publish to this subscriber.

  2. Open the publication tree for a publication server (choose the "" box).

    A list of that server's publications appears.

  3. Cancel the subscription.
    • To cancel a subscription to a publication, select the publication (click the publication name, not its or - symbol), and then choose the Un-Subscribe button.

      The server will be unsubscribed from the publication, including all the articles contained within that publication.

    • To cancel a subscription to a single article within a publication, open the article tree for the publication (choose the "" box), select an article, and choose the Un-Subscribe button.

      The server will be unsubscribed from that article.

  4. Choose Yes in the confirmation dialog box.

Another way to stop replication while administering a subscription server is to change the server's subscription options. You can remove the authorization that allows a publication server to send publications to the subscription server, or you can remove the authorization that allows a destination database to subscribe to publications

To stop replication by resetting a server's subscription options
  1. From the Server Manager window, select a subscription server.
  2. From the Server menu, choose Replication Configuration, and then from the drop-down menu that appears, choose Subscribing.

    The Replication-Subscribing dialog box appears.

  3. To stop a publication server from sending replicated data to this subscription server, under Enable Subscribing from These Servers, clear the option box for that server.

    The publication server can no longer publish to this subscription server.

    Caution This does not stop transactions from being placed in the distribution database for this subscriber. To do that, first unsubscribe from the publication. This action should only be taken as an emergency measure, to stop unwanted data from being replicated to a subscription server.

  4. To stop a database on this subscription server from receiving replicated data from any publisher, under Subscribing Databases, clear the option box for that database.

    The database is no longer a destination database and can no longer subscribe to replicated data.

    Note This only affects future subscriptions.

  5. Choose OK.


Stopping Replication from a Publisher

There are a several ways you can stop replication while administering a publication server. While managing a server's publications, you can remove a publication, which cancels replication of that collection of tables, or remove an article from a publication, which cancels replication of that table. Or, while managing publications on the publication server, you can "un-subscribe" one or more subscription servers from a particular article.

You cannot remove a publication or article that has an existing subscription. Before removing a publication or an article, you must drop all subscriptions.

To remove a publication or an article
  1. From the Server Manager window, select a publication server, and then from the toolbar, choose the Manage Publications button.

    The Manage Publications dialog box appears.

  2. Open the publication tree for a database (choose the "" box).

    A list of that database's publications appears.

  3. Select a publication (click the publication name, not its "" box), and then choose Remove.

    Or click the publication's "" box, select an article from the list that appears, and then choose Remove.

    A confirmation dialog box appears.

  4. Choose Yes.

    The selected publication or article is removed. To republish this data, you would need to re-create the publication or article and resubscribe its subscribers.

While managing publications on the publication server, you can "un-subscribe" one or more subscription servers from a particular article.

To un-subscribe subscribers while administering a publication server
  1. From the Server Manager window, select a publication server, and then from the toolbar, choose the Manage Publications button.

    The Manage Publications dialog box appears.

  2. Open the publication tree for a database, select a publication, and then choose the Change button.

    The Edit Publications dialog box appears.

  3. Select an article from the Articles in Publication list, and then choose Edit.

    The Manage Article dialog box appears.

  4. Choose Subscribers.

    The Publication Subscribers dialog box appears.

  5. From the list of subscription servers, select a server, and then choose Un-Subscribe.

    A confirmation dialog box appears.

  6. Choose Yes to confirm the action.

    The server is unsubscribed.

By changing the replication options for a publication server, you can remove the authorization that allows a database to be published, remove the authorization that allows a subscription server to subscribe to publications from this publication server, or set the distribution schedule for a subscription server to a value that will not soon occur.

To stop replication by resetting a server's publication options
  1. From the Server Manager window, select a publication server.
  2. From the Server menu, choose Replication Configuration, and then from the drop-down menu that appears, choose Publishing.

    The Replication-Publishing dialog box appears.

  3. To cancel the authorization for a subscription server to subscribe to the publications of this server, clear the option box for that server under Enable Publishing to These Servers.
  4. To stop a database from publishing data, under Publishing Databases, clear the option box for that database.

    When you choose OK to accept this change, the database will no longer be authorized to publish, and its publications and articles will be dropped. If you wanted to re-create its publications, you would need to reauthorize the database for publication, re-create the publications, and resubscribe its subscribers.

  5. Choose OK.


Stopping Replication from a Distributor

From a remote distribution server, you can stop replication by removing the authorization that allows a publication server to use that remote distribution server.

To remove the authorization that allows a publication server to use a remote distribution server
  1. From the Server Manager window, select a remote distribution server.
  2. From the Server menu, choose Replication Configuration, and then from the drop-down menu that appears, choose Publishing.

    The Replication-Publishing dialog box appears.

  3. Choose the Distribution Publishing button.

    The Replication-Distribution dialog box appears.

  4. To stop a publication server from using this server as its remote distribution server, under Distribution Publishers, clear the option box for that server.

    That publication server can no longer use this server as a remote distributor. Published data from that server is no longer replicated but will continue to be preserved in the transaction log.

    If that publisher is later reconfigured to become a combined publisher/distributor or to use this server or another server as its remote distributor, every publication on the publication server must be republished, and all its subscribers must be resubscribed.

  5. Choose OK.

From any distribution server (either a remote distribution server or a combined publisher/distributor), you can suspend, edit, or drop scheduled replication tasks that are performed by the log reader process, the synchronization process, or the distribution process. For example, stopping a log reader task is a useful way to stop replication to all subscribers from a selected publication database.

To stop a log reader task for a publication
  1. From the Server Manager window, select the distribution server.
  2. Under the selected server, double-click the Executive icon.

    The Task Scheduling window appears, with the Task List tab selected.

  3. From the task list, double-click on the task that will be suspended.

    For example, if the publication server AIREDALE has published a database named inventory, and if there are one or more publications from that database, then the distribution server task list will display a task named AIREDALE_inventory, with a Type of LogReader.

    The Edit Task dialog box appears.

  4. Clear the Enabled option.
  5. Choose Modify.

    The task is suspended. It appears in the task list and retains all its settings but will not be run by SQL Executive.

    To reinstate a suspended task, repeat the preceding procedure, but in step 4 select the Enabled option. For more information about suspending, editing, or dropping tasks, see Chapter 16, Scheduling Tasks.


Replication Tips

Here are some tips that you can use to more efficiently configure replication:

Where possible, publish a table only once

Using the same table in multiple publications will cause multiple distribution events (and thus a higher load on network traffic) every time data in that table changes.

Publish only the amount of data required

Since the publication of replicated data is quite easy to set up, there is a tendency to publish more data than is actually required. This has the effect of both consuming additional resources within the distribution databases and lowering the throughput for required data.

Establish as many subscriptions as possible before initial synchronization

Synchronization of databases or even individual tables requires a fairly high amount of system overhead. Using automatic synchronization on a scheduled basis allows an interval between the time a server subscribes to a publication and the initial synchronization of the destination database on that subscription server. This allows subscription servers a period of minimal impact during which they can subscribe to several publications. It also allows synchronization to be scheduled for a low-activity period on the publication server.

When a scheduled initial synchronization time arrives, synchronization occurs only for those subscribers that have requested synchronization (not for all subscribers to that publication). This minimizes the impact on the other subscribers.

To replicate to numerous subscribers, establish a multilevel replication scheme

A publication server can publish to one or more "publishing subscribers," which in turn publish the data to their own subscribers. For more information, see the advanced replication examples in Chapter 15, Advanced Replication.

To replicate to numerous subscribers, reduce their distribution frequency

A single distribution server will be able to distribute transactions to a larger number of subscribing servers if the frequency of the distribution task associated with each subscribing server is scheduled to run less frequently. Additional performance gains can be achieved by staggering the initial times of these distribution tasks so that they do not all attempt to start simultaneously.

For example, suppose transactions are being replicated to 30 subscribing servers, and distribution is scheduled to occur for all machines every 3 minutes. By creating 10 distribution tasks with a starting time of 12:00 AM, 10 tasks with a starting time of 12:01 AM, and 10 tasks with a starting time of 12:02 AM, the times when these tasks start will be staggered, reducing contention for resources and improving overall throughput.


Replication Examples

The examples in this section show you how to:

  • Set up servers in basic replication roles and establish replication relationships between those servers
  • Replicate a table from one server to another
  • Filter a published table so that only specified rows and columns are replicated
  • Restrict a publication so that it can be seen by and can be replicated to only a selected list of servers
  • Reduce the replication load on the publication server by setting it up to use a separate distribution server
  • Selectively subscribe a subscription server to a subset of the available publications
  • Replicate a table locally, to another database on the publication server

In general, each succeeding example builds on the replication configuration established by the previous examples. For this reason, it is a good idea to review the examples in sequence.

For information, choose one of the following topics.

Setting Up A Replication Topology

Replicating a Table

Replicating a Partitioned Table

Restricting a Publication

Using a Remote Distributor

Selectively Subscribing to Data

Replicating a Table Locally


Setting Up a Replication Topology

This example will show you how to set up servers in basic replication roles and how to establish replication relationships between servers. In this example:

  • The server TERRIER will be configured as a publication server. It will also act as its own distribution server.
  • The servers AIREDALE, COLLIE, and MUTT will be configured as subscription servers to TERRIER.
  • The pubs database on TERRIER will be enabled for publishing.
  • On each subscription server, one destination database will be created and enabled for subscribing.

The following example assumes that the servers AIREDALE, COLLIE, MUTT, and TERRIER have had SQL Server installed and that the servers are registered with the copy of SQL Enterprise Manager that is used to set up replication.

To set up the replication topology example
  1. On TERRIER, verify that at least 16 MB of memory is assigned to SQL Server.

    Start SQL Enterprise Manager; from the Server Manager window, select TERRIER; from the Server menu, choose Configurations; and from the Server Configuration/Options dialog box that appears, select the Configuration tab. Verify that the memory setting is 8192 or greater. If it is not, change it, and then restart the server.

    This computer must have at least 32 MB of memory installed.

  2. Install a distribution database on TERRIER.
    • From the Server menu, choose Replication Configuration, and from the drop-down menu that appears, choose Install Publishing. The Install Replication Publishing dialog box appears. By default, the Local option is selected, and the Database Name box has an entry of distribution.

    • Add a device for the distribution database by choosing <new> from the Data Device box and completing the New Device dialog box that appears. Name the device distdata and give it a size of 30 MB.
    • Add a device for the distribution database transaction log by choosing <new> from the Log Device box and completing the New Device dialog box that appears. Name the device distlog and give it a size of 15 MB.
    • Choose OK. A dialog box asks whether you will configure publication options for this server at this time.

    • Choose Yes. The Replication-Publishing dialog box appears.
  3. Set the publishing options for TERRIER.

    • Under Enable Publishing to These Servers, select the Enable checkboxes for AIREDALE, COLLIE, and MUTT.
    • Under Publishing Databases, select the checkbox for pubs.

      This does not publish the database but does authorize the database to publish.

    • Choose the OK button.
  4. Create a database on each subscription server, to be used as the destination databases.

    On AIREDALE, create a database named inaire; on COLLIE, create incollie; and on MUTT, create inmutt. For information on using SQL Enterprise Manager to create a database, see Chapter 6, Managing Databases.

  5. Set the subscription options for each subscriber. For AIREDALE, COLLIE, and MUTT, perform these steps:
    • From the Server Manager window, select the subscription server (for example, AIREDALE); from the Server menu, choose Replication Configuration; and from the drop-down menu that appears, choose Subscribing. The Replication-Subscribing dialog box appears.

    • Under Enable Subscribing from These Servers, select the Enable checkbox for TERRIER.
    • Under Subscribing Databases, select the Enable checkbox for the database that will be authorized to be a destination database (for example, inaire).

      This does not subscribe the database to any publications, but it does authorize the database to subscribe.

    • Choose OK.

    You have finished setting up your example replication topology.

  6. To view a graphic depiction of the replication topology that you have set up, from the Server Manager window, choose TERRIER, and then from the toolbar, choose the Replication Topology button.

    The Replication Topology dialog box appears.

The replication topology you have created will be the basis for most of the subsequent examples in this chapter.


Replicating a Table

Now that the basic replication relationships between servers have been established by the preceding example, we will show how easy it is to set up replication of a table from one server to another. In this example, the server TERRIER will publish the titles and publishers tables from the pubs database, and the server COLLIE will subscribe to them.

To replicate tables from TERRIER to COLLIE
  1. Publish the titles and publishers tables by creating the publication newpub.

    • From the Server Manager window, select TERRIER, and then from the toolbar, choose the Manage Publications button. The Manage Publications dialog box appears.
    • Select the pubs database, and then choose the New button. The Edit Publications dialog box appears.
    • In the Publication Title box, type:
      newpub
    • In the Description box, type:
      Publishing two tables from the pubs database.
    • From the Database Tables list, select the titles and publishers tables, and then choose the adjacent Add button. The tables are added to the Articles in Publication column.
    • From the top right corner of the dialog box, choose Add. The Manage Publications dialog box returns.
    • Choose Close.
  2. Subscribe the incollie database on COLLIE to the newpub publication from TERRIER.

    • From the Server Manager window, choose COLLIE, and then from the toolbar, choose the Manage Subscriptions button. The Manage Subscriptions dialog box appears.
    • Open the published database tree for TERRIER (choose the "" box next to the server name), and then open the publications list for the pubs database (choose the "" box next to the database).
    • Select the newpub publication, and then choose Subscribe. The Subscription Options dialog box appears.
    • From the list in the Destination Database box, select the incollie database.
    • Choose OK. The Manage Subscription dialog box returns.
    • Choose Close.

This replication example is now set up. If the default synchronization setting for the publication newpub was not changed, synchronization will occur within five minutes. Synchronization will copy the schema and data from the published tables to the destination database. After that, replication of changes to table data will occur as changes are made.


Replicating a Partitioned Table

If appropriate for your requirements, you can publish only a subset of the data from a table. You can create an article that:

  • Replicates only selected columns of the base table. Subscription servers receive only that vertically partitioned subset of the data. The replicated columns must include the declared primary key column.
  • Replicates only selected rows of the base table. Subscription servers receive only that horizontally partitioned subset of the data. The following illustration shows the replication of a horizontally partitioned table.

Of course, an article can be simultaneously partitioned both vertically and horizontally.

In this example we publish a table and partition its article both vertically and horizontally. The server TERRIER publishes the pubs..employee table. It is vertically partitioned so that only the emp_id (primary key), fname, and lname columns are replicated. It is partitioned horizontally on the job_lvl value so that only rows for employees with a job level greater than 99 will be replicated. The server AIREDALE subscribes to this article.

To replicate a partitioned table
  1. Publish the pubs..employee table.

    • From the Server Manager window, select TERRIER, and then from the toolbar, choose the Manage Publications button. The Manage Publications dialog box appears.
    • Select the pubs database, and then choose the New button. The Edit Publications dialog box appears.
    • In the Publication Title box, type:
      filterpub
    • In the Description box, type:
      Publishing a horizontally and vertically filtered table.
    • From the Database Tables list, select the employee tables, and then choose the adjacent Add button. The table is added to the Articles in Publication column.
  2. Set up vertical and horizontal partitions.
    • Choose the Edit button. The Manage Article dialog box appears, with the Filter tab selected.
    • Partition the table vertically by clearing the Replicate check boxes for all the columns that will not be replicated. In this example, only the check boxes for emp_id, fname, and lname should remain selected.

      Note that the primary key column (in this case, emp_id) must be replicated.

    • Partition the table horizontally by typing this in the Restriction Clause box:
      job_lvl > 99
    • Choose OK. The Edit Publications dialog box returns.
    • Choose Add. The Manage Publications dialog box returns.
    • Choose Close.
  3. Subscribe AIREDALE to the filterpub publication from TERRIER.

    • From the Server Manager window, choose AIREDALE, and then from the toolbar, choose the Manage Subscriptions button. The Manage Subscriptions dialog box appears.
    • Open the published database tree for TERRIER (choose the "" box next to the server name), and then open the publications list for the pubs database (choose the "" box next to the database).
    • Select the filterpub publication, and then choose Subscribe. The Subscription Options dialog box appears.
    • From the list in the Destination Database box, select the inaire database.
    • Choose OK. The Manage Subscription dialog box returns.
    • Choose Close.

This replication example is now set up. If the default synchronization setting for the publication filterpub was not changed, synchronization will occur within five minutes. Synchronization will copy the schema and data from the published tables to the destination database. After that, replication of changes to table data will occur as changes are made.

Only the specified columns and rows will be synchronized and replicated.


Restricting a Publication

Each publication has a security status of unrestricted (the default) or restricted. An unrestricted publication is visible to and can be subscribed to by any registered subscription server. A restricted publication is visible to and can be subscribed to by only those subscription servers that have been granted access.

Here we will show you how to publish a restricted publication. In this example:

  • The server TERRIER will publish the pubs..stores table in the RESTRICT1 publication and will grant access to the subscribers COLLIE and MUTT only.
  • The servers COLLIE and MUTT will subscribe to the RESTRICT1 publication.
  • The server AIREDALE cannot subscribe to the RESTRICT1 publication. The publication will not be visible to AIREDALE (it will not appear in any publication lists displayed by SQL Enterprise Manager).

To publish a restricted publication
  1. Publish the pubs..stores table by creating the publication safepub.

    • From the Server Manager window, select TERRIER, and then from the toolbar, choose the Manage Publications button. The Manage Publications dialog box appears.
    • Select the pubs database, and then choose the New button. The Edit Publications dialog box appears.
    • In the Publication Title box, type:
      safepub
    • In the Description box, type:
      A restricted publication.
    • From the Database Tables, list select the stores table, and then choose the adjacent Add button. The table is added to the Articles in Publication column.
  2. Restrict access to the publication.
    • Choose the Security tab.
    • Choose the Restricted To option, and then select the Allow Access check boxes for COLLIE and MUTT.
    • Choose Add. The Manage Publications dialog box returns.
    • Choose Close.
  3. Subscribe COLLIE and MUTT to the safepub publication from TERRIER. For each subscriber, perform these steps:

    • From the Server Manager window, choose the name of the subscription server, and then from the toolbar, choose the Manage Subscriptions button. The Manage Subscriptions dialog box appears.
    • Open the published database tree for TERRIER (choose the "" box next to the server name), and then open the publications list for the pubs database (choose the "" box next to the database).
    • Select the safepub publication, and then choose Subscribe. The Subscription Options dialog box appears.
    • From the list in the Destination Database box, select a destination database.
    • Choose OK. The Manage Subscription dialog box returns.
    • Choose Close.


Using a Remote Distributor

Here we will show you how to configure replication so that separate servers perform the publication and distribution roles. This configuration is useful when the publication server¾for example, a heavily used online transaction processing (OLTP) server¾should be freed from the distribution role because of performance and storage space considerations. The publication server must be connected to the distribution server by a reliable, high-speed communications link.

In this example:

  • The server AKITA will be configured as a publication server.
  • The server MALAMUTE will be configured as a distribution server for AKITA.
  • The servers AIREDALE, COLLIE, and MUTT will be configured as subscription servers to AKITA.

To set up the replication topology using a remote distributor
  1. On MALAMUTE, verify that at least 16 MB of memory is assigned to SQL Server.

    From the Server Manager window, select MALAMUTE; from the Server menu, choose Configurations; and from the Server Configuration/Options dialog box that appears, select the Configuration tab. Verify that the memory setting is 8192 or greater. If it is not, change it, and then restart the server.

    The distribution server (MALAMUTE) must have at least 16 MB of memory assigned.

  2. Install replication publishing on MALMUTE.
    • From the Server menu, choose Replication Configuration, and from the drop-down menu that appears, choose Install Publishing. The Install Replication Publishing dialog box appears. By default, the Local option is selected, and the Database Name box has an entry of distribution.
    • Add a device for the distribution database by choosing <new> from the Data Device box and completing the New Device dialog box that appears. Name the device distdata, and give it a size of 60 MB.
    • Add a device for the distribution database transaction log by choosing <new> from the Log Device box and completing the New Device dialog box that appears. Name the device distlog, and give it a size of 30 MB.
    • Choose OK. A dialog box asks whether you will configure publication options for this server at this time.
    • Choose Yes. The Replication-Publishing dialog box appears.
  3. Allow MALAMUTE to distribute for AKITA.
    • Choose the Distribution Publishers button. The Replication-Distribution dialog box appears.
    • Select the Enable checkbox for AKITA. This allows MALAMUTE to distribute for AKITA.
    • Choose OK. The Replication-Publishing dialog box returns.
    • Choose OK.
  4. Install replication publishing on AKITA.
    • From the Server Manager window, choose AKITA; from the Server menu, choose Replication Configuration; and from the drop-down menu that appears, choose Install Publishing. The Install Replication Publishing dialog box appears.
    • Choose the Remote option, and then from the list under Use Existing Remote Distribution Server, choose MALAMUTE.
    • Choose OK. A dialog box asks whether you will configure publication options for this server at this time.
    • Choose Yes. The Replication-Publishing dialog box appears.
  5. Set the publishing options for AKITA.
    • Under Enable Publishing to These Servers, select the Enable check boxes for AIREDALE, COLLIE, and MUTT.
    • Under Publishing Databases, select the check box for the databases that will be authorized to publish.

      This does not publish the databases, but it does authorize the databases to publish data.

    • Choose the OK button.
  6. Set the subscription options for each subscriber. For AIREDALE, COLLIE, and MUTT perform these steps:
    • From the Server Manager window, select the subscription server (for example, AIREDALE); from the Server menu, choose Replication Configuration; and from the drop-down menu that appears, choose Subscribing. The Replication-Subscribing dialog box appears.
    • Under Enable Subscribing from These Servers, select the Enable check box for AKITA.
    • Under Subscribing Databases, select the Enable check box for the databases that will be authorized to be destination databases.

      This does not subscribe the databases to any publications, but it does authorize the databases to subscribe.

    • Choose OK.

    You have finished setting up your example replication topology using a remote distributor.

  7. To view a graphic depiction of the replication topology that you have set up, from the Server Manager window, choose AKITA, and then from the toolbar, choose the Replication Topology button.

    The Replication Topology dialog box appears.

You can now create publications on AKITA and subscribe to those publications and articles from AIREDALE, COLLIE, and MUTT. MALAMUTE will act as the distribution server.


Selectively Subscribing to Data

A subscription server can subscribe to none, some, or all publications offered by a publication server. Within each publication, it can subscribe to some or all of the articles.

In this example:

  • The server AKITA creates two publications, PUB1 and PUB2. Two tables are added to PUB1 and become articles 1A and 1B. Three tables are added to PUB2 and become articles 2A, 2B, and 2C.
  • The server AIREDALE subscribes to PUB1 and PUB2 and receives all articles.
  • The server COLLIE subscribes only to article 2B.
  • The server MUTT subscribes only to articles 1B, 2A, and 2C.

To selectively subscribe to data
  1. Create the publications and articles on AKITA.
    • Create a publication named PUB1.

      Add the authors table, and then edit that article and rename it 1A.

      Add the titles table, and then edit that article and rename it 1B.

    • Create a publication named PUB2.

      Add the publisher table, and then edit that article and rename it 2A.

      Add the sales table, and then edit that article and rename it 2B.

      Add the stores table, and then edit that article and rename it 2C.

  2. Subscribe AIREDALE to PUB1 and PUB2.

    Subscribing to a publication is the same as subscribing to all articles in the publication. AIREDALE will receive articles 1A, 1B, 2A, 2B, and 2C.

  3. Subscribe COLLIE only to article 2B.
  4. Subscribe MUTT to articles 1B, 2A, and 2C.


Replicating a Table Locally

A table can be replicated locally, to another database on the same server. In this example, on the server TERRIER, the pubs..titles table will be replicated to the localdest database.

The following example assumes that the replication topology has been configured following the example in Setting Up A Replication Topology, earlier in this chapter.

To replicate a table to a local database
  1. Create a database named localdest on TERRIER.

    For this example, this will be used as the destination database. For information on using SQL Enterprise Manager to create a database, see Chapter 6, Managing Databases.

  2. Authorize TERRIER to publish to itself.
    • From Server Manager, select TERRIER; from the Server menu, choose Replication Configuration; and then from the drop-down menu that appears, choose Publishing. The Replication-Publishing dialog box appears.
    • Under Enable Publishing to These Servers, select the check box for TERRIER.

      This authorizes the server to replicate to itself.

    • Choose OK.
  3. Authorize localdest to be a subscription database.
    • From the Server menu, choose Replication Configuration, and then from the drop-down menu that appears, choose Subscribing. The Replication-Subscribing dialog box appears.
    • Under Enable Subscribing from These Servers, the Enable check box for TERRIER should already be selected. If it is not, select it.
    • Under Subscribing databases, choose the Enable check box for localdest.

      This does not subscribe the database to any publications, but it does authorize the database to subscribe.

    • Choose OK.
  4. Publish the pubs..authors table.

    • From the toolbar, choose the Manage Publications button. The Manage Publications dialog box appears.
    • Select the pubs database, and then choose the New button. The Edit Publications dialog box appears.
    • In the Publication Title box, type:
      allauthors
    • In the Description box, type:
      Publishing a table from the pubs database.
    • From the Database Tables, list select the authors table, and then choose the adjacent Add button. An article named authors_Table is added to the Articles in Publication column.
    • From the upper-right corner of the dialog box, choose Add. The Manage Publications dialog box returns.
    • Choose Close.
  5. Subscribe the localdest database to the allauthors publication.

    • From the toolbar, choose the Manage Publications button. The Manage Subscriptions dialog box appears.
    • Open the published database tree for TERRIER (choose the "" box next to the server name), and then from the displayed list of published databases, open the publications list for the pubs database (choose the "" box next to the database).
    • Select the allauthors publication, and then choose Subscribe. The Subscription Options dialog box appears.
    • From the list in the Destination Database box, select the localdest database.
    • Choose OK. The Manage Subscription dialog box returns.
    • Choose Close.

This replication example is now set up. If the default synchronization setting for the publication allauthors was not changed, synchronization will occur within five minutes. Synchronization will copy the schema and data from the published tables to the destination database. After that, replication of changes to table data will occur as changes are made.


Chapter 15 Advanced Replication

Advanced Replication

This chapter describes some advanced replication scenarios; explains how to monitor, maintain, and troubleshoot replication; describes the tables, stored procedures, scripts, and registry entries used by replication; and shows you how to set up replication manually, without the use of SQL Enterprise Manager.

For information, choose one of the following topics.

Advanced Replication Examples

Replication Maintenance

Troubleshooting and Recovery

Advanced Setup Tasks

Monitoring Replication

Tables, Stored Procedures, and Scripts Used by Replication

Manual Replication


Advanced Replication Examples

This section provides examples that tell you how to implement some advanced replication scenarios. These are more complex than the basic examples provided in Chapter 14, Setting Up Replication. As with the basic examples in that chapter, these advanced replication examples are provided to help orient you to the capabilities of SQL Server 6.0 replication.

You are not limited to these configurations¾many others are possible.

For information, choose one of the following topics.

Setting Up a Publishing Subscriber

Replicating Downloaded Data


Setting Up a Publishing Subscriber

Establishing a hierarchy of replication servers can minimize the amount of communications traffic that is passed over a slow or expensive network link. In this example, a hierarchy of replication servers is established, with a single subscription server that is physically located at the far side of a network link from the publisher. This subscriber receives all changes to the published tables and then republishes these changes to other nearby subscription servers.

Because any server can act as both publication and subscription server, setting up this configuration is simple. For this example, we will consider the publication of a table that exists in New York and needs to be distributed to four different cities in Europe: London, Oslo, Paris, and Lisbon. The server in London is chosen to subscribe to the published table originating in New York, because the London site meets these conditions:

  • The network link back to New York is relatively reliable
  • The New York-to-London communication costs are acceptable
  • There are good network communications lines from London to all other European subscriber sites

The step-by-step process for setting up replication has been presented in Chapter 14, Setting Up Replication. The following summaries assume you know how to set up replication, and only address the changes to a standard configuration that are required to set up this hierarchy of replication servers.

The information that follows discusses considerations when:

  • Setting up the first-level publisher (New York)
  • Setting up the subscriber/publisher (London)
  • Setting up the second-level subscribers (Oslo, Paris, Lisbon)
Setting up the First-level Publisher
  1. On the New York server, authorize the London server as a server permitted to subscribe.

    Set this up in the Replication Publishing dialog box by selecting the London server in the Enable Publishing to These Servers list.

    Even though this publication will eventually be replicated to many servers in Europe, the publication server in New York defines only the London server as a server permitted to subscribe.

  2. On the New York server, reduce the setting for Commit Every <x> Transactions to Subscriber.

    Set this up in the Replication Publishing dialog box by selecting the London server from the Enable Publishing to These Servers list, choosing the Distributions Options button, and entering a smaller number (for example, 1) in the Distribution Options dialog box that appears.

    Because the London server sits on the far side of a slow network link, selecting a smaller size for replicated transactions will allow published table changes to be distributed across the network using reasonably sized transactions.

  3. Publish the table.

    When creating the article, you must be sure to replicate the primary keys. To do this, choose the Include DRI-PK option for the article's synchronization script. This is set by choosing the Generate button from the Manage Article dialog box. For information see Chapter 14, Setting Up Replication.

Setting up the Subscriber/Publisher
  1. On the London subscription server, subscribe to the table published by the New York server.
  2. While subscribing, decide the initial synchronization option.
    • If the published table is fairly large in size, consider performing a manual initial synchronization.

      This prevents the distribution process from having to send a large data file across the slow or expensive network link. When manual data synchronization is selected, the initial Synchronization task will still create a .TMP file containing an image of the published table, but it is not automatically applied. The .TMP file must be physically sent to the remote site and manually applied.

    • If you know that both the table on the publication server and the destination table on the subscription server already exist and are completely synchronized with one another, consider choosing the No Data Synchronization option.

      This allows replication of table data changes to begin without producing or applying a .TMP initial synchronization file.

  3. On the London server, install a distribution database, or select a remote distributor.

    To do this, select the Replication Configuration/Install Publishing command from the Server menu, and then complete the dialog box that appears.

  4. Set the publication options on the London server.
    • Authorize the Oslo, Paris, and Lisbon servers to act as subscribers.
    • Authorize the publication of the appropriate database on the London server. This is the same database that has subscribed to the publication from the New York server.

    Both of the settings are performed in the Replication Publishing dialog box.

  5. Publish the table.

    This is the local table that has been replicated from the New York server.

  6. On the London server, set the Commit Every <x> Transactions to Subscriber option for the Oslo, Paris, and Lisbon servers.
    • Unless the Distribution process from New York to the London server was set to commit for each individual transaction using the Distribution Option of Commit Every 1 Transaction, then groups of transactions from New York may have been applied as a single transaction at the London server. When the table changes are republished, this group of transactions will appear as a single transaction on the London server.

      To avoid the problem of exponentially increasing groups of transactions, the distribution option to second-level subscribers should be set to Commit Every 1 Transaction.

      Set this up in the Replication Publishing dialog box by selecting a server from the Enable Publishing to These Servers list, choosing the Distributions Options button, and entering a number in the Distribution Options dialog box that appears.

    • Setting the Commit Every 1 Transaction option can also be done for just the specific database receiving the republished table changes. This can only be done once the second-level subscriber has subscribed to a publication within the republishing database. To change the commit option for an individual database use the SQL Enterprise Manager Task Scheduling tool, edit the appropriate distribution task, and set the -c parameter within the command window to -c1.
Setting up the Second-level Subscribers

The second-level subscribers (Oslo, Paris, Lisbon) subscribe to the London publication using normal subscription procedures. As long as all replicated data is treated as read-only, it can remain completely transparent to the second-level subscription servers that the original publisher of the replicated table was not the server in London but a server in New York.

An exception to this occurs if a second-level subscriber needs to send a change back to the primary owner of the replicated table. In this case, the change needs to be applied not to the London server but to the server in New York.

SQL Enterprise Manager allows you to display origination information to second-level subscribers. When creating a second-level publication, the publication description field can be used to provide the origination server information, and the article description field can provide the original table name if it has changed. This information can then be accessed by subscribers in two ways:

  • From the Manage Subscriptions dialog, the description for each publication and article is displayed when the subscriber selects the appropriate icon.
  • The publication information can also be displayed by selecting the More Info button within the Manage Subscriptions dialog. However, the table name provided here for each article is the name of the table on the second-level publication server and is not necessarily the same as the table name on the original publisher.


Replicating Downloaded Data

In today's complex computing environment, data often resides on varying storage platforms within an organization. Replication provides an efficient method of distributing data that has been imported into a SQL Server. Once data resides on a SQL Server, it can be replicated outward to other SQL Servers throughout the organization.

Several conditions must be met to ensure that imported data is properly replicated:

  • The SQL Server into which the data is imported must be configured as a publisher.
  • The database into which the data is imported must be authorized for publication.
  • To allow publication of the table, the imported data must be placed into a table with a declared primary key.
  • The import of the data must take place as a logged operation.

    This implies that either the data will be imported as individual transactions or, if a bulk load operation is performed, a user-defined index must exist on the target table to ensure that the bulk load will default to a logged mode of operation.

  • If a full table publication is required, no text or image datatypes may be imported.


Replication Maintenance

With replication, the modification of data at one site can affect data being used at one or many remote locations. When a production system consists of multiple distinct locations, an administrator must consider the relationships between those locations when designing a method of maintaining data that resides on servers.

This section discusses some of the issues that should be considered when establishing a maintenance plan for servers that participate in a distributed data replication system.

For more information, choose one of the following topics:

Replication Backup

Replication Cleanup


Replication Backup

Data replication is a transaction log-based activity. Because a backup can affect the transaction log, the replication role of a server must be considered when performing or scheduling a backup. For more information choose one of the following topics:

Backup Considerations for a Publication Server

Backup Considerations for a Distribution Server

Backup Considerations for a Subscription Server


Backup Considerations for a Publication Server

A publication server retains all replicated transactions within the transaction log of the published database until they are successfully transferred and preserved within the distribution database of the distribution server. Because of this, the transaction log of the publication server acts as an interim holding queue. Replicated transactions that have not yet been transferred are automatically preserved within the log.

A database dump of a published database may be accomplished at any time, because this does not affect the transaction log. However a transaction log dump of a published database will remove old transactions from the transaction log and must be coordinated with backup of the distribution database (as discussed in Backup Considerations for a Distribution Server, next in this chapter).

Because the transaction log also serves as an interim holding queue for replicated transactions, a transaction log dump of a published database does not truncate the log past the oldest replicated transaction that is not preserved within the distribution database of the associated distribution server.

If the transaction log of a published (replicated) database continues to fill and absolutely must be truncated, unsubscribe all subscribers of that database. This allows you to truncate past the oldest distributed transaction.


Backup Considerations for a Distribution Server

Note When a publication server acts as its own distribution server, the following information applies to the distribution database on the publisher. When a publication server uses a remote distribution server, the following information applies to the distribution database on that remote distribution server.

A distribution server retains individual transactions within the tables of the distribution database until they are applied to all eligible subscribers. The distribution server also preserves a transaction ID within the MSjobs table of its distribution database. This provides a pointer into the publication servers' transaction log, providing access to the last distributed transaction that was successfully transferred from that publication server into the distribution database.

There is no replication-specific information preserved within the transaction log of a distribution server.

For a distribution server to be automatically recovered using a previously performed database or transaction log backup, after recovery the MSjobs table must contain a valid pointer to a transaction that still resides within the publication server's transaction log. This pointer defines the relationship between these servers.

Transaction log dumps of published databases truncate the publishing database's transaction log and may remove the transaction pointed to by the image of the MSjobs table preserved in an earlier backup of the distribution server.

Important To automatically recover a distribution server, the database or transaction log dump used must recover the distribution server to a point in time later than the last transaction log dump of all associated publication servers. To ensure that the distribution server can always be automatically recovered from a backup, the administrator needs to establish a coordinated backup of these associated servers to ensure that a backup is performed on the distribution server after every transaction log backup of any associated publication server.


Backup Considerations for a Subscription Server

Subscribers are the least affected of the servers that participate in a data replication system. Replication is essentially transparent to a subscription server. The subscriber receives replicated data as if it were sent by a SQL Server client.

Replication information concerning the last received transaction is maintained with the job_id column of the MSlast_job_info table, which is resident within each destination database. There is no specific replication information preserved within the transaction log of a subscription server.

The important issue when considering the backup of a subscription server is that the subscribed database must be able to be recovered to a known point in time. This can be accomplished through the use of:

  • Scheduled database dumps, combined with scheduled transaction log dumps which reduce the size of the subscription server's transaction log
  • Scheduled database dumps that rely on the database option Truncate Log On Checkpoint to reduce the size of the transaction log

In both these cases the backup events occur on a scheduled basis, and the administrator can count on a preserving an image of each subscription server's database within a specific period of time. This is an important issue when determining the replication cleanup schedule of the associated distribution server(s).


Replication Cleanup

When a replication is set up, a replication cleanup task is automatically created on the distribution server for each publisher/subscriber pairing. For example, if three publishers use one remote distributor, and if one subscriber subscribes to various publications from all three publishers, then there are three cleanup tasks on the distributor (one to support each publisher/subscriber pairing).

Replication cleanup is an important task that helps replication to effectively function in a long-running environment. The replication cleanup task:

  • Retains transactions for each subscribed database for a defined retention period after all subscription servers have received them.
  • Deletes associated .TMP files for initial sync events when this transaction is removed.

There is a parameter associated with the cleanup task¾the retention period¾that determines the period of time that transactions will be guaranteed to be retained within the distribution database after they have been distributed to a destination database. The setting of the retention period, in conjunction with scheduling implemented for backup of a subscription server, can be used to ensure that the information required to automatically recover a destination database is always available within the distribution database.

For example, if the subscription server POODLE has scheduled a transaction log dump of a destination database for once every 24 hours, you could set the retention period for POODLE's cleanup task to 48 hours. Then, even if POODLE experienced a catastrophic failure immediately before a scheduled backup, after restoring the server from the last available transaction log dump, all transactions necessary to automatically restore the replicated tables would still be available to the distribution process of the distribution server.

Setting the Retention Period

The first subscription established between a publisher/subscriber pair causes a replication cleanup task to be created on the distributor. This task is created using the existing setting for the retention period. Because of this, it is best to set the retention period before establishing any subscriptions for that publisher/subscriber pair.

To set the retention period for a subscription server before any subscriptions are established
  1. In the Server Manager window select the publication server, from the Server menu choose Replication Configuration, and from the drop-down menu that appears choose Publishing.
  2. In the Replication Publishing dialog box, select the subscription server, then select the Distribution Options button.

    The Distribution Options dialog box appears.

  3. Enter a number (representing hours) in the Retention Period After Distribution box.
  4. Choose OK.

If the replication cleanup task already exists, you can (without dropping subscriptions) change the retention period by editing the cleanup task on the distributor.

To change the retention period for an existing cleanup task
  1. In the Server Manager window select the distribution server, and then from the Tools menu choose Task Scheduling.

    The Task Scheduling dialog box appears.

  2. Select the cleanup task for the appropriate publisher/subscriber pair.

    For example AIREDALE_TERRIER_Cleanup.

  3. Select the Edit Task button.

    The Task Editing dialog box appears.

  4. In the command line, change the retention period setting.

    There are four parameters in the command line for the cleanup task:

    • The cleanup stored procedure, sp_replcleanup.
    • The publication server name (for example, TERRIER).
    • The subscription server name (for example, AIREDALE).
    • The retention period setting. The default is 0, which removes all distributed transactions whenever the cleanup task is run.

    Enter a new retention period value. The number you enter represents hours. For example, type 48 to indicate a retention period of 48 hours.

  5. Choose the Modify button.


Troubleshooting and Recovery

This section discusses the isolation and correction of problems that may arise during replication, and how to recover from failures on publication, distribution, and subscription servers.

For information, choose one of the following topics.

Troubleshooting

Recovery


Troubleshooting

SQL Server replication has been designed to require minimal user interaction. In most cases, once a subscription has been successfully established, and maintenance routines such as scheduled backup and replication cleanup have been configured, little or no user intervention is required.

However, if your particular replication configuration experiences problems during initial setup or while running replication, review the following troubleshooting information. While not inclusive, this troubleshooting overview contains helpful hints and techniques for isolating and correcting problems that may arise during data replication.

The following situations are discussed:

  • No subscription servers receiving changes
  • One subscription server (of many) not receiving changes
  • Transaction log on the publishing database filling up
  • Transaction log on the publishing database is completely full
  • Initial synchronization task not applied at subscription server
  • Monitoring scheduled table refresh
  • Deadlocks caused by replication processes
  • Using ODBCPING.EXE to verify a connection
No Subscription Servers Receiving Changes

The best way to troubleshoot a situation where no subscribers are receiving changes is to determine which of these two replication components has a problem:

  • The log reader task
  • The distribution task

To determine which component has a problem, first check whether the changes have been stored in the distribution database of the distribution server. The commands themselves can be viewed by examining the command column of the MSjob_commands table.

Note For security reasons, distribution tables are only accessible to the SA.

In the distribution database, execute the following Transact-SQL statement:

SELECT command FROM MSjob_commands

If the changes to the replicated tables are not stored in the table, then the problem resides in the replication log reader task. If the changes are stored in the command column, then the problem resides in the distribution task.

This result set can be further restricted by specifying in the SELECT statement both the publisher_id and publisher_db columns of the table.

To troubleshoot the log reader task
  1. In the Server Manager window select the distribution server, then from the Tools menu choose Task Scheduling.
  2. In the Task Scheduling dialog box, select the appropriate log reader task and choose the Task History button.

    The Task History is displayed for that log reader task. Review the history, then choose Close. The Task Scheduling dialog box returns.

    Note If the log reader task is running in Auto Start mode, recent status may not be available.

  3. With the log reader task still highlighted, choose the Edit Task button.

    The Edit Task dialog box appears.

  4. Under the Scheduling options, select Recurring and then select Change.

    The Task Schedule dialog box appears.

  5. Within the Task Scheduling dialog select Occurs Daily, and then under Daily Frequency select Occurs every 1 Minute(s).
  6. Choose OK, then in the Edit Task dialog box that returns choose OK.
  7. In the Server Manager window, stop and restart SQL Executive.

    To do this, click the right mouse button on the SQL Executive icon top, and then from the drop-down menu that appears choose Stop. Repeat this process, and choose Start.

    This terminates the currently running autostart log reader task. The log reader will now run once every minute and record the appropriate status messages in the Task History (see step 2) to help you determine why it is not moving table changes to the distribution database.

To troubleshoot the distribution task, follow the same steps outlined above for obtaining status for the log reader task, but focus on a distribution task instead.

If subscribers are all failing on distribution of a replicated transaction, this can be repaired as follows:

  1. For all associated distribution tasks, set the distribution task to Commit Every 1 Transaction.

    To do this, open the Task Scheduling window, select the appropriate distribution task, and choose the Edit Task button. In the Edit Task dialog box that appears, change the -c parameter in the Command window to -c1.

    Once the distribution task commits each individual transaction, it will fail on the specific transaction that is causing your problem.

  2. The job_id for this transaction can be obtained in two steps:
    • First, using the appropriate publisher_id, publisher_db, subscriber_id, and subscriber_db, select the maximum job_id from the MSsubscriber_status table in the distribution database.

      This provides you with the maximum job_id that was successfully distributed. (This job_id is also available in the MSlast_job_info table on the subscription server.)

    • Second, select the minimum job_id from MSsubscriber_jobs that is larger than this number, once again using the appropriate publisher_id, publisher_db, subscriber_id, and subscriber_db.

      This result will provide you with the job_id of the transaction that is failing.

  3. Using a utility such as ISQL/w you may now select the command column of the failing transaction
    SELECT command FROM MSjob_commands
WHERE publisher_id = 'publisher_id'
AND publisher_db = 'publisher_db'
AND job_id = 'job_id'
  4. At this point there are three alternatives:
    • The administrator can use Transact-SQL statements to correct the command within the MSjob_commands table, allowing distribution to continue.

      This should only be attempted by an individual well-versed in Transact-SQL. Applying an incorrect update to the distribution tables can result in unexpected data loss.

    • The administrator can simply remove the command using the sp_MSkill_job stored procedure:

      sp_MSkill_job job_id, publisher, publisher_db

    • The administrator can manually correct and apply this transaction through a utility such as ISQL/w. The transaction can then be removed from the MSjob_commands table using sp_MSkill_job.

      This allows further distribution to then continue automatically.

One Subscription Server (of many) Not Receiving Changes

If only one subscription server is not receiving changes, there can be a problem with the distribution task. Troubleshoot the distribution task following the steps described in "No Subscription Servers Receiving Changes", earlier in this chapter.

If a single subscription server is not receiving changes, also check for (and if necessary correct) the following error conditions:

  • Is the subscribing database available?
  • Is the subscription server available?

    Check the stoplight status indicator of this server in the Server Manager window of SQL Enterprise Manager, or in SQL Service Manager. Green indicates the SQL Server is running.

    Another way to verify server availability is to establish a connection from the distribution server to the subscription server, using a utility such as ISQL/w.

  • Has the replication login been removed from the subscription server?

    If for some reason the repl_publisher login ID has been removed from the subscription server, the distribution task will experience a login failure.

  • Is the distribution task waiting on a manual synchronization event?

    Check the MSlast_job_info table in the subscription database of the subscription server. If this table contains entries in the publication, article and description columns, the distribution task is paused until a manual synchronization is accomplished.

    If this condition occurs, ensure that the file named in the description column of the MSlast_job_info table is applied to the subscription server, then use SQL Enterprise Manager to acknowledge the completion of the manual synchronization. This will enable the distribution task to begin sending changes to the subscription server. For more information about applying and acknowledging a manual synchronization, see Chapter 14, Setting Up Replication.

Transaction Log on the Publishing Database Filling Up

If the transaction log of a publication database is filling up there is a problem with the log reader task. Troubleshoot the log reader task following the instructions provided in "No Subscription Servers Receiving Changes", earlier in this chapter.

You can use the sp_repltrans and sp_replcmds stored procedures to help you determine whether there are replicated transactions residing within the transaction log that have not been moved into the tables of the distribution database.

sp_repltrans
Returns a result set of all the transactions in the publication database transaction log that are marked for replication but that have not been marked as distributed. It returns a results set displaying the row identifier (RID, containing the page and row) and the timestamp for each nondistributed transaction.

If sp_repltrans returns no results, then there are no transactions available within the publication database transaction log for the log reader to move into the distribution database.

sp_replcmds
Used when sp_repltrans returns a replicated transaction that is awaiting distribution. This stored procedure allows you to view the transactions that are currently not distributed (those transactions remaining in the transaction log that have not been sent to the distribution server). sp_replcmds returns article ID, partial command (true or false), and command, page, row, and timestamp.

For more information about sp_repltrans and sp_replcmds, see the Microsoft SQL Server Transact-SQL Reference.

Transaction log on the Publishing Database is Completely Full

If you are unable to resolve a problem with the log reader task, the transaction log of the publication database can become completely full. Replicated transactions that have not been moved into the distribution database may not be truncated from the transaction log. This can prevent you from truncating the transaction log of the publication database. If this occurs, two solutions can allow you to continue using the publication database.

  • Increase the size of the transaction log.

    If you have available disk space, increase the space allocated to the log. Use SQL Enterprise Manager to expand the database onto additional log space, or use the ALTER DATABASE command or sp_extendsegment procedure to increase the size of the segment. For more information see Chapter 6, Managing Databases. Also see the Microsoft SQL Server Transact SQL Reference.

  • Clear the transaction log of non-distributed transactions.

    If more transaction log space is not available, and if normal processing must continue within the publication database, then replicated transactions that have not been moved into the distribution database may be manually removed from the transaction log of the publication database.

Note If non-distributed transactions are removed from the transaction log of the publication database, they will not be delivered to subscribing servers. All servers subscribing to publications within this database may need to re-synchronize to the published tables by unsubscribing and resubscribing.

To remove non-distributed transactions from the transaction log of the publication database, the system administrator must execute the following stored procedure, using the parameters shown:

sp_repldone 0, 0, NULL, 0, 0, 1

This marks all replicated transactions as distributed. The transaction log may then be truncated by executing this statement:

DUMP TRANSACTION database_name WITH NO_LOG

This allows normal processing to continue within the publication database.

Since you don't know which subscribers expect to receive the replicated data that was just truncated from the log, normally you should unsubscribe and resubscribe each subscriber to any publications in that database. This will force new initial synchronization events to occur.

Initial Synchronization Task Not Applied at Subscription Server

The best way to troubleshoot a situation where the initial synchronization has not been applied at a subscriber is to determine which of these two replication components has a problem:

  • The sync task
  • The distribution task

To determine which component has a problem, check to see if the sync events have been stored in the distribution database of the distribution server. The commands themselves can be viewed by examining the command column of the MSjob_commands table.

If the sync events are not stored in the command column, then the problem resides in the sync task. If the changes are stored in the command column, then the problem resides in the distribution task. (Sync commands appears as Sync, followed by table and file information.)

The following actions can help you troubleshoot a sync task:

  • Check the Task History for the appropriate sync task.

    This can be checked in SQL Enterprise Manager by selecting the server, choosing Task Scheduling from the Tools menu, selecting the task, and choosing the Task History button.

  • You can immediately test the initial synchronization event.

    Select the appropriate sync task from the Task Scheduling window, and choose the Run Task button.

  • If no history is available, check the scheduling frequency of the initial sync event.

    Sync events are often scheduled to occur infrequently and during quiet processing periods. Scheduling information is displayed under the Frequency column in the Task List of the Task Scheduling window. For more detailed information, select the task and choose the Task Edit button.

  • Check the setting for the replication working directory.

    The initial sync task can fail when it does not have access to the replication working directory. This is a directory where all bcp image synchronization files for a publisher are stored.

    The working directory can be reviewed and modified in the SQL Enterprise Manager Replication Publishing dialog box. To access this dialog box, select the publication server from the Server Manager window, and from the Server menu, choose Replication Configuration/Publishing.

To troubleshoot the distribution of an initial synchronization, you can perform the following tasks:

  • Audit logins for the subscription server.

    Because an initial synchronization is often the first attempt by the distribution task to communicate with the subscription server, it can reveal login permission problems. By default, replication uses the login ID repl_publisher to log into the subscriber.

    You can set the subscription server to audit both successful and failed logins. To do this, select the subscription server in the Server Manager window; from the Server menu, choose Configurations; and in the Server Configuration window that appears, choose Security Options. Under Audit Level, select the check boxes for Successful Login and Failed Login.

    Information concerning user logins will be written to the Windows NT Server application log and/or the SQL Server error log (depending on how logging has been configured on that server).

  • Check to see if the replicated table has been created without the expected rows.

    You can determine if the bcp portion of the distribution task has a problem by checking to see if the replicated table has been created without the expected rows. If this is the case, check in the working directory to ensure that the appropriate .TMP file has been created by the sync task.

  • If the distribution task is failing while attempting to apply the initial bcp image, the administrator could use bcp to manually apply the appropriate .TMP file to the subscription server and then increment the job_id of the corresponding row in the MSlast_job_info table.

    This allows the distribution task to bypass this operation and begin to apply the individual changes to the replicated table.

Monitoring Scheduled Table Refresh

If you have set up an article to be replicated using scheduled table refresh, how can you determine whether the destination table on the subscriber has been updated? This can be checked by monitoring the MSlast_job_info table in the destination database.

A table refresh will distribute at least two and sometimes three jobs. If the existing table is being deleted from or truncated, there are two jobs:

  • Delete or truncate the table
  • bcp data into the table

If you monitor MSlast_job_info on the subscriber and job_id increments by two, the table refresh was successful.

If the existing table is being dropped, then there are three jobs:

  • Drop the table
  • Create the table
  • bcp data into the table

If you monitor MSlast_job_info on the subscriber and job_id increments by three, the table refresh was successful.

Deadlocks Caused by Replication Processes

Under some conditions, deadlocks can occur between the log reader and distribution processes due to log reader page locks being escalated to an exclusive table lock. To avoid this, you can:

  • Decrease the -c commitbatchsize value for a log reader task, where commitbatchsize is the size of the commit batch. This determines how many transactions are placed in the distribution database before a commit can be issued against the distribution database. The default is 100.
  • Add the -b jobbatchsize option to the distribution task command,, where jobbatchsize is the maximum number of jobs to be read from the distribution database. The default behavior is to return all jobs. If there are many jobs, many locks are requested and lock escalation may be forced.
  • If there are a number of distribution tasks, stagger the execution intervals for those tasks so that they do not typically occur simultaneously.

For more information about using the log reader -c commitbatchsize option and the distribution -b jobbatchsize option, see Chapter 16, Scheduling Tasks.

You can also customize the lock escalation level by increasing the LE threshold maximum setting of sp_configure, allowing more page locks. This change is primarily useful on remote distribution servers. However, be aware that changing this option affects the entire server (not just the replication processes).

Using ODBCPING.EXE to Verify a Connection

If replication between two servers is not functioning properly you can use the ODBCPING.EXE utility to check whether ODBC is properly installed (by connecting to a server using the ODBC SQL Server Driver). This utility is a 32-bit application that is stored in the \SQL60\BINN directory.

To verify ODBC connectivity
  • From a command prompt, type

    odbcping /S servername /U login_id /P password

    where

    servername
    Is the name of a server you will connect to.
    login_id
    Is a valid login ID for that server.
    password
    Is the password for that login ID.

If the ODBC connection is established, this message is displayed:

CONNECTED TO SQL SERVER

If the ODBC connection cannot be established, this message is displayed:

COULD NOT CONNECT TO SQL SERVER


Recovery

In many cases, SQL Server replication can automatically recover from events that in the past would have been considered a catastrophic failure. Recovery considerations vary based on the replication role that a server performs: publication server, distribution server, or subscription server. This section discusses both automated and manual replication recovery for each type of server.

Important This recovery process can be further assisted by appropriate scheduling of database backups and cleanup retention periods. (For more information, see Replication Maintenance.)

For information, choose one of the following topics.

Publication Server Recovery

Distribution Server Recovery

Subscription Server Recovery


Publication Server Recovery

In many situations a publication server can be automatically recovered. Because the distribution server retains a pointer to the last distributed transaction within the publication server's transaction log, the publication server can easily recover from off-line situations caused by events such as loss of power, loss of network connection, or minor hardware failure.

When the publication server returns online and the database is again available, the distribution log reader process locates the last distributed transaction and proceeds forward from that point, transferring replicated transactions into the distribution database. It is not necessary to drop and re-create publications.

However, if it becomes necessary to rebuild a published database on the publication server using an older backup tape, the distribution server may no longer contain a valid pointer to a publication server's last distributed transaction. If this situation occurs, the log reader task will log an error and reschedule itself in retry mode. (For information about retry mode, see Distribution Server Recovery., next.)


Distribution Server Recovery

Distribution servers support automatic recovery. If the distribution server is taken off-line, when it again becomes available, all of the distribution processes will continue from their last successful operation. For each distribution task, the distribution server connects to the subscription server to find the last transaction that was successfully applied and continues distributing replicated transactions from that point forward.

In a similar way, the replication log reader task works to automatically recover the distribution server. Each distribution server stores a pointer into all of the associated publication server transaction logs. This provides the log reader task with access to the last distributed transaction which was successfully transferred.

During recovery, if this transaction is found to exist within the transaction log of the publication server, the log reader task will automatically recover the distribution server by moving transactions into the distribution database from that point forward.

Important Setting up a coordinated server backup scheme, as described in Replication Backup, maximizes the probability that the last distributed transaction will be available within the transaction log of all publication servers. This allows automatic recovery of the distribution server to occur even in the event of a major server failure requiring the recovery of the distribution database from a backup tape.

If a situation occurs where the distribution server needs to be rebuilt using an older backup tape, the distribution server may not contain a valid pointer to the last distributed transaction for the publication server. If this happens, the log reader task will log an error and reschedule itself in retry mode, which will keep the automatic recovery of the distribution server from succeeding. The following steps describe how the distribution server can be successfully recovered from this condition, without disturbing any of the existing publications.

To recover a distribution server when the log reader task is in retry mode
  1. Unsubscribe and then resubscribe all subscribers to all publications of the publication server that has caused the log reader failure.

    Be careful during subscription to select the original destination database and initial synchronization option for each subscription server.

  2. In SQL Enterprise Manager, select the distribution server, and then from the Tools Menu, choose Task Scheduling.
  3. In the Task Scheduling window, select a cleanup task associated with a subscription server that has been resubscribed, and then choose the Run Task button. This immediately executes the cleanup task, removing all old transactions from the distribution database.

    Repeat for all subscribers that have been resubscribed.

Once all old transactions are removed from the distribution database, the invalid pointer into the publication server's transaction log will no longer exist and the log reader task will able to successfully execute. All subscription servers will have their replicated tables synchronized with the current state of the publication server, and replication will continue.


Subscription Server Recovery

A subscription server is the easiest type of server to recover. At the beginning of each scheduled distribution event, the distribution server connects to the subscription server and finds the value of the highest transaction that has been applied. This value is stored in the job_id column of the MSlast_job_info table.

If a subscription server is unavailable for an extended period of time, all replicated transactions are held in the distribution server's distribution database. When the subscription server is again available on the network, distribution of replicated transactions continues at the point where it last stopped. This allows a subscription server to automatically recover and receive all replicated transactions after situations such as a loss of power, loss of network connection, or minor hardware failure. In many cases, a subscription server can also recover from a major failure.

If a major subscription server failure occurs and the subscribing database must be recovered from a backup tape, it is still possible for the subscription server to automatically recover and receive all replicated transactions. Not only are all nondistributed transactions retained within the distribution server's distribution database, but distributed transactions are also retained for a configurable period of time after they have been sent to the subscription server. After a previous image of the subscription server is restored from backup, if the job_id column in the MSlast_job_info points to a valid transaction that is still available on the distribution server, all replicated transactions with job_id greater than this entry will be automatically distributed to the subscription server.

To ensure the best chance of this occurring automatically, immediately after the subscription server fails, disable the scheduled cleanup task associated with that subscription server until restoration is accomplished. This will keep the system from aging retained transactions off of the distribution server before they can be reapplied.

There is a potential problem to be aware of when a subscription server is recovered from an earlier backup tape. Because any subscription server need not receive all replicated transactions from a publication server, it is a perfectly valid condition for the subscription server to contain a job_id in the MSlast_job_info table that is much smaller than the next job_id that needs to be passed to this server. For this reason, the distribution server will not declare an error condition if the subscription server contains an old job_id.

In this situation, the distribution server will send all stored transactions to the subscription server, but a logical gap can exist of transactions that had previously been sent to the subscriber removed from the distribution database but were not preserved on the backup used to recover the subscription server. Should this condition exist, an information message will be produced by the distribution process. All replicated changes can be recovered by unsubscribing and then resubscribing to the affected publications.

When the distribution task runs and encounters a missing job, it raises a warning. Optionally, you can run the distribution task so that a missing job will raise a fatal error. This is set by running the distribution task with the -m missingjobsfailure option, where missingjobsfailure is 0 or 1. If 1, a missing job will raise an error with a severity of 20 (fatal). If 0, a missing job will raise an error with a severity of 10 (informational). The default is 0. For more information see Chapter 16, Scheduling Tasks.


Advanced Setup Tasks

Under certain conditions, advanced users may find it useful to:

  • Add custom stored procedures that are run when the log reader process encounters an INSERT, UPDATE, or DELETE transaction that is marked for replication in the transaction log of the publication database
  • Change the distribution database that a publication server uses
  • Edit the replication entries in the Windows NT Registry.

For information, choose one of the following topics.

Adding Stored Procedures for Insert, Update, and Delete

Changing a Publisher's Distribution Database

Editing Replication Registry Entries


Adding Stored Procedures for Insert, Update, and Delete

Normally, when the log reader process encounters an INSERT, UPDATE, or DELETE command that is in the transaction log of a publication database and is marked for replication, a single row SQL statement is reconstructed from the recorded data changes. The replication processes then send that reconstructed SQL statement to each server that is subscribed to that article and apply the statement to the destination table in each destination database.

This is the default data replication mechanism used by SQL Server replication. In most cases, it is the appropriate replication method. However, you have the option of customizing this process to meet specific replication requirements.

For each published table, there are three ways you can handle each type of statement (INSERT, UPDATE, or DELETE) that is detected by the log reader. You can:

  • Leave the default replication mechanism in place.
  • Specify that no action will be taken at any subscriber.
  • Specify that custom processing will occur at all subscribers.

You define the Data Replication Mechanism for a published table by using the options provided in the Scripts tab of the Edit Article dialog box. See the following illustration. (For information about how to access and edit this dialog box, see Chapter 14, Setting Up Replication.)

To use the default data replication mechanism for a statement type
  • In most cases, you will do nothing. Leave the default option selected (INSERT Command, UPDATE Command, or DELETE Command).
To specify no processing for a statement type
  • Choose the Custom option for the statement type, and then in the Custom box, type NONE. Transactions of that type will not be replicated.

    For example, if you choose the Custom option for DELETE and type NONE, then DELETE statements will not be replicated for that article.

To specify custom processing for a statement type
  • Choose the Custom option for the statement type, and then in the Custom box, type:

    CALL customproc

    where

    customproc
    Is the name of a stored procedure that has been created in the destination database on each server subscribing to this article.

    When the log reader encounters a statement of the specified type (INSERT, UPDATE, or DELETE) in a transaction marked for replication, it will construct a stored procedure call based on this syntax and will pass column values to the referenced stored procedure.

About the Custom Stored Procedures

To implement stored procedure-based replication for a published table, you must create stored procedures that expect to receive and process the following parameters. These parameters must be passed in the order shown (that is, using the same column order as in the base table, as defined in syscolumns).

INSERT stored procedures
Stored procedures handling INSERT statements will be passed the inserted values for all columns:
c1, c2, c3,... cn
UPDATE stored procedures
Stored procedures handling UPDATE statements will be passed the updated values for all columns defined in the article, followed by the original values for the primary key columns:
c1, c2, c3,... cn, pkc1, pkc2,... pkcn

Note No attempt will be made to determine which columns were changed.

DELETE stored procedures
Stored procedures handling DELETE statements will be passed values for the primary key columns:
pkc1, pkc2,... pkcn

If you would like your INSERT, UPDATE, or DELETE stored procedure to return an error when a failure status is encountered, you must add a RAISERROR statement so that the distributor will catch the failure status coming back. If severity is greater than 12, it stops the distribution process to that subscriber. If this procedure definition is distributed as part of the article schema definition file, it will be sent using ODBC. In this case, only single quotes (') may be used to define the RAISERROR message string, because use of double quotes (") will generate an error. For information about using the RAISERROR statement, see the Microsoft SQL Server Transact-SQL Reference.

Creating the Stored Procedure on All Subscribers

To implement stored procedure-based replication for a statement type (INSERT, UPDATE, or DELETE) for a published table, you must create the stored procedure in the destination database of each subscriber to that article.

A simple way to propagate a stored procedure to all subscribers is to edit the schema script for an article and add the CREATE PROCEDURE statement. However, this is only effective if the schema script is edited before subscription servers are initially synchronized to the article. For information on editing schema scripts, see Chapter 14, Setting Up Replication.

Another method is to manually create the stored procedure in the destination database on each server subscribing to the article. Although this is more laborious, it does have the advantage of allowing you to implement a unique solution for each subscriber.


Changing a Publisher's Distribution Database

If necessary you can change the distribution database used by a publication server. The technique you use to change the distribution database depends on whether or not you need to retain existing publications:

  • If you do not need to retain existing publications, the procedure is simpler but requires you to completely reestablish replication, including re-creating all publications.
  • If you need to retain existing publications, the procedure is slightly more complex, but does not require you to re-create publications.

Except where otherwise noted, the following steps assume the use of SQL Enterprise Manager.

To drop existing publications and change a publisher's distribution database
  1. Make a list of existing publications and subscriptions, so that they can later be re-created.

    Information on publications can be obtained using sp_helppublication and sp_helparticle. Information on subscriptions can be obtained using sp_helpsubscription.

  2. Make a list of existing subscription servers so that they can later be re-created.

    Information on subscription servers can be obtained using sp_helpserver and sp_helpsubscriberinfo.

  3. On the publication server, remove all published databases from the Publishing Databases list.

    With SQL Enterprise Manager, this list is accessed using the Replication Configuration/Publishing command from the Server menu.

    Note Removing a published database from the Publishing Databases list drops all of its publications, and all subscriptions associated with each publication.

  4. On the publication server, remove all subscription servers from the Enable Publishing to These Servers list.

    This list is also accessed using the Replication Configuration/Publishing command from the Server menu.

  5. On the publication server, run sp_serveroption to clear the distribution server setting. Type:

    sp_serveroption servername, 'dist', false

    If the publication server is configured as its own distributor, servername is the name of the local server. If the publication server is configured to use a remote distribution server, servername is the name of that remote distribution server.

  6. Disconnect from and then reconnect to the publication server.
    • To disconnect, in the Server Manager window, click the right mouse button on the publication server, and then from the drop-down menu that appears, choose Disconnect.
    • To reconnect, click on the "" box for the publication server.
  7. If the publication server was configured as its own distributor, drop the distribution database. However, if the publication server was configured to use a remote distribution server, skip this step.
  8. Install or select a distribution database.

    Select the publication server; from the Server menu, choose Replication Configuration; choose Install Publishing; and complete the Install Replication Publishing dialog box that appears.

  9. Continue with replication setup and completely configure replication.
    • On the publication server, set the server publication options. Re-select the publication databases. This automatically sets the status of the database to "published" and creates a log reader task for each published database.
    • On the publication server, re-enable publishing to all subscription servers. For each subscriber, if it does not already exist, this adds a new entry in the sysservers table. The server status is set to "sub" (subscription server) and an associated entry for the server is placed in the MSsubscriber_info table of the distribution database. Finally, this creates a cleanup task for the server.
    • On the publication server, re-create publications and articles.
    • On the subscription servers, subscribe to the publications and articles. The first subscription for each destination database will create a distribution task.

If you need to retain existing publications, the procedure is slightly different. You do not remove published databases from the Publishing Databases list, which allows you to retain the server's publications.

To retain existing publications and change a distribution database
  1. Make a list of existing publications and subscriptions.

    Information on publications can be obtained using sp_helppublication and sp_helparticle. Information on subscriptions can be obtained using sp_helpsubscription.

  2. Make a list of existing subscription servers.

    Information on subscription servers can be obtained using sp_helpserver and sp_helpsubscriberinfo.

  3. From all subscription servers of the publisher, drop all subscriptions to all publications of that publication server.
  4. On the publication server, remove all subscription servers from the Enable Publishing to These Servers list.

    With SQL Enterprise Manager, this list is accessed from the Replication Configuration/Publishing command from the Server menu.

    Important Do not clear the check boxes for published databases in the Publishing Databases list. If you do so, all publications for those databases will be dropped. If that occurs, to reestablish replication you will need to re-create all publications.

  5. On the publication server, run sp_serveroption to clear the distribution server setting. Type:

    sp_serveroption servername, 'dist', false

    If the publication server is configured as its own distributor, servername is the name of the local server. If the publication server is configured to use a remote distribution server, servername is the name of that remote distribution server.

  6. Disconnect from and then reconnect to the publication server.
    • To disconnect, in the Server Manager window, click the right mouse button on the publication server, and then from the drop-down menu that appears, choose Disconnect.
    • To reconnect, click on the "" box for the publication server.
  7. If the publication server was configured as its own distributor, drop the distribution database. However, if the publication server was configured to use a remote distribution server, skip this step.
  8. Install or select a distribution database.

    Select the publication server; from the Server menu, choose Replication Configuration; choose Install Publishing; and complete the Install Replication Publishing dialog box that appears.

  9. On the publication server, set the server publication options.

    In the Replication Publishing dialog box, add subscription servers to the Enable Publishing to These Servers list. For each subscriber, if it does not already exist, this adds a new entry in the sysservers table. The server status is set to "sub" (subscription server) and an associated entry for the server is placed in the MSsubscriber_info table of the distribution database. Finally, this creates a cleanup task for the server.

    If this dialog box does not appear after you install or select a distribution database, open it by selecting the server and choosing Replication Configuration/Publishing from the Server menu.

  10. On the distribution server, add a log reader task for each published database.

    To add a scheduled task, select the server from the Server Manager window; from the Tools menu, choose task scheduling; in the Task Scheduling dialog box, choose the New Task button; and complete the New Task dialog box that appears.

    For information about creating replication tasks, see Chapter 16, Scheduling Tasks.

  11. On the subscription servers, resubscribe to the publications and articles.

    The first subscription for each destination database will create a distribution task.


Editing Replication Registry Entries

The Windows NT Registry key

HKEY_LOCAL_MACHINE
\SOFTWARE
\Microsoft
\MSSQLServer
\Replication

has two replication values:

  • The name of the distribution database
  • The working directory for replication

These values are automatically set up by SQL Enterprise Manager¾it should not be necessary to modify them manually. Editing of the Registry is normally not recommended. However, if necessary, these key values can be viewed and modified by using regedt32.

HKEY_LOCAL_MACHINE
\SOFTWARE
\Microsoft
\MSSQLServer
\Replication

Value 0
Name: DistributionDB
Type: REG_SZ
Data: distribution

Value 1
Name: WorkingDirectory
Type: REG_SZ
Data: \\servername\C$\SQL60\REPLDATA

In the Working Directory data entry, servername is the name of the distribution server. It may be a remote distribution server or the local publisher/distributor.

Note The working directory entry can easily be modified using SQL Enterprise Manager. For information see Chapter 14, Setting Up Replication.


Monitoring Replication

Once replication has been set up, you can monitor replication activities several ways. You can:

  • Use SQL Performance Monitor to monitor replication-related counters.
  • Use SQL Enterprise Manager to view scheduled replication tasks and to see a history for each task.
  • Set up alerts on replication events. If the event occurs, SQL Enterprise Manager will respond automatically, either by executing a task that you have defined or by sending an e-mail and/or a pager message to an operator that you have specified.

For information choose one of the following topics.

Using SQL Performance Monitor to Monitor Replication

Viewing Replication Tasks and the Task History

Setting Up Alerts for Replication


Using SQL Performance Monitor to Monitor Replication

SQL Performance Monitor¾the integration of Microsoft SQL Server 6.0 with the Windows NT Performance Monitor¾makes it possible for you to get up-to-the-minute activity and performance statistics on SQL Server replication.

SQL Performance Monitor obtains statistics from performance counters, several of which are grouped within a performance object. When you install SQL Server, two replication-related objects are automatically provided to SQL Performance Monitor:

  • A publication object, SQLServer Replication-Published DB
  • A subscription object, SQLServer Replication-Subscriber

The SQLServer Replication-Published DB object provides three publication database counters.

Publication counter | Description
Replicated Transactions | The number of transactions in the transaction log of the publication database that are marked for replication but have not yet been delivered to the distribution database.
Replicated Transactions/sec | The number of transactions per second that have been read out of the transaction log of the publication database and delivered to the distribution database.
Replication Latency (msec) | The number of milliseconds between the time a transaction marked for replication is entered into the transaction log of the publication database and the time it is read out of the log and delivered to the distribution database.

The SQLServer Replication-Subscriber object provides four subscription server counters.

Subscription counter | Description
Delivered Transactions | The number of delivered transactions in the distribution database. A delivered transaction is one that has already been executed against the destination database but still resides in the distribution database.
Delivered Transactions/sec | The number of transactions delivered per second¾that is, the number of jobs per second that were executed in the last batch sent to the subscription server from the distribution server.
Delivered Latency (sec) | The number of seconds a transaction remains in the distribution database before delivery to the subscription server¾that is, the time between a job being inserted in the distribution database and being executed against the destination database.
Undelivered Transactions | The number of undelivered transactions in the distribution database. An undelivered transaction is one that has not been executed against the destination database.

SQL Performance Monitor can be started by choosing its icon from the Microsoft SQL Server 6.0 program group. For information on how to use SQL Performance Monitor to view information from the publication and subscription counters, see Part 7, Other Operations.


Viewing Replication Tasks and the Task History

When you use SQL Enterprise Manager to set up replication, it automatically creates the replication tasks that are required. You can view a list of all scheduled tasks, a list of tasks that are currently running, and a history for each replication task.

To view the task list and the task queue
  1. From the Server Manager window, select a server.

    This is the server for which tasks will be viewed.

  2. Under the selected server, double-click the Executive icon.

    Or from the toolbar, choose the Set Schedules button.

    The Task Scheduling window appears.

  3. To view a list of existing tasks (both scheduled and disabled) for this server, select the Task List tab. The following information is displayed:
    • Task is the task name.
    • Owner is the task owner (usually the task creator).
    • Type is the type of task. CmdExec is an operating system command or executable file. TSQL is a Transact-SQL statement. Distribution, LogReader, and Sync are replication tasks.
    • Frequency is the task's schedule type: Recurring, One Time, or On Demand. (An on-demand task is run by an alert when the alert occurs).
    • Last Run Date is the day the task last ran.
    • Last Run Time is time of day the task last ran.
    • Enabled tells you whether the task is enabled or disabled.
  4. To view a list of the tasks that are currently running, choose the Running Tasks tab. The following information is displayed:
    • Task is the task name.
    • Owner is the task owner (usually the task creator).
    • Type is the type of task. CmdExec is an operating system command or executable file. TSQL is a Transact-SQL statement. Distribution, LogReader, and Sync are replication tasks.
    • Start Date is the first day on which the recurring task will be executed.
    • Status displays status information about the task.

    Note Queued tasks are also shown in the Running Tasks tab. For subsystems (task type) other than TSQL, a task may be queued if it is scheduled to run but there are no free threads available in the subsystem. The maximum number of threads available to a subsystem can be changed using regedt32. The default for all subsystems (except TSQL) is 10.

  5. To update the display with current information, choose the Refresh button.

You can view a task's history, which provides information about the last run date of a task, the time and duration of the last run, the status of that run, and whether a user was sent e-mail by SQL Executive. You can also view any messages sent by SQL Executive.

To view the history of a replication task
  1. From the Server Manager window, select a server.

    This is the server for which task history will be viewed.

  2. Under the selected server, double-click the Executive icon.

    Or from the toolbar, choose the Set Schedules button.

    The Task Scheduling window appears.

  3. From the Task List, select the replication task to view history for.

    Replication tasks have an entry in the Type column of Distribution, LogReader, or Sync.

  4. Choose the Task History button.

    The Task History dialog box appears.

    The following information is displayed:

    • Run Date shows the date the information is about.
    • Run Time shows when the task ran.
    • Status shows whether the task completed successfully.
    • E-mailed indicates whether e-mail was sent by SQL Executive after task execution.
    • Run Duration shows the amount of time the task took to run. For this release, the value will always be zero.
    • Message displays any messages that resulted from the task execution.

      If selected for preservation in the Windows NT Event (application) log, success and failure messages can also be viewed using the Windows NT Event Viewer. This avoids the 256-character truncation that will occur when viewing task history.

    • Clear All clears (erases) the history.

For more information about replication tasks, see Chapter 16, Scheduling Tasks.


Setting Up Alerts for Replication

SQL Enterprise Manager and the SQL Executive service provide an easy way to set alerts on SQL Server events. SQL Executive monitors the Windows NT application log, watching for an event that qualifies as one of the defined alerts. If such an event occurs, SQL Executive will respond automatically, either by executing a task that you have defined or by sending an e-mail and/or a pager message to an operator you have specified. You can use this capability to set up alerts on replication events.

To create an alert
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Manage Alerts button.

    The Manage Alerts window appears, with the Alerts tab selected.

  2. Choose the New Alert button.

    The New Alert dialog box appears.

  3. In the Name box, type a name to assign to this alert.
  4. Optionally, to create an disabled alert, clear the Enabled box.

    The Enabled box is selected by default. In most cases, this is the appropriate setting. It is useful to clear this option if you want to create the alert now but do not want it to take effect until later.

  5. To define the conditions that will cause an alert, specify either an error number or a severity level.
    • To specify that an alert will occur whenever an error of a specific severity level is entered in the Windows NT application log, select Severity and select an error level from the list.
    • To specify that an alert will occur whenever a specific error message is entered in the Windows NT application log, select Error Number and type the error number.

      To select from a list of error messages, or to create a custom error message, select Error Number, select the browse button, and complete the SQL Server Messages dialog box that appears. In this dialog box you can view a list of messages, and you can filter the list to display only replication (or other) messages.

    Note that an alert will occur only if the specified event is entered in the Windows NT application log.

    For information about which events are logged, and to learn how to filter the list of messages displayed in the SQL Server Messages dialog box, see Chapter 17, Managing Alerts.

    For a list of error numbers and a discussion of severity levels, see Part 8, Troubleshooting.

  6. Optionally, to narrow the alert notification criteria further, select a database name and/or provide an error message string.
    • To specify that an alert will occur only when an error is received from a specific database, choose Database Name, and select a database from the list.
    • To specify that an alert will occur only when the error message contains a particular character string, type the character string in the Error Message Contains String box.
  7. To specify the action the system will take when the defined alert occurs, complete the Response Definition options.
    • To have a task execute when a qualifying alert occurs, select a task from the Task to Execute list.

      A task can invoke a command execution or a Transact-SQL statements. For information on creating tasks, see Chapter 16, Scheduling Tasks.

    • To provide additional information to the alert recipients, type text (instructions or a message) in the Alert Notification Message to Send to Operator box.

      You can enter up to 255 characters. Note that this is any text you want to add to the alert. Do not type in the actual error message text.

    • To include the actual text of the error message as part of the alert, choose Include Error Message Text in Notifications, and then select the e-mail and/or the Pager options.
    • To set a delay between responses for recurring alerts, type a number (representing seconds) in the Delay Between Responses for Recurring Alerts box.

      For example, suppose you type 8 in this box. Later, five alerts that meet the alert definition occur within a period of eight seconds or less. Only one alert is sent to the operators specified in step 9.

  8. To specify the operators who will be notified when the defined alert occurs, select an operator from the list under Operators to Notify, and then select the option box for e-mail and/or for Pager. Repeat for each operator to be notified.

    A solid envelope or solid telephone icon indicates that the operator already has address information of that type defined. An outline envelope or outline telephone icon indicates that the operator does not have address information of that type defined.

    If the necessary operators have not yet been created, the list will be empty. For instructions on creating operators, see Chapter 17, Managing Alerts. You can continue with alert creation, since you will be given the opportunity later, during operator creation, to assign this alert to each operator. You can also later edit this alert to add operators, after operators have been created.

  9. Choose OK.

    The alert is created.

The following messages can be raised by the replication subsystems, and can be used to set up replication alerts.

Message: 14150, Severity: 10, State: 0,
  Replication-subsystem: Task 'task_name' succeeded. message

Message: 14151, Severity: 20, State: 0,
  Replication-subsystem: Task 'task_name' failed. message

Message: 14152, Severity: 18, State: 0,
  Replication-subsystem: Task 'task_name'
    scheduled for retry after number attempt(s). 'message'

Message: 14153, Severity: 10, State: 0,
  Replication-subsystem: Task 'task_name'
    detected the potential for missing jobs on 'message'

where

subsystem
Is the replication subsystem (Distribution, LogReader, or Sync).
task_name
Is the task name.
number
Is the number of attempts.
message
Is additional information returned by the subsystem. For example, "Unable to Connect to MALAMUTE."

For more information on alerts, including information on how SQL Server alerts are generated, how to create and manage operators, and how to edit, view, and cancel alerts, see Chapter 17, Managing Alerts.


Tables, Stored Procedures, and Scripts Used by Replication

This section presents descriptions of the tables, stored procedures, and scripts that are used by replication. Note that in most cases you will not need to directly modify these tables or run these stored procedures or scripts, since when you use the SQL Enterprise Manager to set up and maintain replication it handles those chores for you.

For information, choose one of the following topics.

Tables Used by Replication

Stored Procedures Used by Replication

Scripts Used by Replication


Tables Used by Replication

Replication employs tables from publication databases, the distribution database, destination databases, and the master database.

In addition to the tables described here, SQL Executive uses the scheduling tables in the msdb database to handle scheduling of replication tasks. For information on the tables in the msdb database, see the Microsoft SQL Server Transact-SQL Reference.

For more information, choose one of the following topics.

Publication Database Tables

Distribution Database Tables

Destination Database Tables

Master Database Tables


Publication Database Tables

Publication databases use the following tables for replication purposes:

Table | Description
sysarticles | Has a row for each of the articles posted by the publication server.
sysobjects | Has a category field set by replication for each object marked for replication. This is set when an article is created and when an article is initially subscribed to.
syspublications | Has a row for each of the publications posted by the publication server.
syssubscriptions | Associates the IDs of published articles with the IDs of all subscription servers expecting to receive the data.

For more information about these tables, see the Microsoft SQL Server Transact-SQL Reference.


Distribution Database Tables

Distribution databases contain the following tables dedicated to replication:

Table | Description
MSjob_commands | Contains one entry for each command associated with a transaction in the MSjobs table. One transaction can contain many commands.
MSjob_subscriptions | Associates a subscriber with a particular article. (This is actually subscriber-side information that is maintained in the distribution database.)
MSjobs | Contains the actual transactions. There is one entry for every transaction stored in the distribution database.
MSsubscriber_info | Contains information used by SQL Executive for passing jobs.
MSsubscriber_jobs | Associates each subscriber with the command that subscriber needs to receive.
MSsubscriber_status | Contains status information for the individual batches of transactions sent to subscribers.

For more information about these tables, see the Microsoft SQL Server Transact-SQL Reference.


Destination Database Tables

Destination databases maintain replication information in the MSlast_job_info table.

Table | Description
MSlast_job_info | Contains the job ID of the last job (from a batch) that was successfully applied. A job is a complete transaction stored in the distribution database. Also, if present, this table contains the publication name, article name, and description of a job that has paused distribution while waiting for manual synchronization.

For more information about this table, see the Microsoft SQL Server Transact-SQL Reference.


master Database Tables

All servers participating in replication keep some replication-related data in the sysservers and sysdatabases tables in the master database.

Table | Description
sysservers | Used by both the publication and subscription servers. The srvstatus column has status bits set for RPC, PUBLISH, SUBSCRIBE, and DISTRIBUTE. A publication server uses all four options to register the servers with which it participates in replication. A subscription server uses only the RPC option to register the publication servers that it authorizes to send it publications. The options can be reviewed by running sp_helpserver and viewing the status column.
sysdatabases | Used by publication and subscription servers. Setting a status bit permits a database to publish. On the subscription server, sets a status bit allowing a database to subscribe, and aliases the repl_publisher login ID to DBO.

For more information about these tables, see the Microsoft SQL Server Transact-SQL Reference.


Stored Procedures Used by Replication

This section describes the stored procedures used by replication to implement and initiate replication on a SQL Server 6.0 server. This section provides a brief summary of the role each stored procedure plays in replication. For detailed information, see the Microsoft SQL Server Transact-SQL Reference.

Note If you use the SQL Enterprise Manager to set up and maintain replication, you will not need to directly use these stored procedures. They are presented here primarily for reference purposes. However, it is possible to use these stored procedures to set up replication manually. For more information, see Manual Replication.

For information about the stored procedures used by replication, choose one of the following topics:

Stored Procedures Used for Server Configuration

Stored Procedures Used for Publication Administration

Stored Procedures Used for Subscription Administration

Stored Procedures Used for Replication Operations

Stored Procedures Used for Replicated Transaction Management

Stored Procedures Used for Replication Scheduling


Stored Procedures Used for Server Configuration

The following stored procedures are used by replication for server configuration.

Stored procedure | Description
sp_addpublisher | Adds a new publication server.
sp_addsubscriber | Adds a new subscription server.
sp_changesubscriber | Changes options for a subscription server.
sp_dboption | Enables a database to publish or subscribe to replicated data. (Note that sp_dboption can be used to administer many nonreplication database options. For more information, see the Microsoft SQL Server Transact-SQL Reference.)
sp_droppublisher | Drops a publication server.
sp_dropsubscriber | Drops a subscription server.
sp_helpdistributor | Lists information about the distribution server, database, working directory, and SQL Executive user account.
sp_helpserver | Lists replication servers known to the server being administered.
sp_helpsubscriberinfo | Displays information about a subscription server.
sp_replsync | Used from a subscription server to acknowledge completion of a manual synchronization.

For more information about these stored procedures, see the Microsoft SQL Server Transact-SQL Reference.


Stored Procedures Used for Publication Administration

The following stored procedures are used by replication for publication administration tasks.

Stored procedure | Description
sp_addarticle | Creates an article and adds it to a publication.
sp_addpublication | Creates a publication.
sp_articlecolumn | Adds a column to an article. Used to create vertical partitions.
sp_changearticle | Changes article properties.
sp_changepublication | Changes publication properties.
sp_droparticle | Drops an article.
sp_droppublication | Drops a publication and its associated articles.
sp_enumfullsubscribers | Returns a list of subscribers who have subscribed to all articles in a publication.
sp_helparticle | Displays information about an article.
sp_helparticlecolumns | Displays all columns in the underlying table. Returns 1 for those that are published and 0 for those that are not published. Useful to check a vertical partition.
sp_helppublication | Displays information about a publication.
sp_helppublicationsync | Provides information about a replication synchronization task. It is the equivalent of issuing sp_helptask in full mode against the publication task ID.
sp_helpreplicationdb | Returns a list of all published databases on the server. Or for an individual database, indicates whether or not the database is published.

For more information about these stored procedures, see the Microsoft SQL Server Transact-SQL Reference.


Stored Procedures Used for Subscription Administration

The following stored procedures are used by replication for subscription administration tasks.

Stored procedure | Description
sp_addsubscription | Adds a subscription to a specified article and sets the subscriber's status.
sp_changesubscription | On a subscription server, changes subscription properties for an article or a publication.
sp_changesubstatus | Changes the status of an existing subscriber.
sp_dropsubscription | On the publication server, drops subscriptions to a particular article, publication, or set of subscriptions.
sp_helpsubscription | Lists subscription information associated with a particular publication, article, subscriber, or set of subscriptions.
sp_subscribe | Remotely adds a subscription to a particular article within a publication.
sp_unsubscribe | Remotely cancels a subscription to a particular article within a publication, a whole publication, or to all publications.
sp_helpreplicationdb | For an individual database, indicates whether or not the database is subscribed (is a destination database).

For more information about these stored procedures, see the Microsoft SQL Server Transact-SQL Reference.


Stored Procedures Used for Replication Operations

The following stored procedures are used for replication operations.

Stored procedure | Description
sp_distcounters | Displays the latest information about all subscribers. Used by SQL Performance Monitor. Provides the information used by the counters in the SQLServer Replication-Subscriber object.
sp_MSkill_job | On the distribution server, removes a single job from the distribution database while continuing to send all other data to the subscriber.
sp_replcleanup | Removes transactions from the distribution database tables after they have been successfully distributed to the subscriber's database.
sp_replica | Remotely sets, on a subscription server, a sysobjects category bit that marks the table as a replica (indicates the table is a copy, not an original). Used for informational purposes only.
sp_replsync | Used from a subscription server to acknowledge completion of a manual synchronization.

For more information about these stored procedures, see the Microsoft SQL Server Transact-SQL Reference.


Stored Procedures Used for Replicated Transaction Management

The following extended stored procedures are used to manage and return information about replicated transactions. Generally, these are used only for troubleshooting.

Stored procedure | Description
sp_replcmds | Returns the commands for transactions marked for replication.
sp_replcounters | Returns replication statistics for all published databases. Used by SQL Performance Monitor. Provides the information used by the counters in the SQLServer Replication-Published DB object.
sp_repldone | Updates the record identifying the server's last distributed transaction.
sp_replflush | Flushes the article cache.
sp_replstatus | Used to update the internal table structure for replication (that indicates whether the table is being replicated).
sp_repltrans | Returns a result set of all the transactions in the publication database transaction log that are marked for replication but that have not been marked as distributed.

For more information about these stored procedures, see the Microsoft SQL Server Transact-SQL Reference.


Stored Procedures Used for Replication Scheduling

The following stored procedures are used for scheduling of replication tasks in the msdb database.

Stored procedure | Description
sp_addtask | Adds a scheduled task.
sp_droptask | Removes a scheduled task.
sp_helptask | Displays information about a scheduled task.

For more information about these stored procedures, see the Microsoft SQL Server Transact-SQL Reference.


Scripts Used by Replication

When the distribution database is created, SQL Server runs the INSTDIST.SQL script. This script creates these tables:

MSjob_commands
MSjobs
MSsubscriber_status
MSsubscriber_jobs
MSsubscriber_info
MSjob_subscriptions

It also creates the stored procedures used by the log reader, synchronization, and distribution processes.


Manual Replication

SQL Enterprise Manager provides full functionality for setting up and maintaining replication. Replication can be managed using this easy-to-use, graphical interface. However, as an option you can set up replication manually, primarily through the use of replication and scheduling stored procedures. This section provides a summary of the steps you will accomplish to set up replication manually, shows you a sample schema creation script and describes how to manually perform partitioning.

For information, choose one of the following topics.

Setting Up Replication Manually

A Sample Schema Script

Manual Horizontal Partitioning

Manual Vertical Partitioning


Setting Up Replication Manually

You can configure replication by using SQL Enterprise Manager, or you can set up replication manually by using the instructions that follow. You will also find the following information useful if you want to create a replication setup script.

To set up replication manually
  1. On the publication server, create a device for the distribution database. For example:
    DISK INIT
NAME = 'distdata',
PHYSNAME = 'c:\sql60\data\distrib.dat',
VDEVNO = 5,
SIZE = 15360
go
DISK INIT
NAME = 'distlog',
PHYSNAME = 'c:\sql60\data\dislog.dat',
SIZE = 7680
VDEVNO = 6
go
  2. On the publication server, create the distribution database. For example:
    CREATE DATABASE distribution on distdata = 30
LOG ON distlog = 15
go
  3. Make the distribution database the current database, and then run the INSTDIST.SQL script.

    This script is located in the \SQL60\INSTALL directory. It adds tables, indexes, and stored procedures to the distribution database.

  4. Use regedt32 or xp_regwrite to set key values for the name and the working directory for the distribution database.

    For example, if on a server named WOLFHOUND you have created a distribution database named distribution and will use a working directory of D:\SQL60\REPLDATA, you could set the key values as follows:

    xp_regwrite 'HKEY_LOCAL_MACHINE', 'SOFTWARE\Microsoft\MSSQLServer\Replication', 'DistributionDB', 'REG_SZ', 'distribution'
go
exec("xp_regwrite 'HKEY_LOCAL_MACHINE', 'SOFTWARE\Microsoft\MSSQLServer\Replication', 'WorkingDirectory', 'REG_SZ', '\\"@@servername+"\D$\SQL60\REPLDATA'")
go
  5. Use sp_serveroption to define this server as the distribution server. For example, if the server is named WOLFHOUND:
    sp_serveroption 'WOLFHOUND', 'dist', 'true'
go
  6. Use sp_serveroption to define this server as a publication server. For example:
    sp_serveroption 'WOLFHOUND', 'pub', 'true'
go

    You can check results with sp_helpserver.

  7. On the publication server, use sp_addsubscriber to add subscription servers. For example:
    sp_addsubscriber BLOODHOUND
go
sp_addsubscriber AIREDALE
go

    You can check results with sp_helpserver.

  8. On both subscribers, use sp_addpublisher to add the publication server. For example:
    sp_addpublisher WOLFHOUND
  9. On both subscribers, use sp_dboption to enable a database as a subscription database. For example:
    use master
go
sp_dboption pubs,subscribed,true
go
  10. On the publisher, use sp_dboption to enable a database as a publication database. For example:
    use master
go
sp_dboption pubs,published,true
go
  11. On the publisher, use sp_addtask to manually create the scheduled task that will be used for synchronization of the publication. For example:
    use msdb
go
sp_addtask 'auth_table_sync','Sync','WOLFHOUND','sa','pubs',
1,4,1,8,1,0,0,19940926,19991231,090000,230000,00000000,160000,0,
'',2,1,'',2,2

    This adds a task "auth_table_sync" that will be run in the Sync Subsystem every hour from 9 A.M. to 11 P.M. It is scheduled to run after September 26, 1994. The task will start at 4:00 P.M. the first day.

    You can check the results by using sp_helptask. For example:

    use msdb
go
sp_helptask auth_table_sync, @mode = 'full'
go
  12. On the publisher, use sp_addpublication to add a publication. For example:
    use pubs
go
exec sp_addpublication authors_publication,n,@status = active, @description = 'full authors table'
go

    where "n" is the task ID for the task created using sp_addtask.

    You can check the results by using sp_helppublication. For example:

    sp_helppublication
go
  13. Create a table creation script either by hand or by using a utility such as SQL Transfer Manager. The script should be edited to follow the following rules:
    • The table schema must match the table in the published article.
    • All columns must be created with an explicit NULL or NOT NULL, entered in uppercase only.
    • No columns can be created with the identity property.
    • Timestamp columns must be changed to binary(8).

    The remaining steps in this procedure assume that you have created a script named AUTHORS.SCH. A example of such a script is provided in A Sample Schema Script, next in this chapter.

  14. On the publisher, use sp_addarticle to create an article. For example:
    exec sp_addarticle authors_publication, authors,
authors,
@creation_script = 'c:\sql60\repldata\authors.sch',
@description = 'Authors Table Article'
go

    You can check the results by using sp_helparticle and sp_helparticlecolumns. For example:

    sp_helparticle
go
sp_helparticlecolumns @publication=authors_publication, @article=authors
go
  15. On the publisher, use sp_addsubscription to add a subscription and automatically synchronize. For example:
    sp_addsubscription authors_publication, authors, AIREDALE
go
  16. While setting up replication, the log reader and distribution tasks were created as needed by using default scheduling frequencies. You can view these by using sp_helptask. For example, to display all currently scheduled tasks:
    use msdb
go
sp_helptask @subsystem='Distribution'
go
sp_helptask @subsystem='LogReader'
go


A Sample Schema Script

Following is a sample synchronization schema script. For this example, we present the AUTHORS.SCH script referred to in Setting Up Replication Manually.

EXEC sp_addtype id, 'varchar (11) '
GO
CREATE TABLE authors (
   au_id id NOT NULL PRIMARY KEY,
   au_lname varchar (  40 ) NOT NULL,
   au_fname varchar (  20 ) NOT NULL,
   phone char (  12 ) NOT NULL,
   address varchar (  40 )  NULL,
   city varchar (  20 )  NULL,
   state char (  2 )  NULL,
   zip char (  5 )  NULL,
   contract bit
 )
GO

/* Mark table as a replica */
EXEC sp_replica authors, true

GO


Manual Horizontal Partitioning

Horizontal partitioning¾the replication of selected rows from the base table¾can easily be accomplished using SQL Enterprise Manager. However, as an option, you can create your own stored procedure to implement horizontal partitioning. The filter stored procedure must follow this format:

CREATE PROCEDURE replica_filter FOR REPLICATION
AS

IF sql_statement
RETURN1
ELSE
RETURN 0

Using this procedure format, you could add partitioning to the examples provided in Setting Up Replication Manually.

For example, a horizontally partitioned article that published only the authors who live in California could be added to the authors_publication article. To do this, add the following steps to the replication setup script created in Setting Up Replication Manually.

  1. Create the stored procedure used to qualify rows for publication. For example:
    use pubs
go
create procedure ca_authors_filter for replication as
if exists (select state from authors (NOLOCK) where state = 'CA')
return 1
else
return 0
go
  2. Create a view that will be used to bulk copy out the data during synchronization. For example:
    create view ca_authors_view as select * from authors where state ='CA'
go
  3. Add the article to the appropriate publication. For example:
    sp_addarticle authors_publication,ca_authors,authors,
@creation_script = '\\WOLFHOUND\PUBLIC\ca_authors.sch',
@sync_object = ca_authors_view,
@filter = ca_authors_filter,
@dest_tab = ca_authors,
@description = "Horizontal partition of Authors where state = CA"
@type = 7
go

Note that in this example, since both articles come from the same source table, it is necessary to define a separate destination table for the article. The creation script in this case is a modified copy of authors.sch with the table name changed to ca_authors.

If desired, the results can be checked using sp_helparticle and sp_helparticlecolumns. For example:

sp_helparticle
go
sp_helparticlecolumns authors_publication, ca_authors
go

Additionally, in the creation script, you may want to take advantage of the NOT FOR REPLICATION constraint. For example, in the CREATE TABLE statement, you may want to add:

CONSTRAINT ca_constraint CHECK NOT FOR REPLICATION (state <> 'CA')

For information about using NOT FOR REPLICATION, see the Microsoft SQL Server Transact-SQL Reference.

When a replication filter is executed, it requests a lock on the published table. This lock can cause a replication deadlock situation. Therefore, when setting up manual horizontal partitioning, create the filter with the optimizer hint NOLOCK on the published table.


Manual Vertical Partitioning

Vertical partitioning¾the replication of selected columns from the base table¾can easily be accomplished using SQL Enterprise Manager. However, as an option, you can create your own stored procedure to implement vertical partitioning.

For example, you could add a vertically partitioned article to the publication authors_publication described earlier in Setting Up Replication Manually. The article could create a phone list from data residing within the authors table in the pubs database.

To create this vertically partitioned article, add the following steps to the replication setup script created in Setting Up Replication Manually:

  1. Create a view that will be used to bulk copy out data during synchronization. For example:
    use pubs
go
create view phonelist_view as select au_id, au_lname, au_fname, phone
from authors
go

    Note that this view must contain the primary key of the underlying table (in this case, au_id).

  2. Create a table creation script that will create a table on the subscriber containing the data columns that you want to pass.

    For example, construct a script named PHONELIST.SCH:

    EXEC sp_addtype id, 'varchar ( 11 ) '
/* adds a user defined datatype */
go
create table phonelist (
au_id id NOT NULL,
  PRIMARY KEY,
au_lname varchar ( 40 ) NOT NULL,
au_fname varchar ( 20 ) NOT NULL,
phone char ( 12 ) NOT NULL
)
go
  3. Add the article to the appropriate publication. For example:
    sp_addarticle authors_publication,phonelist,authors,
@creation_script = '\\WOLFHOUND\PUBLIC\phonelist.sch',
@sync_object = phonelist_view,
@dest_tab = phonelist,
@vertical_partition = 'true',
@description = "Vertical partition of Authors containing id, last name, first name, and phone number "
@type = 5
go

    Note that the parameter vertical_partition was passed as 'true' to this stored procedure.

  4. Define the columns that will be published. For example:
    sp_articlecolumn authors_publication,phonelist,au_id,add
go
exec sp_articlecolumn authors_publication,phonelist,au_lname,add
go
exec sp_articlecolumn authors_publication,phonelist,au_fname,add
go
exec sp_articlecolumn authors_publication,phonelist,phone,add
go
  5. Optionally, the results can be checked by using sp_helparticle and sp_helparticlecolumns. For example:
    sp_helparticle authors_publication, phonelist
go
sp_helparticlecolumns authors_publication, phonelist
go

The preceding example creates a vertically partitioned table on all subscribers, one that is automatically updated whenever the underlying data stored in the authors table of the publication server is modified.


Part 7 Other Operations

Other Operations

Using the scheduling engine, you can schedule and automate command executions, Transact-SQL statements, and replication tasks. Using the alerts management interface, you can set up SQL Enterprise Manager to automatically respond to SQL Server events by executing a predefined task or sending an alert or a page to selected users. Using SQLMail, you can send messages through the built-in mail application programming interface (MAPI) client interface in Windows NT. These messages can consist of short text strings, the output from a query, or an attached file. Using SQL Performance Monitor, SQL Enterprise Workbench, and the sp_monitor system stored procedure, you can monitor server activity and performance. The chapters in this part explain how.

Chapter 16, Scheduling Tasks, explains how to use SQL Enterprise Manager to schedule various server tasks for execution at specified times. You can schedule command executions, Transact-SQL statements, or replication tasks. A task can be scheduled to occur at a single specified time, on a recurring schedule, or on demand.

Chapter 17, Managing Alerts, shows you how to set up SQL Server to respond to errors by executing a task that you have defined or by sending an email or a pager message to an operator.

Chapter 18, Setting Up Mail, shows you how to set up SQL Server as a mail client, so that it can send mail messages through the built-in mail application programming interface (MAPI) client interface in Windows NT.

Chapter 19, Monitoring Server Activity and Performance, shows you how to monitor SQL Serveractivity and performance using SQL Performance Monitor and SQL Enterprise Manager. It also explains how to use the sp_monitor system stored procedure to obtain SQL Serverstatistics.


Chapter 16 Scheduling Tasks

Scheduling Tasks

Using SQL Enterprise Manager and the SQL Executive service, you can create server tasks and schedule them for execution at specified times. The tasks can be command executions, Transact-SQL statements, or replication tasks. A task can be scheduled to occur at a single specified time, on a recurring schedule, or when initiated by an alert. A task can also be executed immediately.

SQL Server processes also automatically create and schedule tasks. The System Administrator (SA) can use SQL Enterprise Manager to modify, disable, delete, and immediately run both user-created tasks and SQL Server-created tasks. (Users other than the SA can manage only tasks that they own.)

For more information, choose one of the following topics:

Accessing the Task Window

Creating a Task

Scheduling Task Execution

Setting Task Options

Viewing the Task List and Running Tasks

Viewing Task History

Disabling a Task

Modifying a Task

Removing a Task

Running a Task Immediately

Setting the Task Engine Options

Replication Task Scheduling


Accessing the Task Window

Alerts are administered from the Task Scheduling window of SQL Enterprise Manager, which can be accessed several ways.

To access the Task Scheduling window
  1. From the Microsoft SQL Server 6.0 program group, double-click the SQL Enterprise Manager icon.
  2. From the Server Manager window, select a server.
  3. Open the Task Scheduling window using one of these techniques:
    • From the toolbar, choose the Task Scheduling button.

    • From the Tools menu, choose Task Scheduling.
    • In the Server Manager window, under the selected server, double-click the SQL Executive icon.

    • In the Server Manager window, under the selected server, click the right mouse button on the SQL Executive icon, and then from the drop-down menu that appears, choose Edit Task.

    After you perform one of those techniques, the Task Scheduling window appears.

For simplicity, the procedures in this chapter assume you will use the Task Scheduling button from the toolbar. However, you can substitute any of the other techniques.


Creating a Task

To create a task
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Task Scheduling button.

    The Task Scheduling window appears.

  2. Choose the New Task button.

    The New Task dialog box appears.

  3. Complete the Task and Schedule information in this dialog box.

    For details about the Task and Schedule information managed in this dialog box, see the definitions that follow this procedure. For information about scheduling a task, Scheduling Task Execution.

  4. To set options for the new task, choose Options and complete the Task Options dialog box that appears.

    You can set options for email notification, Windows NT Event log messages, and retry attempts. For more information, see Setting Task Options.

  5. Choose Add.

    The task is created.

Following are brief descriptions of the selections you will make and the information you will provide when creating (or modifying) a task.

Name
A unique name for the task.
Enabled
If this box is selected, the task is created and scheduled. If this box is cleared, the task is created but not scheduled.
Database
The database the task will be executed against.
Type
The type of task to be scheduled. Most often you will select CmdExec or TSQL. The other types are used for replication scheduling. There are five task types:
CmdExec
An operating system command, or a .CMD or .EXE file as specified in the Command box.
Distribution
A replication distribution process command.
LogReader
A replication logreader process command.
Sync
A replication synchronization process command.
TSQL
A Transact-SQL statement to be run against the selected database. The statement is limited to 255 characters and cannot contained embedded "go" commands.
Command
The text of the task to be scheduled. This can be a valid operating system command, the filename (including path) of an .EXE file, or a Transact-SQL statement.

This can also be a command to one of the replication processes. For information about replication-related commands, see Replication Task Scheduling.

Schedule
Used to schedule the task.
On Demand
The task is created but is not scheduled. On demand tasks are the only type of tasks that can be used by alerts. When the alert occurs, the task is run.

On-demand tasks can also be run from the Task Scheduling window by using the Run Task button.

One-Time
The task occurs once, at the specified date and time. After running, it will be disabled but not deleted.
When
If One Time is selected, the When date and time boxes set the schedule for the one-time execution of the task.
Recurring
Specify a recurring schedule for the task. The schedule is displayed in the box below Recurring. The default for a recurring task is once a week on Sunday. Choose Change to change the schedule.
Change
Allows you to change the schedule of a task. Opens the Task Schedule dialog box. For information about this dialog box, Scheduling Task Execution.
Auto Start
SQL Server automatically starts the task when SQLExecutive starts. Used by replication processes.
Add
Adds the task you have specified.
Options
Allows you to specify options about email and Windows NT Event log notification and retry attempts for a particular task.


Scheduling Task Execution

When creating or modifying a task, you have the option of specifying that the task be executed repeatedly, at specified intervals. The default is for a recurring task to be executed once a week, on Sunday. You have the option of changing this.

To schedule a task
  1. While creating a task (using the New Task dialog box) or while modifying an existing task (using the Edit Task dialog box), choose the Change button.

    The Task Schedule dialog box appears.

  2. Complete the scheduling information in this dialog box.

    For information about the options in this dialog box, see the definitions that follow this procedure.

  3. Choose OK.

    The recurring schedule is set. The previous dialog box (New Task or Edit Task) returns.

Following are brief descriptions of the selections you will make while scheduling a task in the Task Schedule dialog box.

Occurs
The frequency with which the task should occur. Choices are Daily, Weekly, and Monthly.
Daily
If you choose Daily occurrence, then the Daily frame appears in the dialog box. Enter the number of days in the recurrence cycle. The default is Every 1 Day(s), indicating that the recurring task will be executed each day.

For example, you might enter 3. The recurring task will be executed every third day.

Weekly
If you choose Weekly occurrence, then the Weekly frame appears in the dialog box. Enter the number of weeks in the recurrence cycle, and select the day. The default is Every 1 Week(s), on Sunday.

For example, you might enter 4 and select Tuesday. The recurring task will be executed every four weeks, on Tuesday.

Monthly
If you choose Monthly occurrence, then the Monthly frame appears in the dialog box. Complete the choices in this frame.

For example, if you enter Day 4 of Every 2 Month(s), the recurring task will be executed on the fourth day of every other month.

Daily Frequency
The frequency with which the task should occur. This can be either once a day at a specified time or repeated at a specified interval within a specified range of hours.
Duration
The period during which the task is executed.
Start Date
The first day on which the recurring task will be executed.
End Date
The last day on which the recurring task will be executed. Not valid if No End Date is selected.
No End Date
The recurring task has unlimited duration.


Setting Task Options

When creating or modifying a task, you have the option of setting options for administrator email notification upon task failure or success, Windows NT Event log entries upon task failure or success, and task retry parameters.

To set task options
  1. While creating a task (using the New Task dialog box) or while modifying an existing task (using the Edit Task dialog box), choose the Options button.

    The Task Options dialog box appears.

  2. To notify an operator by email of the status of the task execution, select a name from the list in the Operator box, and then select the Email On Success and/or the On Failure check boxes.

    If necessary, you can remove an assigned operator by choosing <No Operator> in the Operator box. Or, you can add a new operator by selecting <New Operator> and completing the New Operator dialog box that appears.

    For more information about creating new operators, see Chapter 17, Managing Alerts, or the online Help for SQL Enterprise Manager.

  3. To record information about the task execution in the Windows NT Event log, select the NT Event Log On Success and/or the On Failure check boxes.

    Note that regardless of this setting, information about task execution is always logged in the Task History table. For more information, see Viewing Task History, later in this chapter.

  4. To specify the number of retry attempts for a failed task, type a number in the Retry Attempts box, and another number¾representing the number of minutes to wait before retrying a failed task¾in the Retry Delay box.
  5. For LogReader and Distribution tasks only you can specify a remote target server and database by typing the server name in the Server box, and the database name in the Database box.
  6. Choose OK.

    The options are set. The previous dialog box (New Task or Edit Task) returns.


Viewing the Task List and Running Tasks

You can view a list of the tasks that are defined for a particular SQL Server, and the list of tasks currently running.

To view the task list and running tasks
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Task Scheduling button.

    The Task Scheduling window appears.

  2. To view a list of existing tasks (both scheduled and disabled) for this server, select the Task List tab. The following information is displayed:
    • Task is the task name.
    • Owner is the task owner (usually the task creator).
    • Type is the type of task. CmdExec is an operating system command or executable file. TSQL is a Transact-SQL statement. Distribution, LogReader, and Sync are replication tasks.
    • Frequency is the task's schedule type: Recurring, One Time, or On Demand. (An on-demand task is run by an alert when the alert occurs).
    • Last Run Date is the day the task last ran.
    • Last Run Time is the time of day the task last ran.
    • Enabled tells you whether the task is enabled or disabled.
  3. To view a list of the tasks that are currently running, choose the Running Tasks tab. The following information is displayed:
    • Task is the task name.
    • Owner is the task owner (usually the task creator).
    • Type is the type of task. CmdExec is an operating system command or executable file. TSQL is a Transact-SQL statement. Distribution, LogReader, and Sync are replication tasks.
    • Start Date is the first day on which the recurring task will be executed.
    • Status displays status information about the task.

    Note Queued tasks are also shown in the Running Tasks tab. For subsystems (task type) other than TSQL, a task may be queued if it is scheduled to run but there are no free threads available in the subsystem. The maximum number of threads available to a subsystem can be changed using regedt32. The default for all subsystems (except TSQL) is 10.

  4. To update the displayed information, choose the Refresh button.


Viewing Task History

You can view information about the last run date of a task, the time and duration of the last run, the status of that run, and whether any email was sent by SQL Executive. You can also view any messages encountered while running the task.

To view task history
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Task Scheduling button.

    The Task Scheduling window appears.

  2. From the Task List, select the task to view history for.
  3. Choose the Task History button.

    The Task History dialog box appears. The following information is displayed:

    • Run Date shows the date the information is about.
    • Run Time shows when the task ran.
    • Status shows whether the task completed successfully.
    • Emailed indicates whether email was sent by SQL Executive after task execution.
    • Run Duration shows the amount of time the task took to run.
    • Message displays any messages that resulted from the task execution.
    • Clear All clears (erases) the history for the current task. (Only the task owner can do this.)


Disabling a Task

If you do not want a task to run but you do not want to delete it, you can temporarily disable it.

To disable a task
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Task Scheduling button.

    The Task Scheduling window appears.

  2. From the task list, select a task, and then choose the Edit Task button or double-click on the name of the task.

    The Edit Task dialog box appears.

  3. Clear the Enabled check box.
  4. Choose Modify.

    The task is disabled. It appears in the task list and retains all its settings but will not be run by SQL Executive.

    To reinstate a disabled task, repeat the preceding procedure, but in step 4 select the Enabled check box.


Modifying a Task

After a task has been created, you can modify it. You can change all the information and options you specified when you created the task: the name of the task, the type of task, the command information for a task, the task schedule, and the task options.

To modify a task
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Task Scheduling button.

    The Task Scheduling window appears.

  2. From the task list, select a task, and then choose the Edit Task button or double-click on the name of the task.

    The Edit Task dialog box appears.

  3. Change the task information as appropriate.

    The information managed while modifying a task is the same information managed while creating a task. For details about the task information you can manage, see Creating a Task.

  4. Choose Modify.

    The task is modified.


Removing a Task

If a task is no longer needed, you can remove it.

To remove a task
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Task Scheduling button.

    The Task Scheduling window appears.

  2. From the task list, select the task to be removed.
  3. Choose the Delete Task button or press the Del key.

    The task is removed.


Running a Task Immediately

Any task in the task list can be run immediately by the task owner. For the task to run, the SQL Executive service must be running on the target server.

To run a task immediately
  1. From the Task List of the Task Scheduling dialog box, select a task.

    You must be the owner of this task.

  2. Choose the Run Task button.

    The task begins execution.


Setting the Task Engine Options

You use the Task Engine Options to control the size of the task history log. The task history log contains the information that is displayed when you select a task from the Task List and choose the Task History button. (For more information, see Viewing Task History, earlier in this chapter.)

By managing the size of this log, you effectively control how long task history information is retained. The system maintains the task history log as information in the syshistory table of the msdb database. Only the SA can set the task engine options.

To set the task engine options
  1. From the Task Scheduling dialog box, choose the Task Engine Options button.

    The Task Engine Options dialog box appears.

  2. Select or clear the Limit Size of Task History Log option.

    If you clear this option, there is no limit on the size of the history log, and the number in the Maximum Task History Log Size has no effect.

    Important Depending on the activity level at the server, clearing this option can cause the size of the msdb.dbo.syshistory table to grow rapidly. In some cases, it can grow until it completely fills the msdb database. This can cause subsequent alert and history tasks to fail. If you need to keep large amounts of task history information, expand the msdb database to a size sufficient to accommodate the growth of syshistory.

  3. Specify a maximum number of rows in the task history by typing a number in the Maximum Task History Log Size box.

    The task history log will retain the most recent rows entered, up to the number specified. When this number is exceeded, the oldest entry (row) in the task history log is purged to make room for the newest entry. The default is 1000.

    This number can be set only if the Limit Size of Task History Log option is selected.

  4. Choose OK.


Replication Task Scheduling

In most cases, replication is scheduled through the replication administration interface provided by SQL Enterprise Manager, and you will not need to use SQL Executive to set up scheduled replication tasks.

However, it is possible to use SQL Executive to create replication tasks or modify already-scheduled replication tasks. You might typically:

  • Change the schedule for a replication task.

    Once you have set up replication, you can use SQL Executive to fine-tune replication process execution intervals for best performance. For example, by default the log reader runs continuously. You could use SQL Executive to change this to every five minutes. Or you may have configured replication so that a sync task occurs once a week. You could use SQL Executive to change that interval.

  • Change what happens in the event of an error.

    For example, you can enter the email name of a user to be notified if a scheduled replication task fails to execute.

  • Modify the command for a replication task.

    Command parameters are discussed in the text that follows.

  • Disable a replication task.

    For example, to temporarily stop replicating data from a publication server, you could disable the log reader task for that server.

Another reason to use SQL Executive is if you choose to set up replication manually, using replication stored procedures instead of SQL Enterprise Manager. You may find it convenient to schedule replication tasks using SQL Executive, instead of using the scheduling stored procedures.

There are three types of replication tasks that can be scheduled:

  • LogReader tasks schedule replication log reader process tasks.
  • Distribution tasks schedule replication distribution process tasks.
  • Sync tasks schedule replication synchronization process tasks.

When administering a LogReader task, the following optional commands can be entered in the Command box of the New Task or Edit Task dialog boxes:

-a packetsize
Where packetsize is the network packet size used for connections. The default is 4096.
-b transbatchsize
Where transbatchsize is the size of the transaction batch. This determines the maximum number of transactions that are read out of the log in each attempt. The default is 100.
-c commitbatchsize
Where commitbatchsize is the size of the commit batch. This determines how many transactions are placed in the distribution database before a commit can be issued against the distribution database. The default is the -b value (100).
-i pollinginterval
Where pollinginterval is the size of the polling interval, in milliseconds, when log reader runs as a continuous task.
-l logintimeout
Where logintimeout is the login timeout, in seconds. The default is 5 seconds.
-o filename
Where filename is the name of an optional output file. This outputs some debug information into the specified file as the log reader runs.
-p performancecounters
Where performancecounters is either 1 or 0. Providing 1 enables performance counter information to be maintained by the LogReader; providing 0 stops maintenance of that information. The default value is 1.
-q querytimeout
Where querytimeout is the query timeout, in seconds. The default is 30 seconds.

When administering a Distribution task, the following optional commands can be entered in the Command box of the New Task or Edit Task dialog boxes:

-a packetsize
Where packetsize is the network packet size used for connections. The default is 4096.
-b jobbatchsize
Where jobbatchsize is the maximum number of jobs to be read from the distribution database. The default is 0, which indicates all jobs in the database.
-B commandbuffers
Where commandbuffers is the number of 4K command buffers to use in the distribution buffer pool. The default number of buffers is 2.
-c commitbatchsize
Where commitbatchsize is the number of jobs to be issued to the subscription server before performing a commit on the subscription server. The default is 100.
-d subscriberdb
Where subscriberdb is the name of the subscription database.
-i pollinginterval
Where pollinginterval is the polling interval, in milliseconds. The polling interval is in effect when the distribution process is set for continuous.
-l logintimeout
Where logintimeout is the login timeout, in seconds. The default is 5 seconds.
-m missingjobsfailure
Where missingjobsfailure is 0 or 1. If 1, a missing job will raise an error with a severity of 20 (fatal). If 0, a missing job will raise an error with a severity of 10 (informational). The default is 0.

When you recover a subscriber there may be a case when the distribution database does not have the jobs to properly re-create transactions. This could happen if jobs between the subscriber's last job_id (in MSlast_job_info) and the distributor's last job_id (in MSsubscriber_status) are no longer in the distribution database (which can occur if sp_replcleanup was run and the retention period was inadequate).

-n publisherdb
Where publisherdb is the name of the publication database.
-o filename
Where filename is the name of an optional output file. This outputs some debug information into the specified file as the distribution process runs. It will output to the screen when a filename is not supplied.
-p publishername
Where publishername is the name of the publication server.
-P subpassword
Where subpassword is the password used for the subscription server login ID.
-q querytimeout
Where querytimeout is the query timeout, in seconds. The default is 30 seconds.
-s initscript
Where initscript is the filename of an initialization script that is run against the subscription database if the distribution process has never been run against that database before. The default is the DBREPL.SQL script, which configures the database as a subscription database and adds the MSlastjob_info table.
-S subscribername
Where name is the name of the subscription server.
-t subscribertype
Where subscribertype is 0 for SQL Server and 1 for an other ODBC source.
-U subloginid
Where subloginid is the login ID used when the process logs into the subscription server. The default is REPL_PUBLISHER.

When administering a Sync task, the following optional commands can be entered in the Command box of the New Task or Edit Task dialog boxes:

-a packetsize
Where packetsize is the network packet size used for connections. The default is 4096.
-l logintimeout
Where logintimeout is the login timeout, in seconds. The default is 5 seconds.
-o filename
Where filename is the name of an optional output file. This outputs some debug information into the specified file as the synchronization process runs.
-q querytimeout
Where querytimeout is the query timeout, in seconds. The default is 30 seconds.
-t pubtaskid
Where pubtaskid is the publication task ID (the ID of the synchronization task associated with the publication).

For information about replication, see Part 6, Replication. For information about using SQL Executive to create, modify, or disable a replication task, see Creating a Task, Modifying a Task, and Disabling a Task.


Chapter 17 Managing Alerts

Managing Alerts

SQL Enterprise Manager and the SQL Executive service provide an easy way to set alerts on SQL Server events. If the event occurs, SQL Executive will respond automatically, either by executing a task that you have defined or by sending an email and/or a pager message to an operator you have specified.

For information, choose one of the following topics.

Alerts Overview

Accessing the Alerts Window

Creating an Operator

Creating an Alert

Viewing Alerts

Editing an Alert

Canceling an Alert

Viewing Operators

Editing an Operator

Removing an Operator

Setting Alert Engine Options

Generating Alerts from Performance Monitor Thresholds

Setting Alerts on Forwarded Events

Managing Messages

Tips and Troubleshooting


Alerts Overview

SQL Server 6.0 provides the ability to set alerts on SQL Server events. For example, you could generate alerts when a database is about to become full or when a database dump is unsuccessful.

If the proper SQL Server options are set, SQL Server events are written to the Windows NT application (event) log. SQL Executive constantly monitors the Windows NT application log, waiting for events from SQL Server. When an event occurs, SQL Executive compares the event details against the alerts previously defined by the SQL Server administrator. If it finds a match, SQL Executive carries out the defined response. For each alert, the response can be either or both of these:

  • Send email and/or pager notifications to one or more operators.
  • Execute a task. This can be a Transact-SQL command batch or a Windows NT program (.CMD or .EXE file).

Paging is implemented via email. To support this, Microsoft Mail (provided with Windows NT) must be configured so that it is possible to send an email that will result in a page being sent. Email interfaces to pager services are provided by many telecommunications companies, and all that is normally required is the ability to route emails (for example, using Microsoft Mail's External Mail program) to a post office at the pager provider's site. For more information, contact your telecommunications provider.

Whether you are using email or pager-via-email notifications, you must be running Microsoft Mail on the same computer as SQL Server. For information on setting up Microsoft Mail, see your documentation for Microsoft Windows NT or the Microsoft Windows NT Resource Kit. In this documentation, see Chapter 18, Setting Up Mail.

For information on setting up SQLMail, also see the Microsoft SQL Server Transact-SQL Reference.

SQL Server events can either be processed by the local SQL Executive service or forwarded (by the local SQL Executive service) to the Windows NT application log on another computer that is running SQL Server 6.0. It is also possible to have a combination of the two: for example, you could have some events processed locally and some processed remotely. For more details on configuring event forwarding, see Setting Alert Engine Options, later in this chapter.

Microsoft SQL Enterprise Manager provides a graphical interface that allows an administrator to manage the entire alerting system. The alerts capability is supported for Microsoft SQL Server 6.0 only. You must be the System Administrator (SA) to use the alerts features of SQL Enterprise Manager.

Under the following circumstances, errors and messages generated by SQL Server and SQL Server applications are entered in the Windows NT application (event) log and can therefore cause SQL Executive to fire alerts:

  • Severity 19 or higher sysmessages errors
  • Non-sysmessages warnings/errors from SQL Server (severities 110, 120, and 130)
  • Any RAISERROR statement invoked by using the WITH LOG syntax
  • Any event logged by using xp_logevent

    Note RAISERROR WITH LOG is the recommended way to write to the Windows NT Application log from SQL Server.

  • Any sysmessages error modified by using sp_altermessage with_log, which forces an error to be written to the Windows NT application log when the error occurs.

Error messages with a severity lower than 19 can be logged by using RAISERROR, or by designating specific sysmessages errors as "always logged."

Also note that it is not possible to set an alert on a 4002 ("Login failed") message. However, if you turn on the option to audit failed logins, then when a login fails, the server writes a system message (18456 "Login failed - User: username" ) in the Windows NT application log. An alert can then be set on that 18456 message.

The auditing option for failed logins is a security option set by using either SQL Setup or SQL Enterprise Manager. For more information, see Chapter 9, Managing Security.


Accessing the Alerts Window

Alerts are administered from the Manage Alerts window of SQL Enterprise Manager, which can be accessed in several ways.

To access the Manage Alerts window
  1. From the Microsoft SQL Server 6.0 program group, double-click the SQL Enterprise Manager icon.
  2. From the Server Manager window, select a server.
  3. Open the Manage Alerts window by using one of these techniques:
    • From the toolbar, choose the Manage Alerts button.

    • From the Server menu, choose Alerts.
    • In the Server Manager window, under the selected server, click the right mouse button on the SQL Executive icon, and then from the drop-down menu that appears, choose Edit Alerts.

    After you perform one of those techniques, the Manage Alerts window appears.

For simplicity, the procedures in this chapter assume that you will use the Manage Alerts button from the toolbar. However, you can substitute any of the other techniques.


Creating an Operator

An operator is the individual who will be notified, through either email or a pager, that an alert has occurred. When you create an operator, you add information for the operator that can include an email name, a pager email name, and the schedule that the operator is available to be paged. In addition, you can assign alerts to the operator.

To create an operator
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Manage Alerts button.

    The Manage Alerts window appears, with the Alerts tab selected.

  2. Select the Operators tab.

  3. Choose the New Operator button.

    The New Operator dialog box appears.

  4. In the Name box, type a name to assign to this operator.
  5. Optionally, to create the operator but not permit the operator to receive alerts, clear the Enabled box.

    The Enabled box is selected by default. In most cases, this is the appropriate setting. It is useful to clear this option if you want to create the operator now but do not want to allow the operator to receive alerts until later.

    Another reason to clear this box is to temporarily disable the sending of alerts to this operator (for example, if the operator will be absent on vacation).

  6. To use e-mail to notify the operator of alerts, under Email Notifications type the operator's e-mail name ¾ for example, FRED.

    To send a test email, choose the Test button.

  7. To use a page to notify the operator of alerts, under Pager Notifications, type a pager email name, and then select the appropriate pager scheduling options.

    To send a test page, choose the Test button.

  8. To assign alerts to this operator, select an alert from the list under Alerts Assigned to This Operator, and then select the option box for Email and/or for Pager. Repeat for each alert to be assigned.

    A solid envelope or solid telephone icon indicates that the alert already has a notification of that type defined on it. An outline envelope or outline telephone icon indicates that the alert does not have a notification of that type defined on it.

    If you have not yet created the necessary alerts, don't worry. You will be given the opportunity during alert creation to assign this operator to each alert. You can also later edit this operator after alerts have been created.

  9. Choose OK.

If SQL Enterprise Manager is running on a 32-bit client computer (a computer where the SQL Server client utilities have been installed, but not the server software), and if the Microsoft Mail client has been started, you can use the mail integration features of SQL Enterprise Manager by pressing the Test button, and SQL Enterprise Manager will attempt to resolve the entered email name or (as appropriate) pager email name to the closest matching "friendly" email name. If there is not a close match or if the name is ambiguous, a dialog displays a list of possible choices.


Creating an Alert

By creating alerts, you can set up SQL Enterprise Manager to respond automatically to SQL Server events, either by executing a task that you have defined or by sending an email and/or a pager message to an operator that you have specified.

Although it is not required, it is a good idea to create operators before you create alerts.

To create an alert
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Manage Alerts button.

    The Manage Alerts window appears, with the Alerts tab selected.

  2. Choose the New Alert button.

    The New Alert dialog box appears.

  3. In the Name box, type a name to assign to this alert.
  4. Optionally, to create an inactive alert, clear the Enabled box.

    The Enabled box is selected by default. In most cases, this is the appropriate setting. It is useful to clear this option if you want to create the alert now but do not want it to take effect until later.

  5. To define the conditions that will cause an alert, specify either an error number or a severity level.
    • To specify that an alert will occur whenever an error of a specific severity level is entered in the Windows NT application log, select Severity and select an error level from the list.
    • To specify that an alert will occur whenever a specific error message is entered in the Windows NT application log, select Error Number, and type the error number.

      To select from a list of error messages, or to create a custom error message, select Error Number, select the browse button, and complete the SQL Server Messages dialog box that appears. For more information, see Managing Messages, later in this chapter.

    Note that an alert will occur only if the specified event is written to the Windows NT application log. For information about which events are logged, see Alerts Overview.

    For a list of error numbers and a discussion of severity levels, see Part 8, Troubleshooting.

    If an event occurs that matches both an alert set on a error number and an alert set on a severity, only the more specific alert (the error number alert) will run.

  6. Optionally, to narrow the alert notification criteria further, select a database name and/or provide an error message string.
    • To specify that an alert will occur only when an error is received from a specific database, choose Database Name and select a database from the list.
    • To specify that an alert will occur only when the error message contains a particular character string, type the character string in the Error Message Contains String box.
  7. To specify the action the system will take when the defined alert occurs, complete the Response Definition options.
    • To have a task execute when a qualifying alert occurs, select a task from the Task To Execute list.

      A task can invoke a program or a Transact-SQL statement (task types CmdExec or TSQL) and can only have an "On Demand" schedule. For information on creating tasks, see Chapter 16, Scheduling Tasks.

    • To provide additional information to the alert recipients, type text (instructions or a message) in the Alert Notification Message To Send To Operator box.

      You can enter up to 255 characters. Note that this is any text you want to add to the alert. Do not type in the actual error message text.

    • To include the actual text of the error message as part of the notification message, choose Include Error Message Text In Notifications, and then select the Email and/or the Pager options.
    • To set a delay between responses for recurring alerts, type a number (representing seconds) in the Delay Between Responses For Recurring Alerts box.

      For example, suppose you type 8 in this box. Later, five alerts that meet the alert definition occur within a period of eight seconds or less. Only one alert is sent to the operators specified in step 9.

  8. To specify the operators who will be notified when the defined alert occurs, select an operator from the list under Operators to Notify, and then select the option box for Email and/or for Pager. Repeat for each operator to be notified.

    A solid envelope or solid telephone icon indicates that the operator has address information of that type defined. An outline envelope or outline telephone icon indicates that the operator does not have address information of that type defined.

    If you have not yet created the necessary operators, don't worry. You will be given the opportunity during operator creation to assign this alert to each operator. You can also later edit this alert after operators have been created.

  9. Choose OK.

    The alert is created.


Viewing Alerts

You can view a list of all existing alerts, or information about a specific alert.

To view information about all alerts
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Manage Alerts button.

    The Manage Alerts window appears, displaying a list of all alerts defined for this server.

    For each alert, the list displays the alert name, enabled status, message number or severity level, date and time of last occurrence, whether email and/or pager notification is selected for the alert, the name of the task (if any) to be executed by the alert, and the count (the number of times the alert has occurred).

  2. To update the list with the latest information, choose the Refresh button.

To view information about a particular alert
  • From the Manage Alerts window, select an alert, and then choose the Edit Alert button. Or double-click an alert name.

    The Edit Alerts dialog box for that window appears, displaying the options and configuration settings for that alert. The Most Recent Occurrences box displays statistics for the alert.


Editing an Alert

Once you have created an alert, you can change any of the information that defines that alert.

To edit an alert
  1. From the Manage Alerts window, select the alert name from the list, and then choose the Edit Alert button. Or double-click an alert name.

    The Edit Alerts dialog box for that window appears, displaying the options and settings for that alert. The Most Recent Occurrences box displays statistics for the alert.

  2. Reconfigure the options as necessary.

    For example, to select another operator to receive this alert, select the operator name from the Operators To Notify list, and then select the Email and/or the Pager box.

    For information on the configuration options in this dialog box, see Creating an Alert.

  3. Choose OK.


Canceling an Alert

If an alert is no longer applicable, you can drop it. Or you can disable an alert, which inactivates the alert but preserves the alert information.

To drop an alert
  1. From the Manage Alerts window, select an alert.
  2. Choose the Delete Alert button.

To disable or reactivate an alert
  1. From Manage Alerts window, select an alert, and then choose the Edit Alert button. Or double-click an alert name.

  2. Set the Enabled option.
    • To disable an alert, clear this option.
    • To reactivate a disabled alert, select this option.
  3. Choose OK.


Viewing Operators

You can view a list of all existing operators, or information about a specific operator.

To view information about all operators
  1. From the Manage Alerts window, select the Operators tab.

    A list is displayed of all operators defined for this server.

    For each operator, the list displays the operator name, enabled status, email name, pager e-mail name, date and time the last email message was sent, and date and time the last page message was sent.

  2. To update the list with the latest information, choose the Refresh button.

To view information about a specific operator
  1. From the Manage Alerts window, select the Operators tab.
  2. Select the operator name, and then choose the Edit Operator button. Or double-click an operator name.

    The Edit operator dialog box for that window appears, displaying the options and configuration settings for that operator. The Most Recent Notifications box displays statistics for the operator.


Editing an Operator

Once you have created an operator, you can change any of the information that defines that operator.

To edit an operator
  1. From the Manage Alerts window, select the Operators tab.

  2. Select the operator name, and then choose the Edit Operator button. Or double-click the operator name.

    The Edit Operator dialog box for that window appears, displaying the options and settings for that operator. The Most Recent Notifications box displays statistics for the operator.

  3. Change the options as necessary.

    For example, to select another alert for this operator to receive, select the alert name from the Alerts Assigned To This Operator list, and then select the Email and/or the Pager box.

    For information on the configuration options in this dialog box, see Creating an Operator.

  4. Choose OK.


Removing an Operator

If an operator is no longer applicable, you can remove it. Or you can disable an operator, which inactivates the operator but preserves the operator information.

To drop an operator
  1. From the Manage Alerts window, select the Operators tab.

  2. Select an operator, and then choose the Delete Operator button.

To disable or reactivate an operator
  1. From the Manage Alerts window, select the Operators tab.
  2. Select the operator name, and then choose the Edit Operator button. Or double-click an operator name.

    The Edit Operator dialog box appears.

  3. Set the Enabled option.
    • To disable an operator, clear this option.
    • To reactivate a disabled operator, select this option.
  4. Choose OK.


Setting Alert Engine Options

By setting the Alert Engines Options, you can designate an operator who will be notified when all pager notifications for an alert fail, specify a server to whose Event (application) log any unhandled SQL Server events will be sent, restrict the events forwarded to those of a specified severity or above, and format the To, CC and Subject lines of pager emails.

To set alert engine options
  1. From the Server Manager window, select a server, and then from the toolbar choose the Manage Alerts button.

    The Manage Alerts window appears.

  2. From the Manage Alerts toolbar, choose the Alert Engine Defaults button.

    The Alert Engine Options dialog box appears.

  3. To set the Pager Fail-Safe Operator, choose the Fail-Safe tab, select an operator from the Operator to Notify list, and then select the notification method (Email or Pager). If the needed operator does not yet exist, choose New Fail-Safe Operator from the list, and complete the New Operator dialog box that appears.

    The Pager Fail-Safe Operator is the operator who will be notified when all pager notifications for an alert fail. Reasons for such a failure can include (but are not limited to) incorrect pager addresses, a problem with the mail system, or a "hole" in the pager schedules of the intended page recipients.

    The fail-safe operator can be notified via email or pager (subject to necessary address information being defined for the operator). Emails or pages sent to the fail-safe operator have "(Fail-Safe)" at the beginning of the Subject line, to distinguish them from normal notifications.

  4. To specify a server whose event log will be sent unhandled SQL Server events from this server, from the Fail-Safe window select the server name from the Server To Forward Events To list. If the needed server does not appear in the list (meaning it has not been registered with SQL Enterprise Manager), choose New Forwarding Server from the list, and complete the Register Server dialog box that appears.

    The Unhandled SQL Server Event Forwarding Server is a remote server to whose event log any unhandled SQL Server events on the local server (events for which there are no locally defined alerts) will be sent. Once the event is placed in that remote server's Windows NT application log, SQL Executive on that computer can process the events just as if they had been generated by its own local SQL Server.

    For information about using this capability to create a central alert management server, see Setting Alerts on Forwarded Events, later in this chapter.

  5. To restrict the events that are forwarded to the unhandled SQL Server event forwarding server, from the Fail-Safe tab window select a severity level from the Forward Events for Errors with Severity of or Above list.

    Since event forwarding can cause additional network load, you can restrict the events that are forwarded. By specifying a higher severity, fewer events are forwarded (that is, only those events with severity greater than or equal to the indicated severity). A severity of zero (0) causes all SQL Server events to be forwarded.

    For information about severity levels, see Part 8, Troubleshooting.

  6. To create the template that will be used for the To, CC, and Subject lines of a pager email, select the Pager Email tab, and complete the Page Email window.

    Enter prefixes and suffixes as required. For the To and CC lines, select the Pager-Address option if an operator's actual pager address should be inserted after the prefix and before the suffix. When a message is constructed, the prefix is prepended to the Pager Address, and the suffix is appended. If a Pager Address option is not selected, the prefix and suffix (if one is provided) are simply combined.

    These entries allow you accomplish special addressing by creating a template that will be used for the To, CC, and Subject lines of a pager email. Special addressing of the pager email may be required in order to integrate with a pager service provider's email system.

    For more information, see the example that follows this procedure.

  7. To prevent the notification for a single alert from being split over multiple pages, select the option Include Body of Email in Notification Page.

    A notification page is an alert notification sent via pager or via email. A notification (for both page and email) consists of lines of text. For pager notifications (that is, a notification page) where hardware character buffers are at a premium, it is desirable to limit the amount of text sent. When this option in cleared, only the subject line is sent (and therefore there is much less text in the notification page).

    This option is usually used with low-capacity alphanumeric paging systems (for example, those limited to 64 characters per page).

  8. Choose OK.

    The Alert Engine Options are set.

While setting the Pager Email options in step 6, you might enter these values, for example:

Line | Prefix | Pager Address | Suffix
To | @PGR: | X |
CC | MISPager |  |
Subject |  |  |

This template would be constructed as follows:

Line | Template
To | @PGR:<Pager Email Address>
CC | MISPager
Subject |

When an alert occurs and is sent to an operator with the pager address of johnd, the To, CC, and Subject lines of the email could be constructed as follows:

Line | Entry
To | @PGR:johnd
CC | MISPager
Subject | SQL Server Alert System: 'My Alert' occurred on \\MYCOMPUTER

In this example, the Subject line was system-generated. If you had entered a Subject prefix in the template, those characters would have be prepended to the system-generated Subject line. If you had entered a Subject suffix in the template, those characters would have been appended to the system-generated Subject line.


Generating Alerts from Performance Monitor Thresholds

Using the event logging utility, SQLALRTR.EXE, you can generate a SQL Server alert when a selected SQL Performance Monitor threshold is exceeded. To do this, you:

  1. Set a SQL Performance Monitor alert on a SQL Server counter.
  2. Configure SQL Performance Monitor to run SQLALRTR.EXE when the alert threshold is exceeded, thus writing a SQL Server event to the Windows NT application log.
  3. Use SQL Enterprise Manager to define an alert on that event.

When the specified SQL Performance Monitor threshold is exceeded, a Performance Monitor alert is generated, and SQLALRTR.EXE runs. It starts isql, which logs on to the server and issues a RAISERROR WITH LOG command. This causes an event to be written to the Windows NT application log. SQL Executive reads that event, and the alerts engine fires a SQL Server alert.

Note that the SQLALRTR.EXE utility is necessary because isql cannot be used directly with Performance Monitor. Performance Monitor passes the Windows NT alert information as Windows NT command line parameters, and isql will not work correctly in that context.

To generate an alert from a Performance Monitor threshold, you actually define two separate alerts: a SQL Performance Monitor alert and a SQL Server alert.

To generate an alert from a Performance Monitor threshold
  1. From the Microsoft SQL Server 6.0 program group, choose the SQL Performance Monitor icon.

    SQL Performance Monitor starts.

  2. From the View menu, choose Alert, and then from the Edit menu, choose Add to Alert.

    The Add to Alert dialog box appears.

  3. From the Object box, select a SQL Server object, and then from the Counter box, select a counter.

    For a brief description of the selected counter, choose the Explain button. For more information about each SQL Server object and counter, see Chapter 19, Monitoring Server Activity and Performance.

  4. In the Alert If box, select either the Over or Under option, and then type a threshold (a number) in the Alert If box.

    A Performance Monitor alert will occur when the statistic returned for that counter exceeds (if you selected Over) or falls below (if you selected Under) the threshold.

  5. Enter a SQLALRTR.EXE command in the Run Program on Alert box. Type:

    sqlalrtr -E error_number [-S server_name] [-P password]
    [-D database_name] [-V severity] [-T ]

    where

    -E error_number
    Specifies an error number that will be associated with this event, and error_number is the number. For information on SQL Server error numbers, see Part 8, Troubleshooting.
    -S server_name
    Specifies the server on which the alert will be raised, with server_name the server name.
    -P password
    Specifies that the command runs in the context of the SA account, and password is the SA password on the server.

    To avoid the need to supply the SA password on the command line (a possible security exposure), configure the server to run integrated security; or use the -T option instead.

    If you specify neither -P nor -T, then -T is assumed.

    -D database_name
    Specifies that the alert will be defined only for that database, with database_name the database name.
    -V severity
    Specifies the severity level of the error, with severity a number between 1 and 25. For information on SQL Server error severity levels, see Part 8, Troubleshooting.
    -T
    Specifies a trusted connection. To use this, the Windows NT user account used by Performance Monitor must be granted (or be a member of a group that has been granted) SA privileges on the target server. Grant SA privileges using SQL Security Manager.

    For example, to raise error "123456" on the local server:

    D:\SQL60\BINN\SQLALRTR /E123456

    Note The SQLALRTR.EXE parameters (-E, -S, -P, -D, -V, and -T) are case-sensitive and must be entered as capital letters.

  6. In the Run Program on Alert box, choose either the First Time option or the Every Time option.

    The default is Every Time.

  7. In the Add to Alert dialog box, choose Add.

    The Performance Monitor alert is added.

  8. Optionally, repeat steps 3 through 7 to add additional Performance Monitor alerts.
  9. Choose Done.

    The Alerts window of SQL Performance Monitor appears. The Alert Legend displays a list of the defined Performance Monitor alerts. The Alert Log displays a list of alert occurrences.

  10. Now that the SQL Performance Monitor alert has been defined, use SQL Enterprise Manager to create an associated SQL Server alert.

    Generate the SQL Server alert on the error_number or severity that was provided with the SQLALRTR.EXE command in step 5. For instructions on creating a SQL Server alert, see "Creating an Alert," earlier in this chapter.

Once you have defined an alert, SQL Performance Monitor and the SQL Executive service must both be running for the alert to be generated.

For more information about errors and severity levels, see Part 8, Troubleshooting. For more information about SQL Server performance objects and counters, see Chapter 19, Monitoring Server Activity and Performance. For more information about using SQL Performance Monitor, see its online Help. For more information about SQLALRTR.EXE, see the Microsoft SQL Server Transact-SQL Reference.

Note You cannot pass parameters to a SQL Server error that is raised using the SQLALRTR.EXE utility. For example, if you run the command sqlalrtr /E123456, then the message for error 123456 should not take parameters. For more information on defining and using error messages which take parameters, see the discussion of RAISERROR in the Microsoft SQL Server Transact-SQL Reference.


Setting Alerts on Forwarded Events

Event forwarding is a feature of SQL Executive that allows SQL Server events to be forwarded to another SQL Server¾called the alerts management server¾for processing, instead of being processed locally. Event forwarding enables central management of alerts and allows the development of alerts neighborhoods, which are groups of servers that share a common alerts management server.

  • Some advantages of setting up an alerts management server are the following:
  • Centralization. Centralized control and a consolidated view of the events of several SQL Servers is possible from a single server.
  • Scalable. Allows a variable number of physical servers to be administered as one logical server.
  • Efficient. Configuration time is reduced because you only need to define alerts and operators once, at one server.

Some disadvantages of setting up an alerts management server are the following:

  • Increased traffic. Forwarding events to an alerts management server can increase network traffic, although this can be moderated by restricting event forwarding to only higher severity events.
  • Single point of failure. The alerts management server is a potential single point of failure.
  • Server load. Handling alerts for the forwarded events causes an increased processing load at the alerts management server.

Event forwarding is implemented by using the alert engine fail-safe options described in Setting Alert Engine Options, earlier in this chapter.

To set up an alerts management server
  1. On each server that is to forward events, set up unhandled event forwarding.
    • In the Fail-Safe tab of the Alerts Engine Option dialog box, select a server from the list in the Server to Forward Events to box. This will become the alerts management server.
    • In the same dialog box, select a severity level from the list in the Forward Events for Errors with Severity of or Above box. Unhandled alerts of a level equal to or greater than this severity will be forwarded to the alerts management server.
  2. On each server that is to forward events, check that alerts are not defined on the events to be forwarded, or that if alerts are set they are disabled.

    If a locally defined alert is disabled and an event occurs that would have caused the alert to fire, the event will be forwarded to the alerts management server. This allows local overrides¾that is, alerts defined locally that are also defined at the alerts management server¾to be turned off and on as needed.

    Important Only unhandled events will be forwarded, and only those of a severity equal to or greater than the setting in the Fail-Safe tab of the Alerts Engine Option dialog box. An unhandled event is one for which there is no enabled, locally defined alert.

  3. On the alerts management server, set alerts on the events that are expected to be forwarded.

When configuring event forwarding, follow these guidelines:

  • Avoid running critical or heavily used applications on the alerts management server.
  • Avoid configuring large numbers of servers to share the same forward server. If congestion results, reduce the number of servers using a particular alerts management server.

    Note that for each server, the servers that are registered with SQL Enterprise Manager constitute the list of servers available to be configured as its alerts forwarding server.

  • Define server-specific alerts on the local server, instead of forwarding them.

    The alerts management server views all the servers forwarding to it as a logical whole. This means that, for example, the alerts management server makes no distinction between a 605 error on server A and a 605 error on server B.

  • Failure conditions encountered by the alerts engine¾for example, an inability to send an email notification¾are written to the local Windows NT application log with a source name of SQL Executive. Therefore, after configuring your alert system, you should periodically check the Windows NT application log for SQL Executive events.


Managing Messages

While managing alerts, you can:

  • View a list of available messages, and select one to set an alert on.
  • Search for messages by message text, severity, and/or error number and by only those that are always written to the Windows NT application log.
  • Select an option to always write the message to the Windows NT application log.
  • Create and edit user-defined messages.
To select a message to set an alert on
  1. While creating or editing an alert, under Alert Definition, select the Error Number option, and then choose the browse button.

    For information about creating alerts, see Creating an Alert, earlier in this chapter.

    The SQL Server Messages dialog box appears.

  2. To view all available messages, leave the default settings as is, and choose the Find button.

    A list of all messages appears.

  3. To view a subset of all available messages, change the defaults, and then choose the Find button.

    These options control the messages that will be searched for:

    Message Text Contains
    Searches for all messages that contain the text that is entered in this box.
    Severity
    Searches for messages of the selected severity level.
    Error Number
    Searches for a message having the error number entered in this box.
    Logged Messages Only
    Restricts the list to only those SQL Server messages that are always written to the Windows NT application log.

    If the System Messages option is selected, this list includes all system messages with severity levels 19 through 25, plus all user defined messages that are configured to be written to the log. If the System Messages option is cleared, this list includes only user-defined messages that are configured to always be written to the log.

    System Messages
    Lists system and user-defined messages. If this option is deselected, only user-defined messages are displayed.
  4. To sort the list by a column attribute, click on that column (Error, Severity, Language, Logged, or Message Text).

    This option is not available if the list contains more than 750 rows. The default sort is by error number.

  5. Select a message from the list, and then choose the Select button.

    The New Alert or Edit Alert dialog box returns. The number of the selected message is entered in the Error Number box.

You can edit the message list to create, modify, and delete user-defined messages. For user-defined messages, and for system messages with a severity level of 18 or less, you can choose an option to always write the message to the Windows NT application log.

The message list can be accessed from the New Alert or Edit Alert dialog box, as described in the previous procedure, or from the Manage Messages button of the Manage Alerts window, as described in the following procedure.

To edit the message list
  1. From the Manage Alerts window, choose the Manage Messages button.

    The Manage SQL Server Messages dialog box appears.

  2. To create a user defined message, choose the New button, and complete the New Message dialog box that appears.

    Error number assignments for user defined messages begin at 50001.

  3. To Edit a message, define the message search criteria, choose the Find button, select the message from the list, and complete the Edit Message dialog box that appears.

    For user-defined messages, all options except Error Number can be edited. For other messages, only the option Always Write To Windows NT Eventlog can be changed.

  4. To delete a message, select the message from the list, choose Delete, and then choose Yes in the confirmation dialog box that appears.

    Only user-defined messages can be deleted.

  5. When you finish editing messages, choose Close.

Messages can also be managed by the SA beginning from the SQL Enterprise Manager window, without needing to open the Manage Alerts window.

To manage messages, beginning from the SQL Enterprise Manager window
  • From the Server menu, choose the Messages command.

    The Manage SQL Server Messages dialog box appears. From this dialog box, the SA can create, edit, and delete messages, in the same way as described in the previous procedures.


Tips and Troubleshooting

Under conditions of rapidly occurring alerts, the delay between the event appearing in the Windows NT application log and the response by SQL Executive may increase. (Normally, it is only a few seconds.) This can occur because the alerts engine has a top response speed governed by its architecture¾SQL Executive competes with SQL Server for process bandwidth, and is designed to be economical with threads.

The rate at which SQL Executive can process alerts is also dependent upon the complexity of the alert response¾that is, the number of notifications. It is a good idea to send notifications to as few operators as possible. One technique is to send notifications to one group email address rather than notifying several individual operators.

If the rate of alert occurrence exceeds the rate at which SQL Executive can process alerts, a backlog of alerts will develop. If backlogs develop, increase the value for the Delay Between Responses for Recurring Alerts option for each alert. For information about setting this value, see Creating an Alert, earlier in this chapter.

If an alert is not firing, first check the following:

  • Is the SQL Executive service running?
  • Does the event appear in the Windows NT application log?
  • Is the alert enabled?
  • Are the alert's "Last Occurred" and "Count" values changing?

    If the alert's "Last Occurred" and "Count" values are changing, then that alert is occurring but there may be a problem with the response firing. If you have defined email or pager notifications to occur, test the email and/or pager addresses of the assigned operators by using the Test button (next to the address boxes in the Edit Operators dialog box). If a pager notification is not being received, check that the operator's pager notification schedule is set for the necessary days and hours.

The Effect of Windows NT Event Logging

If you turn off Windows NT event logging (by using the Server Options feature of SQL Setup or SQL Enterprise Manager as described in Chapter 3, Configuring Servers), then the alerts engine will not be able to pick up events from the Windows NT application log, and alerts will not be generated. Other SQL Executive functions will operate normally, and SQL Executive will continue to write any of its own errors to the Windows NT application log.

The Effect of the Windows NT Event Viewer Options

The Log Settings options for the Windows NT Event Viewer application affect the ability of the alerts engine to detect SQL Server events and issue alerts.

  • If the computer is running the Windows NT version 3.51 operating system, then in the Event Viewer application, in the Event Log Setting dialog box, you can select the Overwrite Events as Needed option. However, be aware that if the rate of event occurrences exceeds the rate at which SQL Executive processes events, and if this rate is sustained over a sufficient period of time, then some events in the application log will be overwritten before alerts can be generated. If this occurs, SQL Executive may write alert engine events 311 and 312 to the application log. However, as with any event being written to an event log which is being wrapped, these events themselves will eventually be overwritten.
  • If the computer is running the Windows NT version 3.50 operating system, then in the Event Viewer application, in the Event Log Setting dialog box, the Overwrite Events as Needed option must not be selected. The recommended option is Do Not Overwrite Events (Clear Log Manually).

    When the Do Not Overwrite Events (Clear Log Manually) option is selected, be sure to increase the Maximum Log Size setting to at least 2048KB.

    Important If you select the Do Not Overwrite Events (Clear Log Manually) option, you must periodically clear the application log manually. If you do not do this, then when the application log fills no more events can be added to the log, and the SQL Server alerts engine will be unable to generate alerts on subsequent (unlogged) events.

For information about setting the Event Viewer options, see its online Help.

Using Low-capacity Alpha-Numeric Paging Systems

For low-capacity alphanumeric paging systems (for example, those limited to 64 characters per page), you can prevent the notification for a single alert from being split over multiple pages by selecting the option Include Body of Email in Notification Page. This option appears in the Pager-Email tab of the Alert Engine Options dialog box.

Filtering Alerts Invoked Using xp_logevent

The xp_logevent extended stored procedure always has a database context of master, so you cannot filter on database name (other than master) for alerts that will be invoked using xp_logevent.

For information about xp_logevent, see the Microsoft SQL Server Transact-SQL Reference.

Square Bracket Notation for Email Addresses

When using internet and other specially addressed emails (including pager emails), it may be necessary to suppress the name checking features (that is, the check for existence of the email name in the local address book) performed by SQL Enterprise Manager or SQLMail (xp_sendmail). To do this, surround the email address with square brackets: [ ].

This can be done on an address-by-address basis using the Pager Email-Name box in the New Operator or Edit Operator dialog boxes. For more information, see Creating an Operator, earlier in this chapter.

This can be set globally for the server using the To and CC line templates in the Pager Email tab of the Alert Engine Option dialog box. For more information, see Setting Alert Engine Options, earlier in this chapter.

The square bracket notation is a feature of Windows NT Mail, not SQLMail or SQL Enterprise Manager.

Mail Integration Features

When running SQL Enterprise Manager on the server computer, the mail integration features described in Creating an Operator, earlier in this chapter, are available only under these conditions:

  • SQLMail must be started after the Microsoft Mail client is started.

    You cannot specify the Auto Start Mail Client option using the Server Options dialog boxes of the setup or SQL Server programs.

  • SQL Enterprise Manager must be started after the Microsoft Mail client is started.
  • In the SQL Enterprise Manager Registry key, you must add this value:

    HKEY_LOCAL_MACHINE
    \SOFTWARE
    \Microsoft
    \MSSQLServer
    \SQLEW

    Value: UseAddressBook
    Type: REG_DWORD
    Data: 0x1

    •

More About Pager Notifications

The alert notification features of SQL Server 6.0 use SQLMail, which is written using the MAPI 0 API set. To use pager notifications, you need to install some form of mail-server-side software that can process inbound mail and convert this mail into a pager message. This software can take one of several approaches to achieve this, including these three:

  •
Forward the mail to a remote mail server at the pager-providers site (for example, using one of the Microsoft Mail gateway applications). The pager-provider needs to offer this service, although the software required is generally available as part of (or as an add-on to) the local mail system.
    •

  •
Route the mail via the internet to a mail server at the pager-provider's site. This is a variation of the first approach.
    •

  •
Use proprietary pager-provider software to process the inbound mail and do the actual dialing via an attached modem. This software acts as a mail client, periodically processing its inbox either by interpreting part or all of the email address information as the pager number to dial, or by looking up the email name in a translation table to find the pager number to dial. This software is proprietary to the pager service provider.
    •

For specific software requirements contact your pager service provider.

Avoiding Excessive Writing to the Logs

In general, it is a good idea to avoid excessing writing to the logs. If you have set up a substantial number of alerts, you may want to disable writing to the SQL Server error log altogether, and only write to the Windows NT application log. You should avoid using alerts too liberally (for example, do not send an alert every time a row in a table is changed).

To prevent writing to the SQL Server error log, use SQL Setup or SQL Enterprise Manager.


Chapter 18 Setting Up Mail

Setting Up Mail

Microsoft SQL Server includes extended stored procedures that allow SQL Server to send and receive mail messages through the built-in mail application programming interface (MAPI) client interface in Windows NT. A mail message can consist of short text strings, the output from a query, or an attached file. This SQL Server mail capability is called SQLMail.

This chapter shows you how to set up SQL Server as a Mail client, so that it can send mail messages through the MAPI client interface in Windows NT.

For information choose one of the following topics.

SQLMail Overview

LocalSystem and SQLMail

Setting Up a SQLMail Client

Starting and Stopping SQLMail Manually

Setting Up a Mail Post Office

Using SQLMail with a NetWare Post Office

SQLMail Stored Procedures

Troubleshooting SQLMail Problems


SQLMail Overview

Microsoft Windows NT Server includes a MAPI-enabled electronic mail application, Microsoft Windows NT Mail, that can exchange information with other Windows-based computers and can work with Windows-based applications. SQLMail can use Microsoft Windows NT Mail¾or another MAPI provider¾to send and receive mail messages.

SQLMail messages can consist of short text strings, the output from a query, or an attached file. Using the SQLMail extended stored procedures, messages can be sent from within a trigger or a stored procedure. For example, you could set up a trigger to send a mail message when changes occur in the database.

With SQL Server 6.0, mail functionality has been integrated with SQL Enterprise Manager. You can easily configure SQL Server to send mail messages to users when:

  • A SQL Server alert occurs
  • A SQL Performance Monitor threshold is exceeded
  • A scheduled task¾such as a database backup or a replication event¾succeeds or fails

For example, you could configure SQL Enterprise Manager to notify you when long-running processes (such as data downloads) are complete. You could also send mail to a list of recipients when backups occur, and if errors occur during a backup.

Before SQL Server can send mail and receive messages through the MAPI client interface in Windows NT, the server must be configured as a Mail client.

For information about:

  • Setting up a Mail client, see Setting Up a SQLMail Client, later in this chapter
  • Sending a mail message when a scheduled task succeeds or fails, see Chapter 16, Scheduling Tasks
  • Using SQL Enterprise Manager to send a mail message when a SQL Server alert occurs or when a SQL Performance Monitor threshold is exceeded, see Chapter 17, Managing Alerts
  • Using SQLMail extended stored procedures, see the Microsoft SQL Server Transact-SQL Reference


LocalSystem and SQLMail

By default, the SQL Server service is installed to run in the security context of the server's LocalSystem account. If you will be using SQLMail, you can leave the default LocalSystem account assigned, or you can assign a user account to the SQL Server (MSSQLServer) service.

Also by default, the Services application in the Control Panel has the Allow Service To Interact With Desktop option selected for the MSSQLServer service. Do not clear this option.

Note A service running under the LocalSystem account has no user account information associated with it. This prevents certain network server software from allowing the Windows NT service to access resources. For example, Microsoft LAN Manager user-level security servers and Novell NetWare Servers will not allow a Windows NT service running under the LocalSystem account to access their file shares.


Setting Up a SQLMail Client

To enable SQLMail functionality for a server, you will:

  1. Set up the server computer as a Microsoft Windows NT Mail client.
  2. Set up SQL Server as a SQLMail client.

The procedures that follow describe how to accomplish these tasks.

Note As a prerequisite to setting up a SQLMail client, a Mail post office must already be available. If one is not, see Setting Up a Mail Post Office, later in this chapter.

To set up the server computer as a Microsoft Windows NT Mail client
  1. From the Main program group, double-click the Mail icon.

    The Welcome to Mail dialog box appears.

  2. Choose the option Connect To An Existing Postoffice, and then choose OK.

    The Connect to Postoffice dialog box appears.

  3. Enter the network path of the post office, and then choose OK.

    For example:

    \\airedale\wgpo

    A dialog box appears, asking whether or not you have an account on the post office.

  4. Choose Yes or No.
    • To use an existing mail login account, choose Yes. In the Mail Sign In dialog box that appears, enter the mail login name and password, and then choose OK. The server is configured as a Mail client, and the Mail window appears.

      After you sign into an existing mail login account, skip to step 7.

    • To create a new mail login account, choose No. The Enter Your Account Details dialog box appears. To complete this dialog box, proceed with step 5.

  5. Define a mail login account. At a minimum, enter a name, mailbox, and password.
    Name
    Is the full name of the mail user.

    Normally, this would be the full name of a user of this computer. For example:

    John Q. Public

    However, in this case, it is recommended that you consider creating a mail account especially for SQL Server. For example, if the local server is named TERRIER, you might enter:

    SQL Server Terrier
    Mailbox
    Is a mail address that will be used to log in to the post office.

    Normally, this would be a variation of the user's full name. For example, to represent "John Q. Public" you might enter:

    JohnQP

    Or for a mail login that will be used by the local SQL Server, you might enter:

    terrier
    Password
    Is a password for the mail login. For example:
    casey86
  6. Choose the OK button.

    The server is configured as a Mail client, the mail login account is created, and the Mail window appears.

  7. Verify that Mail is set up properly by sending an ordinary mail message to yourself. To send a message, choose the Compose button and complete the dialog box that appears.

    For information about sending and receiving messages, see the online Help for Mail.

  8. From the Mail menu, choose the Options menu and set the Mail options to appropriate values for use by SQL Server. In particular:
    • Set the Check For New Mail option to Every 1 Minute.
    • Clear the option Save Copy Of Outgoing Messages In Sent Mail Folder. (Do not save messages in that folder.)
    • Clear the option Check Spelling Of Messages Before Sending. (Do not check spelling.)

    For information about setting options, see the online Help for Mail.

Once the server is set up as a Microsoft Windows NT Mail client, you can set up SQLMail by using SQL Setup.

To set up SQLMail
  1. Start the Mail client using the same Mail login account SQLMail will use to log on to Windows NT mail.

    You will specify the name and password of this Mail login account in step 7 of this procedure.

  2. From the Microsoft SQL Server 6.0 program group, double-click the SQL Setup icon.
  3. Follow the on-screen instructions until the Microsoft SQL Server 6.0 Options dialog box appears.

  4. Choose Set Server Options, and then choose Continue.

    The Select Server Options dialog box appears.

  5. To start a SQLMail session every time SQL Server starts, select Auto Start Mail Client.
  6. To set the SQLMail login options, choose the Mail Login button.

    The Mail Login dialog box appears.

  7. To specify a mail login account SQLMail will use to log in to Windows NT Mail, in the Mail Login Name box, type a valid Mail login name; in the Mail Password box type the password for that Mail login name; and in the Confirm Password box type the password again.

    If you have configured SQL Server to start SQLMail sessions automatically, you must supply a mail login name and password. If you will be starting mail sessions manually (by using xp_startmail), you can optionally supply your login name and password in this dialog box so that you do not have to type it at the command line. (Note that SQLMail will "piggyback" an existing client session of Mail, if one is running.)

    Note If at any time the Windows NT Mail password is changed, you will need to change the password here as well.

  8. If you are setting up SQLMail on this server for the first time, select the option Copy SQLMail Configuration from Current User Account.

    This copies the post office location and mail options of the user you set up the Windows NT Mail client for previously. The settings are copied to the Default User.

    Even if you don't use the Mail Login dialog box to save a Mail username and password, you must select this option when setting up SQLMail for the first time. Thereafter, the check box does not need to be selected unless you have changed your Mail client configuration information.

  9. Choose Continue.

    The Select Server Options dialog box returns.

  10. Choose Change Options.

    The new settings are processed.

  11. Choose Exit.

After SQLMail is installed, by default the SQL Executive service will automatically attempt to start the SQLMail session every time SQL Executive starts. This behavior can be controlled through a Registry value.

HKEY_LOCAL_MACHINE
\SOFTWARE
\Microsoft
\MSSQLServer
\SQLExecutive

Name: MailAutoStart
Type: REG_DWORD
Data:

If the value is set to 1, SQLMail auto-starts when SQL Executive starts. If the value is set to 0 or the Registry key does not exist, SQLMail does not start when SQL Executive starts. The default is 1.


Starting and Stopping SQLMail Manually

In addition to starting SQLMail automatically when SQL Server starts, SQLMail can be started and stopped manually from the query interface. Only the SA can start and stop SQLMail.

If you do not start the Windows NT Mail client before starting SQLMail, you will not be able to view the Inbox/Sentmail during that SQLMail session. The Windows NT Mail client cannot be started after SQLMail starts.

To start SQLMail manually
  • Type:

    xp_startmail ['user'] [, 'password']

    where

    user
    Is an optional parameter specifying a mail username.
    password
    Is an optional parameter specifying a mail password.

    If no user or password are provided, SQL Server uses the username and password specified in the Mail Login dialog box. If user and password are provided, SQL Server attempts to log on to Windows NT Mail (or other MAPI provider) by using that username and password. If user and password are provided but are incorrect, an error message is returned.

To stop SQLMail
  • Type:

    xp_stopmail

For more information about the Mail client interface, see your documentation for Microsoft Windows NT, or see the Microsoft Windows NT Resource Kit.


Setting Up a Mail Post Office

The Windows NT Mail application provided with Windows NT has a client side and a mail-server side. The client side includes the Mail application, with its graphical user interface. The server side simply contains a directory structure known as the post office and has no programmatic components.

The post office must reside on a shared network directory on a computer running Windows NT, and each Mail client must have access. The post office is a directory structure in which the main directory is called a workgroup post office (WGPO). All post office file manipulation is handed by the Mail client. The post office is a temporary message store, holding a message only until the Mail client computer retrieves it.

Following are instructions for setting up a Windows NT Mail post office on a computer running the Windows NT Server operating system. The post office computer does not need to have SQL Server installed, although it can.

Note This procedure provides only the basic post office setup instructions. For detailed information about setting up Microsoft Windows NT Mail post offices, see your documentation for Windows NT or the Microsoft Windows NT Resource Kit.

To set up a Windows NT Mail post office
  1. From the Main program group, double-click the Mail icon.

    The Welcome to Mail dialog box appears.

  2. Select the option Create New Workgroup Postoffice, and then choose OK.

    A confirmation dialog box appears.

  3. Choose Yes in the confirmation dialog box.

    The Create Workgroup Postoffice dialog box appears.

  4. Select the drive and directory where the post office files will be installed, and then choose OK.

    The Enter Your Administrator Account Details dialog box appears.

  5. Define a mail login account that you will use to administer this post office. At a minimum, enter a name, mailbox, and password.
    Name
    Is the full name of the mail user. For example:
    Peggy Sue Haimbach
    Mailbox
    Is a mail login (email name) that will be used to log onto the post office. For example:
    peggysh
    Password
    Is a password for the mail login. For example:
    royce90
  6. Choose OK.

    The post office is created, the mail login for the post office administrator is created, and a message appears telling you to create a shared network directory for that post office.

  7. Choose OK.

    The Mail window appears.

  8. To add mail users, from the Mail menu choose Postoffice Manager, and complete the Postoffice Manager dialog box that appears.

    For more information about adding Mail users, see your documentation for Windows NT.

After the Mail post office is installed, you must create a shared network directory for that post office. You can do this from the command line or from File Manager. The following procedure tells you how to do this from File Manager. For information on accomplishing this from the command line, see your documentation for Windows NT.

To create a shared network directory for the post office
  1. From the Main program group, start File Manager

  2. In the File Manager window, select the post office directory.
  3. From the Disk menu, choose Share As, and complete the dialog box that appears.

    For more information, see the online Help for File Manager.

When setting up the shared network directory, ensure that the SQL Server service and all Mail clients have RWCD access to the post office share. If a SQL Server is running under the LocalSystem account, this will require that the post office share grant these rights to EVERYONE if the SQL Server is on the same domain as the post office server, and to GUEST if it is not.

If the post office share is on an NTFS drive, permissions must be set for both the network share and the directory. For information on setting share and directory permissions, see the online Help for File Manager.

If the post office resides on a computer running Windows NT Server version 3.5 or later and MSSQLServer on a Mail client computer runs under the LocalSystem account, it is necessary to add the post office share to the list of shares that can be accessed by services running under LocalSystem. This can be done by adding the share name to the Registry key on the Windows NT computer sharing the post office:

\\HKEY_LOCAL_MACHINE
\System
\CurrentControlSet
\Services

\LanmanServer
\Parameters

Name: NullSessionShares
Type: REG_MULTI_SZ
Data: COMCFG

A Registry key can be added by using the Registry Editor (REGEDT32.EXE). For more information, see the online Help for the Registry Editor. You can also set the SQL Server service (MSSQLServer) to run under a Windows NT user account, which does not require the NullSessionShares Registry entry.


Using SQLMail with a NetWare Post Office

You can set the SQL Server service (MSSQLServer) to run under a Windows NT user account. With appropriate permissions, SQL Server will be able to run SQLMail and access a NetWare Post Office.

However, the server's LocalSystem account has no user account information that can be used when accessing remote resources. If the SQL Server service (MSSQLServer) is configured to run under the server's LocalSystem account, it cannot directly access certain server software, including Novell NetWare.

When SQL Server is running under LocalSystem, it is still possible to set up SQLMail to work when the post office is on a Novell NetWare file server by going through the Gateway Services for NetWare, which are provided with Windows NT version 3.5 or later.

The following steps describe how to set up SQLMail running under LocalSystem to work with a NetWare post office:

  1. Set up a gateway share on the Windows NT Server to point to the post office share on the NetWare machine. Supply a valid NetWare user account and password for an account that has RWCD access to the post office share. For information on how to set this up, see the Windows NT documentation on the Gateway Services for NetWare.
  2. Set up the Windows NT Mail client application (MSMAIL32.EXE) to connect to the NetWare post office by using the drive letter specified for the gateway connection.
  3. Verify that the user that is setting up SQLMail can successfully start a mail session and send mail using the Windows NT Mail client.
  4. Using SQL Setup, go to Set Server Options - Mail Login, and check the option to "Copy SQLMail Configuration from Current User Account."

    This copies the post office location and mail options of the user you set up the Windows NT Mail client for previously. The settings are copied to the Default User.

    Even if you don't use the Mail Login dialog box to save a Mail username and password, you must select this option when setting up SQLMail for the first time. Thereafter, the check box does not need to be selected unless you have changed your Mail client configuration information.

Once the above steps have been completed successfully, you can use xp_startmail with a valid mail username and password to start a SQLMail session.


SQLMail Stored Procedures

A dynamic-link library, SQLMAP60.DLL, is installed with SQL Server and includes the extended stored procedures necessary for mail enabling. Following are descriptions of the SQLMail extended stored procedures:

SQLMail extended stored procedure | Description
xp_deletemail | Deletes a specified message.
xp_findnextmsg | Finds the next message in the mail box.
xp_readmail | Reads a message and/or an attachment from the mail box.
xp_sendmail | Sends a message and/or a query result set and/or an attachment to specified recipients.
xp_startmail | Starts a SQL Server Mail client session.
xp_stopmail | Stops a SQL Server Mail client session.

There is also one system stored procedure used by SQLMail:

SQLMail system stored procedure | Description
sp_processmail | Processes mail in the inbox of SQL Server. Finds, reads, responds to, and deletes mail messages. Can return results of a query to a message sender. Can be called by SQL Executive as a scheduled task.

SQLMail system and extended stored procedures, syntax, and functionality are documented in the Microsoft SQL Server Transact-SQL Reference.


Troubleshooting SQLMail Problems

Certain basic troubleshooting techniques can be used to diagnose and resolve most SQLMail problems. Typically, errors in starting a mail session or sending mail fall into two categories: permissions problems when accessing Shared File System (SFS) shares being used as post offices, and registry setup problems.

Check the following, preferably in the order given here:

  1. Ensure that the SQL Server service (MSSQLServer) is assigned the LocalSystem account and that the option Allow Service To Interact With Desktop is selected. These can be checked by using the Services application in the Control Panel.
  2. Ensure that the user who set up SQLMail can successfully start a mail session and send mail by using the Window NT Mail client application, MSMAIL32.EXE.
  3. When starting a mail session, Mail makes use of information in the Windows NT registry to determine startup information, such as the share name serving as a post office for the user logging in. This registry information is configured for the current user when the SQL Setup or SQL Enterprise Manager program is run and the option "Copy SQLMail Configuration from Current User Account" in the Mail Login dialog box is checked.

    This is the Registry key used by SQLMail:

    HKEY_USERS
    \.DEFAULT
    \Software
    \Microsoft
    \Mail

    If this Registry key is not set up properly, ensure that you are able to start a mail session using the account you are currently logged in under, and then rerun SQL Setup or SQL Enterprise Manager, ensuring that the "Copy SQLMail Configuration from Current User Account" is checked.

  4. Ensure that the SQL Server service has RWCD access to the post office share. If the SQL Server is running under the LocalSystem account, this requires the post office to grant these rights to EVERYONE if the SQL Server is on the same domain as the post office server, or GUEST if it is not.

    Access to the file share can be tested by using the xp_cmdshell extended stored procedure. For instance, the following commands can be used to test read and write access to the server:

    xp_cmdshell "dir \\mailserver\poshare"

    and

    xp_cmdshell "echo 'hello' > \\mailserver\poshare\test.txt"

    Note If the post office share is on an NTFS drive, permissions must be set for both the network share and the file system.

  5. If the post office resides on a computer running Windows NT Server version 3.5 or later, and if the MSSQLServer service on a separate Mail client computer runs under the LocalSystem account, ensure that the post office share has been added to the list of shares that can be accessed by services running under LocalSystem. This can be done by adding the share name to the Registry key on the Windows NT computer sharing the post office:

    \\HKEY_LOCAL_MACHINE
    \System
    \CurrentControlSet
    \Services
    \LanmanServer
    \Parameters

    Name: NullSessionShares
    Type: REG_MULTI_SZ
    Data: COMCFG

    A Registry key can be added by using the Registry Editor (REGEDT32.EXE). For information, see the online Help for the Registry Editor. You can also set the SQL Server service (MSSQLServer) to run under a Windows NT user account, which does not require the NullSessionShares Registry entry.


Chapter 19 Monitoring Server Activity and Performance

Monitoring Server Activity and Performance

This chapter shows you how to monitor SQL Server activity and performance using SQL Performance Monitor and SQL Enterprise Manager. It also explains how to use the sp_monitor system stored procedure to view SQL Server statistics and how to view the SQL Server and Windows NT logs.

This chapter focuses on server activity and performance. For information about database performance, integrity, and optimization, see the Microsoft SQL Server Database Developer's Companion.

For more information, choose one of the following topics:

Monitoring Server Performance

Monitoring Server Activity

Monitoring Server Statistics

Viewing the Logs


Monitoring Server Performance

SQL Performance Monitor¾the integration of Microsoft SQL Server 6.0 with the Windows NT Performance Monitor¾makes it possible for you to get up-to-the-minute activity and performance statistics about SQL Server.

SQL Performance Monitor obtains statistics from performance counters, several of which are grouped within a performance object.

When you install SQL Server, the setup program automatically provides six performance objects to SQL Performance Monitor.

For more information, choose one of the following topics:

Integration with Windows NT Performance Monitor

Using SQL Performance Monitor

Objects and Counters


Integration with Windows NT Performance Monitor

Three server options determine whether and in what mode SQL Server performance statistics are made available to Performance Monitor:

SQL Performance Monitor Integration
Provides SQL Server performance statistics to Performance Monitor. By default, the setup program installs SQL Server with this option selected.

When SQL Performance Monitor Integration is selected, SQL Server statistics are gathered and displayed using one of the following modes.

Direct Response Mode
In this mode, SQL Server statistics are gathered separately from the SQL Server Statistics display. Data is available immediately to SQL Performance Monitor, and response time is good; however, the statistics displayed are one period behind the statistics retrieved. This is the default mode.
On Demand Mode
In this mode, Performance Monitor requests and waits for the latest data from SQL Server during each Performance Monitor update (refresh) period. With this option, you get the latest data, but response time is not as good as with Direct Response Mode.

The time it takes for SQL Server to return statistics to the Performance Monitor using On Demand Mode depends on how busy SQL Server and the Windows NT - based server are. This mode is useful when monitoring a SQL Server statistic that is updated infrequently, or when monitoring SQL Server statistics and other system statistics in the same Performance Monitor view.

When using this mode, set the Performance Monitor update time (the refresh interval) long enough so as not to overload SQL Server with requests. For information on setting the Performance Monitor update time, see the Performance Monitor online Help.

When a new SQL Server is installed, by default the setup program configures it for integration with Performance Monitor, using the direct response mode. After installation, you can use SQL Setup to review or change the Performance Monitor integration options.

To review or change the Performance Monitor integration options
  1. From the Microsoft SQL Server 6.0 program group, double-click the SQL Setup icon.
  2. Follow the on-screen instructions until the Microsoft SQL Server 6.0 Options dialog box appears.

  3. Choose Set Server Options, and then choose Continue.

    The Select Server Options dialog box appears.

  4. Review and if appropriate change the settings for these server options:
    • SQL Performance Monitor Integration
    • Direct Response Mode
    • On Demand Mode
  5. Choose Change Options.

    The new settings are processed.

  6. Choose Exit.


Using SQL Performance Monitor

When you install SQL Server, the setup program automatically installs a SQL Performance Monitor icon in the Microsoft SQL Server 6.0 program group.

To start SQL Performance Monitor
  • From the Microsoft SQL Server 6.0 program group, double-click the SQL Performance Monitor Icon.

    The Performance Monitor window appears.

By default, when SQL Performance Monitor is started, it monitors a predefined set of SQL Server counters. It displays:

  • The percentage of time that a request was found in the data cache (instead of being read from disk)
  • The number of Transact-SQL command batches executed per second
  • The number of physical page reads per second
  • The number of single page writes performed per second by logging and cache flushes
  • The number of user connections

You can configure SQL Performance Monitor to display statistics from any of the SQL Server counters. For information on configuring and using SQL Performance Monitor, see the Performance Manager online Help. For information about the statistics returned by each SQL Server counter, see Objects and Counters, later in this chapter.

SQL Server statistics are displayed only when SQL Server is running. If you stop and then restart SQL Server, the display of SQL Server statistics is interrupted and then automatically resumed.

As with all performance monitoring tools, you should expect some performance overhead when monitoring SQL Server using the Performance Monitor. In tests using the default SQL Server counters defined in the SQL Server program group, the monitoring overhead was found to be less than 5 percent on a single processor computer, and a negligible amount on a multiprocessor machine. Note, however, that these results are to be used only as guidelines about what to expect; the actual overhead in any specific instance will depend on the hardware platform, the number of counters, and the update interval selected.

If the server is running SQL Server integrated security, Performance Monitor can be run only by a SQL Server user who has SA privileges. If the server is not running integrated security, the probe user ID is used to retrieve the values displayed in Performance Monitor. In this case, be aware that if you delete the probe user ID, you will not be able to use Performance Monitor.

If you want to run Performance Monitor without SQL Server running, you can increase the response time by disabling the SQL Performance Monitor Integration option. This is a server option set that uses SQL Setup or SQL Enterprise Manager. For more information, see Chapter 3, Configuring Servers.

For additional information about displaying statistics and for information about setting alerts based on thresholds reported by these statistics, see your documentation for Windows NT.


Objects and Counters

SQL Server statistics can be obtained from the counters in six Performance Monitor objects:

SQLServer Object

SQLServer Replication-Published DB Object

SQLServer Replication-Subscriber Object

SQLServer-Locks Object

SQLServer-Log Object

SQLServer-Users Object


SQLServer Object

The following counters are part of the SQLServer object. These counters provide statistics about global SQL Server performance:

Cache ¾ Ave. Free Page Scan
The average number of data cache buffers scanned by Lazywriter while searching for an unused buffer to replenish the free buffer pool.
Cache ¾ Max. Free Page Scan
The maximum number of data cache buffers scanned by Lazywriter while searching for unused buffers to replenish the free buffer pool.
Cache ¾ Number of Free Buffers
The number of cache buffers currently in the free buffer pool. Running out of free buffers is expensive, so this statistic should not be much lower than the free buffer threshold that is specified by the free buffers parameter of sp_configure. Lazywriter will normally ensure that the number of free buffers does not fall below the threshold. If it does, you may need to either increase the max asyn IO and max lazywrite IO parameters, and/or increase the free buffer threshold.
Cache Hit Ratio
The percentage of time that a request was found in the data cache (instead of being read from disk). Because reading from the cache is much cheaper than reading from disk, you want this ratio to be high. Generally, you can increase the cache hit ratio by increasing the amount of memory reserved for the data cache using the memory parameter of sp_configure. Note that some transactions can cause the cache hit ratio to be "artificially" high (80 - 90 percent). For example, in the course of certain transactions, a page might be requested multiple times, creating the likelihood that, after the first request, all requests would be satisfied by the data cache.
I/O ¾ Batch Average Size
The default maximum is 8. This is the average number of 2K pages written to disk during a batch I/O operation. The checkpoint thread is the primary use of batch I/O.

If you have a good disk I/O subsystem that can handle queued I/O requests (one that supports disk arrays or includes a smart SCSI controller), you can increase this maximum (and the I/O - Batch Max Size and I/O - Batch Writes/sec) using the max async IO option of sp_configure. However, setting the max async IO option too high can result in too much overhead and can be counterproductive, because it could flood the disk subsystem with writes and induce overload.

I/O ¾ Batch Max Size
The default maximum is 8. This is the maximum number of 2K pages written to disk during a batch I/O operation.

See the remarks under I/O - Batch Average Size.

I/O ¾ Batch Writes/sec
It is optimal for Batch Writes/sec to be high. This is the number of 2K pages written to disk per second using batch I/O. The checkpoint process is the primary user of batch I/O.

See the remarks under I/O - Batch Average Size.

I/O ¾ Lazy Writes/sec
The number of 2K pages flushed to disk per second by Lazywriter.

The Lazywriter is a system process whose main task is to flush out batches of dirty, aged buffers (buffers that contain changes that must be written back to disk before the buffer can be reused for a different page) and make them available to user processes by placing them in the free buffer pool.

The Lazywriter eliminates the need to checkpoint frequently for the purpose of creating available buffers. The batch I/O size used by the Lazywriter can be set by using SQL Enterprise Manager or sp_configure to adjust the server's max lazywrite IO parameter. This controls the Lazywriter's batch I/O size, and it can be tuned to maximize the I/O throughput for specific hardware platforms and I/O subsystems.

The maximum number of batched asynchronous I/Os performed by the Lazywriter can be tuned by using SQL Enterprise Manager or sp_configure to adjust the server's max lazywrite IO parameter. This parameter is comparable to max async IO, which controls batch I/O such as BCP and checkpoints, but max lazywrite IO is specific to the Lazywriter. This option should be configured only on systems with multiple disks. This parameter is dynamically configurable up to the value specified by max async IO, which makes it easier to tune this parameter. Setting this too low can hinder performance, while setting it too high could flood the disk subsystem with writes and thus slow disk reads.

Important Do not change the max lazywrite I/O value unless your primary support provider instructs you to do so.

For information on setting the max lazywrite I/O and max async I/O parameters, see the Microsoft SQL Server Transact-SQL Reference.

I/O ¾ Log Writes/sec
The number of log pages physically written to disk per second. Because all changes must be physically logged to disk before a transaction can be considered complete, overall throughput can be limited by the disk drive on which the log is located. If Log Writes/sec reaches the maximum sequential write capability of the disk drive (60 - 70 per second for a typical 12-15 millisecond seek time disk drive and more for disk arrays), the system will be limited by that maximum, so you should consider placing the log on a striped disk set to increase the I/O capacity.. For best performance, the log device should be placed on a disk or logical disk capable of optimal write performance.
I/O ¾ Outstanding Reads
The number of physical reads pending. This statistic gives you an idea of how the I/O subsystem is performing. A large number of outstanding reads over an extended time period can be an indicator that the I/O subsystem is a bottleneck and that changing to faster disks or a disk array would help performance.
I/O ¾ Outstanding Writes
The number of physical writes pending. This statistic gives you an idea of how the I/O subsystem is performing. A large number of outstanding writes over an extended time period can be an indicator that the I/O subsystem is a bottleneck and that changing to faster disks or a disk array would help performance.
I/O ¾ Page Reads/sec
The number of physical page reads per second. This statistic displays the total number of physical page reads per second across all databases. Because physical I/O is very expensive, you may be able to minimize it by using a larger data cache, intelligent indexes, more efficient queries, or by changing the database design.
I/O ¾ Single Page Writes/sec
The number of single page writes performed per second by logging and cache flushes. (Pages written out during the checkpoint process are recorded in the Batch Writes/sec statistic.) This does not include lazywriter batch statistics.

Single-page writes are generally expensive, as opposed to batch-wide IO (used by lazywriter and checkpoint). Reducing single-page write activity is important for optimal tuning. One way is to do this is to ensure that you do not run out of free buffers in the free buffer pool. If you do, single page writes will occur when waiting for an unused cache buffer to flush.

I/O ¾ Trans. per Log Record
The number of transactions that were packed into a log record before the log record was written to disk. Because log records must be physically written to disk before a transaction is considered complete, the rate at which log writes are completed is the ultimate limit on system throughput. If the log writes from many transactions are packed into a single physical write, throughput can be improved. It may be possible to increase the number of transactions per log record by adjusting the logwrite sleep parameter of sp_configure.
I/O ¾ Transactions/sec
The number of Transact-SQL command batches executed per second. This statistic is affected by all constraints (such as I/O, number of users, cache size, complexity of requests, and so on). High Transactions/sec means good throughput. It is important to note that this is command batches per second (not transactions per second).
NET ¾ Command Queue Length
The number of client requests waiting to be handled by the SQL Server worker threads. When this statistic is high, it indicates a backlog of commands waiting to be processed. To decrease the wait times, use sp_configure to increase the number of worker threads.
NET ¾ Network Reads/sec
The number of tabular data stream (TDS) packets read from the network. This statistic is an indicator of network throughput. When this statistic is high, it indicates lots of network traffic. This statistic is best used in conjunction with the other network statistics.
NET ¾ Network Writes/sec
The number of tabular data stream (TDS) packets written to the network. This statistic is an indicator of network throughput. When this statistic is high, it indicates lots of network traffic. This statistic is best used in conjunction with the other network statistics.
RA ¾ Pages Fetched into Cache/sec
Pages prefetched into cache by Read Ahead Manager.

If this counter is monitored in conjunction with the "RA ¾ Pages Found in Cache/sec" counter, can be used to determine read-ahead effectiveness. If "Pages Fetched" is high and "Pages Found" is low, then read-ahead is effective. The less effective read-ahead is, the closer the two counters become. If "Pages Fetched" is less than "Pages Found," then read-ahead is simply overhead and is not helping scan times.

Read-ahead configuration options control "parallel data scan" capabilities, which enable asynchronous read-ahead of data when SQL Server determines that pages are being retrieved in sequential order. With read-ahead (RA), separate background threads will be used to prefetch pages for a given results set. Read-ahead is used by queries, DBCC CHECKTABLE, DBCC CHECKDB, DBCC CHECKALLOC, UPDATE STATISTICS, CREATE INDEX, exporting with BCP, and the retrieval of text and image data. Read-ahead prefetches are configured based on extents. The read-ahead sp_configure options are RA cache hit limit, RA cache miss limit, RA delay, RA pre-fetches, RA slots per thread, and RA worker threads. For more information about read-ahead, see the Microsoft SQL Server Transact-SQL Reference.

RA ¾ Pages Found in Cache/sec
Pages found to be already in cache by Read Ahead Manager. (Shows how many 2K pages were already found to be in the cache.)
RA ¾ Physical Reads/sec
Physical reads (each consisting of 8 2K pages, meaning 16K reads) issued by Read Ahead Manager. Provides a general idea of how busy read-ahead is in terms of actual physical IO.
RA ¾ Slots Used
Total slots used. Shows you how many slots you are using (compared to how many you have configured). Also indicates the number of queries using read-ahead at any given time. If this counter hits the maximum slots ceiling, you should increase the number of slots using sp_configure.
User Connections
The number of user connections. Since each user connection consumes some memory, configuring overly high numbers of user connections could impact throughput. User connections should be set to the maximum expected number of concurrent users.

If a performance slowdown coincides with an increased number of user connections, then you can use sp_configure to restrict user connections, lower the number of worker threads, or increase memory.


SQLServer Replication-Published DB Object

The following counters are part of the SQLServer Replication-Published DB object. They provide information about the delivery of transactions from the transaction log of the publication database to the distribution database.

Replicated Transactions
The number of transactions in the transaction log of the publication database that are marked for replication but have not yet been delivered to the distribution database.
Replicated Transactions/sec
The number of transactions per second that have been read out of the transaction log of the publication database and delivered to the distribution database.
Replication Latency (msec)
The number of milliseconds between the time a transaction marked for replication is entered into the transaction log of the publication database and is read out of the log and delivered to the distribution database.


SQLServer Replication-Subscriber Object

The following counters are part of the SQLServer Replication-Subscriber object. They provide information about the delivery of transactions from the distribution database to the destination database.

Delivered Transactions
The number of delivered transactions in the distribution database. A delivered transaction is one that has already been executed against the destination database, but still resides in the distribution database.
Delivered Transactions/sec
The number of transactions delivered per second¾that is, the number of jobs per second that were executed in the last batch sent to the subscription server from the distribution server.
Delivered Latency (sec)
The number of seconds a transaction remains in the distribution database before delivery to the subscription server¾that is, the time between a job being inserted in the distribution database and being executed against the destination database.
Undelivered Transactions
The number of undelivered transactions in the distribution database. An undelivered transaction is one that has not been executed against the destination database.


SQLServer-Locks Object

Locks are held on pages that are read or modified during a transaction to prevent problems that might arise from concurrent use of resources by multiple transactions. Minimizing locks increases concurrency, which can improve performance results. Although there are many ways to minimize locks, one method is to commit transactions as soon as you have completed them. (For information about concurrency, see the Microsoft SQL Server Database Developer's Companion.)

SQL Server can hold several types of locks. In general, read operations acquire shared locks, and write operations acquire exclusive locks. Update locks are created at the page level and are acquired during the initial portion of an update operation when the pages are being read or by cursors opened with pessimistic concurrency. Update locks are compatible with shared locks. Later, if the pages are changed, the update locks are promoted to exclusive locks.

SQL Server locks can be held on a table (table or intent), a page, or an extent. SQL Server tries to satisfy requests with page locks before acquiring table locks. However, if many page locks are held during the course of a transaction, SQL Server upgrades the lock to a table lock (shared or exclusive). The point at which escalation occurs is configurable with sp_configure. SQL Server obtains table locks when it suspects that a transaction might affect an entire table. Table locks provide a way of avoiding lock collisions at the page level.

An intent lock indicates the intention to acquire a shared or exclusive lock on a data page. (An intent lock prevents another transaction from acquiring an exclusive lock on the table containing that page.) An extent lock is held on a group of eight database pages while they are being allocated or freed. Extent locks are set while a CREATE or DROP statement is running or while an INSERT statement that requires new data or index pages is running.

In addition, some SQL Server locks are considered blocking locks. A blocking lock is a lock that blocks another process that needs to acquire a lock. As soon as the process that is causing the block finishes, the other process can move forward.

For more information about locks, see the discussion about monitoring database integrity and optimizing databases in the Microsoft SQL Server Database Developer's Companion.

The following statistics are included in the SQLServer-Locks object:

Extent Locks ¾ Exclusive
A count of exclusive extent locks.
Extent Locks ¾ Shared
A count of shared extent locks.
Extent Locks ¾ Total
A count of all extent locks.
Intent Locks ¾ Exclusive
A count of exclusive intent locks.
Intent Locks ¾ Shared
A count of shared intent locks.
Intent Locks ¾ Total
A count of all intent locks.
Page Locks ¾ Exclusive
A count of exclusive page locks.
Page Locks ¾ Shared
A count of shared page locks.
Page Locks ¾ Total
A count of all page locks.
Page Locks ¾ Update
A count of update page locks.
Table Locks ¾ Exclusive
A count of exclusive table locks.
Table Locks ¾ Shared
A count of shared table locks.
Table Locks ¾ Total
A count of all table locks.
Total Blocking Locks
A count of all locks blocking other processes.
Total Exclusive Locks
A count of all exclusive locks.
Total Locks
A count of all locks being used by SQL Server.
Total Shared Locks
A count of all shared locks.


SQLServer-Log Object

The following counters are part of the SQLServer-Log object, which includes statistics for SQL Server transaction logs. Each of these counters displays statistics for the transaction log for a specific database.

Log Size (MB)
The transaction log size.
Log Space Used (%)
The percentage of the transaction log that is full. When the log is full, transactions that require logging are rejected. You can use this statistic to set a Performance Monitor alarm based on a percent full threshold and then spawn a task to dump or truncate the transaction log or to send a message (for example, using net send).

You can use the alerter utility, sqlalrtr, to generate a SQL Server alert on a threshold for this statistic (or for any Performance Monitor statistic). Alert response can include email or pager email notification of an operator. For more information and configuration instructions, see Chapter 17, Managing Alerts.


SQLServer-Users Object

The following counters are part of the SQLServer-Users object, which includes statistics for SQL Server user connections. Each of these counters displays statistics for a specific server process ID (spid). Note that the spid is prefaced by the username. (It may be logged on the username.)

CPU Time
The cumulative CPU time for a user connection (and checkpoint process). You can use this statistic to determine how much time a user connection has consumed and compare that amount with the CPU consumption for other users.
Locks Held
The number of locks held by a user connection.
Memory (2K pages)
The amount of memory (in 2K pages) allocated to a user connection. You can use this statistic to determine if queries executed by a particular user are consuming significant memory.
Physical I/O
The number of disk reads and writes for the current statement. You can use this statistic to determine how expensive a query or statement is in terms of physical I/O. You can tune this statistic by changing indexes or rewriting the query.


Monitoring Server Activity

Using SQL Enterprise Manager, you can view information about current server activity. You can view information about current user connections and locks; see the process number, status, locks, and commands that the active users are running; and determine which objects are locked and the kinds of locks that are present. If you have SA privileges, you can also view additional information about a selected process, send a message to a selected user, or terminate a selected process.

For information about monitoring server activity, choose one of the following topics:

Displaying Current Server Activity

Viewing User Activity

Viewing Detail Activity

Viewing Object Locks

Viewing More Information

Sending a Message

Killing a Process

SQL Server activity can also be monitored by using the sp_who and sp_lock system stored procedures. For information about these system stored procedures, see the Microsoft SQL Server Transact-SQL Reference.


Displaying Current Server Activity

Only the SA can open the Current Activity window.

To display current server activity
  1. From the Server Manager window, select a server.
  2. From the toolbar, choose the Current Activity button.

    The Current Activity window appears.

The Current Activity window has three tabs:

  • The User Activity tab displays information about the current connections and locks. For more information, see Viewing User Activity.
  • The Detail Activity tab displays more detailed information about the process number, status, locks, and commands that the active users are running. For more information, see Viewing Detail Activity.
  • The Object Locks tab displays information about the objects that are locked and the kinds of locks that are present. For more information, see Viewing Object Locks.

While viewing any of the tabs in the Current Activity window, you can display a legend explaining the graphics used in the list. You can also update the display with current information.

To display a legend explaining the graphics used in the list
  • Choose the Toggle Legend button.

    The Activity Legend appears.

To update the list with current information
  • Choose the Refresh on-screen information button.

If you have SA privileges, you can also select an item from the list and:

  • Display detailed information about the selected process. For more information, see Viewing More Information.
  • Send a message to the connected user or computer. For more information, see Sending a Message.
  • Kill the selected process. For information see Killing a Process.


Viewing User Activity

From the User Activity tab, you can view information about active connected users, see the processes that are running, and view information about locks.

To view user activity
  1. From the Server Manager window, select a server.
  2. From the toolbar, choose the Current Activity button.

    The Current Activity window appears.

  3. If it is not already selected, select the User Activity tab.

The items in the User Activity list are grouped by login ID. Each item in the User Activity list displays an icon indicating the type of activity, the process ID of the process, the user, the status, the name of the connected computer, and (if present) locks. A red background indicates a blocking lock.

The information for an item in the list or for the items under a login ID can be expanded or contracted by choosing the plus ("") or minus ("-") adjacent to the item. To display a legend explaining the graphic elements used, choose the Legend button from the toolbar.


Viewing Detail Activity

From the Detail Activity tab, you can view information about the process number, status, blocking, locks, and commands that the active users are running, and more.

To view detail activity
  1. From the Server Manager window, select a server.
  2. From the toolbar, choose the Current Activity button. Or from the Server menu, choose Current Activity.

    The Current Activity window appears.

  3. Select the Detail Activity tab.

The list in the Detail Activity tab displays this information:

Status
An icon representing the activity and status.

A definition for each icon can be displayed by choosing the Toggle Legend button and viewing the Activity Legend.

Process ID
The process identification number (spid) of the process.
Login ID
The login ID of the user executing the command. System indicates SQL Server.
Database
The name of the database the process is running against.
User Name
The database username of the user executing the command.
Command
The command currently being executed.
Host
The computer from which the command was initiated.
Application
The name of the application program.
Blocked By
The process ID of a blocking process, if any. A blocking process (which can have an exclusive lock) is one that is holding resources that another process needs.
Blocking
Shows whether or not this process is blocking another. Zero indicates that it is not blocking. Any number other than zero indicates that it is blocking.
Lock Type
An icon indicating the type of lock, or No Lock, indicating that there are no locks.

A definition for each type of lock can be displayed by choosing the Toggle Legend button and viewing the Activity Legend.

Locked Object
The name of the locked object. For example:
pubs.dbo.authors
Group Name
The name of the database group the user belongs to.
CPU Usage
Cumulative CPU time for the process.
Physical I/O
Cumulative disk reads and writes.
Host Process
The workstation process ID number.

Most of this information can also be obtained by querying the sysprocesses table in the master database. For more information, see the Microsoft SQL Server Transact-SQL Reference.


Viewing Object Locks

From the Object Lock tab, you can view information about object locks on the server.

To view object locks
  1. From the Server Manager window, select a server.
  2. From the toolbar, choose the Current Activity button. Or from the Server menu, choose Current Activity.

    The Current Activity window appears.

  3. Select the Object Locks tab.

Each item in the Object Locks list displays an icon indicating the type of lock, the process ID of the process holding the lock, the user, the type of statement that is being executed against the locked object, and the name of the connected computer. A red background indicates a blocking lock.

The information for an item in the list can be expanded or contracted by choosing the plus ("") or minus ("-") adjacent to the item. To display a legend explaining the graphic elements used, choose the Legend button from the toolbar.


Viewing More Information

If you have SA privileges, you can view detailed information about a selected process. While viewing more information, you can also kill the process or send a message to the connected computer or user.

To view more information about a process
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Current Activity button.

    The Current Activity window appears.

  2. Select a tab (User Activity, Detail Activity, or Object Lock), and then select an item from the list in that window.
  3. Choose the More Info button.

    The Process Information For dialog box appears.

  4. Review the displayed information.
    • Last Statement displays the first 255 bytes of text of the statement run by the selected process.
    • CPU Usage displays cumulative CPU time for the process.
    • Physical DISK I/O displays cumulative disk reads and writes.
  5. To terminate the process, choose the Kill Process button.
  6. To send a message to the connected user or computer, choose the Send Message button and complete the dialog box that appears.
  7. To update the displayed information, choose the Refresh button.


Sending a Message

If you have SA privileges, you can send a message to a connected user or computer. This feature is available only for Microsoft networks.

To send a message to a connected user or computer
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Current Activity button.

    The Current Activity window appears.

  2. Select a tab (User Activity, Detail Activity, or Object Lock), and then select an item from the list in that window.
  3. Choose the Send Message button.

    The Send Message dialog box appears.

  4. In the Message box, type the text of the message.
  5. Under Destination, specify where the mail will be sent.
    • Select Using Username to send the message to the displayed username.
    • Select Using Hostname to send the message to the computer name. To change the computer that will receive the message, type a computer name in the Hostname box.

      To send a message to all users connected to the computer, type an asterisk (*) in the Hostname box. This sends a message to all users connected to the computer (not just users connected to SQL Server).

  6. Choose Send.


Killing a Process

If you have SA privileges you can terminate a process.

To kill a process
  1. From the Server Manager window, select a server, and then from the toolbar, choose the Current Activity button.

    The Current Activity window appears.

  2. Select a tab (User Activity, Detail Activity, or Object Lock), and then select an item from the list in that window.
  3. Choose the Kill Process button.

  4. If a confirmation dialog box appears, choose Yes.


Monitoring Server Statistics

Using the sp_monitor system stored procedure, you can display statistics that indicate how busy SQL Server has been. Each time sp_monitor is run, these statistics are returned:

last_run
The time the sp_monitor system procedure was last run.
current_run
The time the sp_monitor system procedure is being run.
seconds
The number of elapsed seconds since the sp_monitor system procedure was run.
cpu_busy
The number of seconds that the server computer's CPU has been doing SQL Server work.
io_busy
The number of seconds that SQL Server has spent doing input and output operations.
idle
The number of seconds that SQL Server has been idle.
packets_received
The number of input packets read by SQL Server.
packets_sent
The number of output packets written by SQL Server.
packet_errors
The number of errors encountered by SQL Server while reading and writing packets.
total_read
The number of reads by SQL Server.
total_write
The number of writes by SQL Server.
total_errors
The number of errors encountered by SQL Server while reading and writing.
connections
The number of logins or attempted logins to SQL Server.

You execute the sp_monitor system stored procedure by using any of the SQL Server client utilities (such as ISQL/w or the query window of SQL Enterprise Manager). Because it updates the spt_monitor table in the master database, you must have SA privileges to execute sp_monitor.

To view server statistics
  • Type:

    sp_monitor

For example:

sp_monitor
last_run             current_run          seconds
-------------------  -------------------  -------
MAR 11 1995 3:26PM   MAR 11 1995 4:34PM   4038

cpu_busy             io_busy              idle
-------------        ----------           ------------
4250(215)-68%        67(1)-0%             109(100)-31%

packets_received     packets_sent         packet_errors
-------------------  -------------------  -------------
781(15)              10110(9596)          0(0)

total_read           total_write          total_errors   connections
--------------       --------------       ------------   -----------
394(67)              5392(53)             0(0)           15(1)

The information returned shows not only the current value for each statistic but also how much each has changed since the last time the procedure was executed. Each statistic is returned in the form number(number)-number% or number(number). The first number refers to the number of seconds (for cpu_busy, io_busy, and idle) or the total number (for the other variables) since SQL Server was restarted. The number in parentheses refers to the number of seconds or the total number since the last time sp_monitor was run. The percentage is the percentage of time since sp_monitor was last run.

For example, if the report shows cpu_busy as 4250(215)-68%, the CPU has been busy 4250 seconds since SQL Server was last started up, 215 seconds since sp_monitor was last run, and 68 percent of the total time since sp_monitor was last run.

SQL Server keeps track of these statistics by using a series of predefined global variables. With the exception of last_run, current_run, and seconds, the names of the sp_monitor statistics are also the names of global variables, except that the names of the global variables are preceded by @@.

Variables are defined entities that are assigned values. Global variables are predefined and maintained by the system. Global variables are distinguished from local variables by having two "at" symbols (@@) preceding their names.

The unit of time reported by a global variable is a timetick. Each timetick on the operating system is 31.25 milliseconds (1/32 second).

Not all global variables are reported on by sp_monitor. Many of these global variables report on system activity, and their reports refer to activity since the last time SQL Server was started. You can use the SELECT statement to query the global variables directly.

These are the server global variables provided with SQL Server:

@@CONNECTIONS
Specifies the number of logins or attempted logins since SQL Server was last started.
@@CPU_BUSY
Specifies the amount of time, in ticks, that the CPU has spent doing SQL Server work since the last time SQL Server was started.
@@DATEFIRST
Returns the current value of the SET DATEFIRST parameter. Indicates the first day of each week: 1 for Monday, 2 for Tuesday, and so on through 7 for Sunday.
@@DBTS
Specifies the value of the current timestamp datatype for the database. This timestamp is guaranteed to be unique for the database.
@@IDLE
Specifies the amount of time, in ticks, that SQL Server has been idle since it was last started.
@@IO_BUSY
Specifies the amount of time, in ticks, that SQL Server has spent doing input and output operations since it was last started.
@@MAX_CONNECTIONS
Specifies the maximum number of simultaneous connections that can be made with SQL Server in the current computer environment. The user can configure SQL Server for fewer connections with sp_configure. @@MAX_CONNECTIONS is not necessarily the number configured currently.
@@MAX_PRECISION
Returns the level of precision used by decimal and numeric datatypes as currently set in the server. By default, the maximum precision is 28; however, a larger precision can be set when SQL Server starts by using the /p parameter with sqlservr.
@@MICROSOFTVERSION
A version used internally to track the current version of the server. If version checking is necessary, see @@VERSION.
@@PACK_RECEIVED
Specifies the number of input packets read by SQL Server since it was last started.
@@PACK_SENT
Specifies the number of output packets written by SQL Server since it was last started.
@@PACKET_ERRORS
Specifies the number of errors that have occurred while SQL Server was sending and receiving packets since the last time SQL Server was started.
@@SERVERNAME
Specifies the name of the local SQL Server. You must define this name with the sp_addserver system stored procedure and then restart SQL Server. The setup program sets this variable to the computer name during installation. Although @@SERVERNAME can be changed with sp_addserver, this method is not recommended.
@@SERVICENAME
Specifies the name of a running service. Currently, @@SERVICENAME defaults to the @@SERVERNAME.
@@TIMETICKS
Specifies the number of microseconds per tick. The amount of time per tick is computer-dependent. Each tick on the operating system is 31.25 milliseconds (1/32 second).
@@TOTAL_ERRORS
Specifies the number of errors that have occurred while SQL Server was reading or writing since the last time SQL Server was started.
@@TOTAL_READ
Specifies the number of disk reads by SQL Server since it was last started (this includes disk reads only, not cache reads).
@@TOTAL_WRITE
Specifies the number of disk writes by SQL Server since it was last started.
@@VERSION
Specifies the date, version number, and processor type for the current version of SQL Server.

Any user (not just the SA) can use the SELECT command to query a global variable directly.

To query a global variable
  • Type:

    SELECT global_variable

    where

    global_variable
    Is the global variable name.

For example:

select @@cpu_busy

------------------
4250

For more information about global variables and about using sp_monitor, see the Microsoft SQL Server Transact-SQL Reference.


Viewing the Logs

Microsoft SQL Server can log events to the SQL Server error log and/or the Windows NT application log. Both logs record similar information; however, the SQL Server error log contains only SQL Server messages, and the Windows NT event log contains messages for all activities on the computer. Both logs automatically time-stamp all events recorded.

By default, setup installs the server to use both logs, but by using SQL Enterprise Manager or SQL Setup, you can control whether SQL Server uses one or both of the logs. For information about setting up logging, see Chapter 3, Configuring Servers.

For information about viewing the logs, choose one of the following topics:

Viewing the Error Log

Viewing the Application Log


Viewing the Error Log

The SQL Server error log can be viewed by using SQL Enterprise Manager.

To view the SQL Server error log
  1. In the Server Manager window, select a server.
  2. From the Server menu, choose Error Log.

    The SQL Server error log appears.

You can also view the SQL Server error log using any text editor. By default, the error log is \SQL60\LOG\ERRORLOG.

When SQL Server is configured to use its error log, each SQL Server session creates a new log, and SQL Server retains the last six logs created. The current log has no filename extension. SQL Server maintains the last 6 error logs created. The old logs are distinguished by their filename extension (.1, .2, .3, etc.), with the lowest number designating the newest file.


Viewing the Application Log

When SQL Server is configured to use the Windows NT application log, each SQL Server session writes new events to that log. The Windows NT application log is a special file that can be viewed and managed only by using Windows NT Event Viewer. Unlike the SQL Server error log, a new application log is not created each time you start SQL Server.

To view the Windows NT application log
  1. From the Administrative Tools program group, start the Event Viewer application.

    The Event Viewer window appears.

    SQL Server events are identified by the entry MSSQLServer in the Source column. SQL Executive events are identified by the entry SQLEXECUTIVE.

  2. To view the log of a remote computer, from the Log menu, choose Select Computer, and then complete the dialog box that appears.

    If you will be viewing the log of the local computer, skip this step.

  3. If the Application log is not displayed, from the Log menu, choose Application.

    There are three Windows NT logs¾Application, System, and Security¾that can be displayed by Event Viewer. The name of the displayed log is shown on the title bar of the dialog box. SQL Server and SQL Executive events are written to the Application log.

  4. Optionally, to display only SQL Server events, choose Filter Events from the View menu, select MSSQLServer from the Source box, and then choose the OK button.

    To view only SQL Executive events, select SQLEXECUTIVE instead.

  5. To view more information about an event, double-click the event.

    The Event Detail dialog box appears.

For additional information about using Event Viewer, managing the application log, and understanding the information it presents, see the online Help for Event Viewer, or see your documentation for Windows NT.


Part 8 Troubleshooting

Troubleshooting

The chapters in Part 8 list error messages, describe error conditions, and suggest troubleshooting procedures and techniques.

Chapter 20, Troubleshooting Overview, provides an introduction to SQL Server troubleshooting.

Chapter 21, Configuration Issues, explains how SQL Server manages resources (such as memory).

Chapter 22, Transaction Log Management, assists in the long-term management of Microsoft SQL Server transaction log.

Chapter 23, Understanding Showplan Output, defines and explains each of the output messages from SHOWPLAN and gives example queries and output.

Chapter 24, Additional Problem-Solving Techniques, provides information about additional problem-solving techniques, such as using trace flags, stopping processes, associating a page with an object, and creating useful stored procedures.

Chapter 25, Handling Common Error Messages, contains explanations and corrective actions for the most frequently occurring SQL Server error messages.

Chapter 26, System Messages, provides information about system messages (each system error or warning that can be returned by SQL Server).

Chapter 27, DB-Library Error Messages, describes DB-Library error messages and severity levels.

Chapter 28, ODBC Messages, describes ODBC error messages.


Chapter 20 Troubleshooting Overview

Troubleshooting Overview

This chapter provides background information about how to troubleshoot and resolve the most common errors that you may encounter when using Microsoft SQL Server. If you encounter a problem while running SQL Server, first check the error log for entries that might help identify the cause.

How you start SQL Server determines where SQL Server events are logged:

  • If you start SQL Server as a service under Windows NT, events are logged to the SQL Server error log, the Windows NT event log, or both.
  • If you start SQL Server from the command line, events are logged to the SQL Server error log and to standard output (typically the monitor, unless output has been redirected elsewhere).

The SQL Server error log contains only SQL Server messages; the Windows NT event log contains messages for all activities on the computer. Both logs include informational messages (such as startup data), and both automatically record the date and time of all events.

The default is to use both the Windows NT event logging service and the SQL Server error log. However, you can set certain installation options to log SQL Server events to only one log.

Note References to the error log refer to the specific error log that you are using.


Error Log

SQL Server Error Log

The current SQL Server error log is a text file. You can view it by using any text editor. The default location of the error log is determined by an entry in the Windows NT Registry from information supplied during setup. The default location is C:\SQL60\LOG\ERRORLOG.

A new error log is created each time SQL Server is started. Typically, SQL Server retains backups of the previous six error logs, giving the most recent log backup the extension .1, the second-most recent the extension .2, and the oldest the extension .6.


Windows NT Event Log

The Windows NT event log is a special file that can be viewed only by using the Windows NT Event Viewer. If you are part of the Windows NT Administrators group, you can also view remote event logs. The event log contains SQL Server error messages as well as messages for all activities on the computer.

When you use the Windows NT event log, each SQL Server session writes new events to an existing event log; you can filter the log for specific events. Unlike the SQL Server error log, a new event log is not created each time you start SQL Server; however, you can specify how long logged events will be retained. For information about viewing the Windows NT event log, see your documentation for Windows NT.


Error Messages

When SQL Server encounters a problem, it writes a message from the sysmessages system table to the error log or sends it to the client, depending on the severity level.

Each message contains:

  • A message number that uniquely identifies the error message
  • A severity level
  • An error state number that identifies the source from which the error was issued (if the error can be issued from more than one place)
  • A message that states what the problem is and possibly how to fix it

For example, if you try to access a table that doesn't exist:

select * from bogus

The error message sent to the client looks something like this:

Msg 208, Level 16, State 1
Invalid object name 'bogus'.

You can see a list of SQL Server error messages by selecting data from the sysmessages table in the master database. For a complete list of the messages in sysmessages, see Chapter 26, "System Messages."


RAISERROR

The RAISERROR statement provides centralized error message management. User-defined error messages can be added to the sysmessages table by using the sp_addmessage system stored procedure. RAISERROR returns a user-defined error message and sets a system flag to record that an error has occurred (it is no longer necessary to hard code user-defined error messages). RAISERROR can retrieve an entry from sysmessages, or it can use a hard-coded message. The message can include C PRINTF-style format strings, which are filled with arguments specified by RAISERROR at run time. Once defined, the message is sent back to the client as a server error message.

User-defined error message should be given numbers greater than 50000 and severity levels of 0 through 18. Only system administrators can issue RAISERROR with severity level of 19 through 25.

For details on RAISERROR and sp_addmessage, see the Microsoft SQL Server Transact-SQL Reference.


Error Message Numbers and Descriptions

A message number uniquely identifies each error message; the error message text describes the problem. The error message text often includes placeholders for information (such as object names) to be inserted in the error message when it is displayed.

In the description column of the sysmessages table, a percent sign (%) followed by a character serves as a placeholder; the specific data is supplied when the error message is generated. The notation %d is a placeholder for a number; %s (or %.*s) is a placeholder for a string. For example, the actual error message displayed for error 105 might be:

Unclosed quote before the character string 'Smith'.

When you report an error to your primary support provider, it is important to include error numbers, error states, object types, and object names. For additional information about reporting errors, see "Reporting Errors," later in this chapter.


Severity Levels

The severity level provides an indication of the type of problem SQL Server has encountered.

Severity levels 0 and 10 are informational messages and indicate problems caused by mistakes in the information you have entered. Both severity level 0 and 10 messages are sent as severity 0 (for backward compatibility).

Severity levels 11 through 16 are generated by the user, and these errors can be corrected by the user.

Severity levels 17 and higher indicate software or hardware errors. When a level 17, 18, or 19 error occurs, you can continue the work you're doing, although you might not be able to execute a particular statement.

Severity levels 20 and higher indicate system problems. These are fatal errors, which means that the process (the program code that accomplishes the task specified in your statement) is no longer running. The process freezes before it stops, recording information about what occurred. The process then terminates. The client connection to SQL Server closes, and, depending on the problem, the client might not be able to reconnect. Some problems with a severity level of 19 or higher affect only one user and one process. Others affect all the processes in the database. These problems don't necessarily damage a database or its objects, but they can. Still other problems are caused by hardware malfunctions.

Users should inform the system administrator (SA) whenever problems that generate errors with severity levels 17 and higher occur. The SA must resolve these errors and track their frequency. The SA should monitor all problems that generate severity levels 18 through 24 and print the error log, which contains information to help backtrack from the error.

If the problem affects an entire database, you can use the DBCC (database consistency checker) statement to determine the extent of the damage. DBCC might identify some objects that must be removed, and if the damage is extensive, the database might have to be reloaded. For more information about DBCC and about loading a database, see Chapter 12, "Backing Up and Restoring," and the Microsoft SQL Server Transact-SQL Reference.

The following sections briefly describe each severity level. For specific instructions for correcting errors, see Chapters 21 through 25.


Severity Levels 0 through 18

Error messages with severity levels 0 and 10 are informational. Error messages with severity levels 11 through 16 are generated by user errors and can be corrected by the user. Severity levels 17 and 18 are generated by resource or system errors; the user's session is not interrupted.

Using sp_addmessage, user-defined messages with severities 1 through 25 can be added to sysmessages. Only the SA can add messages with severities 19 through 25.

Error messages with severity levels 17 and higher should be reported to the SA.

Severity Level 0 and 10: Status Information (Reported as Level 0)
These messages are not errors; they provide additional information after certain statements have executed.
Severity Levels 11 through 16
These messages indicate errors that can be corrected by the user.
Severity Level 17: Insufficient Resources
These messages indicate that the statement has caused SQL Server to run out of resources (such as locks or disk space for the database) or to exceed some limit set by the SA.

These system limits include the number of databases that can be open at the same time and the number of connections allowed to SQL Server. Limits are stored in the sysconfigures table in the master database and can be changed with the sp_configure system stored procedure. (For details about using sp_configure, see the Microsoft SQL Server Transact-SQL Reference)

Level 17 messages that indicate you have run out of space can usually be corrected by the database owner. Other level 17 messages are best addressed by the SA.

Severity Level 18: Nonfatal Internal Error Detected
These messages indicate that there is some type of internal software problem, but the statement finishes, and the connection to SQL Server is maintained. For example, a level 18 message occurs when SQL Server detects that a decision about the access path for a particular query has been made without a valid reason.

The SA should be informed every time a level 18 message occurs.


Severity Levels 19 through 25

Problems that generate error messages with severity levels 19 and higher are considered fatal errors. The program code that was running to accomplish the current task is no longer running. Fatal errors of severity level 20 terminate the client connection to SQL Server. To continue working, you must reconnect to SQL Server.

The SA should be informed every time an error with severity level 19 or higher occurs.

Severity Level 19: SQL Server Error in Resource
These messages indicate that some nonconfigurable internal limit has been exceeded. Level 19 errors rarely occur and they must be corrected by the SA or by your primary support provider.

The SA should be informed every time a level 19 message occurs.

Severity Level 20: SQL Server Fatal Error in Current Process
These messages indicate that a statement has encountered a problem. Because the problem has affected only the current process, it is unlikely that the database itself has been damaged.
Severity Level 21: SQL Server Fatal Error in Database (dbid) Processes
These messages indicate that you have encountered a problem that affects all processes in the current database. It is unlikely, however, that the database itself has been damaged.
Severity Level 22: SQL Server Fatal Error Table Integrity Suspect
These messages indicate that the table or index specified in the message has been damaged by a software or hardware problem.

Level 22 errors are rare. If you should encounter one, run the DBCC diagnostics as described in the Microsoft SQL Server Transact-SQL Reference to determine if other objects in the database are also damaged. It is possible that the problem is in the cache only and not on the disk itself. If so, restarting SQL Server will fix the problem. To continue working, you must reconnect to SQL Server.

If restarting does not help, the problem is on the disk. Sometimes it can be solved by destroying the object specified in the error message. For example, if the message tells you that SQL Server has found a row with a length of 0 in a nonclustered index, delete the index and rebuild it.

Severity Level 23: SQL Server Fatal Error: Database Integrity Suspect
These messages indicate that the integrity of the entire database is suspect due to damage caused by a hardware or software problem.

Level 23 errors are rare. If you should encounter one, run the DBCC diagnostics as described in the Microsoft SQL Server Transact-SQL Reference to determine the extent of the damage. Even when the whole database is suspect, it is possible that the damage is confined to the cache and that the disk itself is fine. If so, restarting SQL Server will fix the problem.

Severity Level 24: Hardware Error
These messages indicate some type of media failure. The SA might have to reload the database. It might also be necessary to call your hardware vendor.
Severity Level 25: Internal System Error
These messages indicate some type of system error, such as a page chain corruption.


Reporting Errors

If you are unable to resolve a problem using the procedures described in Chapters 21 through 25 and in the Microsoft SQL Server Transact-SQL Reference, call your primary support provider for assistance. When you report an error to your primary support provider, be sure to have the following information:

  • The environment in which the error occurred, including:
    • SQL Server version (as reported to the error log or returned by
      SELECT @@VERSION)
    • DB-Library API version (as reported by the Client Configuration Utility) or ODBC driver version (as reported by ODBC Driver Setup)
    • Front-end application version (for example, SQL Enterprise Manager or ISQL.EXE)
    • Operating-system version
    • Hardware platform
    • Production or development environment
  • The message number, the message state, and the complete error message text
  • Any variables (numbers, database object types, or database object names) included in the error message
  • The context in which the message was generated (what statement was running at the time)
  • The number of users who were logged in to SQL Server when the error occurred
  • The frequency with which the error occurs

It is also helpful to provide a hard copy of the entire error log, including all messages displayed from startup to immediately before or after the error occurred.


FAXing Error Log Fragments

Whenever your primary support provider asks you to FAX the error log, be sure to send all information beginning with the time of startup and ending with the error message in question.

The first message written to the error log provides the exact SQL Server version number.

Although most startup messages are exactly the same each time you start SQL Server, additional messages sometimes appear during startup that can provide clues for solving problems that occur during or after startup.


Reproducing Problems

In general, the time it takes for your primary support provider to resolve a problem is greatly reduced if you generate a reproducible test case demonstrating the error. These test cases can range from a single query that is not acting as expected to a relatively complex code fragment that encounters a problem. A quick resolution is more likely when the test case is simple. Nothing you can do will support a quick resolution more than providing a simple test case. If a problem cannot be reproduced, it is usually impossible to solve.

Whenever possible, create the test case using the pubs sample database. In many cases, creating a simple test case can save you from having to send large amounts of data to your primary support provider.


Examining the Error Log and DBCC Output

As part of troubleshooting, it is necessary to frequently examine the SQL Server error log and DBCC output to check for problems. This can be an error-prone or laborious process, especially if you must do this on several servers, each of which may have multiple databases.

Use DBCC with the WITH NO_INFOMSGS option to isolate error messages in the error log. Informational messages (severity levels 0 through 10) are excluded from the check.

To make this examination process easier, you can use the Windows NT findstr utility (FINDSTR.EXE). This powerful pattern-searching utility helps to automate troubleshooting. It is even possible to conditionally execute a batch file based on whether certain error strings are found.

The findstr utility uses Win32 asynchronous and file-mapped I/O for best throughput. It allows the use of regular expressions, recursive searching through a directory tree, and the ability to exclude patterns (achieving a NOT function). For details, see your documentation for Windows NT.

There are two basic approaches to searching the SQL Server error log or DBCC output for errors:

  1. State explicitly what strings to find.
  2. State what strings you do not want to find (the search will find all but those strings).

In the first approach, you build a list of strings that define errors you want findstr to match. This list of strings can be supplied as an input file to findstr.

For example, to find all occurrences of the strings "table corrupt" (which accompanies many serious data errors) and "msg 605" (which is a specific type of error), place these strings into a search.txt file. The content looks like this:

table corrupt
msg 605

Run findstr on the DBCC output files using this syntax:

findstr /i /g:search.txt dbcc.* > findstr.out

where

search.txt
Is the file containing the search strings.
dbcc.*
Matches a group of DBCC output files to search.
findstr.out
Is the file where the search results are placed.

The challenge with this approach is knowing ahead of time which error strings to search for. Unfortunately, there is no comprehensive list of SQL Server error strings that encompasses all possible errors. However, searching for the following strings may provide fairly good coverage as a starting point: "table corrupt," "level 16" ... "level 21," "Severity: 16" ... "Severity: 21." It is usually possible to refine the search, resulting in reliable checking (certainly more reliable than doing a visual search).

In the second approach. you build a list of strings that you do not want to find (in other words, exclude these strings from the search).

This sample exclusion list for error logs will filter out nonessential messages and trap the most significant errors:

Copyright
All rights reserved
Logging SQL Server
initconfig: number
SQL Server is start
initializing virtual
Opening Master Data
Loading SQL Server
Recovering Database
Recovery dbid
transactions roll
Activating disk
initializing virtual
server name is
Clearing
rolled forward
default sort
nocase
default character
recovery complete
terminating due
windows nt
(id =
killed by hostname
17824
17825
1608
17832
OS error : 109
OS error : 232
unable to write to
restrictions
contracts
server is unnamed
no_log
working thread
network error
united states
unable to read login
duplication
subdivision
clause
number of buffers
using asynchronous disk
pipe name is
number of proc buffers
network information
file descriptors
transactions before ckpt
shutdown by request

For example, to run findstr on the error log and have the above text saved as SEARCH.TXT, use:

run findstr /v /i /g:search.txt errorlog *.* > f.out

In some cases, combining the inclusion and exclusion approaches works well, combining the best characteristics of each.

For example, when searching error logs for the strings "Severity: 16" ... "Severity: 21," which should match most serious errors, you notice in the search output several communication-related errors that normally do not indicate a serious problem. To refine the search, keep the original search conditions and exclude only these specific unwanted errors from the search output by piping one findstr command into another:

findstr /i /g:search.txt errorlog*.* | findstr /v /i /g:exclude.txt > f.out

where

search.txt
Is the file containing the search strings.
errorlog*.*
Specifies which SQL Server error log files to search.
exclude.txt
Is the file containing the search strings to exclude.
f.out
Is the file where the search results are placed.

This approach can be cascaded several levels deep, excluding successively more at each level.


Using Alerts with Errors

You can use alerts to take action when an error occurs. By creating alerts, you can set up SQL Enterprise Manager to respond automatically to SQL Server events, either by executing a task that you have defined or by sending an e-mail message and/or a pager message to an operator you have specified. For example, you can use an alert to send a pager message to an operator any time a particular error occurs.


Isolating Connection Problems

When a DB-Library application has problems connecting to SQL Server, there might be a problem with SQL Server, with the network, or with both. Regardless of which network you are running on, there are several items that you can check to help isolate the problem. Check that:

  • The local connection to SQL Server over named pipes is available. You can test a local named pipes connection by using isql with no servername argument. If you cannot make a local connection using named pipes, either you are using an invalid login or there is a problem with SQL Server.
  • The network components match the requirements specified in Microsoft SQL Server Startup.
  • The default client Net-Library is appropriate for your network. You can determine and, if necessary, change the default client Net-Library by running the Client Configuration Utility (for all clients except MS-DOS-based clients). For MS-DOS-based clients, you change the default client Net-Library by loading a different terminate-and-stay-resident (TSR) program in place of DBNMPIPE.EXE, as described in the instructions included in your Net-Library package.
  • The network connection information on the server is appropriate for your network (if you are running SQL Server and listening on other interprocess communication [IPC] mechanisms in addition to named pipes). You can determine and, if necessary, change which networks SQL Server is listening on by using the setup program.
  • The network connection between the client workstation and the server computer is established. (The procedures for testing network connections for all supported networks are provided in the following sections.) If you test the network connection and determine that it is not open, check that:
    • The hardware connection is not disabled on account of loose connectors or plugs.
    • The network software is installed and running on both computers.


Named Pipes Client Connections

The following procedure describes how to test a network connection when using named pipes as the IPC mechanism.

To check a named pipes connection
  • At the operating-system prompt on the client workstation, type:

    net view \\servername

    where

    servername
    Is the name of the server you want to connect to.

For example, to check the connection between a named pipes client and a server named \\GIZMO, type the following on the client:

net view \\GIZMO

If the connection is open, the output looks something like this:

Shared resources at \\GIZMO
SQL Server

Sharename      Type            Used as  Comment
----------------------------------------------------
PUBLIC         Disk                     Public Files

The command completed successfully.
To verify that you can connect to a server's named pipe
  • From a command prompt, type:

    netuse \\servername\IPC$

where

servername
Is the server you want to connect to.

For example:

net use \\GIZMO\IPC$
The command completed successfully

If the connection between the client workstation and the server computer is open but you still cannot connect to SQL Server, try testing the network and local named pipes using the makepipe and readpipe utilities, as described in the following sections.


Testing Network Named Pipes

Two utilities included with SQL Server are designed to help test network named pipes. The makepipe and readpipe utilities are installed during installation of both the client and server components. There are different versions of these utilities for the different operating systems they run on ¾ makepipe runs on Windows NT; readpipe runs on Windows NT, Windows, and MS-DOS. Be sure to use the correct version for the operating system that you are testing. (The version that runs on Windows is named readpipw. If the SQL Server tools have been installed, readpipw is located in the \SQL60\BIN directory. No icon is created for it.)

To test the integrity of the network named pipe services
  1. At the operating-system prompt on the server computer, type:

    makepipe

    The makepipe utility returns the following information:

    Making PIPE:\pipe\abc
read to write delay (seconds):0
Waiting for Client to Connect...

    SQL Server is waiting for a client to connect.

  2. At the operating-system prompt on the client workstation, type:

    readpipe /S servername /D string

    where

    server name
    Is the network server name of the SQL Server on which makepipe was started.
    string
    Is a test character string. If the string contains spaces, it must be enclosed in quotation marks. Note that there are no spaces between /S and the server name, and no spaces between /D and the string.

    For example, to connect to a SQL Server named MYSERVER, type either of the following:

    readpipe /Smyserver /Dhello
readpipe /Smyserver /D'hello there'

    If a network named pipe connection can be established, the workstation returns the following information:

    SvrName:\\myserver
PIPE   :\\myserver\pipe\abc
DATA   :hello
Data Sent: 1 : hello
Data Read: 1 : hello

    If a network named pipe connection can be established, the makepipe utility returns information similar to this:

    Waiting for client to send... 1
Data Read:      hello
Waiting for client to send... 2
Pipe closed
Waiting for Client to Connect...

    At this point, SQL Server is waiting for another client to connect. The readpipe utility can be run from other workstations.

  3. When testing is complete, go to the computer where the makepipe utility is running, and press CTRL+BREAK or CTRL+C.

If the results are different from those shown in step 2, network named pipe services are not available. If you are using named pipes as the IPC mechanism, clients cannot connect to SQL Server until named pipes are available. These utilities merely attempt to open and use a named pipe. They do not stress the named pipe connection.


TCP/IP Sockets Client Connections (Windows NT Only)

TCP/IP Sockets Client Connections

The following procedure describes how to test a network connection when using TCP/IP sockets as the IPC mechanism.

To check a TCP/IP sockets connection
  • At the operating-system prompt on the client workstation, type:

    ping ip_address

    where

    ip_address
    Is the TCP/IP address of the server you want to connect to.

For example, to check the connection between a TCP/IP sockets client and a server computer at the TCP/IP address 11.1.4.70, type the following on the client:

ping 11.1.4.70

If the connection is open, the output looks something like this:

[1] echo received from 11.1.4.70 with roundtrip < 50 sec


Novell IPX/SPX Client Connections

The following procedure describes how to test a network connection when using the native Novell Internet Package Exchange/Sequenced Package Exchange (IPX/SPX) protocol.

To check an IPX/SPX connection
  1. Check the connection between the client and the network.

    The client must be connected to the network. If it is connected, you will get the message "Attached to server servername" after NETX.COM is loaded (for MS-DOS- and Windows-based clients). For Windows NT - based clients, check the Event Viewer to ensure that the NWLink network support software was properly loaded.

  2. Check the connection between the server and the network.

    The server must be connected to the network. Under Windows NT, check the Event Log for a message containing "ODS: server-side."

  3. Check the local connection to SQL Server using the service name.

    You should be able to make a local connection to SQL Server with Novell NetWare as the default Net-Library. If you can connect locally using named pipes but cannot connect locally using the Novell NetWare Net-Library, SQL Server is not registered properly on the network.

  4. Check the network connection between the client and the server.

    If you can connect locally (as described in step 3) but cannot connect from a client across the network, check that:

    • The server is accessible to the client. You can test this by typing the following from the client:
      isql /L

      This option makes a call to dbserverenum, which returns the list of available servers from the Bindery. In the list of "Announced network servers," you should see the name of the server you want to connect to. If the server name is not in this list, you will not be able to connect. If the other steps have been done but the server name is not listed, this usually indicates a network problem. Check the SQL Server event log to be sure that the SPX support loaded properly (you will see an error message if it did not). Next, try to eliminate any possible bridge or router problems by attempting to connect from clients on the same LAN segment as the server.

    • The client can connect to a file server on the local area network where the SQL Server is located.

    Failing either of these tests indicates a network routing or configuration problem.

If you are having trouble with connections being dropped or client applications "hanging," this usually indicates a network error. Problems can occur when there are no free network buffers to service requests or when there are conflicts over shared network or memory resources.

If you are running into stability problems running Windows-based client applications over Novell IPX/SPX, the first step is to verify that you have the latest NetWare drivers available for your hardware configuration. SQL Server client applications will run on most systems using "monolithic" NetWare drivers, as long as they meet the minimum version levels specified in Chapter 4, "Configuring Clients." On some hardware, however, the newer "ODI" NetWare drivers are required for reliable operations.

If problems persist with the latest NetWare drivers, you may need to change the setting for the NWShareHandles and/or the RestoreDrives parameters. The effects of these parameters depend on the interrupt load on your system, so your hardware configuration may require a setting different from the default. In Windows for Workgroups version 3.1, these settings can be made through the Network application in the Control Panel. Select the Networks button and then select Novell NetWare in the Other Networks in Use box. Choose the Settings button and try different combinations of the NWShare Handles and Restore Drives check boxes. Try changing just the NWShare Handles setting first. If you are running Windows 3.1, you will need to add or change the [NetWare] section in the SYSTEM.INI file with a text editor. The section should look like this:

[NetWare]
NWShareHandles=TRUE
RestoreDrives=FALSE

The default for both of these settings is FALSE.


Standard Mode

To run client applications in Windows version 3.1 Standard Mode, you need to load TBMI2.COM prior to starting Windows. For more information, see the NETWORKS.WRI file in Windows 3.1 for more information. Microsoft testing has found this configuration to be less reliable for SQL Server client applications than running Windows in Enhanced Mode.


Isolating SQL Server Startup Problems

Two common situations can cause SQL Server to fail to start:

  • Insufficient virtual memory space
  • Insufficient resource space


Insufficient Virtual Memory Space

If there is insufficient space for the virtual memory support file (PAGEFILE.SYS) to expand during SQL Server startup, SQL Server will fail to start.

If SQL Server fails to start, you might receive a message stating specifically that this is the problem, or you might receive a message stating only that the SQL Server service could not start.

There are several ways to correct this problem:

  • Delete some files to free space on the disk.

Or

  • Change the size or location of the virtual memory support file, as described in the following procedure.
To change the size of PAGEFILE.SYS
  1. In the Windows NT Control Panel, start the System application.
  2. Choose the Virtual Memory button.
  3. From the Drive [Volume Label] list box, select the drive on which SQL Server is installed.
  4. In the Maximum Size box, enter a new maximum size, in megabytes, for PAGEFILE.SYS.
  5. Choose the OK button.

For additional information about setting the size of PAGEFILE.SYS, see your documentation for Windows NT.


Insufficient Resource Space

Another cause for SQL Server failing to start can be that a SQL Server configuration option is set too high for the amount of available resources. For example, if the SQL Server open databases option was significantly increased without a corresponding increase in the memory option, SQL Server might not start because it cannot allocate the specified number of database control blocks without exceeding the specified limit of total memory. Reset configuration options to their default values as described in Chapter 3, "Configuring Servers," and in the Microsoft SQL Server Transact-SQL Reference, or start SQL Server with minimal configuration by using the -f startup option as described in Microsoft SQL Server Setup.


Chapter 21 Configuration Issues

Configuration Issues

This chapter explains how SQL Server manages resources, such as memory. The information provided in this chapter should help you to make the best possible configuration choices for your environment.


How SQL Server Uses Memory

SQL Server uses configuration options to control various aspects of memory allocation and performance. When you install SQL Server, the setup program assigns 8 MB of memory to SQL Server if the computer has less than 32 MB of RAM, and 16 MB of memory if the computer has 32 MB or more of RAM. After installation, you can and often should manually configure memory to a greater amount. After installation you can manually configure memory to a greater amount by running sp_configure. Note, however, that as you increase the SQL Server memory configuration, you must be sure that there is sufficient disk space to grow the virtual memory support file (PAGEFILE.SYS) sufficiently to accommodate the additional memory. For additional information, see your manuals for Windows NT.

When SQL Server starts, it requests the amount of configured memory from the operating system. The operating system allocates as much as it can from physical memory and the rest as virtual memory. As memory availability on the system changes, the operating system replaces physical memory with virtual memory (and virtual memory with physical memory). The operating system allocates memory for the server executable code, the static memory used by the server, and the non-cache server data structures.

An additional 5 percent of the remaining memory is allocated for miscellaneous overhead. The other 95 percent is divided between the data and procedure caches based on the value of the procedure cache configuration option.

You can determine the current value of the memory configuration option (and other configuration options) by running sp_configure. If you run sp_configure without any parameters, the output includes the current settings for all configuration options.

You can determine the current settings for a specific configuration option by running sp_configure with the option name. For example, to find the current value of the memory option:

sp_configure 'memory'
name        minimum    maximum     config_value   run_value
----------  ---------  ----------  -------------  -----------
memory      1000       1048576     4096           4096

The output includes five columns:

  • The name column indicates the name of the configuration option.
  • The minimum and maximum columns indicate the SQL Server minimum and maximum values for the option.
  • The config_value column of the sp_configure output indicates the current setting of the option.
  • The run_value column indicates the actual amount of memory SQL Server is using.

For the memory option, the values in these columns indicate memory settings in terms of 2K pages.

You can also adjust the amount of memory available to SQL Server by running sp_configure as follows:

sp_configure 'memory', config_value

where

config.value
Is the new memory configuration @value.

Important When configuring memory using sp_configure, be careful not to set the memory option to an amount greater than the amount of available memory. If SQL Server cannot obtain the memory it needs, it cannot start. If this occurs, start SQL Server in minimum configuration using the -f option. For details, see Microsoft SQL Server Setup.

To view memory usage information and determine if more should be added or allocated to the procedure cache, use DBCC MEMUSAGE, as described in "Using DBCC MEMUSAGE," later in this chapter. Under Windows NT, you can also examine the Cache Hit Ratio by using the Windows NT Performance Monitor. For information about viewing SQL Server statistics using the Windows NT Performance Monitor, see Chapter 19, Monitoring Server Activity and Performance.


Estimating SQL Server Overhead

The following example shows how memory is allocated on a SQL Server with a memory configuration of 4096 pages (8 MB).

Note All calculations in the following example are approximations.

To estimate SQL Server overhead:

  1. Subtract an amount for static server overhead (including the size of the SQL Server executable code) from the total memory available to the SQL Server process.

    Static server overhead, which is typically around 2 MB, is unaffected by configurable options.

    Assuming a static server overhead of 2 MB, the remaining total memory in this example is 6 MB (8 MB - 2 MB).

  2. Subtract an amount for configurable options. The configurable options that use significant amounts of memory are:
    • User connections
    • Open databases
    • Open objects
    • Locks
    • Devices

    To calculate approximately how much memory is required by these configurable options, multiply the current sp_configure value for each option by the bytes per resource value for the option (as indicated by DBCC MEMUSAGE). Convert each calculated value from bytes to MB, and then add all the values to determine the total.

    For purposes of this example, assume the configurable overhead is 0.68 MB.

  3. Estimate the total cache space by subtracting the static overhead (step 1) and the configurable overhead (step 2) from the total memory. In this example, subtract 2.68 MB (2 MB .68 MB) from 8 MB for a total cache space of about 5.32 MB.
  4. Estimate the size of the procedure cache and the data cache. The proportion of the total cache that goes to the procedure cache depends on the run_value of the procedure cache option (as shown by sp_configure). The default value is 20, which indicates to use 20 percent of the total cache space as procedure cache and the remaining 80 percent as data cache.

    If the run_value of the procedure cache option is 20, the total cache space is divided as follows:

    Data Cache = 5.32 * 0.8 = 4.26 MB = 2182 Pages

    Procedure Cache = 5.32 * 0.2 = 1.06 MB = 545 Pages

    (Usually, the amount of procedure cache is slightly higher than the amount indicated in this calculation because the unused portion of the 5 percent miscellaneous overhead is added to the procedure cache.)

Important The amount of overhead is not dependent on the amount of memory available to SQL Server. If you add additional memory to SQL Server using the sp_configure memory option, the total cache space is increased by the amount of memory added. In the example above, if you increase the memory option from 4096 pages to 8192 pages, the total cache space increases by 4096 pages (8 MB) to 13.32 MB (8 MB 5.32 MB).


Using DBCC MEMUSAGE

The DBCC MEMUSAGE statement displays information about how SQL Server uses memory, and it provides a snapshot of both the data cache and the procedure cache. It is the only means of accurately determining the size of the SQL Server executable code.

The output from DBCC MEMUSAGE provides three types of information:

  • How the server's memory was allocated at startup.
  • How much memory is used by the 20 largest objects in the buffer cache (including "pinned" tables).
  • How much memory is used by the 12 largest objects in the procedure cache-stored procedures, triggers, views, rules, and defaults. If multiple copies of an object are in the procedure cache, DBCC MEMUSAGE sums the total memory used by them. Of the multiple copies, some are precompiled versions of the object (trees), and some are compiled versions (plans). DBCC MEMUSAGE shows the sizes of both the trees and plans, and it shows the total trees and plans used to evaluate the largest objects.

For more information, see the Microsoft SQL Server Transact-SQL Reference.


Increasing User Connections

Each configured user connection requires a certain amount of memory, whether or not the connection is used. The approximate overhead per user connection is 37K per user connection.

Whenever you configure additional user connections and restart SQL Server, the additional overhead reduces the data and procedure cache sizes for the server unless you also increase the memory option. Do not configure more user connections than necessary. If you increase user connections substantially, you might need to increase the memory option to give SQL Server additional memory for configuring the connections. For additional information, see "How SQL Server Uses Memory," earlier in this chapter.

The maximum number of SQL Server user connections is 32,767. Note, however, that this limit is theoretical. Because each configured user connection requires a certain amount of memory, the real limit is determined by the amount of physical memory on the computer, and the practical limit is determined by acceptable performance for your application and environment.

If the configured number of user connections are in use and a request is made for another, SQL Server returns an error.

You cannot use sp_configure to specify a configuration option higher than the current maximum value for that option.


Managing Stored Procedures

The following sections describe how stored procedures are processed by SQL Server and provide some of the background needed to manage stored procedures.

Note The information in the following sections is true for both stored procedures and triggers.


Resolution

When a stored procedure is created, the text of the procedure is stored in the syscomments table of the current database. In addition, a normalized form of the procedure, called a query tree, is stored in the sysprocedures table of the current database.

The process of building a query tree is called resolution. This process parses the SQL statements into a more efficient format and resolves all referenced objects into their internal representations. During the resolution process, table names, for example, are resolved into their object IDs, and column names are resolved into their column IDs.


Compilation

The query plan is the optimal data access path used to execute the procedure. SQL Server determines the optimal data access path and builds the query plan based on:

  • The SQL statements stored in the query tree
  • The statistics for each table and index referenced in the procedure
  • The values of any parameters passed to the procedure when first executed

Because query plans are held only in the procedure cache (and not on disk), they must be rebuilt each time SQL Server starts. The process of building a query plan is called compilation.

When a stored procedure is executed the first time, the query tree for the procedure is read from the sysprocedures table and loaded into the procedure cache. Then a query plan is created and loaded into the procedure cache. For more information about query plans, see Chapter 23, "Understanding SHOWPLAN Output."


Multiple Users and the Query Plan

Because stored procedures are reusable ¾ not reentrant ¾ only one user can execute a given copy of a query plan at any one time. If two or more users try to execute the same procedure at the same time, SQL Server creates an additional query plan based on the parameters used on the latter execution. When the user finishes executing the procedure, the query plan is then available in the cache for reuse, for anyone else with execution permission on the procedure.

If a second query plan for a stored procedure is generated, there is no guarantee that it will be the same as the first one. For example, if a user passes a different set of parameters when the second plan is created, the query plans can be different. A new query plan for a procedure can also be different from a previous query plan if a user has updated statistics or added an index to a referenced table any time after the previous query plan was generated.

Updating statistics or adding an index does not force recompilation, but the newly compiled query plan can be different because it might take into account the different (or additional) information. The additional copies of the query plan stay in the procedure cache until they are swapped out, and can cause one execution to run very differently from another (although the returned results will be the same).


Resolving Query Plan Differences

The system administrator or user cannot know or control which query plan is used for a given execution. This can explain unexpectedly different execution times for the same procedure given the same data and parameters. If this occurs, dropping and re-creating the procedure will cause all existing plans to be flushed from the cache.

To ensure that you always get your own plan, you can use either the EXECUTE statement with the WITH RECOMPILE option or the CREATE PROCEDURE statement with the WITH RECOMPILE option. Remember, however, that creating a procedure by using the WITH RECOMPILE option decreases performance because every execution requires compilation.


Recompilation

The process of creating a new query plan from the existing query tree is called recompilation. Recompilation takes place whenever one of the following events occurs:

  • The procedure is loaded from disk to the procedure cache; after you restart SQL Server, the first execution will always be a new compilation.
  • An index on a table referenced in the procedure is dropped.
  • All copies of the execution plan in cache are currently in use; a new procedure must be loaded from disk and compiled.
  • A procedure is created using the WITH RECOMPILE option.
  • A procedure is executed using the WITH RECOMPILE option.
  • A procedure is flagged by the SA for recompilation using the sp_recompile system stored procedure.

In addition, the CREATE INDEX statement causes automatic recompilation of stored procedures the next time they are executed. (Note that the UPDATE STATISTICS statement does not cause recompilation.) Dropping an index or table referenced by a query invalidates all existing cached copies of the query plan.


Re-resolution

The process of updating the existing query tree and invalidating any query plans in the cache is called re-resolution. Re-resolution occurs when one of the tables changes in such a way that the query tree stored in sysprocedures might be invalid (for example, if the datatypes, column offsets, object IDs, or other parts of the table have changed).

Re-resolution can be triggered by various activities, most of which are controlled by SQL Server, not the procedure owner or the SA. Procedure re-resolution occurs after any of the following:

  • Executing LOAD DATABASE on the database containing the procedure.
  • Executing LOAD DATABASE on a database containing a referenced table.
  • Dropping and re-creating a table referenced by the procedure.
  • Dropping and re-creating a database containing a table referenced by the procedure.
  • Binding or unbinding a rule to a table referenced by a query in the procedure.
  • Binding or unbinding a default to a table referenced by a query in the procedure.

During re-resolution, SQL Server rebuilds some parts of the query tree but does not deallocate others. This process slowly causes the query plan to grow, which eventually causes an error. Dropping and re-creating the procedure will resolve this.


Sizing the Procedure Cache

Although there is no formula for determining how much procedure cache is best for a particular environment, you can estimate how much is needed to optimize the procedure cache and therefore the performance of SQL Server. The following calculation is a good starting point for sizing the procedure cache:

Procedure Cache = (Maximum Concurrent Users) * (Size of Largest Plan) * 1.25

Note You can use DBCC MEMUSAGE to determine the size of a query plan for a particular procedure.

The following example illustrates another approach to sizing the procedure cache. Consider a SQL Server application environment consisting of 500 stored procedures. Of these, 100 main procedures are used frequently throughout the day, and the other 400 are executed only periodically. To avoid the run-time overhead of regenerating query plans and loading them into the cache, size the procedure cache so that it can hold at least one copy of each main procedure.

To determine the amount of memory needed to store the query plans of the main procedures, use DBCC MEMUSAGE. Then estimate the total size needed by examining a few representative procedures and determining an average plan size. Because each query plan uses at least one page in the procedure cache, the smallest plan is 2K. When you have determined an average plan size, you can estimate the minimum procedure cache by multiplying the average plan size by the number of main procedures.

The minimum procedure cache size is the smallest amount of memory that can allow at least one copy of each frequently used compiled object to reside in the cache. For this example, assume that the main procedures have an average plan size of 15 pages. To allow at least one copy of each of these procedures to reside in the cache, the minimum procedure cache is 1500 pages (1000 * 15 pages).

After you determine the minimum procedure cache size, add an additional amount to allow for concurrent usage, as well as for less frequently used procedures. Although this amount varies, an extra 10 percent is a reasonable starting point.

These are just two approaches to sizing the procedure cache. Depending on the requirements of your specific environment, you might be able to achieve sufficient performance by using a smaller procedure cache than indicated using these methods. If memory resources are limited, be sure to run several tests to determine that the procedure cache that you have calculated is best for your environment.


Running Out of Procedure Cache

Because the procedure cache is finite, you can occasionally expect to run out of space. Specific problems that you might encounter include:

  • Not enough free space in the procedure cache to load another query tree or plan for all users needing them at the same time. Procedure cache space can be freed only if a query tree or plan is not currently in use.

    When there is insufficient space to load another query tree or plan, error 701 occurs. For information about correcting this error, see the description of error 701 in Chapter 25, "Handling Common Error Messages."

  • The maximum number of procedures or other compiled objects is already in use. The number of objects allowed in the procedure cache is a function of the procedure cache size (and is recorded in the error log during startup).

    If the number of procedures or objects in use exceeds the maximum, error 701 occurs. For additional information about correcting this error, see the description of error 701 in Chapter 25, "Handling Common Error Messages."


Procedure Cache vs. Data Cache

When you change the memory configuration option, the amount of memory dedicated to the data and procedure caches changes as well. Similarly, when you change the value of the procedure cache option, memory is shifted between the two caches, so each cache has a different size than in the previous configuration.

There is not a one-step method to increase or decrease only the data cache or the procedure cache. This makes it harder to determine how much data cache and procedure cache is best for a particular SQL Server.

To more accurately measure the effects of your changes, it is best to change one cache size at a time. To change only one cache size at a time, use the memory and procedure cache options together, as described in the following example.

Consider a SQL Server configured with 4096 pages (8 MB) of memory, 50 user connections, a 28K stack size, and a total cache of 1084 pages (of which 876 pages is data cache and 208 pages is procedure cache). Now, assume that the main stored procedures need 440 pages of procedure cache to store one copy of each in the cache at one time.

To accommodate the main procedures without significantly changing the size of the data cache, you must increase both the memory and the procedure cache options. The new memory option setting is simply the old setting plus the number of additional pages needed:

Memory = 4096 440 - 208 = 4328 Pages

Because adding memory does not increase the amount of overhead, the total cache space increases to 1316 pages (1084 440 - 208). The new procedure cache option setting is as follows:

Procedure Cache = (Total Cache Space) * (Procedure Cache %)

Because the procedure cache percentage is equal to the desired procedure cache divided by the total cache space, the procedure cache percentage in this example is 30 percent (400 / 1316). These same calculations can be used to increase the data cache and leave the procedure cache constant.

When evaluating performance associated with different cache sizes under Windows NT, you can use the Windows NT Performance Monitor. Of particular interest are the Cache Hit Ratio and Physical I/O statistics. Optimally, you want to maximize Cache Hit Ratio and minimize Physical I/O.


Chapter 22 Transaction Log Management

Transaction Log Management

This chapter will assist you in the long-term management of Microsoft SQL Server transaction logs. It includes information about:

  • Separating data and log segments
  • Sizing and truncating the transaction log
  • Managing large transactions
  • Using the bulk copy utility
  • Automating transaction log dumps
  • Detecting long-running transactions

For more information about transaction log management, see Part 3, "Devices, Databases, and Drives."


About Transaction Logs

Most SQL Server processing is logged in the syslogs transaction log table. Each database (including the master, model, and tempdb system databases) has its own syslogs transaction log table. As the database is modified, the transaction log grows until it is truncated, either by a DUMP TRANSACTION statement or automatically (if the trunc. log on chkpt. option is set).

Caution Do not try to access the syslogs transaction log table. It is for internal use by SQL Server only.

The transaction log records data modification requests (UPDATE, INSERT, or DELETE statements) before they are executed. When a transaction begins, a begin transaction event is recorded in the log. This event is used during automatic recovery to determine the starting point of the transaction.

As each data modification statement is received, it is recorded in the log. The change is always recorded in the log before that change is made in the database itself. This type of log is called a write-ahead log.

At the end of the transaction, a commit transaction record is logged. This delineates the transaction and also allows automatic recovery to query this log record and find out if the transaction completed successfully.

Caution It is imperative that SQL Server know that a write has completed. A write-caching disk controller compromises the ability of SQL Server to manage transactions by making it appear as if the write-ahead logging has completed, even though it has not. This can result in errors such as error 605 and can also cause database corruption. For this reason, do not use a write-caching controller with SQL Server unless it can guarantee that a write will complete.

The transaction log is shared by all users of the database. Multiple changes are frequently recorded each time a log page is written to the database device. This greatly improves I/O efficiency.


Transaction Logs and COMMIT TRANSACTION

To ensure recoverability of the transaction, when you issue a COMMIT TRANSACTION, the transaction log pages are immediately written to disk. The modified pages in the data cache, however, might not be written to disk until the data cache buffer is needed by other users, or until a checkpoint is issued either explicitly through the CHECKPOINT statement or implicitly through the internal SQL Server checkpoint process. Pages modified in the data cache can be written to disk prior to the transaction being committed, but not until the corresponding log records have been written to disk. (This happens if buffers in the data cache containing dirty pages are needed to load a new page.)


Transaction Logs and the Checkpoint Process

If the trunc. log on chkpt. option is set for a database, when SQL Server issues a checkpoint in that database, the transaction log is truncated up to the page containing the oldest outstanding transaction. A transaction is considered outstanding if it has not been committed or rolled back. If replication is being used, a transaction is also considered outstanding if it has not yet been replicated.

Important Only implicit checkpoints performed automatically by SQL Server result in this truncation. A CHECKPOINT statement issued by a user does not cause truncation of the transaction log, even when the trunc. log on chkpt. option is set.

An automatic checkpoint process wakes up approximately every 60 seconds and cycles through every database to determine if a checkpoint is needed. This determination is based on the recovery interval configuration option and the number of rows added to the log since the last checkpoint. Only those rows associated with committed transactions are considered in the calculation.

If the trunc. log on chkpt. option is set, the checkpoint process attempts to truncate the log every 60 seconds, regardless of the recovery interval or the number of log records. If there are no committed transactions in the log, the log is not truncated.

The trunc. log on chkpt. option, which is set using the sp_dboption system procedure, is not recommended in production environments where transaction logs are needed for recovery from media failure because it does not save the information contained in the log.

The transaction log of the tempdb database is automatically truncated during every cycle of the checkpoint process, about every 60 seconds. This occurs whether or not the trunc. log on chkpt. option is set on tempdb.


Transaction Logs and the recovery interval Option

The recovery interval configuration option defines the maximum number of minutes that SQL Server needs per database to complete its recovery procedures in case of a system failure. If the activity in the database is such that recovery would take longer than the recovery interval, SQL Server issues a checkpoint. Because the checkpoint process examines a particular database only every 60 seconds, enough logged activity can occur during this interval that the actual recovery time required exceeds the time specified in the recovery interval option.


What Information Is Logged

To ensure that a transaction is recoverable, when a transaction is committed, SQL Server logs all information about the transaction in the transaction log. The amount of data logged for a single transaction depends on the number of indexes affected, the amount of data changed, and the number of pages that must be allocated or deallocated.

Depending on the transaction, certain other page management information might also be logged. For example, when a single row is updated, the following records might be written in the transaction log:

  • A data delete record, including all data in the original row
  • A data insert record, including all data in the modified row
  • One index delete record for each index affected by the change
  • One index insert record for each index affected by the change
  • One page allocation record for each new data or index page required
  • One page deallocation record for each data or index page freed

To ensure the recoverability of all transactions performed on SQL Server, transaction logging cannot be turned off. Any single Transact-SQL statement (or set of Transact-SQL statements within a BEGIN...COMMIT/ROLLBACK TRANSACTION block) that modifies data is considered a transaction and is therefore logged. You can, however, limit the amount of logging performed for specific operations, such as:

  • Bulk copying data into a database using bcp in fast mode
  • Performing a SELECT INTO query

Important These non-logged operations cause the transaction log to get out of sync with the data in a database, which makes the transaction log useless for database recovery.

After a non-logged operation has been performed, the transaction log can be truncated, but it cannot be dumped to a device. To allow the log to be dumped to a device, you must execute a DUMP DATABASE statement, which creates a new point of synchronization between the database and the transaction log.


Separating Data and Log Segments

In most cases, it is recommended that you store transaction logs on a separate database device and segment from the actual data. It is important to separate these segments because:

  • It enables you to save transaction log dumps.

    If the data and log are on the same segment, you cannot save transaction log dumps, so up-to-date recovery after a media failure is not possible. For details about backup and recovery, see Chapter 12, "Backing Up and Restoring."

  • It increases performance for logged operations.

    If you place the data and log segments on different physical devices, such as different disks and controllers, I/O requests for a database are divided between two devices.

  • It enables you to determine the amount of log space used.

    Use Performance Monitor to determined the amount of log space used. Performance Monitor provides a quick and convenient way to monitor log space.


Sizing the Transaction Log

There are no rules dictating how big a transaction log should be. For a new database, a log size of around 20 percent of the overall database size is a good starting point. The actual size required depends on how the database will be used. Factors that affect size requirements include:

  • The rate of UPDATE, INSERT, and DELETE transactions
  • The amount of data modified in each transaction
  • The value of the recovery interval configuration option
  • Whether the transaction log is being saved for media recovery purposes

Because there are many factors involved in transaction logging, you cannot accurately predetermine how much log space a particular database will require. The best way to estimate size requirements is to simulate the production environment as closely as possible (for example, by running applications with the same number of users as you expect to be using the database in the production environment).


Truncating the Transaction Log

To prevent the transaction log from filling up, it must be truncated periodically. You can do this either by enabling the trunc. log on chkpt. option or by regularly executing the DUMP TRANSACTION statement. Even if the trunc. log on chkpt. option is enabled, you might have to explicitly execute DUMP TRANSACTION statements during peak periods to prevent the log from filling up.

Because the trunc. log on chkpt. option causes the equivalent of the DUMP TRANSACTION WITH TRUNCATE_ONLY statement to be executed, it truncates the log without saving it to a device. Use this option only on databases for which transaction log dumps are not being saved (typically development systems or systems where only full database dumps, and not DUMP TRANSACTION, will be used).

If you are in a production environment and using DUMP TRANSACTION to truncate the log, time the statements close enough together so that no process ever receives the 1105 error (which indicates that the log is full). It is possible to automate this process. For details, see "Automating Transaction Log Dumps," later in this chapter.

When you execute a DUMP TRANSACTION statement, transactions completed prior to the earliest outstanding transaction or the earliest transaction marked for replication but not yet moved to the distribution database are truncated from the log, unless they are on the same log page as the last outstanding transaction. All transactions since the earliest outstanding transaction are considered active and are not truncated, even if they have completed.

The following diagram illustrates that all transactions after an outstanding transaction are considered active. Note that because pages are reallocated as necessary, page numbers do not necessarily increase over time.

Because the DUMP TRANSACTION statement truncates only the inactive portion of the log, you should be careful not to allow stranded (uncommitted) transactions to remain in the log for a long time.

For example, suppose a user issues a BEGIN TRANSACTION statement but never commits the transaction. Nothing logged after the BEGIN TRANSACTION can be purged out of the log until one of the following events occurs:

  • The user who began the transaction completes it
  • The user process that issued the BEGIN TRANSACTION statement is forcibly stopped and the transaction is rolled back
  • SQL Server is shut down and restarted

Stranded transactions are usually due to application problems.


Managing Large Transactions

Four common transaction types can result in extensive logging:

  • Mass updates
  • Table deletes
  • Inserts based on subqueries
  • Bulk copies into a database

The following sections explain how to use these transactions so they do not cause extensive logging. Because of the amount of data that SQL Server logs, it is important that you manage large transactions efficiently.


Mass Updates

The following SQL statement updates every row in the table large_tab:

update large_tab set col1 = 0

Each individual row update resulting from this statement is part of one transaction. If large_tab is a large table, this statement results in extensive logging, which can fill the transaction log before it completes, and results in the 1105 error (which indicates that the transaction log is full). If the transaction log is filled before the statement completes, the portion of the transaction that was processed is rolled back. This process can require significant time and server resources.

In addition to causing excessive logging, unnecessarily large transactions have disadvantages in terms of both the number and the type of locks held as a result. For example, an exclusive table lock is usually acquired for a mass update to reduce locking overhead and complete it as soon as possible, and this type of lock prevents all other users from modifying the table during the update.

You can sometimes avoid problems associated with mass updates by breaking up large transactions into several smaller ones and then executing DUMP TRANSACTION statements between the different parts. For example, the single update statement in the previous example could be broken into two or more pieces as follows:

update large_tab set col1 = 0
where col2 < x
go
dump transaction database_name with truncate_only
go

update large_tab set col1 = 0
where col2 >= x
go

dump transaction database_name with truncate only
go

In this example, x is a value selected so that about half the rows in the table meet the condition col2 < x and the remaining rows meet the condition col2 >= x.

Transaction logs saved for media failure recovery should be dumped to a device, and the WITH TRUNCATE_ONLY option of the DUMP TRANSACTION statement should not be used. After you execute a DUMP TRANSACTION WITH TRUNCATE_ONLY statement, you must dump the database before you can dump the transaction log to a device.


Table Deletions

The following example deletes the contents of large_tab within a single transaction and logs the complete before-image of every row in the transaction log:

delete large_tab

If this transaction fails before completing, SQL Server can roll back the transaction and leave the table as it was before the DELETE. Usually, however, you do not need to provide for the recovery of a DELETE operation, so the logging done by an unqualified DELETE statement might not always be needed. If the operation fails halfway through, you can simply repeat it and the results will be the same.

To accomplish the same results as the DELETE statement without the extensive logging, you can use the TRUNCATE TABLE statement instead. For example:

truncate table large_tab

This statement also deletes the contents of the table, but it logs only space deallocation operations, not the complete before-image of every row.


Inserts Based on Subqueries

The following example reads every row in large_tab and inserts the values of the columns col1 and col2 into new_tab, all within a single transaction:

insert new_tab select col1, col2 from large_tab

Each individual insert operation is logged and the records remain in the transaction log until the entire statement has completed. Any locks required for processing the inserts remain in place until the transaction is either committed or rolled back. Because the destination table is often a new table, the locking issue might not be as severe as in previous examples. Depending on the size of the table being read, however, the amount of logging could pose a problem.

Like the mass updates problem, you can often solve this problem by breaking up the statement into several statements that accomplish the same task. For example, the single INSERT statement in the previous example could be broken into two or more pieces, as follows:

insert new_tab
select col1, col2 from large_tab where col1 <= y
go

dump transaction database_name with truncate_only
go

insert new_tab
select col1, col2 from large_tab where col1 > y
go

dump transaction database_name with truncate_only
go

In this example, y represents a median value for col1, and null values are not allowed. This is just one example of several possible ways to break up a query. Although it is not required, the inserts run significantly faster if there is a clustered index on large_tab.col1.

If transaction logs are saved for media failure recovery, the log should be dumped to a device, and the WITH TRUNCATE_ONLY option should not be used. After you execute a DUMP TRANSACTION WITH TRUNCATE_ONLY statement, you must dump the database before you can dump the transaction log to a device.


Bulk Copies into a Database

You can also break up large transactions when using bcp to bulk copy data into a database. If you use bcp without specifying a batch size, the entire operation is performed as a single logical transaction.

Even if another user process does a DUMP TRANSACTION statement, the log records associated with the bulk copy operation remain in the log until the entire operation completes or another DUMP TRANSACTION statement is executed. This is one of the most common causes of the 1105 error. You can avoid the problem by splitting the bulk copy operation into batches.

To ensure recoverability, follow this procedure:

  1. Set the trunc. log on chkpt. option to true:
    use master
go
sp_dboption database_name, trunc, true
go

    Note The trunc option is an abbreviated form of the trunc. log on chkpt. option. The two options are interchangeable.

  2. Run bcp from the command line using the /b batchsize option, as shown in the following example:
    bcp database_name..table_name in /b 100 /U sa /P sa_password
/S server_name
  3. When the bcp operations are complete, turn off the trunc. log on chkpt. option and dump the database.

In this example, a batch size of 100 rows is specified. This results in one transaction for every 100 rows copied. In some cases, you might also need to break the bcp input file into two or more separate files and execute a DUMP TRANSACTION after copying each file (to prevent the transaction log from filling up).

If bcp is performed in the fast mode, the operation is not logged. In other words, only the space allocations are logged, not the complete table, so the transaction log cannot be dumped to a device. In this case, you must use the DUMP TRANSACTION WITH TRUNCATE_ONLY statement to free space in the log. Remember, however, that after you execute DUMP TRANSACTION WITH TRUNCATE_ONLY, you must dump the database before you can dump the transaction log to a device.

For additional information about using bcp, see the Microsoft SQL Server Transact-SQL Reference.


Automating Transaction Log Dumps

One transaction log management strategy is to have an application that automatically dumps the log. This is especially easy if the transaction log is not being saved for recovery from media failure.

If the log is being dumped to a device, additional logic is required to prevent the log from filling up or being dumped more often than necessary. One way is to examine the log periodically and dump it, depending on how full it is.

You can also schedule log dumps using SQL Enterprise Manager and Performance Monitor-triggered dumps. For details, see Part 5, "Data Management," and the SQL Enterprise Manager online Help.


Automatic Transaction Log Dumps Using Performance Monitor

SQL Server for Windows NT is integrated with the Windows NT Performance Monitor, so you can use the "% Full" counter of the SQLServer-Log object to dump or truncate the transaction log.

Here is how to set up the event:

  1. Set up a text file called DUMP.SQL. This file will contain the TRANSACT-SQL commands to dump or truncate the log.

    For example:

    dump tran pubs with truncate_only
go
  2. Start Performance Monitor, and add an alert that will run the script when the log is more than a specified percentage full.
  3. Make sure that SQL Server is running.
  4. Start Performance Monitor.
  5. From the View menu, choose Alert.
  6. Choose the button to add an alert event.
  7. Choose the object SQLServer-Log.
  8. Choose the counter Log Space Used(%).
  9. Choose the instance of the database to monitor (pubs in this example).
  10. Choose the Over button of the Alert If dialog box, and then enter the percentage at which you want the log to be truncated in the box to the right of this button. For example, entering "75" will issue the truncate command when the log becomes more than 75% full.
  11. Enter the isql command under Run Program on Alert. The command should launch the DUMP.SQL file. For example:
    isql -Sserver -Usa -Ppassword -ic:\sql60\dump.sql
  12. Click the Every Time button so that the log will be truncated every time the fullness exceeds the specified threshold.
  13. Choose OK.

You can save these settings using the Save Alert Settings dialog box that appears when you choose Save As from the File menu so that you do not have to re-create this alert every time you start Windows NT.

Note If you are using Integrated Security, Performance Monitor must be started under an administrator account or one that maps to the database owner.


Detecting Long-running Transactions

In some instances, a single long-running transaction can prevent the log from being truncated. These transactions are usually a result of application errors or badly formed queries. It is important to detect the presence of these transactions and act accordingly. Otherwise, the transaction log eventually fills up, even if DUMP TRANSACTION statements have been executed.

The easiest way to detect a long-running transaction is by using DBCC OPENTRAN, which displays information on the oldest active transaction and the oldest distributed and nondistributed replicated transactions, if any, within the specified database. Using the WITH TABLERESULTS option, you can insert the results into a table for easy comparison.

DBCC OPENTRAN is extremely useful in determining whether or not an open transaction exists within the log. When using the DUMP TRANSACTION statement, only the inactive portion of the log can be truncated, so an open transaction could cause the log not to be truncated completely. In earlier versions of SQL Server, all users needed to log off or the server needed to be shut down and restarted to clear the uncommitted transactions from the log. With DBCC OPENTRAN, an open transaction can be identified (the spid, system process ID taken from the sp_who system stored procedure output, is returned) and terminated, if necessary.

After this condition has been detected, your knowledge of any applications using the database can tell you whether or not it represents a problem. For example, suppose that the longest running transaction on a database takes an average of 2 minutes and that the log could not be purged over a 5-minute interval. The average of 2 minutes might have been exceeded because of computer load or SQL Server load, so there is a good chance that no problem exists.

A problem might exist if the log repeatedly fails to be purged over a long period of time, perhaps after several DUMP TRANSACTION statements. This problem can result from any of the following:

  • A badly formed query that might run for many hours (for example, a query with an incorrectly specified join that results in a Cartesian product)
  • An application error that starts a transaction but never completes it
  • An operating-system, network, or SQL Server error
  • A hardware problem

If the blocking transaction is due to a runaway query and the transaction has been identified, use the KILL statement to stop the process. This clears the transaction and allows the log to be truncated. For additional information about stopping processes, see Chapter 24, "Additional Problem-Solving Techniques."

If the KILL statement cannot stop the process, you must restart SQL Server to resolve the problem. Restarting SQL Server causes the database to go through normal recovery, so any outstanding transactions are either committed or rolled back.


Chapter 23 Understanding SHOWPLAN Output

Understanding SHOWPLAN Output

Microsoft SQL Server includes an intelligent cost-based query optimizer which, given an ad-hoc query, can quickly determine the best access method for retrieving the data, including the order in which to join tables and whether or not to use indexes that might be on those tables. Because SQL Server uses a cost-based query optimizer, you do not have to determine the most efficient way of structuring the query to get optimal performance ¾ instead, the optimizer looks at all possible join orders, and the cost of using each index, and picks the plan with the lowest estimated cost in terms of page I/Os.

Detailed information on the final access method that the optimizer chooses can be displayed by executing the SET SHOWPLAN ON statement, which shows each step that the optimizer uses in joining tables and which, if any, indexes it chooses to be the least-cost method of accessing the data. This can be beneficial when analyzing certain queries to determine if the indexes that have been defined on a table are actually being considered by the optimizer as useful in getting to the data.

This chapter defines and explains each of the output messages from SHOWPLAN and gives example queries and output. Wherever possible, the queries use the existing tables and indexes, unaltered, from the SQL Server pubs sample database.

Note ISQL/w and the Query window in SQL Enterprise Manager present graphical views of the SHOWPLAN output. The information provided in this chapter is for users who want to interpret the raw SHOWPLAN output.


STEP n

This statement is included in the SHOWPLAN output for every query, where n is an integer, beginning with STEP 1. For some queries, SQL Server cannot effectively retrieve the results in a single step; it must break the query plan into several steps. For example, if a query includes a GROUP BY clause, the query must be broken into at least two steps: one step to select the qualifying rows from the table and another step to group them.

The following query is a single-step query:

Query:

SELECT au_lname, au_fname
FROM Authors
WHERE city = 'Oakland'

SHOWPLAN:

STEP 1
The type of query is SELECT
FROM TABLE
authors
Nested iteration
Table Scan


The type of query is SELECT (into a worktable)

This statement indicates that SQL Server needs to insert some of the query results into an intermediate worktable, and later in the query processing will then select values from that table. This statement is most often seen with a query that involves a GROUP BY clause; the results are first put into a work table, and then the qualifying rows in the work table are grouped based on the given column in the GROUP BY clause.

The following query returns a list of all cities and indicates the number of authors who live in each city. The query plan is composed of two steps: the first step selects the rows into a worktable, and the second step retrieves the grouped rows from the worktable:

Query:

SELECT city, total_authors = count(*)
FROM Authors
GROUP BY city

SHOWPLAN:

STEP 1
The type of query is SELECT (into a worktable)
GROUP BY
Vector Aggregate
FROM TABLE
authors
Nested iteration
Table Scan
TO TABLE
Worktable 1

STEP 2
The type of query is SELECT
FROM TABLE
Worktable 1
Nested iteration
Table Scan


The type of query is query_type

This statement describes the type of query for each step. For most user queries, the value for query_type is SELECT, INSERT, UPDATE, or DELETE. If SHOWPLAN is turned on while other statements are issued, the query_type will reflect the statement issued.

The following examples show various outputs for different queries:

Query 1:

CREATE TABLE Mytab (col1 int)

SHOWPLAN 1:

STEP 1
The type of query is TABCREATE

Query 2:

INSERT Publishers
VALUES ('9904', 'NewPubs', 'Seattle', 'WA', 'USA')

SHOWPLAN 2:

STEP 1
The type of query is INSERT
The update mode is direct
TO TABLE
publishers


The update mode is deferred

There are two methods, or modes, that SQL Server can use to perform update operations such as INSERT, DELETE, UPDATE, and SELECT INTO. These methods are called deferred update and direct update. When the deferred method is used, the changes are applied to all rows of the table by making log records in the transaction log to reflect the old and new value of the column(s) being modified (in the case of UPDATE operations), or the values that will be inserted or deleted (in the case of INSERT and DELETE, respectively).

When all the log records have been constructed, the changes are then applied to the data pages. This method may generate more log records than a direct update (discussed later in this chapter), but it has the advantage of allowing the execution of statements that might cascade changes throughout a table.

For example, consider a table that has a fixed-length column col1 with a unique index on it and data values numbered consecutively from 1 through 100 in that column. Assume that an UPDATE statement is executed to increase the value in each row by 1:

Query 1:

UPDATE Mytable
SET col1 = col1  1

SHOWPLAN 1:

STEP 1
The type of query is UPDATE
The update mode is deferred
FROM TABLE
Mytable
Nested iteration
Table Scan
TO TABLE
Mytable

Consider the consequences of starting at the first row in the table and updating each row, through the end of the table. Updating the first row (which has an initial value of 1) to 2 would cause an error because the unique index would be violated (there is already a value of 2 in the table); similarly, updating the second row (which has an initial value of 2) to 3 would also cause a unique key violation, as would all rows through the end of the table, except for the last row. By using deferred updates, this problem is easily avoided. The log records are first constructed to show what the new values for each row will be, the existing rows are deleted, and then the new values inserted.

As with UPDATE statements, INSERT statements can also be deferred for similar reasons. Consider the following query (there is no clustered index or unique index on the Mytable2 table):

Query 2:

INSERT Mytable2 SELECT * FROM Mytable2

SHOWPLAN 2:

STEP 1
The type of query is INSERT
The update mode is deferred
FROM TABLE
Mytable2
Nested iteration
Table Scan
TO TABLE
Mytable2

Because there is no clustered index on the table, the new rows will be added to the end of the table. The query processor needs to be able to differentiate between the existing rows that are currently in the table (prior to the INSERT statement) and the rows that will be inserted, so as to not get into a continuous loop of selecting a row, inserting it at the end of the table, selecting the row just inserted, and re-inserting it.

By using the deferred method of inserting, the log records can first be constructed to show all the existing values in the table, and then SQL Server will re-read those log records to insert them into the table.


The update mode is direct

Whenever possible, SQL Server attempts to use the direct method of applying updates to tables because it is faster and requires fewer log records to be generated than the deferred method. Depending on the type of statement, certain criteria must be met in order for SQL Server to perform the update using the direct method. Those criteria are:

Rules for an Update-In-Place

In SQL Server 6.0, various techniques are used to determine whether or not an UPDATE can be performed "in-place." When an "update-in-place" occurs, the overall performance of the UPDATE statement is improved because the update is direct (only the row modifications to the page are logged). The decision as to whether or not an update-in-place can occur is based on the following requirements. If these requirements are not true, a deferred update will take place. A deferred update is a delete followed by an insert.

  • The UPDATE cannot affect the column(s) that participates in a clustered index.
  • The table cannot have an UPDATE trigger.
  • The table cannot be marked for replication.
  • For single-row updates:
    • The updated column(s) can be variable length, but the new total row size must fit on the same page as the old row.
    • The updated column(s) can participate in a nonunique nonclustered index only if the index key is a fixed-width column.
    • The updated column(s) can participate in a unique nonclustered index only if the index key is fixed-width and the WHERE clause criteria must have an exact match (based on an unique index match¾the index could be the same as the updated column).
    • The new row cannot include differing bytes by more than 50 percent of the original row size, and the total number of discontiguous differing bytes is not more than 24.
  • For multirow updates:
    • The updated column must be fixed length.
    • The updated column cannot participate in a unique nonclustered index.
    • The updated column can participate in a nonunique nonclustered index only if the column is a fixed-width column (the index used to find rows cannot be the same as the updated column).
    • The table cannot include a column with the timestamp datatype.

To see the update strategy used (DIRECT or DEFERRED), set the SHOWPLAN session setting. For details, see the SET statement.

Query 1:

UPDATE titles
SET price = $5.99
WHERE title_id = 'BU2075'

SHOWPLAN 1:

STEP 1
The type of query is UPDATE
The update mode is direct
FROM TABLE
titles
Nested iteration
Using Clustered Index
TO TABLE
titles

Query 2:

UPDATE titles
SET price = $5.99
WHERE title_id like 'BU%'

SHOWPLAN 2:

STEP 1
The type of query is UPDATE
The update mode is deferred
FROM TABLE
titles
Nested iteration
Using Clustered Index
TO TABLE
titles

Note that the only difference between Query 1 and Query 2 is qualification of the WHERE clause. In both queries, the column being updated allows nulls. In Query 1, no more than one row is guaranteed to qualify because of the unique clustered index on the title_id column. Therefore, the direct method can be used for the update. In Query 2, multiple rows may qualify for the update, and since the updated column allows nulls the deferred method must be used.


GROUP BY

This statement appears in the SHOWPLAN output for any query that contains a GROUP BY clause. Queries that contain a GROUP BY clause will always be at least two-step queries: one step to select the qualifying rows into a worktable and group them, and another step to return the rows from the worktable.

The following example illustrates this:

Query:

SELECT type, AVG(advance), SUM(ytd_sales)
FROM titles
GROUP BY type

SHOWPLAN:

STEP 1
The type of query is SELECT (into a worktable)
GROUP BY
Vector Aggregate
FROM TABLE
titles
Nested iteration
Table Scan
TO TABLE
Worktable 1

STEP 2
The type of query is SELECT
FROM TABLE
Worktable 1
Nested iteration
Table Scan


Scalar Aggregate

Transact-SQL includes the aggregate functions AVG(), COUNT(), COUNT(*), MAX(), MIN(), and SUM(). Whenever an aggregate function is used in a SELECT statement that does not include a GROUP BY clause, it produces a single value, regardless of whether it is operating on all the rows in a table or on a subset of the rows defined by a WHERE clause. When an aggregate function produces a single value, the function is called a scalar aggregate, and is listed as such by SHOWPLAN.

The following example shows the use of scalar aggregate functions:

Query:

SELECT AVG(advance), SUM(ytd_sales)
FROM titles
WHERE type = 'business'

SHOWPLAN:

STEP 1
The type of query is SELECT
Scalar Aggregate
FROM TABLE
titles
Nested iteration
Table Scan

STEP 2
The type of query is SELECT

Notice that SHOWPLAN considers this a two-step query, similar to the SHOWPLAN from the GROUP BY query shown earlier. Because the query contains a scalar aggregate, which will return a single value, SQL Server keeps internally a "variable" to store the result of the aggregate function. Think of this variable as a temporary storage space to keep a running total of the aggregate function as the qualifying rows from the table are evaluated. After all rows have been evaluated from the table (STEP 1), the final value from the "variable" is then selected (STEP 2) to return the scalar aggregate result.


Vector Aggregate

When a GROUP BY clause is used in a query that also includes an aggregate function, the aggregate function produces a value for each group. These values are called vector aggregates. The Vector Aggregate statement from SHOWPLAN indicates that the query includes a vector aggregate.

The following example includes a vector aggregate:

Query:

SELECT title_id, AVG(qty)
FROM sales
GROUP BY title_id

SHOWPLAN:

STEP 1
The type of query is SELECT (into a worktable)
GROUP BY
Vector Aggregate
FROM TABLE
sales
Nested iteration
Table Scan
TO TABLE
Worktable 1

STEP 2
The type of query is SELECT
FROM TABLE
Worktable 1
Nested iteration
Table Scan


FROM TABLE

This SHOWPLAN step indicates the table that the query is reading from. In most queries, the FROM TABLE will be followed on the next line by the name of the table from which it is being selected. If an alias was specified for the table in the FROM clause, it is also shown in the next line. In other cases, it might indicate that it is selecting from a worktable (discussed later). The main importance of examining the table names after the FROM TABLE output is to determine the order in which the query optimizer is joining the tables. The order of the tables listed after the FROM TABLE statements in the SHOWPLAN output indicates the same order that the tables were joined; this order might be (and often is) different from the order in which they are listed in the FROM clause of the query or the order in which they appear in the WHERE clause of the query. This is because the query optimizer examines all different join orders for the tables involved and picks the join order that will require the least amount of I/Os.

Query:

SELECT authors.au_id, au_fname, au_lname
FROM authors, titleauthor, titles
WHERE authors.au_id = titleauthor.au_id
AND titleauthor.title_id = titles.title_id
AND titles.type = 'psychology'

SHOWPLAN:

STEP 1
The type of query is SELECT
FROM TABLE
titles
Nested iteration
Table Scan
FROM TABLE
titleauthor
Nested iteration
Table Scan
FROM TABLE
authors
Nested iteration
Table Scan

This query illustrates the order in which the SQL Server query optimizer joins the tables; it is not the order in which they were listed in the FROM clause or the WHERE clause. By examining the order of the FROM TABLE statements, you can see that the qualifying rows from the titles table are first located (using the search clause titles.type = 'psychology'). Those rows are then joined with the titleauthor table (using the join clause titleauthor.title_id = titles.title_id), and finally the titleauthor table is joined with the authors table to retrieve the desired columns (using the join clause authors.au_id = titleauthor.au_id).


TO TABLE

When a statement is issued that makes or attempts to make a modification to one or more rows of a table (such as INSERT, DELETE, UPDATE, or SELECT INTO), the TO TABLE statement shows the target table being modified. For operations that require an intermediate step that inserts rows into a worktable (discussed later), TO TABLE indicates that the results are going to the worktable, rather than to a user table.

The following examples illustrate the use of the TO TABLE statement:

Query 1:

INSERT publishers
VALUES ('9904', 'NewPubs', 'Seattle', 'WA', 'USA')

SHOWPLAN 1:

STEP 1
The type of query is INSERT
The update mode is direct
TO TABLE
publishers

Query 2:

UPDATE publishers
SET city = 'Los Angeles'
WHERE pub_id = '1389'

SHOWPLAN 2:

STEP 1
The type of query is UPDATE
The update mode is direct
FROM TABLE
publishers
Nested iteration
Table Scan
TO TABLE
publishers

Notice that the SHOWPLAN for the second query indicates that the publishers table is used both as the FROM TABLE as well as the TO TABLE. In the case of UPDATE operations, the optimizer reads the table that contains the rows to be updated, resulting in the FROM TABLE statement, and then modifies the rows, resulting in the TO TABLE statement.


Worktable n

For some types of queries, such as those that require the results to be ordered or displayed in groups, the SQL Server query optimizer might determine that it is necessary to create its own temporary worktable. The worktable holds the intermediate results of the query, at which time the result rows can be ordered or grouped, and then the final results selected from that worktable. When all results have been returned, the worktable is automatically dropped.

The worktables are always created in the tempdb database, so it is possible that the SA might have to increase the size of tempdb to accommodate queries that require very large worktables. Because the query optimizer creates these worktables for its own internal use, the names of the worktables will not be listed in the tempdb..sysobjects table.

Worktables will always need to be used when a query contains a GROUP BY clause. For queries involving ORDER BY, it is possible that the ordering can be done without a worktable. For example, if there is a clustered index on the column(s) in the ORDER BY clause, the optimizer knows that the rows are already stored in sorted order, so a sort in a worktable is not necessary (although there are exceptions to this, depending on the sort order installed on the server).

Because the data is not stored in sorted order for nonclustered indexes, the worktable will not be necessary if the most efficient access plan uses the nonclustered index. However, if the optimizer determines that scanning the entire table will require fewer I/Os than using the nonclustered index, a worktable will need to be created for the ordering of the results.

Query 1:

SELECT type, AVG(advance), SUM(ytd_sales)
FROM titles
GROUP BY type

SHOWPLAN 1:

STEP 1
The type of query is SELECT (into a worktable)
GROUP BY
Vector Aggregate
FROM TABLE
titles
Nested iteration
Table Scan
TO TABLE
Worktable 1

STEP 2
The type of query is SELECT
FROM TABLE
Worktable 1
Nested iteration
Table Scan

Query 2:

SELECT *
FROM authors
ORDER BY au_lname, au_fname

SHOWPLAN 2:

STEP 1
The type of query is INSERT
The update mode is direct
Worktable created for ORDER BY
FROM TABLE
authors
Nested iteration
Table Scan
TO TABLE
Worktable 1

STEP 2
The type of query is SELECT
This step involves sorting
FROM TABLE
Worktable 1
Using GETSORTED Table Scan

Query 3:

SELECT *
FROM authors
ORDER BY au_id

SHOWPLAN 3:

STEP 1
The type of query is SELECT
FROM TABLE
authors
Nested iteration
Table Scan

In Query 3, notice that no worktable was created for the ORDER BY clause. This is because the authors.au_id column has a unique clustered index, so the data is already stored in sorted order based on the au_id value, and an additional sort for ORDER BY is not necessary. In Query 2, columns au_lname and au_fname have a composite nonclustered index. However, because the optimizer chose not to use the index, and due to the sort order on the SQL Server, a worktable was created to accommodate the sort.


Worktable created for SELECT_INTO

The SELECT INTO statement performs two functions: it first creates a table with the exact same structure as the table being selected from, and then it inserts all rows that meet the WHERE conditions (if a WHERE clause is used) of the table being selected from. The worktable created for the SELECT_INTO statement is slightly misleading, in that the worktable it refers to is actually the new physical table created. Unlike other worktables, it is not dropped when the query finishes executing. In addition, the worktable is not created in tempdb, unless the user specifies tempdb as the target database for the new table.

Query:

SELECT *
INTO seattle_stores
FROM stores
WHERE city = 'Seattle'

SHOWPLAN:

STEP 1
The type of query is TABCREATE

STEP 2
The type of query is INSERT
The update mode is direct
Worktable created for SELECT_INTO
FROM TABLE
stores
Nested iteration
Table Scan
TO TABLE
seattle_stores


Worktable created for DISTINCT

When a query that includes the DISTINCT keyword is issued, all duplicate rows are excluded from the results and only unique rows are returned. To accomplish this, SQL Server first creates a worktable to store the results of the query, including duplicates, just as if the DISTINCT keyword were not included. It then sorts the rows in the worktable and discards the duplicate rows. Finally, the rows from the worktable are returned, ensuring that no duplicate rows will appear in the output.

Query:

SELECT DISTINCT city
FROM authors

SHOWPLAN:

STEP 1
The type of query is INSERT
The update mode is direct
Worktable created for DISTINCT
FROM TABLE
authors
Nested iteration
Table Scan
TO TABLE
Worktable 1

STEP 2
The type of query is SELECT
This step involves sorting
FROM TABLE
Worktable 1
Using GETSORTED Table Scan


Worktable created for ORDER BY

As discussed previously, queries that include an ORDER BY clause often require the use of a temporary worktable. When the optimizer cannot use an available index for the ordering, it creates a worktable for use in sorting the result rows prior to returning them.

The following example shows the worktable being created for the ORDER BY clause:

Query:

SELECT *
FROM authors
ORDER BY city

SHOWPLAN:

STEP 1
The type of query is INSERT
The update mode is direct
Worktable created for ORDER BY
FROM TABLE
authors
Nested iteration
Table Scan
TO TABLE
Worktable 1

STEP 2
The type of query is SELECT
This step involves sorting
FROM TABLE
Worktable 1
Using GETSORTED Table Scan


Worktable created for REFORMATTING

When joining tables, SQL Server might, in some cases, use a reformatting strategy to join the tables and return the qualifying rows. This strategy is considered only as a last resort, when the tables are large and neither table in the join has a useful index. The reformatting strategy inserts the rows from the smaller of the two tables into a worktable. Then a clustered index is created on the worktable, and the clustered index is used in the join to retrieve the qualifying rows from each table.

The main cost in using the reformatting strategy is the time and I/Os necessary to build the clustered index on the worktable; however, that cost is still less than joining the tables with no index. If user queries use the reformatting strategy, it is generally a good idea to examine the tables involved and to create indexes on the columns of the tables being joined.

The following example illustrates the reformatting strategy. Because none of the tables in the pubs database are large enough for the optimizer to consider using this strategy, two new tables are used. Each table has five columns defined as char(200). Tab1 has 500 rows and Tab2 has 250 rows.

Query:

SELECT Tab1.col1
FROM Tab1, Tab2
WHERE Tab1.col1 = Tab2.col1

SHOWPLAN:

STEP 1
The type of query is INSERT
The update mode is direct
Worktable created for REFORMATTING
FROM TABLE
Tab2
Nested iteration
Table Scan
TO TABLE
Worktable 1

STEP 2
The type of query is SELECT
FROM TABLE
Tab1
Nested iteration
Table Scan
FROM TABLE
Worktable 1
Nested iteration
Using Clustered Index


This step involves sorting

This statement indicates that the query must sort the intermediate results before returning them to the user. Queries that specify DISTINCT, as well as queries that have an ORDER BY clause that cannot use an available index, require an intermediate sort. As stated earlier, the results are put into a worktable, and the worktable is then sorted.

The following example demonstrates a query that requires a sort:

Query:

SELECT DISTINCT state
FROM stores

SHOWPLAN:

STEP 1
The type of query is INSERT
The update mode is direct
Worktable created for DISTINCT
FROM TABLE
stores
Nested iteration
Table Scan
TO TABLE
Worktable 1

STEP 2
The type of query is SELECT
This step involves sorting
FROM TABLE
Worktable 1
Using GETSORTED Table Scan


Using GETSORTED Table Scan

This statement indicates one of the ways in which the result rows can be returned from a table. With Using GETSORTED Table Scan, the rows are returned in sorted order. However, not all queries that return rows in sorted order will have this step. If a query has an ORDER BY clause and an index with the proper sort sequence exists on the columns being ordered, an intermediate sort might not be necessary and the rows can simply be returned in order by using the available index. The Using GETSORTED Table Scan method is used when SQL Server must first create a temporary worktable to sort the result rows and then return them in the proper sorted order.

The following example shows a query that requires a worktable to be created and the rows returned in sorted order:

Query:

SELECT au_id, au_lname, au_fname, city
FROM authors
ORDER BY city

SHOWPLAN:

STEP 1
The type of query is INSERT
The update mode is direct
Worktable created for ORDER BY
FROM TABLE
authors
Nested iteration
Table Scan
TO TABLE
Worktable 1

STEP 2
The type of query is SELECT
This step involves sorting
FROM TABLE
Worktable 1
Using GETSORTED Table Scan


Nested iteration

The Nested iteration method is the default technique used to join tables and/or to return rows from a table. It simply indicates that the optimizer is using one or more sets of loops to go through a table and retrieve a row, qualify the row based on the search criteria given in the WHERE clause, return the row to the front-end, and loop again to get the next row. The method in which it gets the rows (such as using an available index) is discussed later.

The following example shows the optimizer doing nested iterations through each of the tables in the join:

Query:

SELECT title_id, title
FROM titles, publishers
WHERE titles.pub_id = publishers.pub_id
AND publishers.pub_id = '1389'

SHOWPLAN:

STEP 1
The type of query is SELECT
FROM TABLE
publishers
Nested iteration
Table Scan
FROM TABLE
titles
Nested iteration
Table Scan


EXISTS TABLE: nested iteration

This SHOWPLAN step is very similar to the Nested iteration method. The difference, however, is that this step indicates a nested iteration on a table that is part of an existence test in a query. An existence test can be written in several ways using Transact-SQL statements, such as EXISTS, IN, or =, <, >, <=, >=, <> ANY.

The following examples demonstrate the SHOWPLAN output with queries that test for existence of values:

Query 1:

SELECT au_lname, au_fname
FROM authors
WHERE EXISTS
(SELECT *
FROM publishers
WHERE authors.city = publishers.city)

SHOWPLAN 1:

STEP 1
The type of query is SELECT
FROM TABLE
authors
Nested iteration
Table Scan
FROM TABLE
publishers
EXISTS TABLE : nested iteration
Table Scan

Query 2:

SELECT title
FROM titles
WHERE pub_id IN
(SELECT pub_id
FROM publishers
WHERE city LIKE 'B%')

SHOWPLAN 2:

STEP 1
The type of query is SELECT
FROM TABLE
titles
Nested iteration
Table Scan
FROM TABLE
publishers
EXISTS TABLE : nested iteration
Table Scan


Table Scan

This statement indicates which method was used to retrieve the physical result rows from the given table. When the Table Scan method is used, execution begins with the first row in the table; each row is then retrieved and compared with the conditions in the WHERE clause, and then returned to the front-end if it meets the given criteria. Regardless of how many rows qualify, every row in the table must be looked at, so for very large tables, a table scan can be very costly in terms of page I/Os.

If a table has one or more indexes on it, the query optimizer might still perform a table scan instead of using one of the available indexes if the optimizer determines that the indexes are too costly or are not useful for the given query.

The following query shows a typical Table Scan:

Query:

SELECT au_lname, au_fname
FROM authors

SHOWPLAN:

STEP 1
The type of query is SELECT
FROM TABLE
authors
Nested iteration
Table Scan


Using Clustered Index

This statement indicates that the query optimizer used the clustered index on a table to retrieve the rows. Unlike the table scan method, using an index to retrieve rows does not require the optimizer to examine every row in the table (unless the WHERE clause applies to all rows). For queries that return a small percentage of the rows from a large table, the savings in terms of I/Os of using an index versus doing a table scan can be very significant.

The following query shows the clustered index being used to retrieve the rows from the table:

Query:

SELECT title_id, title
FROM titles
WHERE title_id LIKE 'PS2%'

SHOWPLAN:

STEP 1
The type of query is SELECT
FROM TABLE
titles
Nested iteration
Using Clustered Index


Index : index_name

Like the previous statement with the clustered index, this statement indicates that the optimizer used an index to retrieve rows instead of scanning a table. The index_name that follows the Index : label is always the name of a nonclustered index on the table. Remember that each table can have no more than one clustered index, but each can have as many as 249 nonclustered indexes.

The following query illustrates the use of a nonclustered index to find and return rows. This query uses the sysobjects table in the master database as an example, rather than a table in pubs. (Using a nonclustered index on the pubs tables is generally more costly in terms of I/O than a straight table scan, because most of the tables are only one page in size.)

Query:

SELECT *
FROM master..sysobjects
WHERE name = 'mytable'
AND uid = 5

SHOWPLAN:

STEP 1
The type of query is SELECT
FROM TABLE
master..sysobjects
Nested iteration
Index : ncsysobjects


Using Dynamic Index

This statement indicates that the query optimizer has built its own index during the execution of the query, for use in its OR strategy. Because queries involving OR clauses are generally not very efficient in terms of quickly accessing the data, the SQL Server optimizer might use the OR strategy. When the OR strategy is used, the optimizer makes several passes through the table ¾ one pass for each argument to each OR clause. The results of each pass are added to a single worktable, and the worktable is then sorted to remove any duplicate rows.

The worktable does not contain the actual data rows from the table; rather, it contains the row IDs for the matching rows. The row IDs are simply a combination of the page number and row number on that page for each of the rows.

When the duplicates have been eliminated, the optimizer considers the worktable of row IDs to be, essentially, its own index (Dynamic Index) pointing to the table's data rows. It can then simply scan through the worktable, get each row ID, and return the data row from the table that has that row ID.

The OR strategy is not limited to queries that contain OR clauses. When an IN clause is used to list a group of possible values, SQL Server interprets this as though the query had a separate equality clause for each of the values in the IN clause.

To illustrate the OR strategy and the use of the Dynamic Index, the following queries are based on a table with 10,000 unique data rows, a unique nonclustered index on column col1, and a unique nonclustered index on column col2.

Query 1:

SELECT *
FROM Mytable
WHERE col1 = 355
OR col2 = 732

SHOWPLAN 1:

STEP 1
The type of query is SELECT
FROM TABLE
Mytable
Nested iteration
Index : col1_idx
FROM TABLE
Mytable
Nested iteration
Index : col2_idx
FROM TABLE
Mytable
Nested iteration
Using Dynamic Index

Query 2:

SELECT *
FROM Mytable
WHERE col1 IN (700, 1503, 311)

SHOWPLAN 2:

STEP 1
The type of query is SELECT
FROM TABLE
Mytable
Nested iteration
Index : col1_idx
FROM TABLE
Mytable
Nested iteration
Index : col1_idx
FROM TABLE
Mytable
Nested iteration
Index : col1_idx
FROM TABLE
Mytable
Nested iteration
Using Dynamic Index

SQL Server does not always resort to using the OR strategy for every query that contains OR clauses. The following conditions must be met before SQL Server uses the OR strategy:

  • All columns in the OR clause must belong to the same table.
  • If any portion of the OR clause requires a table scan (due to lack of index or poor selectivity of a given index), a table scan will be used for the entire query, rather than the OR strategy.
  • The decision to use the OR strategy is made after all indexes and costs are evaluated. If any other access plan is less costly (in terms of page I/Os), SQL Server uses the plan with the least cost. In the examples, if a straight table scan would result in less page I/Os than using the OR strategy, the queries would be processed as a table scan instead of using the Dynamic Index.


AND NOT EXISTS : nested iteration

This SHOWPLAN step indicates a nested iteration on a subquery that is part of a non-existence test in a query. When the result of the subquery is true, subsequent parts of the plan are not evaluated. A non-existence test can be written in several ways using Transact-SQL statements, such as NOT EXISTS, NOT IN, <> ALL, = ALL, < ALL, <=ALL, > ALL, or >= ALL. The plan for the subquery will immediately follow this step and is indented to isolate the steps for the subquery from the steps for the outer query.

The following examples demonstrate the SHOWPLAN output with queries that test for the non-existence of values:

Query 1:

SELECT au_lname, au_fname
FROM authors
WHERE NOT EXISTS
(SELECT *
FROM publishers
WHERE authors.city = publishers.city)

SHOWPLAN 1:

STEP 1
The type of query is SELECT
FROM TABLE
authors
Nested iteration
Table Scan
AND NOT EXISTS : nested iteration
FROM TABLE
publishers
EXISTS TABLE : nested iteration
Table Scan

Query 2:

SELECT title
FROM titles
WHERE pub_id NOT IN
(SELECT pub_id
FROM publishers
WHERE city LIKE 'B%')

SHOWPLAN 2:

STEP 1
The type of query is SELECT
FROM TABLE
titles
Nested iteration
Table Scan
AND NOT EXISTS : nested iteration
FROM TABLE
publishers
EXISTS TABLE : nested iteration
Table Scan


OR EXISTS : nested iteration

This SHOWPLAN step indicates a nested iteration on a subquery that is part of an existence test in an OR clause. When the result of the subquery is true, subsequent parts of the plan are not evaluated and the result of the plan for the OR clause is true. An existence test can be written in several ways using Transact-SQL statements, such as EXISTS, IN, <> ANY, = ANY, < ANY, <=ANY, > ANY, or >= ANY. The plan for the subquery will immediately follow this step, and is indented to isolate the steps for the subquery from the steps for the outer query.

The following example demonstrates the SHOWPLAN output for queries with OR clauses that test for the existence of values:

Query:

SELECT title
FROM titles
WHERE advance > ANY
(SELECT advance
FROM publishers, titles
WHERE titles.pub_id = publishers.pub_id
AND pub_name = 'Algodata Infosystems')
OR pub_id IN
(SELECT pub_id
FROM publishers
WHERE city NOT LIKE 'B%')

SHOWPLAN:

STEP 1
The type of query is SELECT
FROM TABLE
titles
Nested iteration
Table Scan
AND EXISTS : nested iteration
OR EXISTS : nested iteration
FROM TABLE
publishers
EXISTS TABLE : nested iteration
Table Scan
FROM TABLE
titles
EXISTS TABLE : nested iteration
Table Scan
OR EXISTS : nested iteration
FROM TABLE
publishers
EXISTS TABLE : nested iteration
Table Scan


OR NOT EXISTS : nested iteration

This SHOWPLAN step indicates a nested iteration on a subquery that is part of a non-existence test in an OR clause. When the result of the subquery is true, subsequent parts of the plan are not evaluated, and the result of the plan for the OR clause is true. A non-existence test can be written in several ways using Transact-SQL statements, such as NOT EXISTS, NOT IN, <> ALL, = ALL, < ALL, <=ALL, > ALL, or >= ALL. The plan for the subquery will immediately follow this step, and is indented to isolate the steps for the subquery from the steps for the outer query.

The following example demonstrates the SHOWPLAN output for queries with OR clauses that test for the non-existence of values:

Query:

SELECT title
FROM titles
WHERE NOT EXISTS
(SELECT *
FROM publishers p, titles t
WHERE t.pub_id = p.pub_id
AND p.pub_name = 'Algodata Infosystems'
AND titles.advance > t.advance)
OR pub_id NOT IN
(SELECT pub_id
FROM publishers
WHERE city  LIKE 'B%')

SHOWPLAN:

STEP 1
The type of query is SELECT
FROM TABLE
titles
Nested iteration
Table Scan
AND EXISTS : nested iteration
OR NOT EXISTS : nested iteration
FROM TABLE
publishers p
EXISTS TABLE : nested iteration
Table Scan
FROM TABLE
titles t
EXISTS TABLE : nested iteration
Table Scan
OR NOT EXISTS : nested iteration
FROM TABLE
publishers
EXISTS TABLE : nested iteration
Table Scan


SUBQUERY : nested iteration

This SHOWPLAN step indicates a nested iteration on a correlated subquery involving an aggregate. The plan for the subquery will immediately follow this step, and is indented to isolate the steps for the subquery from the steps for the outer query. The plan for the subquery will produce a vector aggregate result in a work table. The GROUP BY clause for the vector aggregate consists of the outer references in the subquery plus the elements of the subquery's GROUP BY clause, if one exists.

The following example demonstrates the SHOWPLAN output for subqueries involving aggregates:

Query:

SELECT ord_num, title_id, qty
FROM sales s1
WHERE qty <
(SELECT avg(qty)
FROM sales s2
WHERE s2.title_id = s1.title_id)

SHOWPLAN:

STEP 1
The type of query is SELECT
FROM TABLE
sales s1
Nested iteration
Table Scan
AND EXISTS : nested iteration
FROM TABLE
Worktable 1
SUBQUERY : nested iteration
GROUP BY
Vector Aggregate
FROM TABLE
sales s2
Nested iteration
Table Scan
TO TABLE
Worktable 1


AND EXISTS : nested iteration

This SHOWPLAN step indicates either a nested iteration on a subquery that is part of an existence test in a query, or a nested iteration on a correlated scalar subquery involving an aggregate, or a nested iteration on the plan for evaluating OR clauses involving subqueries. The plan for the subquery or the OR clause will immediately follow this step and is indented to isolate the steps for the subquery, or the steps for the OR clause, from the steps for the outer query.

The following example demonstrates the SHOWPLAN output for an AND EXISTS nested iteration on a subquery that is part of an existence test:

Query:

SELECT title
FROM titles
WHERE EXISTS
(SELECT *
FROM publishers p, titles t
WHERE t.pub_id = p.pub_id
AND p.pub_name = 'Algodata Infosystems'
AND titles.advance > t.advance)
AND pub_id NOT IN
(SELECT pub_id
FROM publishers
WHERE city  LIKE 'B%')

SHOWPLAN:

STEP 1
The type of query is SELECT
FROM TABLE
titles
Nested iteration
Table Scan
AND EXISTS : nested iteration
FROM TABLE
publishers p
EXISTS TABLE : nested iteration
Table Scan
FROM TABLE
titles t
EXISTS TABLE : nested iteration
Table Scan
AND NOT EXISTS : nested iteration
FROM TABLE
publishers
EXISTS TABLE : nested iteration
Table Scan

The following example demonstrates the SHOWPLAN output for an AND EXISTS nested iteration on a subquery involving aggregates:

Query:

SELECT ord_num, title_id, qty
FROM sales s1
WHERE qty <
(SELECT avg(qty)
FROM sales s2
WHERE s2.title_id = s1.title_id)

SHOWPLAN:

STEP 1
The type of query is SELECT
FROM TABLE
sales s1
Nested iteration
Table Scan
AND EXISTS : nested iteration
FROM TABLE
Worktable 1
SUBQUERY : nested iteration
GROUP BY
Vector Aggregate
FROM TABLE
sales s2
Nested iteration
Table Scan
TO TABLE
Worktable 1

The following example demonstrates the SHOWPLAN output for an AND EXISTS nested iteration on a plan for evaluating an OR clause involving subqueries:

Query:

SELECT au_lname, au_fname
FROM authors
WHERE    EXISTS
(SELECT *
FROM publishers
WHERE authors.city = publishers.city)
OR NOT EXISTS
(SELECT *
FROM publishers
WHERE authors.city = publishers.city)

SHOWPLAN:

STEP 1
The type of query is SELECT
FROM TABLE
authors
Nested iteration
Table Scan
AND EXISTS : nested iteration
OR EXISTS : nested iteration
FROM TABLE
publishers
EXISTS TABLE : nested iteration
Table Scan
OR NOT EXISTS : nested iteration
FROM TABLE
publishers
EXISTS TABLE : nested iteration
Table Scan


WITH CHECK OPTION

This SHOWPLAN step indicates an existence test that is generated by the optimizer when modifying a view that involves one or more subqueries and was created WITH CHECK OPTION. If the existence test fails, the modification will also fail.

Assuming the following view:

CREATE VIEW v1 AS
SELECT *
FROM mytable
WHERE col1 IN (SELECT col1 FROM mytable2)
WITH CHECK OPTION

the following example demonstrates the SHOWPLAN output for a query which updates a view containing subqueries which was created WITH CHECK OPTION.

Query:

UPDATE v1 SET col1 = 2

SHOWPLAN:

STEP 1
The type of query is UPDATE
The update mode is deferred
FROM TABLE
mytable
Nested iteration
Table Scan
FROM TABLE
mytable2
EXISTS TABLE : nested iteration
Table Scan
TO TABLE
mytable
WITH CHECK OPTION
FROM TABLE
mytable2
EXISTS TABLE : nested iteration
Table Scan


Chapter 24 Additional Problem-Solving Techniques

Additional Problem-Solving Techniques

This chapter includes information about:

  • Using trace flags
  • Stopping processes
  • Associating a page with an object
  • Dropping a database when DROP DATABASE fails
  • Creating useful stored procedures


Using Trace Flags

SQL Server trace flags provide additional information about SQL Server operations or change certain behaviors, usually for backward compatibility. In general, trace flags should be used to temporarily work around a problem until a permanent solution is put in place. Although the information provided by trace flags can help you diagnose problems, keep in mind that trace flags are not part of the supported feature set. This means that future compatibility or continued use is not assured. In addition, your primary support provider, including Microsoft, will usually not have further information and will not answer questions regarding the trace flags or their output. In other words, the information provided in this section is to be used "as is."

Caution It is generally recommended that you use trace flags only when directed by your primary support provider or by this chapter. Beware against experimenting with trace flags not documented here. They can cause unexpected and potentially serious problems.

Trace Flags are used to temporarily set a specific server characteristic. Trace flags can be activated through three methods: by using the DBCC statement, with the -T option with the sqlservr command-line executable, or in setup. Once set, and trace flags are in effect only until reset (for options set with the DBCC statement) or until the server is stopped and restarted without the trace flag. For details, see the Trace Flags topic, the Utilities topic, and the DBCC statement in the Microsoft SQL Server Transact-SQL Reference.

These are the trace flags available in SQL Server 6.0. Trace flags noted with an asterisk (*) are for information only. Others are used to change program behavior.

Trace flag | Description
- 1 | Sets trace flags for all client connections, rather than for a single client connection. Because trace flags set using the -T command-line option (with sqlservr) automatically apply to all connections, this trace flag is used only when setting trace flags using DBCC TRACEON and DBCC TRACEOFF. For details, see the sqlservr command-line executable and DBCC statement in the Microsoft SQL Server Transact-SQL Reference.
106* | Disables line number information for syntax errors.
107 | Interprets numbers with a decimal point as float instead of decimal. For details, see the Datatypes topic in the Microsoft SQL Server Transact-SQL Reference.
204 Generally, allows non-ANSI-standard behavior for various features for backward compatibility with earlier version of SQL Server:

Allows queries that contain aggregates or a GROUP BY clause to have items in the select list that are not in the GROUP BY clause and are not aggregate functions. ANSI-standard SQL does not allow this.

Ignores trailing blanks in the LIKE pattern. For details, see the Search Conditions and Wildcard Characters topics in the Microsoft SQL Server Transact-SQL Reference.

206 | Provides backward compatibility for the SETUSER statement. For details, see the SETUSER statement.
242 | Provides backward compatibility for correlated subqueries where non-ANSI-standard results are desired.
243 Provides backward compatibility for nullability behavior. When set, SQL Server has the same nullability violation behavior as that of a 4.2 server:
· Processing of the entire batch will be terminated if
the nullability error (for example, inserting NULL into
a NOT NULL field) can be detected at compile time.
· Processing of the offending row will be skipped,
but the command will continue if the nullability
violation is detected at run time.

The behavior of SQL Server 6.0 is now more consistent ¾ all nullability checks are made at run time and a nullability violation results in the command terminating but the batch/transaction continuing to process.
244 | Disables checking for allowed interim constraint violations. By default, SQL Server checks for and allows interim constraint violations. An interim constraint violation is caused by a change that initially violates a constraint, followed by another change that removes the violation such that the constraint is met, all within a single statement and transaction. SQL Server checks for interim constraint violations for self-referencing DELETE statements, INSERT statements based on a SELECT, and multi-row UPDATE statements. This checking requires more work tables. With this trace flag you can disallow interim constraint violations, thus requiring fewer work tables.
302* | Prints information about whether the statistics page is used, the actual selectivity (if available), and what SQL Server estimated the physical and logical I/O would be for the indexes. Trace flag 302 should be used with trace flag 310 to show the actual join ordering.
310* | Prints information about join order. Index selection information is also available in a more readable format using SET SHOWPLAN ON, as described in the SET statement.
325* | Prints information about the cost of using a nonclustered index or a sort to process an ORDER BY clause.
326* | Prints information about the estimated and actual cost of sorts.
652 | Disables read ahead for the server.
653 | Disables read ahead for the current connection.
1200* | Prints lock information (the process ID and type of lock requested).
1204* | Returns the type of locks participating in the deadlock and the current command affected.
1205* | Returns detailed information about the commands being executed at the time of a deadlock.
1609 | Turns on the unpacking and checking of RPC information with the execution of the sp_sqlexec extended stored procedure in Open Data Services. Use this flag only when applications depend on the old behavior. The application should be changed to use EXECUTE sql_string rather than sp_sqlexec. For details, see the EXECUTE statement in the Microsoft SQL Server Transact-SQL Reference.
1704 | Prints information when a temporary table is created or dropped.
3502* | Prints a message to the log at the start and end of each checkpoint.
3205 | By default, if a tape drive supports hardware compression, the DUMP statement will use it. With this trace flag, you can disable hardware compression for tape drives. This might be useful when you want to exchange tapes with other sites or tape drives that do not support compression.
3503* | Indicates whether the checkpoint at the end of automatic recovery was skipped for a database (this applies only to read-only databases). For details, see the sp_dboption system stored procedure.
3604* | Sends trace output to the client. ( ) This trace flag is used only when setting trace flags with DBCC TRACEON and DBCC TRACEOFF.
3605* | Sends trace output to the error log. (If you start SQL Server from the command line, the output will also appear on the screen.)
3607 | Skips automatic recovery (at startup) for all databases.
3608 | Skips automatic recovery (at startup) for all databases except the master database.
3609 | Skips the creation of the tempdb database at startup. Use this trace flag if the device or devices on which tempdb resides are problematic or problems exist in the model database.
3640 | Eliminates the sending of DONE_IN_PROC messages to the client for each statement in a stored procedure. This is similar to the session setting NOCOUNT, but when set as a trace flag every client session is handled this way. For details, see the SET statement.
4022 | Skips the execution of all startup stored procedures. For more information, see the CREATE PROCEDURE statement and the sp_makestartup system stored procedure.
4030* | Prints both a byte and ASCII representation of the receive buffer. This trace flag is usually used when you need to see what queries a client is sending to SQL Server. You might use this trace flag if you experience a protection violation and need to determine which statement caused it. Typically, you would set this flag globally. You can also use DBCC INPUTBUFFER. For details, see the DBCC statement.
4031* | Prints both a byte and ASCII representation of the send buffers (what SQL Server sends back to the client). You can also use DBCC OUTPUTBUFFER. For details, see the DBCC statement.
4032* | Prints only an ASCII representation of the receive buffer. Usually used in place of trace flag 4030 (if trace output speed is important) when you need to see what queries a client is sending to SQL Server.

Unlike the other trace flags, the trace flag - 1 activates tracing only in processes that were open when the DBCC TRACEON ( - 1) statement was issued. Because new connections are not traced, you should periodically set the - 1 trace flag using DBCC TRACEON ( - 1) if you want to pick up new connections.

Setting trace flags using DBCC TRACEON ( - 1) differs from using the -T command-line option (as described in "Starting SQL Server with Trace Flags," later in this chapter):

  • You can invoke trace flags globally on a production server without shutting down SQL Server.
  • If you know a particular problem tends to occur during a certain period in the day, you can invoke the trace flag globally at that time (and avoid filling up the error log with irrelevant data from startup).


Setting Trace Flags with DBCC

To set and clear trace flags with DBCC, use the TRACEON and TRACEOFF options, as described in the following procedures.

To set trace flags on with DBCC
  • Use the DBCC TRACEON statement.

    The syntax for DBCC TRACEON is as follows:

    DBCC TRACEON (trace#)

    For example, to turn on trace flag 3604:

    dbcc traceon (3604)
To set trace flags off with DBCC
  • Use the DBCC TRACEOFF statement.

    The syntax for DBCC TRACEOFF is as follows:

    DBCC TRACEOFF (trace#)

    For example, to turn off trace flag 3604:

    dbcc traceoff (3604)


Starting SQL Server with Trace Flags

To start SQL Server with a trace flag, add the -T trace_flag_number option to the command line (or in setup), as shown in this example:

sqlservr -dc:\sql\data\master.dat -ec:\sql\log\errorlog     -T4030

Note The -T option is case sensitive. In addition, it does not allow space between the -T and the trace_flag_number.

To start SQL Server with multiple trace flags, repeat the -T option for each trace flag, as shown in this example:

sqlservr -dc:\sql\data\master.dat -ec:\sql\log\errorlog     -T4030 -T4031


Stopping Processes

A process is a task being carried out by SQL Server. Processes can be initiated either by a user executing a statement or by SQL Server itself.

Each process is assigned a unique (but not necessarily consecutive) system process identification number (spid) when it starts. A process can determine its own spid by executing SELECT @@SPID. Process identification numbers and other information about each process are stored in the sysprocesses table in the master database.

Note Each spid identifies a connection to SQL Server. Some client applications establish several connections.

To keep the system operating smoothly, you might want to check ongoing processes regularly with the sp_who system procedure. Another system procedure, sp_lock, also reports on processes. It gives information about all the locks currently held on SQL Server, including the spid of the process holding each one. For additional information about sp_who and sp_lock, see the Microsoft SQL Server Transact-SQL Reference.

The KILL statement is used to terminate an ongoing process. Only the system administrator can issue the KILL statement (permission to use it cannot be transferred). The most frequent reason for stopping a process is that it interferes with other users. A KILL statement is not reversible and cannot be put inside a user-defined transaction.

You cannot stop system processes. Server processes reported by sp_who and sp_lock include CHECKPOINT, MIRROR HANDLER, LAZY WRITER, and RA MANAGER. Any other process can be stopped with the KILL statement. You can stop only one process at a time.

To stop a process
  • From a client utility such as isql, type:

    KILL spid

    where:

    spid
    Is the identification number of the process you want to kill. You can get a list of process ID numbers using the sp_who system procedure.

    For example, to kill process ID 14, type:

    KILL 14


Associating a Page with an Object

Some SQL Server error messages specify a logical page number instead of the table or index name to which the page belongs. The following procedure shows how to determine the object to which a particular database page belongs.

Although you can use DBCC CHECKALLOC and DBCC CHECKDB to identify table names and index IDs, a quicker method is described below. Note, however, that this method tells you only the table or index associated with a particular page number.

Suppose you encounter the following error message:

Error 644, Severity 21, State 1
The non_clustered leaf row entry for page 1342 row 6 was not found in index page 944 indexid 3 database 'production'

The error message implies that a nonclustered index is corrupt, but the corresponding table name or index name is not given ¾ only a page number (944) and an index ID (3).

To determine which table or index is involved, follow these steps:

  1. Log in as sa.
  2. Determine the database ID (dbid) as follows:
    select db_id('database_name')
  3. Enable trace flag 3604 to allow DBCC output to appear on the server:
    dbcc traceon(3604)
  4. To display information about the page in question, use the DBCC PAGE statement as follows:

    dbcc page(database_id, page_number)

    Note The DBCC PAGE statement is not a supported feature, so future compatibility is not assured. It is offered here only for the purpose of providing a faster method of associating a page with an object. Additional information about the output of DBCC PAGE is not available.

    For example, assuming that the output from step 2 indicates that the database ID is 6, you can find information about page 944 (the index page indicated in the error message shown above) as follows. (The objid and indid shown in the boxes in the following example are used in steps 5 and 6, below.)

    dbcc page (6, 944)
PAGE: Page not found in cache - read from disk.
BUFFER: Buffer header for buffer 0x2c4b30 page=0x540800 bdnew=0x0
bold=0x0 bhash=0x0 bnew=0x0 bold=0x0 bvirtpg=7092 bdbid=6
bpinproc=0 bkeep=0 bspid=0
bstat=0x0000 bpageno=0
PAGE HEADER: Page header for page 0x540800
objid=9051068
pageno=944 nextpg=0 prevpg=0 timestamp=0001
000c70f2
indid=3
nextrno=32 level=0  freeoff=52 minlen=7
page status bits: 0x2,
DBCC execution completed. If DBCC printed error messages, see your System Administrator.
  5. Translate the object ID (objid) in the PAGE HEADER section of the output into a table name:
    use database_name
go
select object_name(9051068)
go
--------------
bad_table
  6. If an index is applicable, translate the index ID (indid) into an index name:
    use database_name
go
select name from sysindexes
where id = 9051068 and indid = 3
go
  7. To determine the index type, refer to the following table:
Index Id | Meaning
0 | Table data
1 | Clustered index
2 - 254 | Nonclustered index
255 | Text page

Because the DBCC PAGE output indicated that the indid is 3, the page belongs to a nonclustered index. (If the indid is 0, the page belongs to a table, and it does not belong to an index.)

  8. Disable trace flag 3604:
    dbcc traceoff(3604)


Dropping a Database When DROP DATABASE Fails

You can use the following procedure to drop a database if DROP DATABASE fails.

Caution Do not use this procedure unless directed to do so by your primary support provider or this manual, or unless there is no critical data in the database. Otherwise, you might damage your database.

To drop a database when DROP DATABASE fails
  1. Log in as sa.
  2. Check to be sure that the database has been marked suspect:
    select name from master..sysdatabases
where status & 256 = 256
  3. If the database is marked suspect, go to step 4. If it has not been marked suspect, mark the database suspect using either of the following methods:
    • Execute the sp_marksuspect stored procedure described in "Resetting the Suspect Status," later in this chapter.

    Or

    • Update the sysdatabases table manually as shown in the following example:
      sp_configure 'allow updates', 1
go

reconfigure with override
go

use master
go

begin tran
update sysdatabases set status = status | 256
where name = 'database_name'
go

      Verify that only one row was affected and commit the transaction:

      commit tran

      Then reset the allow updates option using sp_configure:

      sp_configure 'allow updates', 0
go

reconfigure with override
go

      Finally, restart SQL Server to initialize the change.

  4. Remove the database using DBCC DBREPAIR:
    dbcc dbrepair(database_name,dropdb)

    Note DBCC DBREPAIR sometimes displays an error message even though it successfully drops the database. If an error message appears, verify that the database has been removed by executing USE database_name. This should fail with a 911 error because you dropped the database. If any other error occurs, contact your primary support provider.


Creating Supplemental Stored Procedures

The following sections contain code for several useful stored procedures that you can add to your master database. Although these procedures can help you diagnose and recover from certain problems, keep in mind that these procedures are not part of the supported feature set. The performance and reliability of these stored procedures might not be at the level of the supported system procedures, and future compatibility or continued use is not assured.

Note The text of these stored procedures can be found in the INSTSUPL.SQL script installed in the \SQL60\INSTALL directory by the setup program.

For additional information about creating and using stored procedures, see the Microsoft SQL Server Transact-SQL Reference.


Gathering Information About Read/Write Errors

The sp_diskblock procedure shown below translates a SQL Server virtual disk and block number into the corresponding SQL Server device, database, and logical page number. This information can be useful for gathering information about read or write errors that SQL Server might encounter, such as the Read/Write Error described in Chapter 26, "System Messages."

Because the sp_diskblock procedure collects information from the system tables of the SQL Server on which it is executed, you must execute sp_diskblock on the SQL Server where the read/write error occurred.

Syntax

sp_diskblock virtual_disk, block_number

Example
sp_diskblock 0, 22

Virtual disk 0, block 22 corresponds to:
Logical page 18 in the "master" database
(dbid=1) on device "master".
Stored Procedure Code
CREATE PROC sp_diskblock @@disk int, @@block int AS
DECLARE @@low    int,
        @@dname  varchar(30),
        @@msg    varchar(90),
        @@lpage  int,
        @@dbid   int,
        @@segmap int

SELECT  @@low = low,  @@dname = name
    FROM master.dbo.sysdevices WHERE low/16777216 = @@disk

IF (@@low IS NULL)
    BEGIN
        SELECT @@msg = 'Virtual device '  CONVERT(varchar, @@disk)
          ' does not exist on this server.'
        PRINT @@msg
        RETURN (1)
    END
ELSE
    BEGIN
        SELECT  @@lpage = lstart  @@block  @@low - vstart,
            @@dbid = dbid, @@segmap = segmap
            FROM master.dbo.sysusages WHERE (@@block  @@low) >= vstart
            AND (@@block  @@low) <= (vstart  size)
        IF (@@dbid IS NULL)
            BEGIN
                SELECT @@msg = 'Block '  CONVERT(varchar, @@block)
                    ' on disk "'  @@dname
                     '" is currently not in use for any database.'
                PRINT @@msg
                RETURN (1)
            END
        ELSE
            BEGIN
                SELECT @@msg = "Virtual disk "  convert(varchar,@@disk)
                     ", block "  convert(varchar,@@block)
                     " corresponds to:"
                PRINT @@msg
                SELECT @@msg ='Logical page '  convert(varchar,@@lpage)
                     ' in the "'   DB_NAME(@@dbid)
                     '" database (dbid='   convert(varchar(3),@@dbid)
                     ') on device "'  @@dname  '".'
                PRINT @@msg
            END
    END
RETURN (0)

go


Resetting the Suspect Status

The sp_resetstatus procedure shown below turns off the suspect flag on a database but leaves all other database options intact.

Caution Use sp_resetstatus only when directed by your primary support provider or this manual. Otherwise, you might damage your database.

Because this procedure modifies the system tables, the system administrator must enable updates to the system tables before creating this procedure. To enable updates, use this procedure.

use master
go

sp_configure 'allow updates',1
go
reconfigure with override
go

After the procedure is created, immediately disable updates to the system tables.

sp_configure 'allow updates',0
go

reconfigure with override
go

The sp_resetstatus procedure can be executed only by the system administrator. Always shut down SQL Server immediately after executing this procedure.

Syntax

sp_resetstatus database_name

Example
sp_resetstatus PRODUCTION

Database 'PRODUCTION' status reset!
WARNING: You must reboot SQL Server prior to
         accessing this database!
Stored Procedure Code
CREATE PROC sp_resetstatus @dbname varchar(30) AS
DECLARE @msg varchar(80)
IF @@trancount > 0
        BEGIN
            PRINT "Can't run sp_resetstatus from within a transaction."
            RETURN (1)
        END
IF suser_id() != 1
        BEGIN
            SELECT @msg =  "You must be the System Administrator (SA)"
            SELECT @msg = @msg + " to execute this procedure."
            RETURN (1)
        END
IF (SELECT COUNT(*) FROM master..sysdatabases
            WHERE name = @dbname) != 1
        BEGIN
            SELECT @msg = "Database '" + @dbname + "' does not exist!"
            PRINT @msg
            RETURN (1)
        END
IF (SELECT COUNT(*) FROM master..sysdatabases
            WHERE name = @dbname AND status & 256 = 256) != 1
        BEGIN
            PRINT "sp_resetstatus can only be run on suspect databases."
            RETURN (1)
        END
BEGIN TRAN
        UPDATE master..sysdatabases SET status = status ^ 256
            WHERE name = @dbname
        IF @@error != 0 OR @@rowcount != 1
            ROLLBACK TRAN
        ELSE
            BEGIN
                COMMIT TRAN
                SELECT @msg = "Database '" + @dbname + "' status reset!"
                PRINT @msg
                PRINT " "
                PRINT "WARNING: You must reboot SQL Server prior to  "
                PRINT "         accessing this database!"
                PRINT " "
            END

go


Marking a Database Suspect

The sp_marksuspect procedure shown below turns on the suspect status bit on a particular database. Use this procedure to prepare a damaged database so that it can be dropped using DBCC DBREPAIR.

Because this procedure modifies system tables, the system administrator must enable updates to the system tables before creating the procedure. To enable updates, use this procedure.

use master
go

sp_configure 'allow updates',1
go

reconfigure with override
go

After the procedure is created, immediately disable updates to the system tables.

sp_configure 'allow updates',0
go

reconfigure with override
go
Syntax

sp_marksuspect database_name

Example
sp_marksuspect PRODUCTION

Database 'PRODUCTION' status reset!
WARNING: You must reboot SQL Server prior to
         accessing this database!
Stored Procedure Code
CREATE PROC sp_marksuspect @dbname varchar(30) AS
    DECLARE @msg     varchar(80)
    IF @@trancount > 0
        BEGIN
            PRINT "Can't run sp_marksuspect from within a transaction."
            RETURN (1)
        END
    IF suser_id() != 1
        BEGIN
            SELECT @msg = "You must be the System Administrator (SA) "
            SELECT @msg = @msg + "to execute this procedure."
            PRINT @msg
             RETURN (1)
        END
    IF (SELECT COUNT(*) FROM master..sysdatabases
             WHERE name = @dbname) != 1
         BEGIN
            SELECT @msg = "Database '" + @dbname + "' does not exist!"
            PRINT @msg
            RETURN (1)
        END
IF (SELECT COUNT(*) FROM master..sysdatabases
                WHERE name = @dbname and status & 256 = 256) = 1
        BEGIN
                SELECT @msg = "Database '" + @dbname + "' "
                SELECT @msg = @msg + "is already marked suspect."
                PRINT @msg
                RETURN (1)
        END

    BEGIN TRAN
        update master..sysdatabases set status = status | 256
            WHERE name = @dbname
    IF @@error != 0 or @@rowcount != 1 ROLLBACK TRAN
    ELSE
        BEGIN
            COMMIT TRAN
            SELECT @msg = "Database '" + @dbname + "' has been marked "                SELECT @msg = @msg + "suspect!"
            PRINT @msg
            PRINT " "
            SELECT @msg = "WARNING: This database should now be "
            SELECT @msg = @msg + "dropped via DBCC DBREPAIR."
            PRINT @msg
            PRINT " "
        END
go


Moving a Device

The sp_movedevice procedure shown below lets you specify a new physical path for a logical device. This is useful if a user's drive letters have changed, or when you want to move the device.

Syntax

sp_move device device_name, new_path

Stored Procedure Code
/****************************************************************/
PRINT "
PRINT 'Creating Stored Procedure: dbo.sp_movedevice'
PRINT 'Use this prior to moving the device or DB will be suspect'
/***************************************************************/
go
sp_configure "allow", 1
RECONFIGURE WITH OVERRIDE
go
IF EXISTS (SELECT * FROM sysobjects WHERE
    name = 'sp_movedevice' and type = 'P')
    DROP PROCEDURE sp_movedevice
go
CREATE PROCEDURE sp_movedevice @@devname varchar(30),
  @@newpath varchar (255)
AS
BEGIN
EXEC sp_configure "allow",1
RECONFIGURE WITH OVERRIDE
BEGIN TRAN
UPDATE sysdevices set phyname = @@newpath
WHERE name = @@devname
IF @@rowcount <> 1
BEGIN
PRINT "**********************ERROR**********************"
PRINT "Moved failed - more or less than one row affected"
PRINT "**********************ERROR**********************"
ROLLBACK TRAN
END
ELSE
BEGIN
PRINT "Device moved successfully"
PRINT "Change will take effect next time you start SQL Server"
COMMIT TRAN
END
EXEC sp_configure "allow",0
RECONFIGURE WITH OVERRIDE
END
go
sp_configure "allow",1
RECONFIGURE WITH OVERRIDE
go


Chapter 25 Handling Error Messages

Handling Error Messages

This chapter contains explanations and corrective actions for the many SQL Server error messages.

Most of the messages presented here include error numbers from the sysmessages table in the master database. Others, which can occur in the SQL Server error log but are not from sysmessages, do not have error numbers. The messages with numbers appear first, in numerical order, followed by the messages without numbers, in alphabetical order.


Variables in Error Message Text

The following variables appear in the error message text provided with the error message descriptions in this chapter:

Symbol | Meaning
%d, %ld, or %D | A decimal integer
%x | A hexadecimal number
%s or %.*s | A character string
%S_type | A SQL Server - defined structure
%c | A single character
%lf | A double floating-point number


Error 109

Severity Level 15

Message Text

There are more columns in the INSERT statement than values specified in the VALUES clause. The number of values in the VALUES clause must match the number of columns specified in the INSERT statement.

Explanation

This error occurs when more columns are listed in the INSERT statement than values specified in the VALUES clause. The number of values in the VALUES clause must match the number of columns specified in the INSERT statement.

Do not confuse this error 109 with operating-system error 109. Operating-system error 109 means that a named pipe connection has been terminated.

Action

Rewrite the insert statement, ensuring that the number of columns specified matches the number of columns in the VALUES clause. For example:

INSERT t1 (col1,col2,col3) VALUES (val1,val2,val3)


Error 137

Severity Level 15

Message Text

Must declare variable '%.*s'.

Explanation

This error occurs when variables that were declared outside of the EXECUTE statement are not available to the command being executed.

For example, this procedure will produce error 137:

declare @mystr char(50)
select @mystr="abc"
exec ("select @mystr")

Action

Rewrite the procedure so that it does not reference variables in the EXECUTE statement that were declared outside of it.


Error 170

Severity Level 15

Message Text

Line%d: Incorrect syntax near '%.*s'.

Explanation

This error occurs when a function has been entered as part of the EXECUTE statement.

For example, this procedure will produce error 170:

declare @myint int
select @myint = 5
exec ("select "+str(@myint))

Action

Construct the full string before passing it to the EXECUTE statement. The batch in the above example can be changed to the following which works correctly:

declare @mycmd char(50)
declare @myint int
select @myint=5
select @mycmd="select "+str(@myint)
exec (@mycmd)


Error 207

Severity Level 16

Message Text

Invalid column name '%.*s'.

Explanation

This error occurs when an invalid command string was passed to the EXECUTE statement.

Action

Use SELECT to check the string that was created for the EXECUTE statement. For example, if the following statement returns error 207:

EXECUTE("select "@mystr+"from mytable")

Evaluate the problem by looking at the full command, as follows:

SELECT "select "@mystr+"from mytable"


Error 208

Severity Level 16

Message Text

Invalid object name '%.*s'.

Explanation

This error occurs when an object that does not exist is referenced. If the object exists, you might need to include the owner's name in the object name.

If the object is not owned by the user attempting to access it, and it is not owned by the database owner (DBO), all references to the object must include the owner's name. For example, if user1 creates a table called test, other users must use the name user1.test when they refer to the table.

The SQL Server naming convention for database objects is:

[[database.]owner.]object_name.column_name

The default value for database is the current database. The default value for owner is the current user. Because owner is part of the object name, it is possible for two different users to have tables with the same name in the same database (for example, user1.test and user2.test). For additional information about naming conventions, see the Microsoft SQL Server Transact-SQL Reference.

This message can also occur when you reference a temporary table that was created with an EXECUTE statement.

Action

The procedure for handling this error depends on what you know about the object indicated in the error message text.

The appropriate permissions must also be set to allow access to an object. If these permissions are not set, error 229 or 230 occurs.

If you do not know who owns the object
  • Use the sp_help system procedure (with no parameters) to display the object owner.

Or

  • Query the sysobjects system table to determine the object owner and type.

For example, to determine the owner and type of the object, table_1, use the following:

select owner = user_name(uid), name, type
from sysobjects where name = 'table_1'

If no rows are returned from this query, the object either resides in a different database or does not exist.

If you do not own the object in question
  • Include the object owner in the object name. For example:
    select * from user1.table_1

    Although using fully qualified object names eliminates this problem, remember that including the fully qualified object name in an application might complicate the maintenance of the application. For example, if all references to a table include the database name, changing the database name could become difficult.

Or

  • Have the dbo create the object. If the DBO creates the object, any user can find the object without specifying the owner. Note, however, that temporary tables reside in tempdb and are automatically dropped when the user process or server connection that created them is terminated. Users cannot share temporary tables, even if they are created by the dbo.
If the object does not reside in the database
  • Move to the correct database. For example:
    use database_1

Or

  • Qualify the object name with the database name. For example:
    select * from database_1.user1.table_1

    If you own the object or if the object is owned by the dbo, the owner name is not needed. For example:

    select * from database_1..table_1
If a temporary table created with an EXECUTE statement is referenced
  • If you must use the EXECUTE statement to create a temporary table, create it as a global temporary table using the syntax ##tablename.


Error 232

Severity Level 16

Message Text

Arithmetic overflow error for type %s, value = %f.

Explanation

This error occurs when an attempt is made to place a value into a column or variable that cannot be represented by the datatype of the object into which it is being placed. This error prevents the operation from being completed. For example, if you attempt to place the number 32770 into a variable or column defined as type smallint, this error will occur because variables or columns of type smallint can address integers only from -32768 to 32767.

Note Do not confuse this error with operating-system error 232, which occurs when a named pipe connection is closed. Operating-system error 232 is a common communications error.

Action

For numeric operations, you can use the ROUND and CONVERT functions to manipulate the value in question to fit into the column or variable. You can change the datatype of the column or variable in question (for example, in the example described above, you could change the column or variable from smallint to int).


Error 259

Severity Level 15

Message Text

Ad-hoc updates to system catalogs not enabled. System Administrator must reconfigure system to allow this.

Explanation

This error occurs when SQL Server has detected an attempt to directly modify the system catalogs while the allow updates system configuration option is set to 0.

The allow updates system configuration option allows the system administrator to directly change the system catalogs.

Caution Severe problems can result from the direct manipulation of the system catalogs. Do not modify the system catalogs unless instructed to do so by your primary support provider.

Action

Before modifying any system catalogs, be sure that you have a valid backup of the database. For details on backup operations, see Chapter 12, "Backing Up and Restoring." Incorrect modification of the system catalogs can result in database corruption or data loss. Be sure to read all instructions carefully before attempting to alter any system catalog information.

If possible, restart SQL Server in single-user mode (/m) so that inadvertent modifications do not occur. For details, see Microsoft SQL Server Setup.

To modify system catalogs, use the isql command-line utility to perform the following steps. Only the system administrator can carry out this procedure.

  1. Execute the sp_configure system stored procedure and then the RECONFIGURE WITH OVERRIDE statement to alter the allow updates system configuration setting. You will not need to restart SQL Server for the allow updates option to take effect. Type the following:
    sp_configure 'allow updates', 1
go
RECONFIGURE WITH OVERRIDE
go
  2. Verify that the allow updates system configuration option has been successfully changed. Type:
    sp_configure 'allow updates'
go
Results
name    config_value    run_value
allow updates    1    1
  3. Make the specified changes to the system catalogs. It is always a good idea to use a begin transaction statement paired with a specific WHERE clause in your data modification statement to protect the system catalog data. For example:
    begin transaction
data modification statement,
including the specific WHERE clause
go

    Important Never modify the syslogs table directly. Modification causes a looping effect and will completely fill your database, possibly making it unusable in the future.

  4. Issue a select statement to double check that all data modification changes occurred as expected.
  5. If changes took place correctly, then commit the transaction. If data modification did not occur correctly, issue the ROLLBACK TRANSACTION statement to reverse the system catalog changes. Type:
    rollback transaction
go
  6. Be sure to reset the allow updates system configuration option so that system catalog updates are no longer allowed. Type:
    sp_configure 'allow updates', 0
go
RECONFIGURE WITH OVERRIDE
go
  7. Verify that the allow updates system configuration option has been successfully reset. Type:
    sp_configure 'allow updates'
go
    Results
name    config_value    run_value
allow updates    0    0


Error 268

Severity Level 16

Message Text

You can't run SELECT INTO in this database. Please check with the Database Owner.

Explanation

This error occurs when an attempt to use the select into statement has not been permitted because the select into/bulkcopy database option is not enabled for this database. The database owner must turn on the select into/bulkcopy database option before the select into statement can be completed successfully.

This error can also be triggered by stored procedures. For example, sp_help selects into temporary tables that belong in tempdb. If the select into/bulkcopy database option is not enabled for tempdb, this error will occur.

Note Enabling the select into/bulkcopy database option permits non-logged operations to take place. Use caution when enabling this option. You should have a specific backup strategy in place to ensure data integrity after non-logged operations have been performed. You cannot dump a transaction log after a non-logged operation. You must use the dump database statement after non-logged operations have been performed.

Action

The database owner or system administrator must use the sp_dboption system stored procedure to enable the select into/bulkcopy database option. For example, for the pubs database you would use the isql command-line utility to perform the following steps:

  1. Switch to the master database and set the database option for the pubs database. Type:
    use master
go
sp_dboption pubs, 'select into/bulkcopy', true
go
use pubs
go
checkpoint
go
  2. Verify that the change has taken place correctly. Execute the sp_helpdb system stored procedure on pubs. The status result column should show the select into/bulkcopy database option as enabled. Type:
    sp_helpdb pubs
go

You may want to review information about the bcp utility and select into statement. For details, see the and the Microsoft SQL Server Transact-SQL Reference. In some cases, bcp is a logged operation that can affect your backup strategy and transaction log dumping frequency.


Error 404

Severity Level 19

Message Text

Too many ANDs or ORs in expression (limit %d per expression level). Try splitting query or limiting ANDs and ORs.

Explanation

This error occurs when you use more than 250 AND or OR expressions in a query, or when you use more than 250 values in a where clause. For example, the following example WHERE clause(s) would result in an error:

select *
from tblTest
where strDataCol_1 = '1' and
strDataCol_2 = '2' and
strDataCol_n = 'n' and
.
.
.
strDataCol_251 = '251'

select *
from tblTest
where strDataCol in ('1', '2', ..., '251')

Action

You must restructure the query so that the limit is not exceeded. For example, you could restructure the second example above to perform a subquery or join operation, as shown here:

select *
FROM tblTest
WHERE strDataCol in (SELECT strDataCol FROM
tblTest Values)

SELECT tt.*
FROM tblTest tt, tblTestVals ttv
WHERE tt.strDataCol = ttv.strDataCol

SELECT *
FROM tblTest
WHERE strDataCol between 1 and 251

Where tblTestValues holds all the necessary values for the IN clause.

Be very careful as to how you restructure the query. Some operations can perform better than others. The first restructuring example could cause a subquery to be performed; the second restructuring example could cause the Cartesian product to be used to derive the results. For more information on query optimization, see the Microsoft SQL Server Database Developer's Companion.


Error 511

Severity Level 16

Message Text

Updated or inserted row is bigger than maximum size (%d bytes) allowed for this table.

Explanation

This error occurs when you attempt to insert a row that is larger than the maximum defined for that table, or when the definition for a temporary table referenced by a stored procedure is not as expected. This error occurs in the following situations:

  • The row you try to insert into a table is too big to fit into a data page.

    In SQL Server, the maximum allowable size of a row in a table is 1962. A row cannot be split across data pages. A data page is 2K in size and consists of the data row and some internal data structures.

  • If changes have been made to the model database.

    A stored procedure that uses temporary tables may be invalidated when a new object is added to the model database and SQL Server is shut down and restarted. When the tempdb database is rebuilt, the new object in the model database becomes an object in tempdb as well. This new object takes the object ID used by the stored procedure to reference the temporary table. If one new object in model is added, the stored procedure using temporary table(s) may be invalidated. If two objects are added, two references to temporary tables in stored procedures can be invalidated, and so on.

Action

If the definition for a temporary table referenced by a stored procedure is not as expected, drop and re-create the affected stored procedure. If the stored procedure involved is a system stored procedure, re-execute the installation scripts that will drop and re-create the affected system stored procedure.


Error 515

Severity Level 16

Message Text

Attempt to insert the value NULL into column '%.*s', table'%.*s'; column does not allow nulls. %s fails.

Explanation

This error occurs at run time when an attempt is made to use a null value when inserting or updating a column that does not allow null values.

Note This message differs from the following message, which indicates that the attempt has been detected at compile time.

error 232 : "The column "%*s in table %.*s may not be NULL."

This error can also occur if the table that is the target of an INSERT or UPDATE in a stored procedure or trigger is being dropped and re-created, and one or more of the table column definition(s) have changed from NULL to NOT NULL.

Action

If this error occurs when you are running an UPDATE or INSERT statement, verify that the data inserted or updated matches the column definition for the affected table.

Inserting or updating a column does not allow null values.

Note In a direct UPDATE or INSERT by value, you will get compile error 233 instead of error 515. Usually 515 errors occur in an insert/select or an update statement that uses data in another table.

If this error occurs when a stored procedure or trigger references a table that has been dropped and re-created with different nullability, drop and re-create the affected stored procedure or trigger.

If you are unable to resolve the problem, contact your primary support provider for assistance.


Error 544

Severity Level 16

Message Text

Attempting to insert explicit value for identity column in table '%.*s' when IDENTITY_INSERT is set to OFF

Explanation

This error occurs when you have attempted to insert a row that contains a specific identity value into a table that contains an identity column. However, the IDENTITY_INSERT property is not enabled for the specified table.

Action

To successfully insert a specific identity row into a table containing an identity column, you must enable the IDENTITY_INSERT option. The following example inserts identity row 2, where iID is defined as the identity column.

Table: tblTest

iID    strData
1    Jones
3    Smith

/* Enable IDENTITY_INSERT */
set IDENTITY_INSERT tblTest ON
go

/* Insert the specified identity row using a column list */
insert into tblTest (iID, strData) values (2, "Lambert")
go

/* Disable IDENTITY_INSERT */
set IDENTITY_INSERT tblTest OFF
go


Error 601

Severity Level 21

Message Text

Descriptor for system table '%Id' in database '%d' not found in the descriptor hash table.

Explanation

This error indicates that the in-memory structure used by SQL Server to access a system table has been reused. Usually, only user-table descriptors are reused; system table descriptors are always in memory.

Action

Shut down and restart SQL Server. Upon restarting, run DBCC CHECKDB, DBCC NEWALLOC, and DBCC CHECKCATALOG to verify that there are no structural problems in the database that may have led to this error.

Because the problem is with the in-memory structures, shutting down and restarting SQL Server will usually resolve the problem. If the problem persists contact your primary support provider. Have the full output from the DBCC CHECKDB, DBCC NEWALLOC, and DBCC CHECKCATALOG available for review.


Error 602

Severity Level 21

Message Text

Could not find row in Sysindexes for dbid '%d', object '%Id',index '%d'. Run DBCC CHECKTABLE on Sysindexes.

Explanation

This error occurs when SQL Server cannot find a row in the sysindexes table for a needed table or index (for example, when executing a stored procedure that references a table that has been dropped).

Action

If the error occurs because a stored procedure references a dropped table, drop and re-create the stored procedure.This error may also occur in conjunction with other error messages that better point to the root cause of the problem. Run DBCC CHECKTABLE on sysindexes; also run DBCC CHECKDB and DBCC NEWALLOC.

If the problem persists, contact your primary support provider. Have the output from the DBCC CHECKDB and DBCC NEWALLOC commands available for review.


Error 603

Severity Level 19

Message Text

There are not enough system session descriptors available to run this query. The maximum number available to a process is %d. Split query and rerun.

Explanation

This error occurs when the number of table descriptors available to a single query is limited. Complex queries can occasionally exceed this limit, especially if they are inside of a transaction.

Action

Split the query or stored procedure up into smaller parts, or increase the number of open objects with the sp_configure system stored procedure.

Occasionally, this error can be a sign that the overall system is running out of table descriptors. This limit is set by the open objects parameter to sp_configure and should be increased as appropriate.

At server startup, SQL Server builds a pool of descriptor data structures in memory that will be used to describe database objects as they are referenced. The number of descriptors built is equal to sp_configure 'open objects'. Each time a database object is referenced for the first time, SQL Server takes one of the descriptors from this free pool and allocates it to the specific object.

If multiple tasks reference the same object at the same time, it is still considered on open object. For example, if two tasks issue the following command at the same time only one descriptor is allocated to table_a, and this is considered one open object:

UPDATE table_a set cola = @variable

If, however, table_a had an update trigger, a second descriptor would be allocated to the trigger, which would count as a second open object.

Each allocated descriptor has a use counter that indicates how many concurrent queries are referencing the object it defines. The use count is increased by 1 at the start of a query, and decreased by 1 at the end of the query. In the example above, the table_a descriptor would have a use count of 2 until the two queries finished; it would then be decreased to 0.

Once the free pool of descriptors has been used up, SQL Server starts reusing inactive descriptors when it needs to allocate a new descriptor. An inactive descriptor is one with a use count of 0. The first time SQL Server has to reuse a descriptor, it will issue the following message in the error log:

Warning: OPEN OBJECTS parameter may be too low; attempt was made to free up descriptors in localsdes().
Run sp_configure to increase parameter value.

SQL Server repeats this message after each 1000 times it reuses a descriptor. If you notice these messages being issued frequently in the error log, increase the sp_configure system stored procedure's open objects parameter.

If this error is associated with other errors or is not resolved by increasing the number of "open objects, " contact your primary support provider. Be sure to have the SQL Server error log and the output from sp_configure available for review.


Error 605

Severity Level 21

Message Text

Attempt to fetch logical page %ld in database '%.*s' belongs to object '%.*s', not to object '%.*s'.

Explanation

This fatal error occurs when SQL Server detects database corruption. The second object specified in the text not to object '%.*s' is probably corrupt. Because this error can mask the existence of other errors, you must run dbcc to determine the extent of the damage. If dbcc checkdb and dbcc checkalloc do not report additional errors, the first object mentioned is not corrupt.

SQL Server detects database corruption when it traverses the page chain of an object and finds a page in the chain whose object ID does not match that of the object being accessed. There is probably either a damaged page chain or an invalid entry in the sysobjects system table for that object. There is one doubly-linked page chain for the table data as well as one for each index level.

Although error 605 normally displays two object names, other variations can occur:

  • If instead of an object name the error displays a number greater than 0, it means that an attempt was made to reference an object ID that does not exist in a system table for that object.
  • If the error reports the first object ID as 0, an unallocated page was probably encountered. (There is no object ID equal to 0.)
  • If the error states that a page belongs to object ALLOCATION, some of the allocation structures used by the database might be corrupted.

Usually this error occurs after the corruption has been written to the database on disk, but it can also occur entirely in cache without the damage ever being written to disk. This is known as a transient 605 error and is not associated with data corruption. If error 605 occurs during data access, but subsequent dbcc checkdb and dbcc checkalloc statements complete without error, the 605 error was probably transient. Transient 605 errors can be caused by the operating system prematurely notifying SQL Server that an I/O operation has completed; the error message is displayed even though no actual data corruption exists.

Non-transient 605 errors are often caused by hardware or disk device driver failure.

Action

Run the dbcc checktable statement on the second object specified in the error message. To determine the full extent of the corruption, run the dbcc checkdb and dbcc checkalloc statements as soon as possible. Also check the error log for other errors, which often accompany a 605 error. For information about using DBCC, see the Microsoft SQL Server Transact-SQL Reference.

If the 605 error is not transient, the problem is severe and you will probably need to restore from a known clean backup. If the problem persists, contact your primary support provider. Have the output from the appropriate DBCC statements ready for review.

In addition, run hardware diagnostics and correct any problems. You might find it beneficial to perform a completely new setup on the computer, including reformatting the disk drives and reinstalling the operating system. This eliminates the possibility that a .DLL or .EXE program is corrupted. You can also examine your operating-system error log to see if the error occurred as the result of hardware failure.

Finally, be sure that your system does not have write caching enabled on the disk controller. If you suspect this to be the problem, contact your hardware vendor.

Additional Information

Recovering from a data corruption problem using any technique other than restoring the database from a known clean backup is unreliable at best. As a helpful analogy, consider the problem of cross-linked clusters that sometimes occurs in the MS-DOS FAT file system. Understanding the meaning and implications of this problem requires a comprehensive understanding of the FAT file system and its associated data structures. Under some circumstances, a proficient user might be able to use a disk editor to patch the disk structure; however, this would require a great investment in time and, in most cases, the results would be unreliable, especially if the data is not text.

Because SQL Server data structures are more complex than those associated with the MS-DOS FAT file system, they are even more difficult to patch. As recommended earlier, the best recovery for data corruption is to restore from known clean backups and to call your primary support provider if problems persist.

You can prevent problems by following these guidelines:

  1. Run SQL Server only on hardware and controllers that are certified for your operating system.
  2. Perform regular backups in conjunction with DBCC CHECKALLOC and DBCC CHECKDB. This is the only way to be confident of the state of the database at the time of the backup.
  3. If the data is critical, frequently dump the transaction log. This makes it possible to reduce your window of vulnerability ¾ even in the event of a catastrophic hardware problem ¾ to an hour or less.
  4. In the most critical situations, use a "hot standby" computer and a continually running batch job to take transaction dumps off of the primary computer and continually restore them on the standby computer.
  5. If you have persistent data corruption problems, try to swap the computer, the controllers, and the disk device drivers for components of a different type. This makes it easier to determine whether the problem is platform-specific.


Error 614

Severity Level 21

Message Text

A row on page %Id was accessed that has an illegal length of %d in database '%.*s'.

Explanation

This error occurs when an attempt is made to access a row on a page and the actual length of the row is greater than expected. The error indicates that there is a structural problem on the database page accessed during a read or write operation, and it involves a specific row from that page.

This structural problem can occur as a result of the following:

  • Hardware problem related to but not limited to the hard drive, controller, or the controller's implementation of write caching
  • A structural problem determined when loading a database dump; it may indicate a integrity problem with the database dump file

Action

If the problem occurred after a load, check the sysusages system table and make sure that the database you created has the same fragments and segmaps in sysusages as the database that generated that dump. If not, drop the database, re-create it with correct fragments and segmaps, and then reload the database.

If the error is not associated with a database load operation, run DBCC CHECKDB and DBCC NEWALLOC to determine the full extent of the structural problems in the database. Examine the output from these commands; if the DBCC statements reveal other structural problems in the database, resolve those first.

If there are no other errors, examine the page referenced in the error message to determine which table is damaged. (For more information about associating a page with an object, see Chapter 24, "Additional Problem Solving Techniques.") If the page is associated with an index, it is sometimes possible to resolve the problem by dropping the index and re-creating it. If the page is a data page and a clean current backup is available, recover the database from that backup.

If no backup is available, try to select the table into another table or bulk copy the data out of the table, drop the table, re-create it, and then select the data back in.

If this error occurred during recovery, the syslogs table is corrupted. The database will be marked as suspect. Recover it from a clean backup. If the page was found to be associated with syslogs, use:

DUMP TRAN with no_log

Although this may resolve the problem, be sure to also run DBCC CHECKDB and DBCC NEWALLOC. Review the output; if there are no structural problems, immediately dump the database.

If you suspect a hardware problem, run available hardware diagnostics and disable write caching if it is enabled on the controller. Contact your hardware vendor for problems reported in the diagnostics and for persistent read/write problems. Verify with the vendor that the hardware-specific HAL layer components are current and at the recommended levels.


Error 624

Severity Level 24

Message Text

Attempt to retrieve row from page via RID failed because the requested RID has a higher number than the last RID on the page. %S_RID.%S_PAGE.

Explanation

This error occurs when an attempt to retrieve a row from a data page by specifying the row ID (RID) failed because the requested RID was a higher number than the last RID on the page. This can happen:

  • During normal processing, if the leaf page of a corrupt nonclustered index points to an incorrect or nonexistent RID on a data page.
  • During database recovery, if the data structure that contains the last checkpoint record in the transaction log points to an incorrect or nonexistent record in the log. The database recovery process occurs during startup and when a load database statement executes.

If the error occurs on a system table during a read-only operation while other users are updating system tables (executing DDL), it is probably a transient 624 error (rather than a corrupted index). To confirm that there is no corruption, run DBCC CHECKTABLE.

Action

The recovery procedure depends on when the error occurred. If problems persist, the following procedures might not be sufficient to clean up the index corruption. In this case, contact your primary support provider. Have the output from the appropriate DBCC statements available for review.

If the error occurred during normal processing

For instructions on using the dbcc page statement to determine the table involved, see "Associating a Page with an Object" in Chapter 24, "Additional Problem-solving Techniques." Save this information and use it in the appropriate section below.

The specific action you take depends on whether or not you know which index and/or query caused the problem. In general, dropping and re-creating the index should resolve the index corruption.

Index unknown, query known

If you do not know which index is causing the problem but you do know which query encounters the problem, follow the instructions below. If you don't know the index or the query, follow the instructions under the next section, "Index and query both unknown."

  1. Determine which index should be dropped by reading the showplan output for the query that encounters the error. If you set SHOWPLAN on, set NO EXECUTE on, and then run the query in question, the output will indicate which nonclustered index the query is using to access the table in question.

    For example:

    set showplan on
go
set noexec on
go
select title from titles where title > "Cooking"
go
STEP 1
The type of query is SELECT
FROM TABLE
titles
Nested iteration
Index: titleind
  2. Set NOEXEC off and showplan off again:
    set noexec off
go
set showplan off
go
  3. Drop and re-create the index identified in step 1 (in this example, titleind).
Index and query both unknown

If you do not know the index or the query, rebuild all nonclustered indexes on the table as follows:

  1. Look at the output you created with dbcc page when you obtained the table name:
    • If the object ID is less than 100, you cannot drop and re-create the indexes. Do not continue with steps 2 or 3. You must restore the database from a known clean backup.
    • If the object ID is 100 or greater, continue with step 2.
  2. Use sp_helpindex to list all indexes on the table, and then rebuild all the nonclustered indexes using one of the following methods:
    • Drop and re-create each nonclustered index on the table.
    • If the table has a clustered index, drop and re-create it. This causes all nonclustered indexes to be rebuilt automatically. If your table is large, you might not have the space to do this. Generally, 120 percent of your table size must be available.
  3. After the appropriate index has been re-created, run dbcc checktable on the table to confirm that the problem has been resolved.
If the error occurred during database recovery

When this error occurs during recovery, the database is marked "suspect" and is not accessible. In this case, you usually need to load the database from a known clean backup, as follows:

  1. Drop the suspect database using the instructions in Chapter 24, "Additional Problem-solving Techniques."
  2. Create a database to receive the load using the CREATE DATABASE statement.
  3. Load the database from a backup using the load database statement.

For information about using the CREATE DATABASE and LOAD DATABASE statements, see the Microsoft SQL Server Transact-SQL Reference.


Error 625

Severity Level 21

Message Text

Could not retrieve row from logical page %Id via RID because the entry in the offset table (=%d) for that RID (=%d) is less than or equal to 0.

Explanation

This error occurs when an object to which this row belongs is corrupt. The corruption was detected during the reading of a specific row from that logical page. This corruption can occur as a result of:

  • Hardware problems, especially, problems with the hard drive, controller or hardware write caching
  • Other corruption in the database

Action

Run DBCC CHECKDB and DBCC NEWALLOC to determine the full extent of the corruption. Also check the error log for other errors such as 25xx messages, which often accompany this error.

If DBCC commands issue other corruption messages, resolve those messages first; that may take care of this error. If it doesn't, determine which table is corrupt by examining the page in the error message. For additional information about associating a page with an object, see Chapter 24, "Additional Problem-solving Techniques." If the page is associated with an index, you may be able to resolve the problem by dropping and then re-creating the index. If the page is a data page and a clean current backup is available, restore the database from the backup.

If no backup is available, try to select the table into another table or bulk copy data out of the table, drop the table, re-create it, and then select data back in.

If this error occurs during recovery, it indicates that the syslogs table is corrupted. The database will be marked as suspect. Restore the database from a clean backup. If the page was found to be associated with syslogs, running the dump tran with no_log statement may resolve this problem; then run DBCC checkdb and dbcc newalloc. If the database is clean, dump the database immediately.

If you suspect a hardware problem, run hardware diagnostics and correct any problems. You might find it beneficial to perform a completely new setup, including reformatting the disk drives and reinstalling the operating system. This eliminates the possibility that a .dll or .exe program is corrupted. Also examine the Windows NT event log to see if the error occurred as the result of hardware failure.

Finally, be sure that your system does not have write caching enabled on the disk controller. If you suspect this to be the problem, contact your hardware vendor.


Error 632

Severity Level 20

Message Text

Memmove() was called with a length of %d - maximum allowed length is 2048.

Explanation

SQL Server detects an internal error caused by possible inconsistencies in a database or as a result of a system layer or configuration problem.

Important This error may be an indication of a more serious error and should be addressed immediately.

Action

Stop and restart SQL Server.

Verify the consistency of your databases by running DBCC CHECKDB and DBCC NEWALLOC.

Review your SQL Server error logs.

Review the Windows NT event log to determine if hardware errors might have caused the problem. If you suspect a hardware problem, run appropriate hardware diagnostics procedures. Make sure to review all your system-level components, such as SCSI termination, disk controller firmware revisions, appropriate disk device drivers, and so on. Also check with your hardware vendor to make sure you run appropriate hardware diagnostics.

If you are unable to resolve this problem, contact your primary support provider for assistance.


Error 644

Severity Level 21

Message Text

The non_clustered leaf row entry for page %ld row %d was not found in index page %ld indexid %d database '%.*s'

Explanation

This error occurs when the nonclustered index indicated by indexid is corrupt. The corruption is detected when a process tries to delete a nonexistent row.

Action

Drop and re-create the index, as follows:

  1. Record the value of index page and indexid specified in the error text.
  2. Identify which table and index correspond to the index page number. Use the instructions in "Associating a Page with an Object," in Chapter 24, "Additional Problem-solving Techniques."
  3. Note the object ID.

    If the object with the error is a system table (the object ID is less than 100), you cannot drop the index. Restore the database from a known clean backup.

  4. If the object ID is greater than 100, drop and re-create the index using the table name and index name obtained in step 1. In most cases, this will clear the corruption.
  5. Run dbcc checktable and dbcc CHECKALLOC on the affected table to verify that all problems have been resolved. For information about using DBCC, see the Microsoft SQL Server Transact-SQL Reference.

If problems persist, this procedure might not be sufficient to clean up the index corruption. In this case, contact your primary support provider. Have the output from the appropriate DBCC statements available for review.


Error 701

Severity Level 19

Message Text

There is insufficient system memory to run this query.

Explanation

This error occurs when there is not enough procedure cache available to execute a stored procedure, trigger, or batch of one or more SQL statements. This can happen when trying to load a query plan into the procedure cache or when trying to resolve or compile a procedure, trigger, or batch. (For information about resolution, see "Resolution" in Chapter 21, "Configuration Issues.")

Because the amount of available procedure cache is based on SQL Server use, this error might occur intermittently as procedure cache is used and released. Because query plans vary greatly in size, one or more procedures can repeatedly fail with this error while others complete normally. Although there might not be sufficient space to load a large query plan, several smaller plans might fit.

Action

Increase the size of the procedure cache using one of the following methods:

  • Use the memory configuration option of sp_configure to increase the total amount of memory requested by SQL Server.
  • Use the procedure cache configuration option of sp_configure to increase the percentage of total cache space dedicated to procedure cache.
  • Decrease the amount of memory required for other resources, for example, unnecessary user connections.

Increasing the memory option for SQL Server is the most straightforward method to resolve this error. Although it increases both the procedure and data caches, it can also waste memory. If your memory resources are limited, you can increase the procedure cache option for SQL Server without changing the value of the memory option. However, this shifts space from the data cache to the procedure cache and might result in performance degradation or other problems if not enough data cache remains.

You can also increase the size of the procedure cache without substantially changing the amount of data cache. This requires some combination of increasing both the memory and procedure cache parameters in such a way that the majority of the new memory goes to the procedure cache. Although this method requires more planning, it allows you to control where the additional memory goes. For more information about increasing the size of the procedure cache, see Chapter 21, "Configuration Issues."

To view current memory usage information in preparation for tuning memory configuration, use the DBCC MEMUSAGE statement, as described in Chapter 21, "Configuration Issues."


Error 707

Severity Level 20

Message Text

System error detected during attempt to free memory at address 0x%1x. Please consult the SQL Server error log for more details.

Explanation

SQL Server detects an internal memory error possibility caused by a system layer problem.

Action

Stop and restart SQL Server.

Verify the consistency of your databases by running DBCC CHECKDB and DBCC NEWALLOC.

Review your SQL Server error logs.

Review the Windows NT event log to determine if hardware errors might have caused the problem. If you suspect a hardware problem, run appropriate hardware diagnostics procedures. Make sure to review all your system-level components, such as SCSI termination, disk controller firmware revisions, appropriate disk device drivers and so on. Also check with your hardware vendor to make sure you run appropriate hardware diagnostics.

This error could be related to your memory configuration. Make sure the SQL Server has been configured to allocate the recommended amount of memory. Verify this by running the sp_configure system stored procedure with no parameters.


Error 801

Severity Level 20

Message Text

Process %d tried to remove resource lock it doesn't hold on buffer 0x%1x - %S_PAGE.

Explanation

This error occurs when a SQL Server process attempts to unlock a resource that is not currently locked.

Note This error is not usually indicative of data loss, but it can be accompanied by other, more serious, errors.

Action

Address other errors if they exist, especially if problems are reported by DBCC CHECKDB or DBCC NEWALLOC. If this error still persists, contact your primary support provider.

Restarting SQL Server can often clear up this error, but may not help in determining the cause of the problem.

If this error occurs on its own, contact your primary support provider, and have the output from all SQL Server error logs, from DBCC CHECKDB and DBCC NEWALLOC, from sp_configure and xp_msver, and information about the server hardware configuration available for review.


Error 803

Severity Level 20

Message Text

Unable to place buffer 0x%lx holding logical page %ld in sdes for object '%.*s'¾either there is no room in sdes or buffer already in requested slot.

Explanation

Under certain rare circumstances, a select-based insert of the following form:

insert into tblDestinationData
select tblSourceData.* from tblSourceData

on a table with two or more nonclustered indexes can result in an 803 session descriptors (sdes) error condition. This error is dependent on the data in the indexes at the time the operation was attempted.

Action

This condition can generally be corrected by dropping all nonclustered indexes in the table, and then retrying the option. If the action succeeds, the indexes can then be re-created.


Error 806

Severity Level 21

Message Text

Could not find virtual page for logical page %Id in database '%.*s'

Explanation

This error occurs when SQL Server does not have a virtual page that maps to logical page %Id in database '%s.' SQL Server maps virtual pages to logical pages within a database. The logical pages of the database will range from 0 to the size of the database, in pages.

This error can be caused by hardware or other system-level problems that deal specifically with read/write operations.

Action

Although some newer controllers safely support write caching, there may be a problem with the HAL layer software or with controller firmware. Verify with your hardware vendor that the disk subsystem being used by SQL Server is at currently supported and recommended levels. Check the SQL Server error log for system errors, such as an operating-system I/O error to a SQL Server data file. Also check the Windows NT event log.

Run DBCC CHECKDB and DBCC CHECKALLOC on the database. Review the output; if structural problems are reported, resolve the problem(s) and monitor the system. If the structural problems persist, contact your hardware vendor and your primary support provider.


Error 813

Severity Level 20

Message Text

Logical page 0x%1x in database %d is already hashed.

Explanation

This error occurs when SQL Server attempts to hash logical page 0x%Id of database %d and the page is already in SQL Server's hash table.

This error usually occurs as a side effect of other data corruption that can usually be detected by running DBCC NEWALLOC and DBCC CHECKDB.

Action

Review the SQL Server error log, and then execute the DBCC CHECKDB and DBCC NEWALLOC statements on the database. This error may be associated with errors 1203 and 2521. Focus on these errors first; investigate their cause and correct them.

Verify with your hardware vendor that the disk subsystem being used by SQL Server is at the currently supported and recommended firmware and hardware level.

If DBCC CHECKDB and DBCC NEWALLOC find no errors, or if errors are found and corrected so that subsequent DBCC statements indicate no errors, but this error reoccurs, call your primary support provider. Have the SQL Server error logs and the output from DBCC CHECKDB, DBCC NEWALLOC, and sp_configure, available for review.


Error 815

Severity Level 21

Message Text

Unable to find buffer holding Sysindexes page in the cache - pageno = %1d dbid = %d

Explanation

This error occurs when SQL Server cannot find the structure that determines where a particular page of the sysindexes system table is cached in memory.

The occurrence of this error may indicate other structural issues in the database referenced by the dbid value in the referenced text. Determine the database being referenced. Use:

SELECT db_name(dbid)

Action

If the database referenced is tempd, shut down and restart SQL Server.

If this error occurs frequently or in a user database, execute DBCC CHECKDB and DBCC NEWALLOC. Contact your primary support provider and have the results from the DBCC CHECKDB and DBCC NEWALLOC, as well as the SQL Server error log available for review.


Error 822

Severity Level 20

Message Text

Could not start I/O for request %S_BLKIOPTR

Explanation

SQL Server encountered an error while attempting to initiate a read or write request. This error can occur for any of the following reasons:

  • A database device is off-line.
  • A database device has been removed or renamed.
  • A database device is inaccessible for another reason (such as insufficient permissions).

The parameter in the error message refers to an internal structure and does not help determine which database device or file is involved. However, other error messages appearing in the error log just before error 822 usually indicate the device involved.

Action

Examine the availability and condition of the device involved using your standard operating-system procedures, and be sure the device is accessible.

Because error 822 marks the database as "suspect," SQL Server cannot recover the database upon restarting. If you know that the database was marked suspect because the device was unavailable, you can reset the status of the database to allow recovery to continue.

Caution Do not use these procedures if there are other errors in the error log, near the error 822 message, that suggest that the database might have been marked suspect for some other reason.

Reset the suspect status using one of the following procedures:

  • Execute the sp_resetstatus procedure as described in Chapter 24, "Additional Problem-solving Techniques." This is the safest method. After you execute sp_resetstatus, restart SQL Server.

Or

  • Use the following procedure on the suspect database:
    1. Reset the suspect status, as follows:
      sp_configure 'allow updates', 1
go

reconfigure with override
go

use master
go

begin tran
go

update sysdatabases
set status=0 where name='database_name'
go

      When you reset the suspect status using this procedure, all options on the database are reset to their default values. (Using sp_resetstatus leaves these options intact.)

    2. Use sp_dboption to reestablish the options after you complete this procedure. (For additional information, see the Microsoft SQL Server Transact-SQL Reference.)
    3. If only one row is affected by the UPDATE statement, continue with these instructions. If more than one row is affected by the UPDATE statement, roll back the transaction and find out why other rows are being affected.
    4. If the above statements affect only one row, use the following statements to commit the transaction, disable updates to the system tables, issue a checkpoint, and shut down SQL Server:
      commit tran
go

sp_configure 'allow updates', 0
go

reconfigure with override
go

checkpoint
go

shutdown
go
    5. Restart SQL Server.
    6. If the database is marked suspect again, examine the error log for indications of other errors. If the database is not marked suspect, use sp_dboption to restore database options that might have been reset when you reset the status in the first step of this procedure.

Here are two examples of error 822 and the associated messages from the log. Examining the error messages that occurred just before error 822 usually helps determine the type of problem.

Device missing

In this example, the device C:\SQL60\DATA\DEVICE.DAT (corresponding to virtual device 6) did not exist when SQL Server started, causing access to the device to fail:

kernel: initializing virtual device 6, "c:\sql60\data\device.dat"
kernel: dopen: open "c:\sql60\data\device.dat", No such file or directory
kernel: dinit: failed to open primary device c:\sql60\data\device.dat for
        vdn 6
kernel: udstartio: vdn 6 has not been set up
server: Error: 822, Severity: 20, State: 3
server: Could not start I/O for request BLKIO ....

To correct an error like this, be sure that the virtual device appearing in the error message exists, and correct whatever error prevented SQL Server from finding it. For example, it might have been renamed or moved while SQL Server was not running.

If the virtual device no longer exists, you must restore from known clean backups. Merely creating an empty device with the correct name will not solve this problem.

Permission problems

Permission problems can occur if the device is on an NTFS partition.

In this example, the permissions on C:\SQL60\DATA\DEVICE.DAT (virtual device 6) were incorrect, so SQL Server could not access it:

kernel: initializing virtual device 6, "c:\sql60\data\device.dat"
kernel: dopen: open "c:\sql60\data\device.dat", Permission denied
kernel: dinit: failed to open primary device c:\sql60\data\device.dat for
        vdn 6
kernel: udstartio: vdn 6 has not been set up
server: Error: 822, Severity: 20, State: 3
server: Could not start I/O for request BLKIO ....

To correct an error like this, change the object ownership for the device to Administrator, and be sure that the account that SQL Server was started under has read and write permissions on the object.


Error 823

Severity Level 24

Message Text

I/O error detected during %S_MSG for %S_BUF

Explanation

SQL Server encountered an I/O error on a read or write request made to a device. This error usually indicates disk problems. The parameters in the error message refer to internal structures and don't often help determine which device is involved. However, additional kernel messages in the error log, recorded before error 823, should indicate which device is involved.

Action

Check the accessibility and condition of the device in question. After you have identified and corrected the problem, run dbcc checkdb and dbcc checkalloc to ensure that no other damage was caused by the bad device. For information about using DBCC, see the Microsoft SQL Server Transact-SQL Reference.

In addition, run hardware diagnostics and correct any problems.


Error 911

Severity Level 16

Message Text

Attempt to locate entry in Sysdatabases for database '%.*s' by name failed¾no entry found under that name. Make sure that name is entered properly.

Explanation

This error occurs when attempting to use (with the USE statement) a database that does not exist or when the default database set up for a login does not exist. In the latter case, the user login then attempts to access the master database.

Action

You may want to obtain a list of databases by using the sp_helpdb system stored procedure, or by issuing the following command:

SELECT name from master..sysdatabases

The list returned will contain the databases that exist on the SQL Server. You must create a missing database or connect to an existing one. You might also need to use the sp_defaultdb system stored procedure to correct login-level errors.


Error 913

Severity Level 22

Message Text

Could not find row in Sysdatabases with database id %d. Run DBCC CHECKTABLE on Sysdatabases.

Explanation

This error can occur if there is a problem with the view resolution process. During execution of various compiled objects in a database that reference the database dbid (such as stored procedures and views), it is a normal process to resolve the dbid with other structures within the database. When a compiled object is first created, the dbid where the object is located is embedded in the compiled code. For example, when a view is accessed or a stored procedure is executed, the rights to access the view or execute the stored procedure are checked.

Action

If the error occurs when a stored procedure or view is accessed, you may be able to correct the problem by simply dropping and re-creating the database object (stored procedure or view).

If this error continues to occur, contact your primary support provider and have the SQL Server error log and any additional information relevant to the circumstances when the error occurred available for review.


Error 924

Severity Level 14

Message Text

Database '%.*s' is already open and can only have one user at a time.

Explanation

This error occurs when trying to access a database that is already in use by another user or session. SQL Server detected an attempt to access a database that is in single-user mode.

Action

Verify that the database in question is actually in single-user mode. Do this by executing the following Transact-SQL statement:

sp_helpdb database
go

If the database is truly in single-user mode, the status result column will list single user as the access mode.

To see what login is accessing the database, you can execute an sp_who system procedure and scan the database name result column for the specified database.

If single-user mode privilege is a problem, you might need to contact your system administrator and ask to have the database's option set to multi-user. The system administrator can do so by using the sp_dboption system stored procedure from the master database, as shown here:

sp_dboption database, 'single user', false


Error 926

Severity Level 14

Message Text

Database '%.*s' cannot be opened - it has been marked SUSPECT by recovery. The SA can drop the database with DBCC.

Explanation

This informational message occurs when an attempt to open or use a database that has a sysdatabase status column value greater than or equal to 256 and less than 1024 occurs.

The database is marked as suspect because it failed the recovery process that brings a database to a consistent transactional state during startup or during the load database or load transaction procedures.

Action

Inspect the SQL Server error log and determine the cause of the error. If SQL Server has been restarted since the failed recovery, look at previous SQL Server error logs to see the reason why recovery failed. Correct the underlying problem. If you are unable to resolve this problem, contact your primary support provider. Have the SQL Server error log available for review.


Error 933

Severity Level 22

Message Text

Logical page %1d of the log encountered while retrieving highest timestamp in database '%.*s' is not the last page of the log and we are not currently recovering that database.

Explanation

This error occurs when SQL Server retrieved the highest timestamp and found that it was not on the last log page. This indicates that the log was damaged and recovery cannot proceed. During recovery, when SQL Server first opens a database, it must retrieve the highest timestamp value from the last log page. The highest timestamp value should also be on the last page in the log, because log pages are written in succession and each one receives a higher timestamp than the previous one.

Action

This problem can be caused by loading a damaged or truncated dump file. If it happens during a database load, the dump file is probably damaged and you will need to re-dump the original database, and then retry the load. If the file was copied across a network, it may have been damaged during the copy. Always verify the copy (use copy/v or xcopy/v) when you copy database dump files across the network. For maximum reliability, compare the original and copied dump file using FC/B.


Error 1002

Severity Level 16

Message Text

Line %d: Specified scale %d is invalid.

Explanation

This error occurs when the scale of a decimal or numeric column does not fall between the allowable minimum and maximum values based on the precision of the column.

Action

Specify the precision with p, which must be between 1 and the maximum precision, and the scale with s, which must be between 0 and p. If you do not specify the precision, SQL Server uses a default precision of 18. If you do not specify the scale, SQL Server uses a default scale of 0. For details, see the Microsoft SQL Server Transact-SQL Reference.


Error 1105

Severity Level 17

Message Text

Can't allocate space for object '%.*s' in database '%.*s' because the '%.*s' segment is full. If you ran out of space in Syslogs, dump the transaction log. Otherwise, use ALTER DATABASE or sp_extendsegment to increase the size of the segment.

Explanation

This error occurs when SQL Server is unable to allocate space for a database. The object ID of the object identified in the message text indicates what type of space could not be allocated:

  • If the object ID is not 8, data space could not be allocated.
  • If the object ID is 8, log space could not be allocated.

These errors are written to the error log only when they occur during the checkpoint process. When a user process encounters this error, the message is returned to the client application without being written to the error log.

Action

Use one of the following procedures to correct the error, depending on whether the error occurred during run time or recovery.

Run-time 1105 errors

The specific action you take on a run-time 1105 error depends on the object ID.

Object ID ¹ 8 In this case, the message indicates that the data segment is full on the database indicated in the message. To obtain more data space, do one or more of the following:

  • Use alter database to increase the size of the data segment.
  • Drop objects from the database.
  • Delete rows from tables in the database.

Object ID = 8 In this case, the message indicates that the log segment is full on the database indicated in the message. To clear space in the log, follow these steps:

  1. Determine how many rows are in the syslogs table, as follows:
    use database_name
go
select count(*) from syslogs
go
  2. Dump the inactive portion of the transaction log using the dump transaction statement. If this statement fails with the 1105 error, retry the statement using the with no_log option.
  3. Repeat step 1. If the number of rows in syslogs has decreased significantly, proceed to step 4. If not, an outstanding transaction is probably preventing the log from being cleared. If this is the case, restart SQL Server and repeat step 2.

    When SQL Server starts and the database is recovered, the outstanding transaction is rolled back, allowing the log to be cleared by a subsequent dump transaction statement. For information about managing the transaction log, see Chapter 4, "Transaction Log Management."

  4. If the dump transaction statement was executed using either the no_log option or the truncate_only option in step 2, dump the database now, because these options prevent subsequent changes recorded in the log from being used to recover from a media failure. You must run dump database to ensure the recoverability of subsequent database modifications.

    Note The database dump is not required if your environment does not save transaction logs for media failure recovery.

    Do not assume that the occurence of error 1105 means that your transaction log is too small. If the data and the log are on the same segment, the actions described above can often free enough space without requiring you to increase the size of the transaction log.

    If you are concerned that your transaction log is too small, read Chapter 4, "Transaction Log Management," before increasing the transaction log size. For information about using the alter database statement to increase log size, see the Microsoft SQL Server Transact-SQL Reference.

Recovery 1105 errors

The specific action you take on a recovery 1105 error depends on which type of database it occurs on.

On a user database If error 1105 occurs on a user database during recovery, correct the problem using the following procedure:

  1. Use the sp_dboption system procedure to note the current user options on the database (so you can reset them in step 7).
  2. Manually set the database status to no chkpt on recovery (status bit 16) and single user (status bit 4096) by adding the two status bits together and then using the | (OR) operator, as follows:
    sp_configure 'allow updates', 1
go
reconfigure with override
go
begin tran
go
update master..sysdatabases
set status = status | 4112
where name = 'database_name'
go

    Caution Because the database was marked suspect on the original recovery attempt, this procedure also resets some internal status bits to allow the database to recover normally. Do not use this procedure under any other circumstances.

    The value of 4112 in the SET STATUS statement corresponds to the single user and no chkpt on recovery database options.

  3. Check that the SET STATUS statement affected only one row.
  4. If more than one row was affected, issue a rollback transaction statement. Otherwise, commit the transaction and shut down SQL Server:
    commit tran
go
shutdown
go
  5. Restart SQL Server.
  6. After you restart SQL Server, dump the transaction log with the no_log option and reset the database status:
    dump tran database_name with no_log
go
sp_dboption database_name, 'no chkpt', false
go
sp_dboption database_name, single, false
go
use database_name
go
checkpoint
go
sp_configure 'allow updates', 0
go
reconfigure with override
go
  7. Use sp_dboption to reestablish any database options such as select into/bulkcopy noted in step 1.

On the master database If error 1105 occurs on the master database during recovery but SQL Server still starts, correct the problem by logging in and dumping the transaction log using the NO_LOG option, as shown in the following example:

dump tran master with no_log

If error 1105 occurs on the master database and prevents SQL Server from starting, contact your primary support provider.

On the model database If error 1105 occurs on the model database during recovery, SQL Server will not start. This is because the tempdb database, which is required to start the server, could not be built due to the problem with the model database. To correct this problem and restart SQL Server, use the following procedure:

  1. Start SQL Server with the 3608 trace flag. This trace flag causes SQL Server to recover only the master database at startup. For details about using trace flags, see "Using Trace Flags," in Chapter 24, "Additional Problem-solving Techniques."
  2. Execute the following statements to set the no chkpt on recovery option on the model database:
    sp_dboption model, 'no chkpt', true
go
use model
go
checkpoint
go
  3. Restart SQL Server.
  4. Execute the following statement to truncate the inactive portion of the transaction log in model:
    dump tran model with no_log
go
  5. Reset the database option on model:
    sp_dboption model, 'no chkpt', false
go
use model
go
checkpoint
go


Error 1108

Severity Level 21

Message Text

Cannot deallocate extent %Id, database %d. Object id %Id, index id %d, status %d in extent does not match object id %Id, index id %d, status %d in object being deallocated. Run DBCC CHECKALLOC.

Explanation

This error occurs when SQL Server traverses the extent chain for deallocation and finds an extent with an object ID that is different from what was expected.

SQL Server allocates storage space as a single unit called an extent. The extent is made up of 8 2K pages. As each database table object requires more space, SQL Server allocates additional extents to the object. Non-log extents are chained together and they all belong to the same database table object. This chaining enables SQL Server to rapidly deallocate or disassociate the entire extent from the database table object rather than on a page by page basis. Log extents are not chained.

Action

If this error occurs in tempdb, shut down and restart SQL Server. You may minimize the likelihood of the error reoccurring by increasing the size of tempdb. If the error continues to occur or if it occurs in a user database, contact your primary support provider. Have the SQL Server error log and specifics regarding the circumstances surrounding the appearance of the error available for review.


Error 1109

Severity Level 21

Message Text

Attempt to read allocation page %ID failed either because object ID is not correct (%Id) or the page ID is not correct (%ID).

Explanation

This error occurs when SQL Server attempts to read the specified allocation page and finds a page belonging to another object instead. The allocation page is used to control the allocation of the next 255 pages in the database. This error is equivalent to a 605 error on any other object. It is almost always caused by hardware- or operating-system-level problems.

Action

An allocation page cannot be repaired. Restore from backup. It is often possible to bulk copy out the data from your tables if there are no other errors in the database.

Run hardware diagnostics and correct any problems. Contact your hardware vendor and confirm that you are running your system with the most current updates. You should also confirm that the hardware and controllers are certified for your operating system.


Error 1117

Severity Level 21

Message Text

Extent chain for object %ID is not correctly linked.

Explanation

This error occurs when the extent chain used to manage the space allocation for an object is not linked correctly. This may be the result of hardware or operating-system problems.

Action

Execute DBCC CHECKDB and DBCC NEWALLOC. If DBCC CHECKDB reports no errors, the data in the object is most likely unaffected. Follow these steps:

  1. Load the database from backup.
  2. Bulk copy the data out, drop the table, re-create the table, and then bulk copy the data back in.

    Important The extent linkages are used to drop an object, and the drop command may fail. Before attempting any repairs, make a physical backup of the physical device files.

  3. Execute SELECT INTO another table, drop the original table, and then use the sp_rename stored procedure to change the name of the table back to the original name.

    Important The extent chain is used as the means to determine what extents to deallocate when an object is to be dropped; the drop table statement may fail. Before attempting any repairs, shut down SQL Server and perform a physical file backup of database device files on the server.

To confirm that the most current versions of software and hardware are being used, run hardware diagnostics and contact your hardware vendor.

If you are unable to resolve this problem, contact your primary support provider. Have the SQL Server error log and the DBCC CHECKDB and DBCC NEWALLOC output available for review.


Error 1203

Severity Level 20

Message Text

Caller of lock manager is incorrectly trying to unlock an unlocked object. spid=%d locktype=%d dbid=%d lockid=%Id.

Explanation

This error occurs when SQL Server is engaged in some activity other than normal post-processing clean-up and it finds that a particular page it is attempting to unlock is already unlocked. The underlying cause for this error may be related to structural problems within the affected database. SQL Server manages the acquisition and release of pages to maintain concurrency control in the multiuser environment. This mechanism is maintained through the use of various internal lock structures that identify the page and the type of lock present. Locks are acquired for processing of affected pages and released when the processing is completed.

Action

Run DBCC CHECKDB and DBCC NEWALLOC against the database in which the object belongs. If DBCC reports no errors, attempt to re-establish the connection and execute the command. If the problem persists, or if there are structural problems reported, contact your primary support provider.


Error 1204

Severity Level 19

Message Text

SQL Server has run out of LOCKS. Re-run your command when there are fewer active users, or ask your System Administrator to reconfigure SQL Server with more LOCKS.

Explanation

This error occurs when there are not enough system locks to complete the current command.

Action

Either execute the command again, when activity on the server is low, or have the system administrator increase the number of locks by calling the sp_configure system stored procedure from the master database.

To view the current configuration:

sp_configure locks
go

This will report the minimum, maximum, current run, and configuration values. To increase the number of locks, run sp_configure again, specifying the number of locks to be configured. For example, to configure 10,000 locks:

sp_configure locks, 10000
go

reconfigure with override
go

Stop and re-start SQL Server so the changes can take effect. Locks are allocated at system startup.

If the number of locks cannot be increased at the current time, and the single action requires more locks than the server is currently configured for, you may be able to reduce the number of locks required for the operation. For example, try the following:

  • For large update statements, break the updates into smaller units that will affect only a subset of records at a time. For example, you could use the primary key, changing the single UPDATE statement from:
    UPDATE employees
SET salary= salary * 1.05
WHERE employee_id between 1000 and 9999
go

    to several UPDATE statements:

    UPDATE employees
SET salary= salary * 1.05
WHERE employee_id between 1000 and 4999
go
UPDATE employees
SET salary= salary * 1.05
WHERE employee_id between 5000 and 9999
go
  • For a maintenance type of task or for a global update, you could also put the database into single-user mode (if it is feasible to keep other users out of the database). Single-user mode does not set locks, so you will not run out of locks, and the operation will run somewhat faster (because you save the locking overhead).
  • For a large bcp operation, the entire operation is treated as a single transaction. When you use the batch parameter (/b), bcp will treat the operation in small transactions with the number of rows specified. At the end of each small transaction, the system resources held by that transaction are freed, so fewer locks are needed.


Error 1205

Severity Level 13

Message Text

Your server command (process id#%d) was deadlocked with another process and has been chosen as deadlock victim. Re-run your command.

Explanation

This error occurs when SQL Server encouters a deadlock. A deadlock occurs when two (or more) processes attempt to access a resource that the other process holds a lock on. Since each process has a request for another resource, neither process can be completed. When a deadlock is detected, SQL Server rolls back the command that has the least processing time and returns this error message 1205 to the client application. This error is not "fatal" and may not cause the batch to be terminated.

Action

In some instances, a deadlock condition will cause a DB-Library function (such as dbsqlexec, dbsqlok, dbresults, or dbnextrow) to return FAIL. It is always the responsibility of the program to check the return codes from each DB-Library function. If FAIL is returned by one of these DB-Library functions, the program should cancel the batch and not attempt to continue. In some cases, it is possible to continue execution of subsequent functions in the batch. However, because a deadlock situation occurred and the functions that caused it were rolled back, later functions in the batch will probably fail with a more serious error, such as "object not found."

In other instances, a deadlock condition will not cause a DB-Library function to return FAIL. In these cases, the program must check for error message 1205 in the message handler and use the dbsetuserdata function to communicate this to the application (an example can be found in the Microsoft SQL Server Programming DB-Library for C under dbsetuserdata). The program must then check for the deadlock indicator after every DB-Library call and should cancel the batch if a deadlock is detected.

While it may seem unnecessary to cancel a batch after receiving a 1205 deadlock message, it is necessary because the server does not always terminate the batch in a deadlock situation. If the batch is not canceled, any attempt to submit a new batch can result in a DB-Library error 10038 "Results Pending."

You can also use the SET statement with the DEADLOCKPRIORITY option (LOW | NORMAL). SET DEADLOCKPRIORITY controls how the session reacts when in a deadlock situation. If set to LOW, the process will be the preferred victim of a deadlock situation. If set to NORMAL, the session will use the default deadlock-handling method.

If a deadlock situation continues, it is often useful to use the DBCC trace flag 1204 to gather more information. Trace flag 1204 prints out the deadlock chains and victim, as shown in this sample output:

***Deadlock detected - process 5 trying to wait on a process 1
Deadlock chain -->
LOCK REQUEST INITIATING DEADLOCK: LOGICAL:
SH_PAGE at 0x1887551e
    lockid=6074 spid=5 dbid=6
Process 1 waiting on Process 5 for resource: LOGICAL
Lock requested by spid 1:
SH_PAGE at 0x1867151e
    lockid=4301 spid=1 dbid=6

BLOCKED by spid 5 with the following lock:
EX_PAGE Blocking at 0x256752c0
    lockid=4301 spid=5 dbid=6
    pstat=0x0100[]

    VICTIM: process 1;pstat 0x0100[]; cputime=26
    VICTIM: process5;pstat 0x0100[]; cputime=8
    Process 5 was selected as victim
Your server command (process id j#5 was deadlocked with
another process and has been chosen as deadlock victim.
Re-run your command.
(Msg 1205, Level 13, State 1)
    Caller is deadlock victim (5: 0x0100)

You can extract the following information from this output:

  • The spid and dbid numbers accurately reflect the spid and dbid involved.
  • For a page lock, the lockid value is the logical page number in the database on which the deadlock occurred. For information on associating a page with an object to determine the table name that the page belongs to, see Chapter 24, "Additional Problem-solving Techniques." For a table lock, the lockid is the object id.
  • The hex values for the lock pointers (SH_Page at 0x1887551e) are lock pointers. They are not of immediate value in debugging a deadlock problem.
  • The deadlock victim is accurately reflected.
  • The process with the least CPU time is selected as deadlock victim.

For details about deadlocking and an example of how to detect a deadlock condition, see the Microsoft SQL Server Database Developer's Companion.


Error 1206

Severity Level 20

Message Text

Locksleep was called with incorrect process id. Process %d is trying to sleep on itself.

Explanation

This error occurs when a process asks SQL Server to call this routine and the process ID passed to the routine is the same as that of the calling process. This can happen as a result of the SQL Server running out of locks, or after an abnormally terminated process has not freed all of its locks. SQL Server sometimes puts a process to sleep while it is waiting for another process to free a lock. It does this by calling an internal "locksleep" routine.

Action

You must restart SQL Server to correct this error. Examine the SQL Server error log to see if there are any other error messages. If there are errors indicating that the server is out of locks (error 1204), use the sp_configure system stored procedure to add more locks to your system. For more information, see the explanation for error 1204.


Error 1207

Severity Level 20

Message Text

Locksleep called with bad process id %d

Explanation

SQL Server sometimes puts a process to sleep while it is waiting for another process to free a lock. It does this by calling an internal "locksleep" routine. If SQL Server calls this routine with a process ID that does not exist or is incorrect, a 1207 error occurs. This usually happens after a process has terminated abnormally and has not freed all of its locks.

Action

Run sp_who to see if the process ID from the error message is a valid server process. Then run sp_lock with the process ID to see if the process holds locks. If sp_lock shows a server process ID (spid) that is not in sysprocesses, use shutdown with the nowait option to shut down SQL Server immediately without doing a checkpoint.

If restarting does not clear the error condition, or if the problem occurs regularly, contact your primary support provider. When calling your primary support provider, be prepared to provide a copy of the error log. Also have output from sp_who and sp_lock ready.


Error 1505

Severity Level 14

Message Text

Create unique index aborted on duplicate key. Primary key is '%S_KEY'

Explanation

This error occurs when you attempt to create a unique index and more than one row contains the duplicate value. SQL Server has detected a uniqueness violation and cancels the create index operation.

For example, the creation for the index below would be canceled due to the uniqueness violation at row 3. The DORR ROBERT combination is already located in row 1.

TABLE:

tblTest

Row

strLastName

strFirstName

strCity

strState

1

DORR

ROBERT

IRVING

TX

2

DEDECKER

TODD

LEWISVILLE

TX

3

DORR

ROBERT

PLANO

TX

4

SCOTT

HULKE

PLANO

TX

create unique nonclustered index
idxUniqueNames ON
tblText(strLastName, strFirstName)

Action

You must review your index objective. If your index does not need to be unique, remove the UNIQUE keyword and reissue the create index statement. However, if you still want to create a unique index, you must query the table in question and remove the rows in error. For more detailed information on the create index statement, see the Microsoft SQL Server Transact-SQL Reference.

To find the duplicate rows, issue a GROUP BY statement:

SELECT * FROM tblTest
GROUP BY strLastName, strFirstName


Error 1508

Severity Level 14

Message Text

Create index aborted on duplicate rows. Primary key is '%S_KEY'

Explanation

This error occurs when you attempt to create a clustered index and a duplicate row is encountered in the table.

The following example produces error 1508 when the index creation process reaches row 3, which is an exact duplicate of row 1:

TABLE:

tblTest

Row

strLastName

strFirstName

strCity

strState

1

DORR

ROBERT

IRVING

TX

2

DORR

ROBERT

LEWISVILLE

TX

3

DORR

ROBERT

IRVING

TX

4

DORR

JOAN

IRVING

TX

create clustered index
idxClusteredName ON
tblText(strLastName)

Action

You must decide whether to allow or prevent duplicate rows in the table. To allow duplicate rows, you should add the allow_dup_row keyword to the create index statement. Be cautious when using ignore_dup_row, because it physically removes duplicate data from the table. Also note that when creating clustered indexes, the amount of space required can be 120 percent to 150 percent of the original table size. For detailed information about the create index statement, see the Microsoft SQL Server Transact-SQL Reference.

The following example creates the clustered index while allowing the duplicate rows to remain in the table:

create clustered index
idxClusteredName ON
tblText(strLastName)
WITH allow_dup_row


Error 1510

Severity Level 17

Message Text

Sort failed: Out of space or locks in database '%.*s'

Explanation

This error occurs when you attempt to create an index and there is not enough space in the database to complete the operation or no more locks are currently available.

Creating indexes can require 120 percent to 150 percent of the original table size when building a clustered index without the 'WITH SORTED_DATA' option (this amount is in addition to the table size¾but just during the time that CREATE INDEX is processing). This space must be available in the indicated database or in the segment on which you were attempting to create the index.

Action

When there is not enough space in the database, you may be able to select a specific segment on which to place the index. Use the sp_helpsegment system stored procedure to locate a specific segment and to check the size available on the segment. Type:

sp_helpsegment 'default'

Or use the alter database statement to increase the overall database size. Note that once you increase the size of the database, you may not be allowed to decrease the size. For information on creating and extending segments and altering or moving databases, see the Microsoft SQL Server Transact-SQL Reference.

If your database has no more locks available, use the sp_configure system stored procedure to increase the number of locks. For example:

sp_configure 'locks', #####
go
reconfigure
go

In order for the configuration option to take effect, you must stop and restart the SQL Server service. For user convenience, you may want to pause the service and allow current user activity to gracefully finish before officially stopping the service. For information on starting, pausing, and stopping the SQL Server service, see Microsoft SQL Server Setup and the online Help for SQL Enterprise Manager.


Error 1520

Severity Level 18

Message Text

Sort failed because dpages in the Sysindexes row for table '%.*s' in database '%.*s' had an incorrect value. Please run DBCC CHECKTABLE on this table to correct the value, then re-run your command.

Explanation

This error occurs when the create index statement fails while attempting to sort table data. The create index statement allocates work area based on an estimate in the system catalogs for the number of data pages used by the table. If the value is too small, the work area will not be large enough to complete the sort operation.

Maintaining an up-to-date record of the number of pages in use by a table would require significant overhead and could significantly slow performance.

Action

To correct the page count, use one of the following statements:

dbcc tablealloc(tablename)

dbcc newalloc(databasename)

dbcc checktable(tablename)

After running DBCC, you should be able to create the index.


Error 1521

Severity Level 18

Message Text

Sort failed because a table in tempdb used for the processing of the query had a bad data page count. Tempdb should not have been damaged.

Explanation

This error can occur when you are running complex queries that use inefficient query plans. Effective use of indexes can improve query performance.

In most cases, you can resolve the error immediately by inspecting and redefining the indexes on the affected tables.

Action

Follow these steps:

  1. Run the UPDATE STATISTICS statement on the table(s) in question. This will update the information about the distribution of key values in the indexes of the specified table(s).
  2. Modify the query so that the optimizer produces a different query plan. Here are examples of how this can be done:
    • Use SHOWPLAN to make sure your query is using indexes in the query plan.
    • Change BETWEEN clauses to the corresponding <= and >= expressions.
    • Make sure your indexes have been designed correctly and efficiently.
    • Use optimizer hints to manually control the access plan.
  3. Examine the table structure of the table(s) involved to ensure that normalization is not an issue.

If the problem persists, contact your primary support provider for assistance. Have the table and index structure of the table(s) involved, as well as a copy of the problematic query, available for review.


Error 1530

Severity Level 16

Message Text

Create index with sorted_data was aborted because of row out of order. Primary key of first out of order row is '%S_KEY'

Explanation

This error occurs when you try to create an index using the CREATE INDEX statement's sorted_data option on a column or columns containing data that is not in sorted order. When this error occurs, no index is created.

The sorted_data option speeds creation of an index when the data in the table is already in sorted order. The space required to build a clustered index is less when the sorted_data option is used.

The sorted_data option speeds index creation only for clustered indexes or unique nonclustered indexes. Creating a non-unique nonclustered index with the sorted_data option may succeed, but there is no improvement in performance.

Action

Use either of these strategies:

  • Sort the data, bulk copy it into the table, and then create the index using the sorted_data option.
  • Create the index without the sorted_data option.

You can also use the SORTED_DATA_REORG option, which physically reorganizes the data.

For more information about indexes and their options, see the CREATE INDEX statement in the Microsoft SQL Server Transact-SQL Reference.


Error 1601

Severity Level 16

Message Text

No resources available to start '%s' process. Use sp_configure to increase the number of user connections.

Explanation

This error occurs when SQL Server is not configured with enough user connections to support all requests. There is one resource for each configured user connection. When all resources are in use and a request is made to create another process, error 1601 occurs.

Action

Use the sp_configure system procedure to increase the number of user connections:

  1. Set the new value for user connections:
    sp_configure 'user connections', new_value
go
  2. Using the reconfigure statement, instruct SQL Server to accept the new value:
    reconfigure with override
go
  3. Restart SQL Server.

    Depending on the exact configuration of your SQL Server, each user connection requires a certain amount of memory, whether or not it is in use. Gradually increase the number of user connections until these errors no longer occur. When you change the user connections option, you might need to increase the memory option.

For additional information about configuring user connections, see Chapter 21, "Configuration Issues."


Error 1608

Severity Level 21

Message Text

A network error was encountered while sending results to the front end. Check the SQL Server errorlog for more information.

Explanation

This error occurs when a front-end process stopped without notifying SQL Server, so a subsequent attempt by SQL Server to send results to the front-end failed. Some of the possible reasons a front-end process can disappear are:

  • The front-end application either ended abnormally or was terminated.
  • The front-end computer was turned off or restarted.
  • A network failure occurred.
  • The network was shut down.

Note Using ctrl+c to exit from an application should not result in this error.

Usually, error 1608 is not serious and can be viewed as notification that a front-end process no longer exists.

Action

Do not be concerned if this error occurs sporadically. If the error occurs frequently and continually, however, or if it occurs frequently for short periods of time, it might be a result of excessive network traffic or network problems. If you suspect network problems, have your network administrator isolate the problem by running diagnostics on the network between the client and SQL Server.


Error 1702

Severity Level 16

Message Text

Create table failed because column '%.*s' in table '%.*s' exceeds the maximum of 250 columns.

Explanation

This error occurs when you try to create a table with more than 250 columns. The maximum number of definable columns per table is 250.

Column names must follow the rules for identifiers. They must be unique within a given table, but you can use the same column name in different tables in the same database.

Action

Reduce the number of columns in the table to 250 or less. For details about creating tables, see the CREATE TABLE statement in the Microsoft SQL Server Transact-SQL Reference.


Error 1803

Severity Level 17

Message Text

CREATE DATABASE failed. Could not allocate enough disk space for a new database on the disks named in the command. Total space allocated must be at least %d Mbytes (%ld 2048-byte pages) to accommodate copy of Model Database.

Explanation

This error occurs when there is not enough space on the device or in RAM (depending on the current setting of the tempdb_in_ram configuration option) to create the tempdb database.

Action

The procedure for handling this error depends on whether the error occurred on a user database or on tempdb.

If the error occurred on a user database
  • Create the database on a different disk.

Or

  • Delete some files to free space on the disk.
If the error occurred on tempdb

If you moved tempdb from the device to RAM and you don't have enough memory on the server computer to create the IN_RAM device for tempdb, SQL Server will not start. Correct the problem by starting SQL Server with minimum configuration (using the -f option). For details, see Microsoft SQL Server Setup.

If you moved tempdb from RAM back to any default device and you don't have enough space on the device (2 MB), SQL Server will attempt to create tempdb on another device. If you do not have a device with at least 2 MB free, SQL Server will not start. Start SQL Server using the -f minimum configuration option.

You can create a new device with at least 2 MB or free at least 2 MB on the device. If you create a new device, make sure it is specified as a default device, as in this example:

sp_diskdefault new_device_name, defaulton

If no default is specified, SQL Server sends an "out of memory" message (you can ignore this message) and then automatically moves tempdb to RAM.


Error 1809

Severity Level 14

Message Text

CREATE DATABASE must be preceded by a 'USE master' command. Check with your DBO (or System Administrator) if you do not have permission to USE master.

Explanation

This error occurs when you try to create a new database without being in the master database.

Action

Before issuing the CREATE DATABASE statement, be sure you are in the master database and have the necessary permissions to create a database. Type:

USE master
go


Error 1810

Severity Level 16

Message Text

CREATE DATABASE failed because of incorrect size parameter(s). Total number of megabytes specified must be at least %d megabytes so that the Model Database can be copied to the new database.

Explanation

This message occurs when you try to create a database that is smaller than the model database. The default is 1 MB.

Action

Make sure that the size you plan to use in the create database statement is greater than or equal to the size of the model database. Use the sp_helpdb system stored procedure to check the size of model. Type:

sp_helpdb model
go

When you issue the CREATE DATABASE statement, SQL Server makes a copy of the model database, which contains the system tables needed by each database. You can update model just like any other database, and add your own tables, stored procedures, datatypes, and so on. Whatever you add to the model database will be copied into each new database you create.

For more information, see the CREATE DATABASE statement in the Microsoft SQL Server Transact-SQL Reference.


Error 1814

Severity Level 10

Message Text

Problem creating Temporary Database - if out of space, please extend and reboot. If some other problem, please contact Technical Support.

Explanation

This error occurs when there is not enough space on the device or in RAM (depending on the current setting of the tempdb_in_ram configuration option) to create the tempdb database.

Action

The procedure for handling this error depends on the current setting of the tempdb_in_ram configuration option.

If the tempdb_in_ram configuration option is set to true (1)

If you moved tempdb to RAM and you don't have enough memory on the server computer to create the IN_RAM device for tempdb, SQL Server will not start. Correct the problem by starting SQL Server with minimum configuration (using the -f option). For details, see Microsoft SQL Server Setup.

If the tempdb_in_ram configuration option is set to false (0)

If you moved tempdb from RAM back to any default device and you don't have enough space on the device (2 MB), SQL Server will attempt to create tempdb on another device. If you do not have a device with at least 2 MB free, SQL Server will not start.

You can create a new device with at least 2 MB or free at least 2 MB on the device. If you create a new device, make sure it is specified as a default device, as in the following example:

sp_diskdefault new_device_name, defaulton

If no default device is specified, SQL Server sends an "out of memory" message (you can ignore this message) and then automatically moves tempdb to RAM.


Error 1902

Severity Level 16

Message Text

Cannot create more than one clustered index on table '%.*s'. Drop the existing clustered index '%.*s' before creating another

Explanation

This error occurs when a table can have only one clustered index, but it can have many nonclustered indexes. SQL Server uses the clustered index to sort rows so that their physical order is the same as their logical (indexed) order. The bottom (leaf level) of a clustered index contains the actual data pages of the table.

In a nonclustered index, the physical order of the rows is not the same as the indexed order. In a nonclustered index, the bottom (leaf level) contains pointers to rows on data pages, which creates an extra level between the index structure and the data itself.

Action

Use the sp_helpindex system stored procedure to examine the existing indexes on the table. If a clustered index already exists, you must drop it before creating another clustered index.


Error 1903

Severity Level 16

Message Text

%d is the maximum allowable size of an index. Composite index specified is %d bytes.

Explanation

This error occurs when the sum of the lengths of the columns that make up the composite index exceeds 256 bytes.

A composite index is an index that uses from 2 to 16 columns. For example, the following shows a composite index using objects from the pubs database:

create index idxPubNameCity
ON publishers (pub_name, city)
go

In this example, pub_name is defined as varchar(40) and city as varchar(20). Each character requires 1 byte of storage, so the total length of this composite index is 60 bytes. Note that when using varchar columns, the index will assume the maximum length of the varchar column to calculate the length of the composite index.

Action

Examine the lengths of the columns in your composite index and make sure that the total does not exceed 256 bytes. For information on determining the storage size for different Microsoft SQL Server datatypes, see the Microsoft SQL Server Transact-SQL Reference. For more information on indexes, see the Microsoft SQL Server Database Developer's Companion and the CREATE INDEX statement in the Microsoft SQL Server Transact-SQL Reference.


Error 1904

Severity Level 16

Message Text

Cannot specify more than %d column names for index key list. %d specified.

Explanation

This error occurs when more than 16 columns are used to create a composite index. A composite index is an index that uses from 2 to 16 columns.

The following example shows a composite index using objects from the pubs database:

create index idxPubNameCity
on publishers (pub_name, city)
go

Action

Modify the create index statement to use no more than 16 columns. For more information, see the CREATE INDEX statement in the Microsoft SQL Server Transact-SQL Reference.


Error 1916

Severity Level 16

Message Text

CREATE INDEX options %s and %s are mutually exclusive.

Explanation

This error occurs when you attempt to create an index with two mutually exclusive create index statement options. The index is not created when this error occurs.

This table shows when to use the CREATE INDEX options:

Index type | Option
Clustered | IGNORE_DUP_ROW | ALLOW_DUP_ROW
Unique clustered | IGNORE_DUP_KEY
Nonclustered | None
Unique nonclustered | IGNORE_DUP_KEY

Action

Select the correct options for the create index statement. For details on the CREATE INDEX statement, see the Microsoft SQL Server Transact-SQL Reference.


Error 2501

Severity Level 16

Message Text

Table name %.*s not found; check Sysobjects.

Explanation

This error is usually caused by some form of corruption in the database. This often happens when a table is being dropped and a serious error occurs that causes the drop to fail.

Action

Running dbcc checkdb, dbcc checkalloc, and dbcc checkcatalog can indicate other problems in the database. Restore your database from backup or contact your primary support provider for assistance.

You may also be able to use bcp to copy out other tables. But since this problem is often caused by other problems in the database, problems can occur when you copy out other tables.


Error 2502

Severity Level 16

Message Text

Table Corrupt: A page is linked in more than one chain; check this page:page number=%ld allocation status=%d

Explanation

This error occurs when SQL Server detects an inconsistency in the page linkage of one of the page chains associated with a table. One of the pages has been found to be linked in more than one page chain when it should be linked in only one chain. There is one doubly-linked page chain for the table data, as well as one for each index level.

Important This is a serious error and must be corrected immediately.

If DBCC detects this error during run-time processing, error 605 can also occur.

Action

Follow these steps to resolve the error:

  1. Examine the index ID associated with the page number indicated in the message to determine whether the error occurred on the table data or on an index. For information about how to find the object ID and the index ID of the object that has the error, see Chapter 24, "Additional Problem-solving Techniques."
  2. Restore the database:
    • If the object ID is less than or equal to 100, the error is on a system table. Restore the database from a clean backup.
    • If the object ID is greater than 100, the error is on a user table.
    • If this error occurs on table data (the index ID = 0), restore the database from a clean backup.
    • If the error occurs on an index, you can usually correct it by dropping and re-creating the index. If dropping and re-creating the index is not feasible, or if you cannot drop the index, contact your primary support provider for assistance.

If the problem persists, contact your primary support provider for assistance. Have the output of the appropriate DBCC statements available for review.


Error 2503

Severity Level 16

Message Text

Table Corrupt: Page linkage is not consistent; check the following pages: (current page#=%ld; page# pointing to this page=%ld; previous page# indicated on this page=%ld)

Explanation

This error occurs when SQL Server detects an inconsistency in the page linkage of one of the page chains associated with a table ¾ for example, when a page's next pointer points to a page whose previous pointer points back to a different page. There is one doubly-linked page chain for the table data as well as one for each index level.

Important This is a serious error and must be corrected immediately.

If DBCC statements detect this error during run-time processing, error 605 will also occur.

Action

Determine which table is corrupt by examining the current page in the error message. For additional information about associating a page with an object, see "Associating a Page with an Object" in Chapter 24, "Additional Problem-solving Techniques." If the page is associated with an index, it is sometimes possible to resolve the problem by dropping the index. In most cases, you must recover the database from a known clean backup.

You should also examine your operating-system error log file, in addition to the SQL Server error log, to determine if hardware errors might have caused the corruption.

If the problem persists, contact your primary support provider. Have the output from the appropriate DBCC statements available for review.


Error 2504

Severity Level 16

Message Text

Table Corrupt: The index id in alloc page does not match the index id in Sysindexes (alloc page#=%ld; extent id=%ld; index id in alloc=%ld; index id in Systemindexes=%d)

Explanation

The DBCC CHECKALLOC statement detected a mismatch in the object ID between an allocation structure (extent) and the sysindexes system table.

Note Occasionally, DBCC CHECKALLOC reports this error when no real error condition exists. Run CHECKALLOC in single-user mode if you suspect the 2504 error is incorrect.

Action

Follow these steps:

  1. Examine the index ID associated with the page number indicated by the extent# in the message to determine whether the error occurred on the table data or on an index. To find the object ID and the index ID of the object that has the error, see Chapter 24, "Additional Problem-solving Techniques."
  2. Restore the database:
    • If the object ID is less than or equal to 100, the error is on a system table. Restore the database from a clean backup.
    • If the object ID is greater than 100, the error is on a user table.
    • If this error occurs on table data (the index ID = 1), restore the database from a clean backup.
    • If the error occurs on an index, you can usually correct it by dropping and re-creating the index. If dropping and re-creating the index is not feasible, or if you cannot drop the index, contact your primary support provider for assistance.

If the problem persists, contact your primary support provider for assistance. Have the output of the appropriate DBCC statements available for review.


Error 2506

Severity Level 16

Message Text

Table Corrupt: The values in adjust table should be in ascending order starting from the end of the table (page#=%ld row#=%d); check adjust table in this row

Explanation

This error occurs when SQL Server detects an inconsistency in the storage of the variable columns of a row and a page. This can happen after a fast bcp operation that involves many variable-length columns.

Action

Follow these steps:

Note The select into/bulkcopy option is set to true for the database.

  1. Save the index/trigger/constraint definitions for the problem table. You will need to re-create them later.
  2. Select the data from the problem table into a new one:
    select * into new_table from problem_table
  3. Drop the problem table:
    drop table problem_table
  4. Rename the new table, giving it the problem table's name:
    sp_rename new_table, problem_table
  5. If applicable, re-create the indexes and triggers.

If the problem persists, contact your primary support provider.


Error 2507

Severity Level 16

Message Text

Table Corrupt: Offset table is incorrect (page#=%ld row#=%d offset in offset table is=%d correct offset  is=%d)

Explanation

SQL Server detects an error in the internal structure that contains the data.

Action

Run dbcc checkdb and DBCC newalloc to make sure there are not more serious problems in the database. This problem can usually be resolved by selecting into (SELECT INTO) from this table into another table. As a precaution, dump your database before following the steps below:

  1. Use the object number reported by DBCC checkalloc or DBCC newalloc to determine which table is involved. For example:
    select object_name(object id)
  2. Check that the select into/bulkcopy option is set to true for the database.
  3. Copy the table into a new table:
    select * into newname from problem table
  4. Run dbcc checktable(newname) to ensure there are no problems with the new table.
  5. Drop the old table:
    drop table problem table
  6. Rename the new table using the old table name:
    sp_rename newname,oldname

This error has sometimes been traced to problems with the disk I/O system. If you persistently run into this problem, run diagnostics on the system and contact your primary support provider.


Error 2509

Severity Level 16

Message Text

Table Corrupt: The row number and offset of each row in the page should have a matching entry in row number table: check this page (page#=%1d row#=%d offset in row number table=%d)

Explanation

SQL Server detected an error in the internal structure that contains the data.

Action

Run dbcc checkdb and DBCC newalloc to make sure there are not more serious problems in the database. This problem can usually be resolved by selecting into (SELECT INTO) from this table into another table. As a precaution, dump your database before following the steps below:

  1. Use the object number reported by DBCC checkalloc or DBCC newalloc to determine which table is involved. For example:
    select object_name(object id)
  2. Check that the select into/bulkcopy option is set to true for the database.
  3. Copy the table into a new table:
    select * into newname from problem table
  4. Run dbcc checktable(newname) to ensure there are no problems with the new table.
  5. Drop the old table:
    drop table problem table
  6. Rename the new table using the old table name:
    sp_rename newname,oldname

This error has sometimes been traced to problems with the disk I/O system. If you persistently run into this problem, run diagnostics on the system and contact your primary support provider.


Error 2510

Severity Level 16

Message Text

Table Corrupt: Keys do not match between leaf page %ld and data page %ld; check row # %d on the data page

Explanation

This error indicates that an index is not consistent with the table data that it represents.

Action

Use the following procedure:

  1. Record the leaf page number from the error text. To identify which table and index correspond to the leaf page number, see "Associating a Page with an Object" in Chapter 24, "Additional Problem-solving Techniques."
  2. Record the object ID and index ID.

    If the object with the error is not a system table (its object ID is 100 or greater), continue to the next step.

    If the object with the error is a system table (its object ID is less than 100), you cannot drop the index. Restore the database from a known clean backup.

  3. Find the name of the index involved, as follows:
    select name from sysindexes
where indid = index_id
and id = object_id
  4. Drop and re-create the index. (For information about using DROP INDEX and CREATE INDEX, see the Microsoft SQL Server Transact-SQL Reference.)
  5. Run DBCC CHECKTABLE and DBCC CHECKALLOC on the affected table to verify that all problems have been corrected at the table level.

If problems persist, contact your primary support provider. Have the output from the appropriate DBCC statements available for review.


Error 2511

Severity Level 16

Message Text

Table Corrupt: Keys in %S_MSG should be in ascending order; check page number %ld

Explanation

This error occurs when an index is not ordered correctly. The %S_MSG variable can be a data page (for clustered indexes), an index page, or a leaf page.

Action

Follow these steps:

  1. Identify which table and index correspond to the page number from the error message text using the instructions in "Associating a Page with an Object" in Chapter 24, "Additional Problem-solving Techniques."
  2. Note the object ID.
  3. If the object with the error is not a system table (its object ID is more than 100), continue with the next step.

    If the object with the error is a system table (its object ID is less than 100), you cannot drop the index. Restore the database from a known clean backup.

  4. Find the name of the index involved, as follows:
    select name from sysindexes
where indid = index_id
and id = object_id
  5. Drop and re-create the index.
  6. Run DBCC CHECKTABLE and DBCC CHECKALLOC on the affected table to verify that all problems have been resolved at the table level.

If problems persist, contact your primary support provider. Have the output from the appropriate DBCC statements available for review.


Error 2513

Severity Level 16

Message Text

Table Corrupt: Object id %Id (object name = %.*s) does not match between %.*s and %.*s

Explanation

This error occurs when the DBCC CHECKCATALOG statement deletes a database object in one system table and this is not expected in another. Most often, this occurs when one or more rows in the syscolumns, syscomments, sysindexes, sysprocedures, or sysdepends tables have no corresponding rows in sysobjects. This error can also occur if an operation affecting the system table, such as deletion of a user table, was interrupted.

Action

Although this error seldom interferes with database use, it is a good idea to restore the system table.

Follow these steps to restore the consistency of the system tables:

  1. Display the offending rows by executing a query in the problem database against the two tables mentioned in the message. For example, if the message reports one or more mismatches between syscolumns and sysobjects:
    select * from syscolumns where syscolumns.id not in
(select sysobjects.id from sysobjects)
  2. Enable updates to system tables:
    sp_configure 'allow updates',1
go
reconfigure with override
go
  3. Make sure that the rows displayed in step 1 correspond to reported 2513 errors, and then delete them from the first table mentioned in the message text:
    BEGIN TRAN
DELETE FROM syscolumns WHERE syscolumns.id NOT IN
(SELECT sysobjects.id FROM sysobjects)
go
  4. If the number of rows affected by the delete does not match the number found in step 1, roll back the transaction. If the numbers match, commit it:
    COMMIT TRAN
go
  5. Re-run DBCC CHECKCATALOG to confirm that the mismatches are fixed, then disallow updates to the system tables:
    sp_configure 'allow updates',0
go
reconfigure with override
go
checkpoint
go


Error 2514

Severity Level 16

Message Text

Table Corrupt: Type id %ld (type name = %.*s) do not match between %.*s and %.*s

Explanation

This error occurs when there is a type mismatch between the systypes and the syscolumns system tables. The DBCC CHECKCATALOG statement incorrectly reports type mismatches between systypes and syscolumns using error 2514. It is supposed to report that the usertype column in syscolumns isn't consistent with the usertype column in systypes, but it doesn't print out the offending datatype correctly. Error 2514 often prints out a usertype value that seems out of place (typically 0 or a large number). Usually, the usertype column is either 0 or a number that doesn't appear in systypes.

Action

The following example demonstrates how to find and correct this problem in most circumstances. If your particular example does not match this one, call your primary support provider.

  1. Display the offending rows by executing the following query in the problem database:
    select name, type, usertype
from syscolumns
where usertype not in
(select usertype from systypes)
name

type

usertype

-----------------------

----

--------

BugId

56

0

Description

39

175

  2. Examine systypes:
    select name, type, usertype from systypes
name

type

usertype

-----------------------

----

--------

binary

45

3

bit

50

16

char

47

1

datetime

61

12

datetimn

111

15

float

62

8

floatn

109

14

image

34

20

int

56

7

intn

38

13

money

60

11

moneyn

110

17

smallint

52

6

sysname

39

18

text

35

19

timestamp

37

80

tinyint

48

5

varbinary

37

4

varchar

39

2

Match the type in step 1 to the type in step 2 to determine what the usertype in syscolumns should be. For example, the type for BugId is 56. Matching the type from the first query with the row from the second query, where type is 56, shows that the usertype should be 7.

If more than one row in systypes contains a matching value for type in syscolumns, choose the corresponding usertype from systypes that has the lowest value. In this example, two rows in systypes have a type of 39, corresponding to usertypes 18 and 2. Therefore, 2 should be the new value for usertype in syscolumns.

  3. For each mismatch, update the corresponding row in syscolumns, as follows:
    • Enable updates to system tables:
      sp_configure 'allow updates', 1
go

reconfigure with override
go
    • Update the type column in syscolumns for each type where there is an error. For example:
      begin tran
go

update syscolumns set usertype = 7
where type = 56
and name = 'BugId'
and usertype = 0
go
    • Check your results carefully and commit the transaction only if the update affects only one row. If it affects more than one row, roll back the transaction. To commit the transaction, use the following:
      commit tran
go
    • Perform updates for any other rows, substituting the required values for usertype, type, and name shown above. Always check that the update affects only one row.
    • When you have updated all offending rows, disable updates to system tables:
      sp_configure 'allow updates', 0
go

reconfigure with override
go

checkpoint
go


Error 2519

Severity Level 16

Message Text

Database Corrupt: The last checkpoint in Sysdatabases is incorrect. Syslogs recorded a different checkpoint

Explanation

This error occurs when the DBCC CHECKCATALOG statement finds that a row in the sysdatabases table has not been updated to reflect a new checkpoint in syslogs.

Action

Sporadic appearance of this error is not a cause for concern. It will normally resolve itself as database use continues. If the error persists, contact your primary support provider. Have the output from the appropriate DBCC statements available for review.


Error 2521

Severity Level 16

Message Text

Table Corrupt: Page is linked but not allocated; check the following pages and table: alloc page#=%ld extent id=%ld logical page#=%ld object id in extent=%ld (object name = %.*s) index id in extent=%d

Explanation

This error means that a page is currently in use by a table or index but it has not been marked as allocated. The same page could be allocated again, resulting in a loss of whatever data resides on the page.

Important This error is serious, especially if it occurs on a table's data pages.

Pages encountering error 2521 will not be included in a database dump, because database dumps are performed by reading allocation pages and not by traversing page chains. Correct this error before dumping the database.

Action

If the object id in extent is less than 100, the error is on a system table, which cannot easily be corrected. Restore the database from a known clean backup.

If the object id in extent is 100 or greater, use the DBCC PAGE statement described in "Associating a Page with an Object" in Chapter 24, "Additional Problem-solving Techniques," to display information about the logical page from the error message. The value that DBCC PAGE displays for indid should match the index id in extent printed at the end of the message.

If these values do not match, restore the database from a known clean backup. If they do match, check what type of index is involved. For additional information, see the table of index IDs contained in "Associating a Page with an Object" in Chapter 24, "Additional Problem-solving Techniques."

For tables (index id in extent = 0)

Restore the database from a known clean backup.

For indexes (0 < index id in extent < 255)

The problem can be resolved by dropping and re-creating the index in question. After the index is rebuilt, run DBCC CHECKALLOC to verify that the problem no longer exists. If it persists, call your primary support provider.


Error 2525

Severity Level 16

Message Text

Table Corrupt: Object id wrong; tables: alloc page %ld extent id=%ld l page#=%ld objid in ext=%ld (name = %.*s) objid in page=%ld (name = %.*s) objid in sysindexes=%ld (name = %.*s)

Explanation

The DBCC CHECKALLOC statement detected one of the following errors:

  • The object ID on a page does not match the object ID in the sysindexes table. This is the case when the objid in ext parameter in the message doesn't match the objid in page parameter in the message.
  • The object ID on a page does not match the object ID on the allocation structure (extent) associated with that page. This is the case when the objid in ext parameter in the message matches the objid in page parameter in the message.

Note Occasionally DBCC CHECKALLOC reports this error when no real error condition exists. Run DBCC CHECKALLOC in single-user mode if you suspect that the 2525 error message is incorrect.

Action

Compare objid in ext to objid in page, and then carry out one of the following procedures, depending on whether the object IDs matched.

Caution If you drop an object before you correct the 2525 error condition, the drop operation could cause pages belonging to another object to be deallocated, causing error 1108.

Object IDs don't match

If the object IDs don't match, restore the database from a known clean backup.

Object IDs match

If the object IDs match, the pointer to a distribution page for a particular index is probably invalid.

To correct the problem:

  1. Use the following query to determine which index has the problem. The query compares the id column in the output to the objid in sysindexes parameter in the message, and the distribution column in the output to the l page # parameter in the message.
    use database_name
go
select indid, name, object_name(id)
from sysindexes
where id = objid_in_sysindexes and
distribution = l_page_#
go

    If this query does not return any rows, contact your primary support provider.

  2. Drop and re-create the index specified by this query. (For information about using DROP INDEX and CREATE INDEX, see the Microsoft SQL Server Transact-SQL Reference.)
  3. Run DBCC CHECKALLOC to be sure that the problem is corrected. If the problem still exists, contact your primary support provider. Have output from DBCC CHECKALLOC available for review.


Error 2529

Severity Level 16

Message Text

Table corrupt: Page%ld not found

Explanation

When DBCC CHECKALLOC returns this error, frequently it is an indication that there is a cause such as the following:

  • A page in the database may not have been initialized. This can be caused by a database load failure, either as the result of a database dump file corruption or loading a database dump into a database sized smaller than the original.
  • Hardware problems can be the underlying cause of this error, especially if 605 errors are found with DBCC CHECKDB. Check the SQL Server error log for operating-system errors as well.

Action

If the problem is the result of a database load failure due to corruption, restore from a clean backup.

If hardware problems are the root cause for this error, correct the hardware problems and restore from a clean backup.

If the problem persists, contact your primary support provider. Have the output from DBCC CHECKALLOC, DBCC CHECKDB, and the SQL Server error log available for review.


Error 2540

Severity Level 16

Message Text

Allocation Discrepancy: Page is allocated but not linked; check the following pages and ids: allocation pg#=%ld extent id=%ld logical pg#=%ld object id on extent=%ld (object name = %.*s) indid on extent=%ld

Explanation

This error indicates that a page is marked as allocated to an object, although it is not being used. One page of disk space cannot be used, however, until the error is corrected, so each 2540 error means the loss of one blank data page of disk space. The table data is not corrupt and no data loss is associated with this error.

A few 2540 errors are no cause for concern. If many of these errors occur, however, the amount of disk space lost could be significant.

Action

You can usually correct error 2540 by running DBCC FIX_AL, as follows:

dbcc fix_al (database_name)

Important Before running DBCC FIX_AL, run DBCC CHECKDB to be sure there are no other related problems.

If this doesn't work, restore the database from a known clean backup.

If the problem persists, contact your primary support provider. Have the output from the appropriate DBCC statements available for review.


Error 2541

Severity Level 16

Message Text

Table Corrupt: object id does not match between extent in allocation page and Sysindexes; check the following extent: alloc pg#=%ld extent#=%ld object id on extent=%ld (object name = %.*s) object id in Sysindexes=%ld (object name = %.*s)

Explanation

The DBCC CHECKALLOC statement detected a mismatch in the object ID between an allocation structure (extent) and the sysindexes system table.

Note Occasionally, DBCC CHECKALLOC reports this error when no real error condition exists. Run DBCC CHECKALLOC in single-user mode if you suspect the 2541 error message is incorrect.

Action

Follow these steps:

  1. Examine the index ID associated with the page number indicated by extent# in the message to determine whether the error occurred on table data or an index. To find the object ID and the index ID of the object that has the error, see "Associating a Page with an Object" in Chapter 24, "Additional Problem-solving Techniques."
  2. If the object ID is less than or equal to 100, the error is on a system table. Restore the database from a known clean backup.

    If the object ID is greater than 100, the error is on a user table.

    • If this error occurs on table data (the index ID = 0), restore the database from a known clean backup.
    • If this error occurs on an index, you can usually correct it by dropping and re-creating the index. If dropping and re-creating the index is not feasible, or if you cannot drop the index, contact your primary support provider for assistance.

    If the problem persists, contact your primary support provider. Have the output from the appropriate DBCC statements available for review.


Error 2542

Severity Level 16

Message Text

Table Corrupt: Extent is linked in more than one chain. Check the following allocation page and extent: alloc pg#=%Id extent#=%Id status=%d

Explanation

DBCC CHECKALLOC checks the doubly-linked list used by SQL Server to associate extents with database objects. With this particular error one of the pointers on the extent# is pointing to another object chain. This error is often associated with errors 2541, 2543 and 1117.

Note If DBCC CHECKDB and DBCC CHECKALLOC show no other errors, the data for this object is recoverable either by performing a bcp out or a select into procedure.

Action

Follow these steps:

  1. Note the extent# in the message text. For information about the object ID and the index ID of the object that has the error, see Chapter 24, "Additional Problem-solving Techniques."
  2. If the object ID is less than or equal to 100, the error is on a system table. Restore the database from a known clean backup.

    If this error occurs on table data (the index ID=0), restore the database from a clean backup.

  3. If this error occurs on an object in the database with an ID greater than 100, contact your support provider and have the output from DBCC PAGE, DBCC CHECKALLOC, DBCC CHECKDB, and the SQL Server error log available for review.


Error 2543

Severity Level 16

Message Text

Table Corrupt: Extent structures are linked incorrectly; check the following extent: alloc pg#=%ld extent#=%ld previous extent# on this extent=%ld previous extent should be=%ld

Explanation

DBCC CHECKALLOC detected a break in the chain of allocation structures (extents) for a particular object. SQL Server references an object's extents only when allocating or deallocating space for that object, so this error does not affect queries against the data. However, any operations that require allocating or deallocating space might fail at run time.

Action

Follow these steps:

  1. Note the first extent# in the message text. To find the object ID and the index ID of the object that has the error, see "Associating a Page with an Object" in Chapter 24, "Additional Problem-solving Techniques."
  2. If the object ID is less than or equal to 100, the error is on a system table. Restore the database from a known clean backup.

    If the object ID is greater than 100, the error is on a user table.

    • If this error occurs on table data (the index ID = 0), restore the database from a known clean backup.
    • If this error occurs on an index, you can usually clear it by dropping and re-creating the index. If dropping and re-creating the index is not feasible, or if you cannot drop the index, contact your primary support provider for assistance.

    If the problem persists, contact your primary support provider. Have the output from the appropriate DBCC statements available for review.


Error 2544

Severity Level 16

Message Text

Table Corrupt: Extent id %Id on allocation pg# %Id had object id %Id (object name = %.*s) on but used bit off

Explanation

This error occurs when DBCC CHECKALLOC has found an extent with object information in the structure, even though the extent has been marked as unused. Space is allocated to objects in a database based on the extent structure, which contains 8 2K pages. An extent structure manages each of these 2K pages, indicating whether they are used by the object referenced in the extent structure. When all the pages are not being used, the extent is deallocated, which results in the removal of any references to an object in the database and the extent itself being marked as unused.

Note Occasionally, DBCC CHECKALLOC reports this error when no real error condition exists. Run DBCC CHECKALLOC in single-user mode if you suspect the 2544 error is incorrect.

Action

Follow these steps:

  1. Examine the index ID associated with the page number indicated by the extent# in the message to determine whether the error occurred on a table data or on an index. For information about the object ID and the index ID of the object that has the error, see Chapter 24, "Additional Problem-solving Techniques."
  2. Restore the database:
    • If the object ID is less than or equal to 100, the error is on a system table. Restore the database from a clean backup.
    • If the object ID is greater than 100, the error is on a user table.
    • If this error occurs on a table (the index ID = 0), restore the database from a clean backup.
    • If this error occurs on an index, you can usually correct it by dropping and re-creating the index. If dropping and re-creating the index is not feasible, or if you cannot drop the index, contact your primary support provider for assistance.

If the problem persists, contact your primary support provider. Have the output from the appropriate DBCC statements available for review.


Error 2546

Severity Level 16

Message Text

Table Corrupt: Extent id %ld on allocation pg# %ld has objid %ld and used bit on, but reference bit off.

Explanation

If an allocation structure or extent is not linked to the other extents for the object referenced by objid but references a page that is linked in the object's page chain, DBCC CHECKALLOC will trigger this error. Each occurrence of this error can represent a loss of up to 8 pages on disk (16K). There is no data loss because these pages have not been used, but the pages cannot be used until the error is corrected. This error can result in various run-time failures and should be corrected; however, if no other errors are occurring, you can wait to correct the problem until non-peak hours.

Note Occasionally DBCC CHECKALLOC reports this error when no real error condition exists. Run DBCC CHECKALLOC in single-user mode if you suspect the 2546 error message is incorrect.

Action

Restore the database from a known clean backup. If the problem persists, contact your primary support provider. Have the output from the appropriate DBCC statements available for review.


Error 2558

Severity Level 16

Message Text

Extent not within segment: Object %ld, indid %d includes extents on allocation page %ld which is not in segment %d.

Explanation

This error occurs when a portion of a database resides on a segment that was not defined to contain that type of data. The database can still function, possibly generating 1105 errors. There can also be problems with recoverability. Running DBCC CHECKALLOC will find this problem. There are no run-time errors associated with this error.

Segments are used to map where future allocations of different types of data can occur. By default, when SQL Server creates a database, it creates three segments: a system segment, a default segment, and a log segment.

  • The system segment allows system tables to be placed on devices that contain the system segment for the database.
  • The default segment allows user tables or indexes to be placed on devices that contain the default segment without specifying the ON clause for the database. For example:
    CREATE TABLE test (i int) ON segment_1
  • The log segment allows the transaction log to be placed on devices that contain the log segment for the database.

For example, this statement creates the log segments on the example database:

create database example
on device_1 = 10
log on device_2 = 2

The system and default segments are mapped to device_1 and the log segment is mapped to device_2. For the example database, all future space allocations for system or user objects occur on device_1, and all transaction log records are placed on device_2. Other databases can use other portions of device_1 or device_2, and these devices can have different segment mappings for that database. More than one segment can be mapped to the same device for a database.

If system or user objects are located on device_2 or transaction log records are located on device_1, a 2558 error results in the example database. Although several situations can cause a 2558 error, these are the most common:

  • Loading a database that has different data and log mapping or different user segment definitions than the dumped database.
  • Using the sp_placeobject system procedure.
Different data and log mapping

If this error occurred after you re-created and loaded a database from a dump, there were probably incorrect entries in the master..sysusages table. A database loaded from a dump must be created in exactly the same way as the database that was dumped. If it isn't, there might be different entries in master..sysusages and error 2558 results. Keep an up-to-date copy of the master..sysusages system table as well as scripts to re-create all databases.

The resulting master..sysusages entries for the newly created database must be exactly the same as the database that was dumped. If a 2558 error occurs, the error falls into one of two cases:

Case 1 The data and log mappings on the newly created database do not match the mappings of the dumped database. The database being loaded into was not created in the same way as the database that was dumped.

This can cause a "data on log" situation, where user or system objects are loaded into a log segment, which results in less log space available to the database. The data is still accessible, but processing might be slowed, if not totally stopped, by the shortage of log space.

There can also be a "log on data" situation, where portions of the transaction log are loaded into a data segment. This isn't as serious as the "data on log" scenario, because the portion of the transaction log on the data segment is eventually truncated via the DUMP TRANSACTION statement, which frees up the space. All future transaction log allocations will be correctly placed on the log segment.

Suppose that the above example database was altered as follows:

alter database example on device_1 = 2

The logical order of the database pages is:

  • 10 MB of data (default and system segments)
  • 2 MB of log
  • 2 MB of data

A 2558 error could result if the database were dumped, then dropped and re-created with different segment mappings. For example:

create database example on device_1 = 12
log on device_2 = 2

Although both ways of creating the database (CREATE and ALTER, or only CREATE) allocate the same amount of data and log space on the same devices, the mapping of data and log space is not the same. Here is an example:

In this example, Database 1 is dumped and loaded into Database 2, resulting in incorrect mapping of data and log space.

SQL Server DUMP and LOAD statements operate at the logical page level. In this example, logical pages 5120 through 6143 on Database 1 might contain transaction log records but, when loaded on Database 2, they are mapped onto a data segment. Similarly, pages 6144 through 7167 are mapped for data on Database 1, but are mapped for log on Database 2.

If the 2 MB data segment in this example was completely full on Database 1, there would be absolutely no log space available on Database 2 after the load. Dumping the transaction log at this point would have no effect since the log segment is filled with data.

All space allocations that occur on Database 2 after the load completes are correctly mapped.

Case 2 The mapping of user-defined segments in sysusages for the database being loaded does not match the segments of the database that was dumped. This can result from:

  • Creating user-defined segments in a different order on the database being loaded than on the database that was dumped.
  • Dropping user-defined segments on the database that was dumped and not reflecting this change on the database being loaded into.

After you execute a LOAD DATABASE statement with one of these error conditions, the 2558 error exists but is not reported until you run DBCC CHECKALLOC on the loaded database.

sp_placeobject

Error 2558 can also occur if you execute the sp_placeobject system procedure, which places future allocations for a table or index on a particular segment. It does this by updating the sysindexes.segment column to contain the number of the segment where the object was placed.

This type of 2558 error is due to existing allocations not residing on the segment specified in sp_placeobject and is not related to the segment type. There is no negative impact of this type of 2558 error and you can ignore it. For a procedure to clear the error, see the following section.

Action

The action to correct error 2558 depends on the type of page on which the error occurred. Error 2558 occurs on four types of pages:

  • Data pages or clustered index pages
  • Nonclustered index pages
  • Text or image data pages
  • System table pages

If you have 2558 errors and cannot re-create the database from scripts or hard copy, use the following table to match the object ID value (Object in the error message) and index ID (indid in the error message) with the corresponding data page type, and then refer to the appropriate section below.

Type of data | Object ID | Index ID
Data or clustered index pages | > 99 | 0 or 1
Nonclustered index pages | > 99 | >1 or < 255
Text or image data pages | > 99 | 255
System table pages | < 100 |

Data pages or clustered index pages

The error occurred on the data page or the clustered index of a user table. Resolve the problem as follows:

  1. Create a clustered index on the table. If a clustered index already exists, drop and re-create it. If not, creating one will clear the error. You can then drop the clustered index.
  2. Copy the data out of the table, drop and re-create the table, and copy the data back in using bcp or SELECT INTO.
Nonclustered index pages

The error occurred on the index of a user table. The error can be cleared by dropping and re-creating the index. Creating a clustered index causes all nonclustered indexes to be rebuilt as well. Therefore, if 2558 errors are occurring on several indexes on the same table, you can create a clustered index on that table to clear all these errors.

Text or image data pages

The error occurred on text or image data. Use one of the following methods to correct the situation:

  • Select all the information from the corrupted table into a new table, drop the corrupted table, and then use sp_rename to rename the new table with the old table name. (Any subsequent DBCC CHECKALLOC statement will continue to show this error until the corrupted table is dropped.)

Or

  • Copy the table data out using bcp or SELECT INTO, drop and re-create the table, and then copy the contents of the table back in using bcp or SELECT INTO.

Or

  • Restore the database from a known clean backup.
System table pages

The error occurred on a system table. Recover from a known clean backup or contact your primary support provider for assistance.

Additional Information

If this error occurred after re-creating and loading a database from a dump, you can prevent it by ensuring that the entries in the master..sysusages table for the database being loaded match the corresponding entries for the database that was dumped.

More specifically, the segmap, lstart, and size columns of sysusages must be identical in content and order. Verify this before beginning the LOAD DATABASE statement.

The entries in sysusages will be correct on the database being loaded into if you execute the following with the same parameters and in the same order as on the dumped database:

  • CREATE DATABASE
  • ALTER DATABASE
  • sp_addsegment
  • sp_dropsegment
  • sp_extendsegment
  • sp_MSlogdevice

Note You cannot depend on the output of the sp_helpdb system procedure to compare the contents of the sysusages table because it does not necessarily display rows from sysusages in the actual logical page order. Instead, execute direct SELECT statements against the sysusages table.

If a substantial number of 2558 errors occur due to an incorrect LOAD DATABASE action, it might be a good idea to drop and correctly re-create the database, and then reload it.


Error 2559

Severity Level 16

Message Text

Data page number %ld is empty but is not the first page. Status = 0x%x.

Explanation

This error occurs when SQL Server encounters an empty page while traversing the page chain of an object that is not the first page of the chain. When an object is first created, a single, empty page is allocated to it. Usually there are no other empty pages.

If you are not encountering any other errors either at run time or from DBCC, it is possible that the empty page will not cause any further problems. Therefore, it is acceptable to wait to correct this problem until non-peak hours. If other errors are occurring, follow the procedures below or contact your primary support provider.

Action

Force the page chain involved to be rebuilt. This can be accomplished in different ways, depending on whether or not the page chain involved is associated with an index or with actual table data. To determine this, use the DBCC PAGE statement to determine the index ID (indid) and object name associated with the page number from the error message. For more information about DBCC PAGE, see "Associating a Page with an Object" in Chapter 24, "Additional Problem-solving Techniques."

Tables or clustered indexes (indid = 0 or indid = 1)

There are two ways to correct this error on tables or clustered indexes, depending on whether you have enough extra disk space to create a clustered index on the table in question. (Clustered index creation requires considerable disk space.) You can either drop the index and re-create it, or you can use bcp.

Dropping the index If a clustered index exists, drop and re-create it. If not, create a dummy clustered index and then drop it. This removes the problem because creation of a clustered index causes the table to be copied but does not copy the empty pages. For information about creating clustered indexes, see the Microsoft SQL Server Transact-SQL Reference.

Using bcp If you don't have enough extra disk space to create a clustered index on the table, you can use bcp to copy the table data out of SQL Server, remove all rows from the table, and then use bcp again to copy the table data back into SQL Server. Follow this procedure:

  1. Use the bcp utility to copy the table data out of SQL Server into an operating-system file.
  2. Empty the table using the TRUNCATE TABLE statement.
  3. Drop all indexes on the table. (This step is optional.)
  4. Use the bcp utility to copy the table data back into SQL Server.
  5. Re-create all indexes on the table. (This step is optional.)
Nonclustered indexes (1 < indid < 255)

There are two ways to correct this error on a nonclustered index. You can either drop the index or create a clustered index.

Dropping the index

To drop the index, follow this procedure:

  1. To determine the index name, execute the following query in the database in question:
    select name from sysindexes
where id = object_id and indid = index_id

    In this example, object_id is the ID of the table and index_id is the indid of the page involved in this error (obtained using the DBCC PAGE statement).

  2. Drop and re-create the nonclustered index identified in the results of the query.
Creating a clustered index

You can correct this error on a nonclustered index by creating a clustered index on the table, because creating a clustered index on a table forces all nonclustered indexes on the table to be rebuilt. Note, however, that this method might not be suitable for large tables because of the overhead required for creating clustered indexes.


Error 2572

Severity Level 10

Message Text

Database '%.*s' is not in single user mode ¾ may find spurious allocation problems due to transactions in progress.

Explanation

This error occurs when you execute dbcc checkalloc on a database that is not in single-user mode. The error will appear and dbcc checkalloc will continue to execute.

If the database is not in single-user mode, dbcc checkalloc may report errors that do not reflect the actual state of your database. These errors are referred to as spurious.

Action

If errors are reported after executing dbcc checkalloc, run dbcc checkalloc in single-user mode. Any errors reported then are real errors. Be sure to reset the single-user option back to false, as shown in the following example:

use master
go

exec sp_dboption pubs, 'single user', true
go

DBCC CHECKALLOC ('pubs')
go

exec sp_dboption pubs, 'single user', false
go

For details on modifying database options, see the sp_dboption system stored procedure in the Microsoft SQL Server Transact-SQL Reference.


Error 2573

Severity Level 16

Message Text

Database '%.*s' is not marked suspect. You cannot drop it with DBCC.

Explanation

This error occurs when you attempt to drop a database using dbcc dbrepair. Only databases marked as suspect can be dropped using this method.

A database can be marked suspect by the following:

  • SQL Server if it detects critical errors
  • The system administrator, in order to drop it by using dbcc dbrepair

Action

Try to drop the database using the drop database statement. If this fails, see dbcc in the Microsoft SQL Server Transact-SQL Reference for more information on dropping databases.


Error 2601

Severity Level 14

Message Text

Attempt to insert duplicate key row in object '%.*x' with unique index '%.*s'

Explanation

This error occurs when you attempt to put duplicate index values into a column or columns that have a unique index. SQL Server does not allow two rows to have the same index value (including NULL) in columns that have a unique index. SQL Server checks for duplicate values when the index is created and each time the table is modified using the insert or update statement.

Action

If you need duplicate index values in the indexed column(s), drop the unique index and create a nonunique index.

To use a unique index on data that contains duplicate values, you must change some values to prevent the duplication. You can change the data already in the table by using the select or update statement, or you can change the data to be inserted.

For more information about indexes, see the CREATE INDEX statement in the Microsoft SQL Server Transact-SQL Reference.


Error 2610

Severity Level 22

Message Text

Could not find leaf row in nonclustered index'%.*s' that corresponds to data row from logical data page %Id, row offset %d during update index attempt after data page split.

Explanation

This error most commonly occurs after insert operations when a data page is full and needs to be split. In a table with a clustered index, a data page split will occur when the row to be inserted will come sequentially after the last row in an already full page, before the first row on the next page. When this data page split occurs, the index nodes in the clustered index, and in all nonclustered indexes, must be updated.

Action

You can usually correct this error by dropping and re-creating the index.

If this error indicates a corrupt system table index, drop and recreate your system tables indexes:

USE master
go
sp_dboption <db_name>,single,true
go

USE <db_name>
go

CHECKPOINT
go

sp_fixindex <db_name>,<system_table_name>,1
go

USE master
go

sp_dboption <db_name>,single,false
go

USE <db_name>
go

If the problem persists, contact your primary support provider. Have the output from the appropriate DBCC statements available for review.


Error 2615

Severity Level 14

Message Text

Attempt to insert duplicate row in table '%.*s' with index '%.*s' in database '%.*s'. Could drop and recreate index with ignore duprow or allow duprow

Explanation

This error occurs when you attempt to insert a duplicate row into a table that has a clustered index. By default, tables with clustered indexes do not allow duplicate rows.

Action

You can change the clustered index to allow duplicate rows or you can delete duplicate rows.

To allow duplicate rows, create the clustered index with the allow_dup_row option. Duplicate rows can then be created using the insert or update statement, as shown here:

create clustered index idx_pubname
on publishers(pub_name) with ALLOW_DUP_ROW
go

Do not use this method if you have a unique index on any columns in the table. Unique indexes are only used on tables that do not allow duplicate rows.

To delete duplicate rows, you can create the clustered index with the ignore_dup_row option, as shown here:

create clustered index idx_pubname
ON publishers(pub_name) with IGNORE_DUP_ROW
go

Existing duplicate rows will be deleted when the index is created. Future attempts to enter a duplicate row with the INSERT or UPDATE statement are ignored and the INSERT or UPDATE is canceled. If the INSERT or UPDATE is part of a transaction, the remainder of the transaction will continue.

If the duplicate data is the result of invalid data, you can change or delete the duplicate data and rerun the transaction.

Note that the allow_dup_row and ignore_dup_row options are mutually exclusive. Using them in the same create index statement causes error 1916.

For more information about indexes, see the CREATE INDEX statement in the Microsoft SQL Server Transact-SQL Reference.


Error 2620

Severity Level 21

Message Text

The offset of the row number at offset %d does not match the entry in the offset table of the following page: %S_PAGE.

Explanation

This error can occur during the recover phase of LOAD DATABASE. DBCC statements run before and after the dump often do not show any errors, which can indicate that the dump file became damaged.

Action

The problem is usually fixed only by getting a clean dump and restoring from it.

If the dump file is to be transferred across a network, use a transfer utility that has a verify option, for example, copy /v or xcopy /v. Ideally, the copied dump file should be compared with the original. You can use the Windows NT command FC /B for this.


Error 2750

Severity Level 16

Message Text

Column or parameter #%d: -- specified column precision %d is greater than the maximum precision of %d.

Explanation

This error occurs when the precision of a float, decimal or numeric column exceeds the maximum value for the specified datatype.

For decimal and numeric datatypes, SQL Server normally supports a maximum precision of 28 digits for compatibility with various front ends, such as Microsoft Visual Basic. However, if a precision greater than 28 is desired, use the /p parameter with sqlservr.exe from a Win32 command prompt. For more information on running sqlservr.exe, see the Utilities topic in the Microsoft SQL Server Transact-SQL Reference.

Action

Define the column to have a precision that falls within the allowable precision range for that datatype.


Error 2751

Severity Level 16

Message Text

Column or parameter #%d: -- specified column scale %d is greater than the specified precision of %d.

Explanation

This error occurs when the scale of a decimal or numeric column exceeds the precision value for that column.

For decimal and numeric datatypes, SQL Server normally supports a maximum precision of 28 digits for compatibility with various front ends. However, if a precision greater than 28 is desired, use the /p parameter with sqlservr.exe from a Win32 command prompt. For more information on running sqlservr.exe, see the Utilities topic in the Microsoft SQL Server Transact-SQL Reference.

Action

Specify the precision with p, which must be between 1 and the maximum precision, and the scale with s, which must be between 0 and p. If you do not specify the precision, SQL Server uses a default precision of 18. If you do not specify the scale, SQL Server uses a default scale of 0.


Error 2812

Severity Level 16

Message Text

Stored procedure '%.*s' not found.

Explanation

An attempt was made to execute a stored procedure that does not exist. If the procedure does exist (it appears when sp_help is run with no parameters), the error might have occurred because you did not fully qualify the procedure name. If the procedure is not owned by the user attempting to execute it, and it is not owned by the database owner (DBO), all references to it must include the owner name. For example, suppose user1 creates a procedure called proc1. Any users must add the owner name before the procedure name, as shown in the following example:

execute user1.proc1

Naming conventions for database objects are as follows:

[[database.]owner.]object_name.column_name

The default value for database is the current database; the default value for owner is the current user. If the current user is not the owner, the current user must specify the owner name when using the procedure. Because the owner name is part of the object name, two different users can have procedures with the same object name in the same database (for example user1.proc1 and user2.proc1). For additional information about naming conventions, see the Microsoft SQL Server Transact-SQL Reference.

The only exceptions to this naming convention are system procedures, which can be executed from any database. System procedures reside in the master database, are owned by the system administrator, and have names that begin with sp_. System procedures reference the system tables for the current database.

If error 2812 occurs while running INSTMSTR.SQL, it means that the sp_configure procedure was not found. You can ignore this message.

Action

If you do not know who owns the procedure, use sp_help to display the owner. If you run sp_help without any parameters, it displays objects owned by other users. To determine which procedures exist in a database and who owns them, use the following:

select name,owner=user_name(uid)
from sysobjects
where type = "P"

If the procedure does not appear in the output of this query, the procedure is either in a different database or does not exist.

If you do not own the procedure in question, you can avoid error 2812 by qualifying the procedure name with the owner name, as shown in the following example:

execute user1.proc1

For procedures used by many users of a database, it is usually easiest if the DBO creates the procedure. This allows any user to find the procedure without specifying an owner name.

If the procedure is not in the database where it is executed, you can avoid this error by fully qualifying the procedure name with the database name, as shown in the following example:

execute database_1.user1.proc1

The owner name is not needed if you or the DBO own the procedure. For example:

execute database_1..proc1

Execute permission must be provided so that other users can execute this procedure, but no permissions are required to see the text of the procedure.

If this error occurs on system procedures, it might be resolved by running INSTMSTR.SQL. This reinstalls all system procedures and initializes various other structures.


Error 3004

Severity Level 10

Message Text

%ld uninitialized pages encountered while dumping database %.*s. Run DBCC CHECKALLOC on this database for more information, then call technical support if there are any errors.

Explanation

Some internal storage structures (extents) were found in an abnormal state during a database dump. More specifically, a database page was found to be allocated but not initialized. Because the referenced page is not used, it is reported as an uninitialized page. This error does not affect the validity of the database dump.

Action

After the database dump is complete, run DBCC CHECKALLOC on the database in question. If no errors are reported, ignore error 3004.

Even if DBCC CHECKALLOC does not return errors, the uninitialized pages might still exist, so a subsequent database dump might display the same message. This condition is eventually resolved through normal SQL Server operations.


Error 3101

Severity Level 16

Message Text

Database in use. System Administrator must have exclusive use of database to run load.

Explanation

This error occurs when you attempt to load a database dump while users are accessing the database. You cannot use the LOAD DATABASE statement while the database is in use by any user, including yourself.

Action

Wait until all users have finished using the database, and then use the LOAD DATABASE statement. Make sure that you are not in the database being loaded when you issue the LOAD DATABASE command. Although not required, it is best to run the LOAD DATABASE statement from the master database.


Error 3105

Severity Level 16

Message Text

Data on dump will not fit into current database. Need %ld Mbyte database.

Explanation

An attempt was made to load a database dump into a database that is not as large as the dumped database. You cannot use DUMP DATABASE or LOAD DATABASE to shrink a database, regardless of the amount of actual data in the database.

Action

If your goal is to load the database from the dump, you must increase the size of the destination database to at least the configured size of the dumped database. You can do this using either the ALTER DATABASE statement or by dropping the database and then creating a larger one.

If your goal is to shrink the total size of a database, you cannot use DUMP and LOAD. You must copy all the data out of the database using bcp, drop the database, create a smaller database, create the database structure with scripts, and then reload the data with bcp.

If the destination database does not have identical data and log mapping, and identical segment mappings, as the dumped database, error 2558 might also occur. For additional information about segment mapping, see the description of error 2558.


Error 3120

Severity Level 16

Message Text

The database you are attempting to LOAD was DUMPed under a different sort order ID (%d) than the one currently running on this server (%d), and at least one of them is a non-binary sort order.

Explanation

This error occurs when you try to load a database that has a different sort order from that of the dumped database. Data does not have to be sorted in binary order.

A database cannot be loaded into SQL Server using LOAD DATABASE unless the sort order on the SQL Server that dumped the database matches the sort order on the SQL Server being loaded into.

Action

You can either move the data (using bcp rather than LOAD), or you can change the sort order on the SQL Server.

You can use the setup program to update your existing installation and rebuild the master database, but you must still rebuild all other databases yourself. For additional information, see Microsoft SQL Server Setup and Chapter 3, "Configuring Servers."


Error 3307

Severity Level 21

Message Text

Process %d was expected to hold logical lock on page %Id.

Explanation

This error occurs during a SQL Server rollback when SQL Server expects a logical lock to be held on the page displayed by the error message, but the lock was not found.

Action

If an update is made through a view that joins a user table with a virtual table such as syslocks or sysprocesses, locks may not be held properly for the duration of the user-defined transaction and can cause errors during rollback.

Do not perform updates through views that join user tables to virtual tables. Instead update the table directly and use stored procedures or triggers to disallow updates that would not be permitted through the view.


Error 3403

Severity Level 22

Message Text

Rec_init: Found that page %d had non-log object id %d while checking Syslogs allocation.

Explanation

This error can occur during startup or during database/transaction log load. It indicates that the transaction log for the database being recovered might be corrupted.

If this error occurs while loading a master database, it is sometimes due to a mismatch between master..sysusages entries in the source and the target master databases.

The following example shows the entries in sysusages that might cause this error:

Source master..sysusages:

dbid

segmap

lstart

size

vstart

------

------

------

------

------

1

7

0

1536

4

1

7

1536

2560

3588

1

7

4096

1280

6148

2

7

0

1024

2564

3

7

0

1024

1540

5

7

0

51200

33554432

6

7

0

51200

16777216

Target master..sysusages:

dbid

segmap

lstart

size

vstart

------

------

------

------

------

1

7

0

1536

4

1

7

1536

2560

8708

1

7

4096

1280

6148

2

7

0

1024

2564

3

7

0

1024

1540

5

7

0

1024

6148

6

7

1024

1536

7172

Notice that vstart for dbid 1 is 6148 in the source master..sysusages; 6148 corresponds to vstart for dbid 4 in the target master..sysusages. During the load process, vstart from the target database will be used for writing pages in the target database, so there is a chance that log pages from the master database might get written in a totally different database on the master device. This can result in a 3403 error.

Action

If this error occurs while you are loading a master database dump, you can sometimes prevent it by ensuring that the entries in the master..sysusages table for the source master database match the corresponding entries for the target master database. Do this by altering or extending the target master database similarly to the source master database. Instead of loading the master database in the target server, you can copy the master.dat file from the source server to the target server.

If this error occurs in a user database or, due to other reasons, in the master database, restore the database from a known clean backup. If the problem persists, contact your primary support provider.


Error 3414

Severity Level 10

Message Text

Database '%.*s' (dbid %d): Recovery failed. Please contact Technical Support for further instructions.

Explanation

During startup, SQL Server could not complete the recovery of the specified database.

Action

To determine why recovery failed, examine the error log for any errors prior to error 3414. It is important to examine errors that occurred before the first occurrence of error 3414 because subsequent attempts to start the server might not give the detailed error information you need to diagnose the problem. If you do not have sufficient information to recover from the previous errors, you can recover from known clean backups, or you can contact your primary support provider for assistance. Note that you cannot use the database until whatever caused the error has been corrected.


Error 3604

Severity Level 10

Message Text

Duplicate key was ignored.

Explanation

This error occurs when you attempt to insert a row that has an index value that violates the uniqueness property (unique with ignore_dup_key) on an existing index.

SQL Server ignores the statement that caused the error and continues processing the transaction.

Action

No action is necessary unless you want to insert that row into the table. If so, you can drop and re-create the index without the unique option, or you can change the data causing the uniqueness violation.

For more information about indexes, see the Microsoft SQL Server Transact-SQL Reference.


Error 4207

Severity Level 16

Message Text

DUMP TRANsaction is not allowed while the select into/bulk copy option is enabled or if a non-logged operation has occurred: use DUMP DATABASE, or disable the option with sp_dboption.

Explanation

This error occurs when you perform a non-logged operation on a database, such as bcp or SELECT INTO, followed by a DUMP TRANSACTION to a dump device. Because there is data in your database that has not been logged and the log therefore cannot be used to properly recover the database, the DUMP TRANSACTION operation is not allowed. For example, if a user executes a SELECT INTO followed by an UPDATE statement, the SELECT INTO operation is not logged, and the UPDATE results cannot be recovered from the log.

Note that simply enabling the select into/bulkcopy option does not, in itself, cause this condition. The option must be set and a non-logged operation executed before this error message is reported.

Dumping the database creates a new savepoint on which subsequent transaction logs are based. Therefore, dumping the database ensures that the non-logged changes are recoverable and dumping the transaction log to a device is once again allowed.

Action

You must perform a DUMP DATABASE. Disabling the select into/bulkcopy option using sp_dboption will not allow you to dump the log (even though the message says this is an option). To clear the 4207 error condition, you must dump the database.

You might need to use DUMP TRANSACTION WITH TRUNCATE_ONLY until you can perform a full database dump. If you must do this, you lose the ability to recover up-to-the-minute data changes in case of a media failure.


Error 4806

Severity Level 16

Message Text

Warning, reverting to slow bulk copy on table '%.*s' because BULKCOPY option not set in database '%.*s'.

Explanation

This error occurs when the select into/bulkcopy option is not set to true when using:

  • WRITETEXT
  • dbwritetext
  • SELECT INTO on a permanent table
  • bcp into a table that has no indexes or triggers

Action

Use the sp_dboption system procedure to set the select into/bulkcopy option as follows:

sp_dboption database_name 'select into/bulkcopy', true
go

use database_name
go

checkpoint
go

For information about using sp_dboption and CHECKPOINT, see the Microsoft SQL Server Transact-SQL Reference.

Additional Information

While the select into/bulkcopy option is turned on, you cannot dump the transaction log to a device because these operations are not logged and changes therefore cannot be recovered from transaction logs. In this situation, using DUMP TRANSACTION to dump the transaction log to a device produces a 4207 error message, which instructs you to use DUMP DATABASE instead. By default, the select into/bulkcopy option is turned off in newly created databases.

For copying data in, bcp is fastest if your database table has no indexes or triggers. Fast bcp (bcp on a table with no indexes or triggers) does not log data inserts in the transaction log. When you copy into a table that has indexes or triggers, a slower version of bcp is used automatically. The slow version, which logs data inserts in the transaction log, can cause the transaction log to become very large.

After backing up your database with DUMP DATABASE, you can truncate the transaction log with DUMP TRANSACTION WITH TRUNCATE_ONLY, and dump the database again (for recoverability).

For additional information about using bcp, see the Microsoft SQL Server Transact-SQL Reference.


Error 5006

Severity Level 16

Message Text

Could not find enough space on disks to extend database %.*s

Explanation

This error occurs when an alter database statement references a device that is completely full.

This error message does not usually appear in the error log. But if the device takes up the space on a physical disk drive as well as the space allocated for SQL Server, messages stating that the file system is full will appear in the error log. If this occurs, you must correct the file-system problem as well as correct the SQL Server space problem.

Note If the device is not full but the ALTER DATABASE statement requests more space than is available on that device, the database will be extended and fill up the available space on the device. No error message will be displayed.

Action

These are your options:

  • In the ALTER DATABASE statement, specify a device that is large enough. Use the sp_helpdevice and sp_helpdb system stored procedures to identify devices that have enough room.
  • Add a new device to SQL Server by using the DISK INIT statement. Then reference this device with the alter database statement.
  • There is no performance benefit to keeping a database entirely on a single device. However, if this is necessary, follow these steps:
    1. Back up all the databases on the device by dumping them to a valid dump device with the dump database statement.
    2. Drop the device by using the sp_dropdevice system stored procedure.
    3. Initialize a larger device with the disk init statement.
    4. Re-create the old databases on the new device. It is important to create the databases exactly like the old ones or errors will occur.
    5. Reload each database with the load database statement.

For information about how to safely create, dump, load, and re-create databases, see the Microsoft SQL Server Transact-SQL Reference and Part 5, "Data Management."


Error 5013

Severity Level 16

Message Text

Cannot extend the MASTER database onto any device other than 'master'. The ALTER DATABASE was aborted.

Explanation

This error occurs when you attempt to extend the master database on a device other than the master device.

Action

Extend the master database only when necessary. If you need to extend master and the master device is full, move user databases to other devices and retry the alter database statement.

If, after moving all user databases off the master device, you find that it is still too small, you can, using great caution, rebuild the master device specifying a larger size.

Caution If you choose to rebuild the MASTER device, make sure that you have a current backup of the master database. Also, be sure that you have read Part 5, "Data Management," and understand how to recover the master database and the MASTER device.


Error 5115

Severity Level 16

Message Text

I/O error during disk initialization. PHYSNAME '%.*s' may be incorrect or %ld (VSTART  SIZE) may exceed the size of the device or permissions may be wrong for the device.

Explanation

The DISK INIT statement has failed because of an incorrect physical device name, an incorrect SIZE option, a non-unique virtual device number, or a permission problem (for SQL Server for Windows NT only).

Action

The action depends on the cause of the failure.

Incorrect physical device name

If the error was caused by an incorrect physical device name, be sure you have the correct physical device name. For more information, see the description of DISK INIT in the Microsoft SQL Server Transact-SQL Reference.

Incorrect size

The SIZE option of the DISK INIT statement must be specified in 2K blocks. For example, to initialize a 10-MB device, specify 5120 for the SIZE (5120 * 2048 = 10 MB).

Virtual device number

The VDEVNO option of the DISK INIT statement must be unique. To determine which virtual device numbers have been used, use sp_helpdevice. For information about using sp_helpdevice, see the Microsoft SQL Server Transact-SQL Reference.

Note If a DISK INIT statement fails, SQL Server must be restarted before the same virtual device number can be used for the VDEVNO option.

Permission problem (for Windows NT only)

If SQL Server was started by the Administrator account, the Administrator must have permission to create a file in the directory specified by DISK INIT. Correct the permissions problem and execute the statement again. Also, see the information about virtual device numbers, above. You must restart SQL Server or use a different virtual device number when you reissue the DISK INIT statement.


Error 5701

Severity Level 0

Message Text

Changed database context to '%.*s'.

Explanation

This is an informational message indicating that the CHECKUPG.EXE utility has changed the current database context to the master database. (It has essentially executed a USE master statement.)

Action

None needed.


Error 5808

Severity Level 16

Message Text

Do not recommend ad hoc updates to system catalogues, use override option to force this configuration

Explanation

This error message occurs in one of these two situations:

  • When a user tries to use the sp_configure system stored procedure with the allow updates option
  • When a user tries to set a configuration parameter to a value that SQL Server recognizes as likely to interfere with performance or smooth operation

When the allow updates option is enabled, SQL Server allows direct updates to the system tables, so any user who can log on as the SQL Server system administrator can update the system tables directly with ad-hoc queries and can create stored procedures that update the system catalog. Incorrect changes to the system tables can cause unrecoverable database corruption or data loss.

Caution Severe problems can result from the direct manipulation of the system catalogs. Do not modify the system catalogs unless instructed to do so by your primary support provider.

Action

If you are aware of the danger and have a specific reason to enable the allow updates option (for example, you have been instructed to do so by your primary support provider), follow these steps:

  1. Enable the allow updates option:
    sp_configure 'allow updates',1
go

  2.
After making the necessary changes to the system tables, disable the allow updates option:
    sp_configure 'allow updates', 0
go
RECONFIGURE WITH OVERRIDE
go

    3.

Caution  Always perform step 2 to prevent ad-hoc queries on the system tables, which might result in unrecoverable database corruption or data loss.

.

  3.
Restart SQL Server so the changes will take effect.
    4.


Error 5813

Severity Level 16

Message Text

Unable to run with specified memory size of %ld. Please see the System Administration Guide for more information on how to calculate this number.

Explanation

A RECONFIGURE statement failed because SQL Server determined that there is not enough memory available for subsequent starts of SQL Server.

Note The calculations performed by RECONFIGURE are internal to SQL Server and do not account for computer resources, which might or might not be adequate to support the SQL Server configuration.

This error is a result of using sp_configure to make configuration changes that cannot be met using the specified value of the memory option. Because RECONFIGURE must be executed before the changes can take effect, SQL Server has a chance to verify that there will be enough memory to satisfy all requirements.

Because of the complexity of SQL Server memory allocation, RECONFIGURE cannot always detect potential problems resulting from setting configuration values too high. If such problems go undetected, SQL Server will not start. For information about using RECONFIGURE, see the Microsoft SQL Server Transact-SQL Reference.

Action

Because this error occurs when the value of the memory option is too low to allocate all requested resources, you can correct this problem by using sp_configure to increase the value of the memory option or decrease the value of other parameters.

After these changes have been made, you can execute RECONFIGURE. If the statement completes without error, the problem is probably resolved. For additional information about memory usage, see Chapter 21, "Configuration Issues."


Error 6103

Severity Level 17

Message Text

Unable to do cleanup for the killed process; received Msg %d.

Explanation

This error message occurs when another error caused a user connection to terminate abnormally. The message number that caused this error will be printed in the error 6103 message.

Action

Examine and resolve the "received message" reported in this error message.


Error 7130

Severity Level 16

Message Text

%s with no log is not valid at this time. Use sp_dboption to set the 'select into/bulkcopy' option on for database %s.

Explanation

This error occurs upon executing the writetext command or dbwritetext routine in a database that does not have the sp_dboption system stored procedure's select into/bulkcopy option enabled. Because these are non-logged operations, the option must be enabled.

Often, writetext and dbwritetext are run against a temporary table. The select into/bulkcopy option must be enabled in tempdb, or these will not run successfully.

Action

Enable the sp_dboption system stored procedure's select into/bulkcopy option for all databases affected by the query that contains a non-logged operation. To do this, the system administrator and database owners should follow these steps:

  1. Enable the option:
    USE master
go
sp_dboption database_name, 'select into/bulkcopy',true
go
USE database_name
go
CHECKPOINT
go

  2.
Verify that the change is active:
    sp_helpdb database_name
go

    3.

  3.
Execute the non-logged operation.
    4.

  4.
When the non-logged operation is complete, dump the database.

Caution  After executing a non-logged operation, do not dump the transaction log. Although the procedure may appear to succeed, you may have been dumping only empty text pages. Whenever you make non-logged changes to your database, you must use the dump database statement, because changes made by the non-logged operation cannot be recovered from transaction logs.

    5.

  5.
Return the database to its original condition by disabling the select into/bulkcopy option:
    USE master
go
sp_dboption database_name, 'select into/bulkcopy',false
go
USE database_name
go
CHECKPOINT
go

    6.

  6.
Verify that the change is active:
    sp_helpdb database_name
go

    7.

For more information about writetext and dbwritetext(), see the Microsoft SQL Server Transact-SQL Reference and Microsoft SQL Server Programming DB-Library for C. For more information about database dumps and recoverability, see Part 5, "Data Management."


Error 7901

Severity Level 16

Message Text

Page %Id was expected to be the first page of a TEXT/IMAGE value.

Explanation

This error indicates one of these two conditions:

  • The page pointer for a text or image column has been corrupted and is referencing a data page instead of a text or image page.
  • The first page of the text or image chain for a given column has not been correctly marked as a text or image page.

Action

Verify the consistency of the database by running DBCC CHECKDB and DBCC NEWALLOC.

If there are no other reported problems and you know which rows in the table are the cause of the problem, follow these steps:

  1. Attempt to create a new table that contains the offending rows. This can be done by running a SELECT statement with the INTO clause and restricting the query by using a WHERE clause so that only the offending rows are inserted into the new table.
  2. Verify that the new table contains the appropriate data.
  3. Run DBCC checktable against the temporary table.
  4. If no errors are reported in step 3, delete the offending rows from the original table.
  5. Insert the rows from the temporary table back into the original table.
  6. Drop the temporary table.
  7. Run DBCC checktable against the original table.
  8. If the problem persists, delete and re-insert the offending rows.

If you cannot determine which rows are causing the error, take the following steps:

  1. Attempt to create a copy of the table by running a SELECT statement with the INTO clause.
  2. Verify that the new table contains the appropriate data.
  3. Run DBCC checktable against the new table.
  4. If the DBCC in step 3 did not report any errors, drop the original table.
  5. Rename the new table by running:
    sp_rename new_table_name name_of_original_table
  6. Run DBCC checktable against the original table.

If the problem persists, contact your primary support provider.

Because of their potentially large size, text and image data in SQL Server is stored in a page chain independent of the page chain for the actual table. The only information stored in the table regarding a text or image column is the page number of the first page in the text or image chain. For more information, see the Text and Image Manipulation topic in the Microsoft SQL Server Transact-SQL Reference.


Error 7902

Severity Level 16

Message Text

Data size mismatch occurred while checking TEXT/IMAGE values. The first page for this value is: %Id. There were %Id bytes found, which is different from the expected data length of %Id bytes.

Explanation

This error occurs when a text or image page does not contain the correct amount of data indicated by the length stored internally in the page. This error is detected when executing DBCC CHECKDB or DBCC CHECKTABLE.

Action

Identify the exact row in the table for the text/image value that is incorrect. Follow these steps:

  1. Run DBCC PAGE for the page listed as the first %Id variable in the error text.
  2. Find the first text page in the page chain by running DBCC PAGE against each page listed as prevpg in the page header until this value is 0. The page that contains prevpg=0 will be the first text page in the chain.
  3. The row can now be uniquely identified by the text pointer value. Execute the following query to determine this row:
    select * from table
WHERE substring(textptr(text column nam>),1,4) = 0xXXXXXXXX

    0xXXXXXXXX is the hexadecimal representation of the byte- and word-swapped page number determined in step 2. The 0x prefix indicates a hexadecimal value.

    For example, if the page number determined in step 2 is page 1649, this would be 0x00000671. Swapping the positions of the first and second words and bytes within each word would result in 0x71060000. Provide this byte-swapped value in the WHERE clause to determine the exact row.

If the query does not display any text data to capture, you may be able to correct the problem by updating the text value to NULL or by deleting the row.

If this technique does not work, you may have to copy out all non-text columns to another table or restore the database from a known clean backup.

If the problem persists, contact your primary support provider. Have the full output from DBCC CHECKDB or DBCC CHECKTABLE available for review.


Error 8101

Severity Level 16

Message Text

An explicit value for the identity column in table '%.*s' can only be specified when a column list is used and IDENTITY_INSERT is ON

Explanation

You have attempted to insert a row, containing a specific identity value, into a table which contains an identity column. However, you did not provide a column list or have the IDENTITY_INSERT property enabled for the specified table.

Action

To successfully insert a specific identity row in a table containing an identity column you must provide a column list and enable the IDENTITY_INSERT option. The following example inserts identity row 2, where iID is defined as the identity column.

Table: tblTest
iID

strData

1

Jones

3

Smith

/* Enable IDENTITY_INSERT */
SET IDENTITY_INSERT tblTest ON
go

/* Insert the specified identity row using a column list */
INSERT INTO tblTest (iID, strData) values (2, "Lambert")
go

/* Disable IDENTITY_INSERT */
SET IDENTITY_INSERT tblTest OFF
go


Error 8102

Severity Level 16

Message Text

Illegal attempt to update identity column '%.*s'

Explanation

You have specifically attempted to alter the value of an identity column in the set portion of the update statement. You can only use the identity column in the where clause of the update statement.

Action

Updating of the identity column is not allowed. To update an identity column, you can use the following techniques:

To reassign all identity values, bcp the data out, drop and recreate the table with the proper seed and increment values. Then bcp the data back into the newly created table. When bcp inserts the values it will appropriately increase the values and redistribute the identity values. You can also use the INSERT INTO and sp_rename commands to accomplish the same action.

To reassign a single row you must delete the row and insert it using the SET IDENTITY_INSERT tblName ON option.


Error 8106

Severity Level 16

Message Text

Table '%.*s' does not have the identity property, unable to perform SET operation

Explanation

You have attempted to use the SET IDENTITY_INSERT property on a table that does not contain an identity column.

Action

Double check the table in question by using the sp_help tblName stored procedure to verify the identity column information.


Error 15080

Severity Level 17

Message Text

Failure using SQLMapi, check SQL Server error log.

Explanation

The sp_processmail stored procedure failed to perform one of its mail functions.

Action

If the SQL Server error log contains errors 17903 and 17951, resolve those errors first and then run the sp_processmail stored procedure again. If errors 17903 and 17951 do not appear in the error log, close and restart the client application and run the sp_processmail stored procedure again.

If error 15080 occurs again, call your primary support provider for assistance.

For more information about troubleshooting SQLMail, see Chapter 18, "Setting Up Mail."


Error 17903

Level 18

Message Text

MAPI login failure.

Explanation

A mail session could not be started for SQL Server. This error, along with error 17951, should occur in the SQL Server error log.

Action

Follow the directions given about using SQLMail in Chapter 18, "Setting Up Mail."

If this error occurs again, call your primary support provider for assistance.

For more information about troubleshooting SQLMail, see Chapter 18, "Setting Up Mail."


Error 17951

Severity Level 18

Message Text

Failed to start Microsoft Mail session.

Explanation

A mail session could not be started for SQL Server.

Action

Follow the directions given about using SQLMail in the Microsoft SQL Server Administrator's Companion.

If this error occurs again, call your primary support provider for assistance.

For more information about troubleshooting SQLMail, see Chapter 18, "Setting Up Mail."


Error 17952

Level 18

Message Text

Failed to start Microsoft Mail session. Check the errorlog file in the SQL Server directory for details.

Explanation

The xp_startmail extended stored procedure could not start a Mail session for SQL Server. This error is received by the client that performs the xp_startmail extended stored procedure.

Action

Follow the directions given about using SQLMail in Chapter 18, "Setting Up Mail."

If this error occurs again, call your primary support provider for assistance.

For more information about troubleshooting SQLMail, see Chapter 18, "Setting Up Mail."


Error 18458

Level 110

Message Text

Login failed - The maximum simultaneous user count of %d licenses for this server has been exceeded. Additional licenses should be obtained and registered via the Licensing application in the NT Control Panel.

Explanation

This error occurs when the server is set for Per Server licensing and the number of attempted client connections exceeds the number of Client Access Licenses for this server.

Action

Obtain additional Client Access Licenses or reduce the number of simultaneous client connection attempts.


Error 18459

Level 110

Message Text

Login failed - The maximum workstation licensing limit for SQL Server has been exceeded.

Explanation

This error occurs when the server is set for Per Seat licensing and a connection is attempted from a client computer that does not have a Client Access License.

Action

Obtain a Client Access License for the client computer.


Read/Write Error

Message Text

kernel: operating system error %d (%s) encountered

Explanation

SQL Server failed to read from or write to the specified location on disk. This failure is usually a result of a physical disk problem.

Action

Identify the device with the problem by selecting the row from sysdevices that has the same virtual disk number indicated in the error message:

select name, phyname from master..sysdevices
where low/power(2,24) = virtual_disk_number

The output from this query should provide the physical name of the damaged disk. Examine the disk as soon as possible and correct any problems. You can also identify the device by using the sp_diskblock procedure described below.

To quickly assess the potential severity of the problem and decide on an appropriate action:

  1. Use the sp_diskblock procedure as described in "Useful Stored Procedures" in Chapter 24, "Additional Problem-solving Techniques." The syntax is:

    sp_diskblock virtual_disk, block_number

    For example, if the read/write error message displays a virtual disk number 4 and a block number 871, use the following:

    sp_diskblock 4, 871
Virtual disk 4, block 871 corresponds to:
Logical page 1895 in the "production" database (dbid=4) on device "main".
  2. Use the DBCC PAGE statement to determine which object is using that page. For information about using DBCC PAGE, see "Associating a Page with an Object" in Chapter 24, "Additional Problem-solving Techniques."
  3. Use the information from step 2 to determine if any steps must be taken to protect your data until the disk drive can be repaires or the controller problem can be resolved.


Server Is Unnamed

Message Text

server: server is unnamed

Explanation

This informational message is displayed during SQL Server startup if the SQL Server has not been given a name using the sp_addserver system procedure. The server name referred to here is stored in the sysservers system table as well as in the @@SERVERNAME global variable. This name is used primarily for managing server-to-server communication and does not absolutely need to match the computer name of the server (but it usually should, for ease of use of replication and other multiple server actions).

Action

No action is required for this message. The SA can prevent this message by assigning a name to the server using the sp_addserver procedure, as follows:

sp_addserver sql_server_name, local

(Under Windows NT, the setup program automatically gives SQL Server the same name as the server computer.) For information about using sp_addserver, see the Microsoft SQL Server Transact-SQL Reference.

The @@SERVERNAME global variable will not reflect the name until SQL Server is restarted. Subsequently, each time SQL Server is started, the new name is displayed. For example, if the SQL Server is named MYSERVER, the message would read:

server: server name is 'MYSERVER'

Although the server name is used during server-to-server communications, specifying a name does not, in itself, facilitate this communication, and therefore does not represent a security risk. Naming all servers makes the SQL Server error logs easy to identify because the server name is contained within each log.


Error 17809 (ODS)

Severity Level 21

Message Text

Unable to connect. The maximum number of '%d' configured user connections are already connected. System Administrator can configure to a higher value with sp_configure.

Explanation

This error results when all configured user connections are in use and a request to create another SQL Server process occurs. SQL Server is not configured with enough user connections to support all requests. There is one "PSS" (Process Slot Structure) for each configured user connection.

Action

Use the sp_configure system procedure to increase the number of user connections:

  1. Set the new number for user connections. Type:
    sp_configure 'user connections', new_number
go
  2. Instruct SQL Server to accept the values by using the RECONFIGURE statement:
    RECONFIGURE
go
  3. Restart SQL Server to activate the changes.

Depending on the exact configuration of your SQL Server, each user connection requires 37K of memory, whether or not it is in use. Gradually increase the number of user connections until this error no longer occurs. When you change the user connections parameter, you may need to increase the memory parameter.


Error 17824 (ODS)

Severity Level

Message Text

Unable to write to server-side connection.

Explanation

This error can occur when a client platform hangs or has been powered off, or when a network error has occurred. This error can appear in the SQL Server error log or the Windows NT Event Viewer application log if SQL Server attempts to write results to a client connection and the write operation fails.

Action

Inspect the Windows NT Event Viewer system and application logs for information that may indicate whether or not the problem is related to the server network protocol, network card, or system configuration. Review the SQL Server-specific entries in the application log or the SQL Server error log for relevant network-related errors that may occur in conjunction with this error. If this review does not provide enough information to resolve the problem, special network monitoring tools and a review of the client's configuration may be needed.

If the problem persists, contact your primary network support provider for assistance.


Error 17825 (ODS)

Severity Level

Message Text

Unable to close server-side connection

Explanation

This error occurs if SQL Server gets an error when attempting to close the network connection to the client. Normally, this should never happen. This error is sometimes a side effect of other, more serious errors. Focus on the more serious errors first.

Action

Look in the SQL Server error log for any errors that occurred at approximately the same time as error 17825. For further help in resolving this error, consult the Microsoft Knowledge Base.


Error 17832 (ODS)

Severity Level

Message Text

Unable to read login packet(s)

Explanation

This error occurs if a client starts to connect but never successfully completes the attempt because of a client operating-system or application failure. It can also be caused when the network fails between the time a connection attempt is initiated and when it is complete.

Wide area networks are more susceptible than local area networks to this type of problem because such networks often have many routers and media types that can delay the delivery of packets to the server and/or fragment or split them.

Action

Verify that all clients connecting to the affected SQL Server are using the latest version of all the SQL Server client components, including the Net-Libraries, DB-Library, and/or ODBC drivers.


Chapter 26 System Messages

System Messages

The master..sysmessages table contains one row for each system error or warning that can be returned by SQL Server. These are the columns in the sysmessages table:

Column | Datatype | Description
error | int | Unique error number.
severity | smallint | Severity level of the error.
dlevel | smallint | Reserved for the number of the descriptive level of this message: terse, short, or long.
description | varchar(255) | Explanation of the error with placeholders for parameters.
langid | smallint NULL | Language.

This chapter lists all messages in master..sysmessages. The messages were obtained by executing the following statement:

select error, severity, description
from sysmessages
order by error
error | severity | description
1 | 10 | Version Date of last upgrade: 10/11/90.
21 | 10 | WARNING - Fatal Error %d occurred at %S_DATE. Please note the error and time, and contact your System Administrator.
101 | 15 | Line %d: SQL syntax error.
102 | 15 | Incorrect syntax near '%.*s'.
103 | 15 | The %S_MSG that starts with '%.*s' is too long. Maximum length is %d.
104 | 15 | Order-by items must appear in the select-list if the statement contains set operators.
105 | 15 | Unclosed quote before the character string '%.*s'.
106 | 16 | Too many table names in the query. The maximum allowable is %d.
107 | 15 | The column prefix '%.*s' does not match with a table name or alias name used in the query.
108 | 15 | The order-by position number '%ld' is out of range of the number of items in the select-list.
109 | 15 | There are more columns in the INSERT statement than values specified in the VALUES clause. The number of values in the VALUES clause must match the number of columns specified in the INSERT statement.
110 | 15 | There are fewer columns in the INSERT statement than values specified in the VALUES clause. The number of values in the VALUES clause must match the number of columns specified in the INSERT statement.
111 | 15 | %s must be the first command in a query batch.
112 | 15 | Variables are not allowed in %s statement.
113 | 15 | Missing end comment mark '*/'.
114 | 15 | Browse mode is invalid for a statement that assigns values to a variable.
115 | 15 | The offset '%d' given in a CONTROLROW command does not correspond to the beginning of a statement.
116 | 15 | The symbol '*' can only be used for a subquery select list when the subquery is introduced with EXISTS or NOT EXISTS.
117 | 15 | The %S_MSG name '%.*s' contains more than the maximum number of prefixes. The maximum is %d.
118 | 15 | Only System Administrator can specify %s option for %s command.
119 | 15 | Must pass parameter number %d and subsequent parameters as '@name = value'. Once the form '@name = value' has been used, all subsequent parameters must be passed in the form '@name = value'.
120 | 15 | The SELECT list for the INSERT statement contains fewer items than the INSERT list. The number of SELECT values must match the number of INSERT columns.
121 | 15 | The SELECT list for the INSERT statement contains more items than the INSERT list. The number of SELECT values must match the number of INSERT columns.
122 | 15 | The debug option '%d' is larger than the maximum allowed. The highest option available is %d.
123 | 15 | Must attach a value to the binary prefix '0x'; zero-length binary value is not allowed.
124 | 15 | CREATE PROCEDURE contains no statements.
125 | 15 | Case expressions may only be nested to level %d.
126 | 15 | Cannot nest CREATE PROCEDURE statements.
127 | 15 | This CREATE may only contain 1 statement.
128 | 15 | The name '%.*s' is illegal in this context. Only constants, constant expressions, or variables allowed here. Column names are illegal.
129 | 15 | Fillfactor '%d' is not a valid percentage; fillfactor must be between 1 and 100.
130 | 16 | Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
131 | 15 | The size (%d) given to the %S_MSG '%.*s' exceeds the maximum. The largest size allowed is %d.
132 | 15 | The label '%.*s': has already been declared. Label names must be unique within a query batch or stored procedure
133 | 15 | A GOTO statement references the label '%.*s' but the label has not been declared.
134 | 15 | The variable name '%.*s' has already been declared. Variable names must be unique within a query batch or stored procedure.
135 | 15 | Cannot use a BREAK statement outside the scope of a WHILE statement.
136 | 15 | Cannot use a CONTINUE statement outside the scope of a WHILE statement.
137 | 15 | Must declare variable '%.*s'.
138 | 15 | Illegal correlation clause in a subquery.
139 | 15 | Cannot assign a default value to a local variable.
140 | 15 | Can only use IF UPDATE within a CREATE TRIGGER.
141 | 15 | A SELECT statement that assigns a value to a variable must not be combined with data-retrieval operations.
142 | 15 | Incorrect syntax for definition of %s constraint.
143 | 15 | A compute-by item was not found in the order-by list. All expressions in the compute-by list must also be present in the order-by list
144 | 15 | Cannot use an aggregate or a subquery in an expression used for the by-list of a GROUP BY clause.
145 | 15 | Order-by items must appear in the select-list if SELECT DISTINCT is specified.
146 | 16 | Too many subqueries in the query. The maximum allowable is %d.
147 | 15 | An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference.
148 | 15 | Incorrect time syntax in time string '%.*s' used with WAITFOR.
149 | 15 | Time value '%.*s' used with WAITFOR is not a legal value. Check date/time syntax.
150 | 15 | Both terms of an outer join must contain columns.
151 | 15 | '%.*s' is an invalid money value.
152 | 15 | Subqueries that use DISTINCT with a GROUP BY clause are not currently supported.
153 | 15 | Invalid usage of the option '%.*s' in '%s' statement.
154 | 15 | %S_MSG is not allowed in %S_MSG.
155 | 15 | '%.*s' is not a recognized %s option.
156 | 15 | Incorrect syntax near the keyword '%.*s'.
157 | 15 | An aggregate may not appear in the set list of an update statement.
158 | 15 | Too many ORDER BY expressions. The maximum is %d.
159 | 15 | For DROP INDEX, must give both the table and the index name, in the form tablename.indexname
160 | 15 | Rule does not contain a variable.
161 | 15 | Rule contains more than one variable.
162 | 15 | The select list item identified by the order by number '%ld' is a '*', rather than a column name. When ordering by column number, a column name must appear in the select list position that corresponds to the order by number
163 | 15 | The COMPUTE BY list does not match the ORDER BY list.
164 | 15 | GROUP BY expressions must refer to column names that appear in the SELECT list.
165 | 16 | Privilege %s may not be GRANTed or REVOKEd.
166 | 15 | %s does not allow specifying the database name as a prefix to the object name.
167 | 16 | May not create a trigger on a temporary object.
168 | 15 | The %S_MSG '%.*s' is out of the range of machine representation (%d bytes).
169 | 15 | Column '%.*s' is specified more than once in the ORDER BY list. Columns in the ORDER BY list must be unique.
170 | 15 | Line %d: Incorrect syntax near '%.*s'.
171 | 15 | Can't use SELECT INTO in Browse Mode.
172 | 15 | Can't use HOLDLOCK in Browse Mode
173 | 15 | The definition for column '%.*s' must include a datatype.
174 | 15 | The function '%.*s' requires %d arguments.
175 | 15 | Functions may only be nested to level %d.
176 | 15 | Function '%.*s' is not yet implemented.
177 | 15 | The IDENTITY function can only be used when the SELECT statement has an INTO clause.
178 | 15 | A RETURN statement with a return status may only be used in a stored procedure.
179 | 15 | Can't use the OUTPUT option when passing a constant to a stored procedure.
180 | 15 | There are too many parameters in this CREATE PROCEDURE statement. The maximum number is %d.
181 | 15 | Can't use the OUTPUT option in a DECLARE statement.
182 | 15 | Table and column names must be supplied for the READTEXT or WRITETEXT utility.
183 | 15 | The scale (%d) for column '%.*s' must be within the range %d to %d.
184 | 15 | Invalid money datatype specification for column '%.*s'. Only money(19, 4) is allowed for non-external tables.
185 | 15 | Data stream is invalid for WRITETEXT command in bulk form.
186 | 15 | Data stream missing from WRITETEXT command.
187 | 15 | Odd number of bytes in IMAGE data.
188 | 15 | Can't specify a log-device in a CREATE DATABASE statement without also specifying at least one non-log-device.
189 | 15 | Function '%.*s' requires %d to %d arguments.
190 | 15 | Can not update the global variable '%.*s'.
191 | 15 | Some part of your SQL statement is nested too deeply. Please re-write the query or break it up into smaller queries.
192 | 15 | Constant expressions are not allowed in ORDER BY lists.
193 | 15 | The object or column name starting with '%.*s' is too long. The maximum length is %d characters.
194 | 15 | A SELECT INTO statement may not contain a SELECT statement that assigns values to a variable.
195 | 15 | '%.*s' is not a recognized %S_MSG.
196 | 15 | SELECT INTO must be the first query in a SQL statement containing set operators.
197 | 15 | Set operators may not appear within the definition of a view.
198 | 15 | Browse mode is invalid for statements containing set operators.
199 | 15 | An INSERT statement may not contain a SELECT statement that assigns values to a variable.
201 | 16 | Procedure %.*s expects parameter %.*s, which was not supplied.
202 | 11 | Internal error -- Unable to open table at query execution time.
203 | 16 | The name '%.*s' is not a valid identifier.
204 | 20 | Normalization error; node %s
205 | 16 | All queries in a SQL statement containing set operators must have an equal number of expressions in their target lists.
206 | 16 | Operand type clash: %s is incompatible with %s
207 | 16 | Invalid column name '%.*s'.
208 | 16 | Invalid object name '%.*s'.
209 | 16 | Ambiguous column name %.*s
210 | 16 | Syntax error converting DATETIME from BINARY/VARBINARY string.
211 | 16 | Syntax error converting SMALLDATETIME from BINARY/VARBINARY string.
212 | 16 | Expression result length exceeds maximum: max - %d found - %d
213 | 16 | Insert error: column name or number of supplied values does not match table definition.
214 | 16 | Cannot convert parameter %.*s to type %.*s expected by procedure.
216 | 16 | Attempt to drop temporary object(s) failed during cleanup processing.
217 | 16 | Maximum stored procedure nesting level exceeded (limit %d).
218 | 16 | Given parameter %.*s is too large; maximum size for this parameter is %d bytes.
219 | 16 | Print format failed to match with a result column.
220 | 16 | Arithmetic overflow error for type %s, value = %ld.
222 | 20 | Unintelligible query plan step encountered.
223 | 11 | Object %ld specified as a default for tabid %ld, colid %d is missing or not of type default.
224 | 11 | Object %ld specified as a rule for tabid %ld, colid %d is missing or not of type default.
225 | 11 | Cannot run query--referenced object (name %.*s) dropped during query optimization.
226 | 16 | %s command not allowed within multi-statement transaction.
227 | 16 | Maximum number of vector aggregates exceeded (%d max, %d found).
228 | 14 | Query is based on a view that no longer exists (id = %ld)--cannot run.
229 | 14 | %s permission denied on object %.*s, database %.*s, owner %.*s
230 | 14 | %s permission denied on column %.*s of object %.*s, database %.*s, owner %.*s
231 | 11 | Getdefault: no such default. id=%ld dbid=%d
232 | 16 | Arithmetic overflow error for type %s, value = %f.
233 | 16 | The column %.*s in table %.*s may not be null.
234 | 16 | There is insufficient result space to convert MONEY value to CHAR.
235 | 16 | Cannot convert CHAR value to MONEY. The CHAR value has incorrect syntax.
236 | 16 | The conversion from CHAR to MONEY resulted in a MONEY overflow error.
237 | 16 | There is insufficient result space to convert MONEY value to %s.
238 | 16 | There is insufficient result space to convert %s value (= %d) to MONEY.
239 | 16 | Table '%.*s' does not exist. Please refer to Sysobjects for correct name.
240 | 16 | There is insufficient result space to convert DATETIME value to CHAR.
241 | 16 | Syntax error converting DATETIME from character string.
242 | 16 | The conversion of CHAR to DATETIME resulted in a DATETIME value out of range.
243 | 16 | Type '%.*s' is not a defined system type.
244 | 16 | The conversion of CHAR value '%.*s' overflowed an INT1 field, use a larger integer field.
245 | 16 | Syntax error converting CHAR value '%.*s' to an INT1 field.
246 | 16 | The conversion of CHAR value '%.*s' overflowed an INT2 field, use a larger integer field.
247 | 16 | Syntax error converting CHAR value '%.*s' to an INT2 field.
248 | 16 | The conversion of CHAR value '%.*s' overflowed an INT4 field. Maximum integer value exceeded.
249 | 16 | Syntax error converting CHAR value '%.*s' to an INT4 field
251 | 16 | Unable to allocate ancillary table for query optimization. Maximum number of tables in a query (%d) exceeded.
252 | 16 | Can't group by a bit field.
253 | 16 | Maximum number of group-by expressions exceeded (16 max, %d found).
254 | 16 | Maximum number of columns in a work table (%d) exceeded.
255 | 16 | Maximum row size (%d) for a work table exceeded.
256 | 16 | The data type '%s' is invalid for the %s function. Allowed types are: CHAR/VARCHAR and BINARY/VARBINARY.
257 | 16 | Implicit conversion from datatype '%s' to '%s' is not allowed. Use the CONVERT function to run this query.
258 | 20 | Database '%.*s' missing during query recompile.
259 | 16 | Ad-hoc updates to system catalogs not enabled. System Administrator must reconfigure system to allow this.
260 | 16 | Disallowed implicit conversion from datatype '%s' to datatype '%s'%s Table: '%s', Column: '%s'%s Use the CONVERT function to run this query.
261 | 16 | '%.*s' is not a recognized global variable.
262 | 16 | %s permission denied, database %.*s, owner %.*s
263 | 16 | Must specify table to SELECT * FROM.
264 | 16 | Column name %.*s appears more than once in the result column list.
265 | 16 | Syntax error converting CHAR value '%.*s' to a BIT field. Field contains non-numeric value(s).
266 | 16 | Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRAN is missing. Previous count = %ld, Current count = %ld.
267 | 16 | Object '%.*s' cannot be found.
268 | 16 | You can't run SELECT INTO in this database. Please check with the Database Owner.
269 | 16 | SETUSER with no name should be invoked from the database where the corresponding SETUSER with name was issued. Use database '%.*s'.
270 | 16 | Table '%.*s' can't be modified.
272 | 16 | Can't update a TIMESTAMP column.
273 | 16 | The user can't INSERT a non-null value into a TIMESTAMP column. Use INSERT with a column list or with a default of NULL for the TIMESTAMP column.
274 | 20 | A SYSTEM exception was raised with an unrecognized minor number %d.
275 | 16 | TEXT and IMAGE datatypes may not be used in an aggregate expression.
276 | 16 | The parameter '%.*s' in the procedure '%.*s' was not declared as an OUTPUT parameter.
277 | 23 | A transaction begun in this stored procedure that did updates in tempdb is still active. This will cause a corruption of tempdb that will exist until the server is rebooted. All BEGIN TRANs must have matching COMMITs or ROLLBACKs.
278 | 16 | TEXT and IMAGE datatypes may not be used in a GROUP BY clause.
279 | 16 | TEXT and IMAGE datatypes are invalid in this subquery or aggregate expression.
280 | 16 | Only TEXT and IMAGE datatypes are valid with the TEXTPTR function.
281 | 16 | %d is not a valid style number when converting from DATETIME to a character string.
282 | 10 | Procedure '%.*s' attempted to return a status of NULL, which is not allowed. A status of 0 will be returned instead.
283 | 16 | You can't use browse mode with DBLIB 2.0 -- you must upgrade to DBLIB 4.0 in order to run this query.
284 | 16 | Rules may not be bound to TEXT or IMAGE datatypes.
285 | 16 | READTEXT and WRITETEXT commands may not be used with views.
286 | 16 | The logical tables INSERTED and DELETED may not be updated.
287 | 16 | %s command not allowed within a trigger.
288 | 16 | The PATINDEX function operates on CHAR, VARCHAR, and TEXT datatypes only.
290 | 16 | Trace 3604 is illegal within a stored procedure
292 | 16 | There is insufficient result space to convert SMALLMONEY value to CHAR.
293 | 16 | Cannot convert CHAR value to SMALLMONEY. The CHAR value has incorrect syntax.
294 | 16 | The conversion from CHAR to SMALLMONEY resulted in a SMALLMONEY overflow error.
295 | 16 | Syntax error converting SMALLDATETIME from character string.
296 | 16 | The conversion of CHAR to SMALLDATETIME resulted in a SMALLDATETIME value out of range.
297 | 16 | There is insufficient result space to convert SMALLDATETIME value to CHAR.
298 | 16 | The conversion from DATETIME to SMALLDATETIME resulted in a SMALLDATETIME overflow error.
299 | 16 | The function DATEADD was called with bad type '%s'.
301 | 16 | Query contains an illegal outer-join request.
303 | 16 | The table '%.*s' is an inner member of an outer-join clause. This is not allowed if the table also participates in a regular join clause.
304 | 16 | The table '%.*s' is outer-joined with itself.
305 | 16 | The column '%.*s' (user type:%.*s) is joined with '%.*s' (user type:%.*s). The user types are not compatible: user types must be identical in order to join.
306 | 16 | TEXT and IMAGE datatypes may not be used in the WHERE or HAVING clause, except with the LIKE predicate and the IS NULL predicate.
307 | 16 | Index id %d on table '%.*s' (specified in the FROM clause) does not exist.
308 | 16 | Index '%.*s' on table '%.*s' (specified in the FROM clause) does not exist.
309 | 16 | Unable to allocate ancillary table for reformatting. Maximum number of tables in a query (%d) exceeded.
401 | 16 | Unimplemented command or expression %s
403 | 16 | Invalid operator for datatype op: %s type: %s
404 | 19 | Too many ANDs or ORs in expression (limit %d per expression level). Try splitting query or limiting ANDs and ORs.
405 | 20 | Cannot route query results - query internal representation corrupted.
406 | 23 | Ord_needed: Can't find index for varno=%d, objid=%ld.
407 | 19 | Unable to allocate ancillary table for query optimization. Maximum number of tables in a query (%d) exceeded.
408 | 20 | Is_var: Unknown data type %d
409 | 16 | The %s operation cannot take a %s datatype as an argument.
410 | 20 | Compute clause #%d, 'by' expression #%d is not in the order-by list.
411 | 20 | Compute clause #%d, aggregate expression #%d is not in the select list.
412 | 16 | Cannot update more than 1 Sysindexes row at a time.
414 | 16 | The current query would generate a key size of %d for a work table. This exceeds the maximum allowable limit of %d.
415 | 16 | The current query would require an index on a work table to be built with %d keys. The maximum allowable number of keys is %d.
416 | 16 | Create of work table failed because the row size would be %d. This exceeds the maximum allowable size of a row in a table, %ld.
418 | 20 | Can't find the real column name corresponding to the column heading '%.*s'.
420 | 16 | TEXT and IMAGE datatypes may not be used in an ORDER BY clause.
421 | 16 | TEXT and IMAGE datatypes may not be selected as DISTINCT.
422 | 19 | Too many nested expressions or logical operators to compile. Try splitting query or limiting ANDs and ORs.
423 | 16 | Too many substitution nodes in worktable. (MAX: %d, ACTUAL: %d). Try splitting query or limiting SELECT list.
424 | 10 | %s
425 | 16 | Datatype '%s' of receiving variable not equal to datatype '%s' of column '%.*s'.
426 | 16 | Length '%d' of receiving variable less than length '%d' of column '%.*s'.
427 | 20 | Unable to load SYSPROCEDURES entries for constraint id '%d' in dbid '%d'.
428 | 20 | Unable find row in SYSCONSTRAINTS for constraint id '%d' in dbid '%d'.
429 | 20 | Unable to find new constraint id '%d' in SYSCONSTRAINTS, dbid '%d' at compile time.
430 | 20 | Unable to resolve table name for object id '%d', dbid '%d' when compiling foreign key.
431 | 19 | Unable to bind foreign key constraint. Too many tables involved in query.
432 | 19 | Unable to bind work table for foreign key constraint. Too many tables involved in query.
433 | 20 | Unable to find CHECK constraint for '%.*s' though table is flagged as having one.
434 | 20 | Insert into worktable for variable '%d' for deferred constraint check failed.
435 | 20 | Unable to open referencing table id '%d' in dbid '%d'.
436 | 20 | Unable to open referenced table id '%d' in dbid '%d'.
437 | 20 | Unable to resolve the referenced column name in table id '%d'.
438 | 20 | Unable to resolve the referencing column name in table id '%d'.
439 | 20 | Unable to find foreign key constraints for table '%.*s' in dbid '%d' though table is flagged as having them.
440 | 20 | Unable to resolve column name for dbid '%d', object id, '%d', column id '%d' in constraint '%.*s'.
501 | 20 | There is no result-list for a SELECT statement.
502 | 18 | Internal error encountered in merging rows; resubmit query batch.
503 | 16 | Stored procedure '%.*s' is a replication filter and cannot be executed.
504 | 11 | Stored procedure '%.*s' not found.
505 | 16 | Current user account was invoked with SETUSER. Changing databases is not allowed.
508 | 20 | No begin-row pointer found in plan.
509 | 11 | User name '%.*s' not found.
510 | 20 | Bad eop type 0x%x .
511 | 16 | Updated or inserted row is bigger than maximum size (%d bytes) allowed for this table.
512 | 16 | Subquery returned more than 1 value. This is illegal when the subquery follows =, !=, <, <= , >, >=, or when the subquery is used as an expression.
513 | 16 | A column insert or update conflicts with a rule imposed by a previous CREATE RULE command. The command was aborted. The conflict occurred in database '%.*s', table '%.*s', column '%.*s'
514 | 16 | Expression stack overflow. Usually this is because built-in functions have been nested too deeply. Try to rephrase the query using less deeply nested functions.
515 | 16 | Attempt to insert the value NULL into column '%.*s', table '%.*s'; column does not allow nulls. %s fails.
516 | 18 | Attempt to get system date/time failed.
517 | 16 | Adding a value to a %s field caused overflow.
518 | 16 | Cannot convert type '%s' to type '%s'.
519 | 16 | Overflow resulted from MONEY multiplication.
520 | 16 | Overflow resulted from MONEY division.
521 | 16 | Overflow resulted from MONEY addition.
522 | 16 | Overflow resulted from MONEY subtraction.
523 | 16 | Overflow resulted from %s minus operation
524 | 16 | Overflow resulted from MONEY remainder (modulo) operation.
526 | 18 | SQL Server has run out of alarms. Re-run your command when there are fewer users running WAITFOR.
527 | 20 | Cannot remove alarm.
528 | 20 | System error detected during attempt to use upsleep system call.
529 | 16 | Explicit conversion from datatype '%s' to '%s' is currently unimplemented.
530 | 16 | Attempt to insert NULL value into column %d in work table (table id %ld); column does not allow NULLS. %s fails.
532 | 16 | The timestamp (changed to %.*s) shows that the row has been updated by another user.
533 | 20 | Can't find a range table entry for range %d.
534 | 16 | TEXT and IMAGE datatypes require DBLIB version 4.0 or greater.
535 | 16 | Difference of two datetime fields caused overflow at runtime.
536 | 16 | Invalid length parameter passed to the substring function.
537 | 16 | Overflow resulted from a SMALLMONEY remainder operation.
538 | 16 | '%.*s' cannot be found. This language might have been dropped. Please see your System Administrator.
540 | 1 | Schema for table '%.*s' has changed since compilation of this query. Please re-execute query.
542 | 16 | An invalid datetime value was encountered. Value exceeds year 9999.
544 | 16 | Attempting to insert explicit value for identity column in table '%.*s' when IDENTITY_INSERT is set to OFF
545 | 16 | Explicit value must be specified for identity column in table '%.*s' when IDENTITY_INSERT is set to ON
546 | 16 | Identity value overflow for column '%.*s' while inserting into table '%.*s'
547 | 16 | %s statement conflicted with %s %s constraint '%.*s'. The conflict occurred in database '%.*s', table '%.*s'%s%.*s%s
548 | 16 | attempt to perform direct %s to range that is maintained by replication. The conflict occurred in database '%.*s', table '%.*s'%s%.*s%s
549 | 16 | data exists in table '%.*s', database '%.*s', that violates %s constraint '%.*s' being added. ALTER command has been aborted.
550 | 16 | The attempted insert or update failed because the target view either specifies WITH CHECK OPTION or spans a view which specifies WITH CHECK OPTION and one or more rows resulting from the operation did not qualify under the CHECK OPTION constraint.
601 | 21 | Descriptor for system table '%ld' in database '%d' not found in the descriptor hash table.
602 | 21 | Could not find row in Sysindexes for dbid '%d', object '%ld',index '%d'. Run DBCC CHECKTABLE on Sysindexes.
603 | 19 | There are not enough system session descriptors available to run this query. The maximum number available to a process is %d. Split query and rerun.
604 | 21 | Could not find row in Sysobjects for object '%ld' in database '%.*s'. Run DBCC checktable on Sysobjects.
605 | 21 | Attempt to fetch logical page %ld in database '%.*s' belongs to object '%.*s', not to object '%.*s'.
606 | 16 | Error %d encountered while reading without locking, command is terminated.
607 | 21 | Insufficient room was allocated in the session descriptor for object '%.*s' for search arguments. Only %d search arguments were anticipated.
608 | 21 | Buffer holding logical page %ld of object '%.*s' in database '%.*s' was not kept in the first or second slot of the session descriptor for that object during a scan.
610 | 19 | Maximum number of databases that may be accessed by a transaction is 8. This number has been exceeded by this query.
611 | 21 | Attempt made to end a transaction that is idle or in the middle of an update.
612 | 21 | Attempt made to log a row of unknown type %d.
613 | 21 | Request made to retrieve more rows from an already completed scan of object '%.*s' in database '%.*s'.
614 | 21 | A row on page %ld was accessed that has an illegal length of %d in database '%.*s'.
615 | 21 | Unable to find database table id = %d, name = '%.*s'.
616 | 20 | Attempt to hash a previously hashed descriptor for object '%.*s' in database '%.*s'.
617 | 20 | Descriptor for object '%ld' in database '%d' not found in the hash table during attempt to unhash it.
618 | 21 | A varno of %d was passed to opentable - the largest valid value is %d.
619 | 20 | A deferred update was requested but the query is not one of INSERT, DELETE or UPDATE.
620 | 21 | Log record encountered at deferred update time with either a row length of less than 2 or an invalid log type. The log type was %d and the row length was %d.
621 | 21 | A log record was encountered of type %d that is not one of the valid deallocation types.
622 | 20 | Opentable was passed a varno of %d. Object '%.*s' already has that session descriptor in use.
623 | 21 | Attempt to retrieve row from page via RID failed because logical page %ld is not a data page. %S_RID. %S_PAGE.
624 | 21 | Attempt to retrieve row from page via RID failed because the requested RID has a higher number than the last RID on the page. %S_RID.%S_PAGE.
625 | 21 | Could not retrieve row from logical page %ld via RID because the entry in the offset table (= %d) for that RID (= %d) is less than or equal to 0.
626 | 21 | Tried to read a data page instead of an index page. %S_PAGE.
627 | 20 | A transaction tried to call beginupdate while in state 'prepare'.
628 | 13 | Attempt to issue 'SAVE TRANsaction' when there is no active transaction
629 | 21 | Fatal attempt to delete clustered index entry for page %ld - index row contains page %ld
630 | 21 | The end of page limit has been exceeded while building an offset table for object %ld on page %ld.
631 | 21 | The length of %d passed to delete row routine for the row at offset %d is incorrect on the following page: %S_PAGE
632 | 20 | Memmove() was called with a length of %d - maximum allowed length is 2048.
633 | 21 | The PG_DEALLOC bit set by recovery is on at runtime on the following page. %S_PAGE.
634 | 20 | Memmove() was called with an address of 0x%lx and a length of %d - which would cross a 2k boundary.
635 | 20 | Process %d tried to remove DES resource lock that it doesn't hold - %S_DES .
637 | 20 | Index shrink program returned invalid status of 0.
638 | 20 | Memmove() was called with an address of 0x%lx - which is not allocated memory.
639 | 21 | Attempt to fetch logical page %ld dbid %d failed - page is not currently allocated.
640 | 21 | Attempt to insert/delete row on wrong type of page. %S_PAGE.
641 | 21 | Attempt to add BEGINUPDATE record in transaction %S_RID that already has an active CMD.
642 | 20 | Attempt to begin update in transaction %S_RID which already has an active transaction.
643 | 20 | Attempt to read page %d in database '%.*s' which is not allocated.
644 | 21 | The non_clustered leaf row entry for page %ld row %d was not found in index page %ld indexid %d database '%.*s'
649 | 21 | Could not find the clustered index entry for Page %ld Objid %ld status 0x%x. Index page %ld was searched for this entry in database '%.*s'
701 | 19 | There is insufficient system memory to run this query.
702 | 20 | Memory request for %d bytes exceeds the size of single page of %d bytes.
704 | 20 | Tried to free procedure header 0x%lx, but it's still in use by procedure '%.*s' at procedure buffer 0x%lx.
705 | 19 | There is no room for process %d to store PROC_HDR 0x%lx in Pss.
706 | 20 | Process %d tried to remove PROC_HDR 0x%lx that it does not hold in Pss.
707 | 20 | System error detected during attempt to free memory at address 0x%lx. Please consult the SQL Server error log for more details.
801 | 20 | Process %d tried to remove resource lock it doesn't hold on buffer 0x%lx - %S_PAGE.
803 | 20 | Unable to place buffer 0x%lx holding logical page %ld in sdes for object '%.*s' - either there is no room in sdes or buffer already in requested slot.
804 | 20 | Unable to find buffer 0x%lx holding logical page %ld in sdes 0x%lx kept buffer pool for object '%.*s'.
805 | 21 | Unable to find descriptor for object '%.*s' in database '%.*s' in hash table when marking buffer dirty or flushing Syslogs.
806 | 21 | Could not find virtual page for logical page %ld in database '%.*s'
807 | 10 | Logical page %ld in buffer 0x%lx already kept in SDES for object '%.*s' in database '%.*s'.
808 | 20 | Alloc page buffer pool in Pss is full - logical pages %ld, %ld, and %ld in respective databases '%.*s', '%.*s' and '%.*s' are already held there. Cannot add logical page %ld in database '%.*s'
809 | 20 | Buffer 0x%lx, alloc pg %ld, in database '%.*s' not in alloc buf pool in Pss.
810 | 20 | Attempt to pin log page buffer
811 | 21 | Attempt to grab buffer which is on descriptor chain
812 | 21 | Attempt to grab a pinned buffer
813 | 20 | Logical page 0x%lx in database %d is already hashed.
814 | 20 | Keep count of buffer 0x%lx holding logical page %ld in database %.*s has become negative.
815 | 21 | Unable to find buffer holding Sysindexes page in the cache - pageno = %ld dbid = %d
816 | 20 | Process %d tried to remove a buffer resource lock %S_BUF that it does not hold in SDES %S_SDES
817 | 20 | Process %d tried to remove a buffer resource lock %S_BUF that it does not hold in Pss 0x%lx.
818 | 19 | There is no room to hold the buffer resource lock %S_BUF in SDES %S_SDES
819 | 19 | There is no room for process %d to hold buffer resource lock %S_BUF in Pss
820 | 21 | Attempt to dirty non-log buffer %S_BUF which is in I/O.
821 | 20 | Attempt to unhash buffer at 0x%lx with a buffer pageno of %ld and database id %d with HASHED status set failed - buffer was not found. %S_PAGE.
822 | 21 | Could not start I/O for request %S_BLKIOPTR.
823 | 24 | I/O error detected during %S_MSG for %S_BUF.
824 | 21 | Attempt made to write page in buffer in database that has no entry in Sysdatabases. %S_BUF.
825 | 21 | Attempt made to write page in buffer in database with no DBTABLE structure - Sysdatabases row marked as in use by process %d. %S_BUF.
826 | 20 | Attempt made to hold allocation page %ld that is already in Pss pool. Database '%.*s'.
827 | 20 | Attempt to dirty page %ld which is not kept in database '%.*s.
840 | 17 | Device '%.*s' (with physical name '%.*s', and virtual device number %d) is not available. Please contact System Administrator for assistance.
901 | 21 | Unable to find descriptor for database '%d' object '%ld' in hash table after hashing it.
902 | 24 | Hardware error detected reading logical page %ld, virtual page %ld in database '%.*s'.
903 | 22 | Unable to find row in Sysindexes for clustered index on system catalog %ld in database %d. This index should exist in all databases. Run DBCC CHECKTABLE on Sysindexes in the database.
904 | 22 | Unable to find master database row in Sysdatabases. Cannot open master database.
905 | 17 | Unable to allocate a DBTABLE descriptor to open database '%.*s'. Another database must be closed or dropped before opening this one.
906 | 22 | Could not locate row in Sysobjects for system catalog '%.*s' in database '%.*s'. This system catalog should exist in all databases. Run DBCC CHECKTABLE on Sysobjects in this database.
908 | 22 | Unable to find any entries in Sysusages for dbid '%d', database '%.*s'. Run DBCC CHECKTABLE on Sysusages in the master database.
909 | 21 | More than %d entries required to build the logical-virtual translation table for database '%.*s'. The database is too fragmented.
910 | 17 | Could not allocate a new object descriptor for required system catalog in database '%d'. Another database must be closed or objects in another database dropped in order to open this database.
911 | 16 | Attempt to locate entry in Sysdatabases for database '%.*s' by name failed - no entry found under that name. Make sure that name is entered properly.
912 | 21 | DBTABLE descriptor cannot be found for database '%.*s' which is supposed to be already open.
913 | 22 | Could not find row in Sysdatabases with database id %d. Run DBCC CHECKTABLE on Sysdatabases.
915 | 21 | Descriptor for system catalog '%.*s' not found in DBTABLE chain for database '%.*s' - all system catalogs should reside permanently in this chain.
916 | 14 | Server user id %d is not a valid user in database '%.*s'
917 | 20 | Illegal attempt to close the master database for the last time - this database must always be open.
918 | 14 | Database '%.*s' has not yet been recovered - please wait before accessing this database.
919 | 21 | Database '%.*s' has been marked 'suspect' by recovery. Please run DBCC to drop this database.
920 | 22 | Could not find Syslogs row in Sysindexes for database '%.*s'. Run DBCC CHECKTABLE on this system catalog.
921 | 14 | Database '%.*s' has not been recovered yet - please wait and try again.
922 | 14 | Database '%.*s' is being recovered - will wait until recovery is finished.
923 | 14 | User %d not allowed in database '%.*s' - only the owner of this database can access it.
924 | 14 | Database '%.*s' is already open and can only have one user at a time.
925 | 19 | Maximum number of used databases for each query has been exceeded. The maximum allowed is %d.
926 | 14 | Database '%.*s' cannot be opened - it has been marked SUSPECT by recovery. The SA can drop the database with DBCC.
927 | 14 | Database '%.*s' cannot be opened - it is in the middle of a load.
928 | 14 | Database '%.*s' cannot be opened - it is currently being created. Wait and try query again.
929 | 20 | Attempting to close a database which is not open. Please report to Technical Support.
930 | 14 | Database '%.*s' cannot be opened because an earlier system termination left LOAD DATABASE incomplete. Reload the database or notify the System Administrator.
931 | 21 | Database '%.*s' cannot be opened because of a failure to initialize the global timestamp. This indicates that a problem exists in the log for the current database. Please contact Technical Support for assistance.
932 | 22 | Database '%.*s' cannot be opened because the log for the current database is corrupt. Page %ld of the log is linked to a page that belongs to a database object with id %ld. Please contact Technical Support for assistance.
933 | 22 | Logical page %ld of the log encountered while retrieving highest timestamp in database '%.*s' is not the last page of the log and we are not currently recovering that database.
935 | 10 | WARNING - the timestamp in database '%.*s' is approaching the maximum allowed.
1001 | 16 | Line %d: Length or precision specification %d is invalid.
1002 | 16 | Line %d: Specified scale %d is invalid.
1003 | 15 | Line %d: %s clause allowed only for %s.
1004 | 15 | Line %d: Use of %s not allowed; use %s.
1005 | 15 | Line %d: Invalid procedure number (%d). Minimum procedure number is 1.
1006 | 15 | CREATE TRIGGER contains no statements.
1007 | 15 | The %S_MSG '%.*s' is out of the range for numeric representation (%d bytes).
1008 | 15 | The select list item identified by the order by number '%d' contains a variable as part of the expression that identifies a column position. Variables are only allowed when ordering by an expression referencing a column name.
1101 | 17 | Unable to allocate new page for database '%.*s'. There are no more pages available on valid allocation pages. Space can be created by dropping objects, extending the database, or dumping the log with no_log.
1102 | 22 | Unable to locate allocation page %ld for database '%.*s'. This allocation page contains the extent that the target allocation page is in, but the allocation page is not in the translation table in the DBTABLE. Run DBCC CHECKTABLE on Sysusages.
1103 | 21 | Allocation page %d in database '%.*s' has different segment id than that of the object to which we are allocating. Run DBCC CHECKALLOC.
1104 | 20 | Conflict between number of extents marked in log record in the allocation bitmap and the allocation count. Allocation count is %d. Bitmap is 0x%lx %lx %lx %lx.
1105 | 17 | Can't allocate space for object '%.*s' in database '%.*s' because the '%.*s' segment is full. If you ran out of space in Syslogs, dump the transaction log. Otherwise, use ALTER DATABASE or sp_extendsegment to increase the size of the segment.
1106 | 20 | First pass through allocation page %d found %d free extents. After logging, only found %d free extents.
1108 | 21 | Cannot deallocate extent %ld, database %d. Object id %ld, index id %d, status %d in extent does not match object id %ld, index id %d, status %d in object being deallocated. Run DBCC CHECKALLOC.
1109 | 21 | Attempt to read allocation page %ld failed either because object ID is not correct (%ld) or the page ID is not correct (%ld).
1110 | 20 | Attempt to resource lock allocation page %d in database '%.*s' by process %d while allocating to non-Syslogs object '%.*s'.
1111 | 20 | Extent bitmap on allocation page %d in database '%.*s' does not have extents marked that are being removed.
1113 | 20 | Extent %d already locked while allocating it in database '%.*s'.
1114 | 20 | Attempt to resource lock page %d in database '%.*s' by process %d failed because lock is already held by process %d.
1115 | 20 | Attempt to transfer a resource lock to process ID 0 on allocation page %d in database '%.*s'.
1116 | 20 | Attempt to backout the allocation of LOG page %ld, in database '%.*s'.
1117 | 21 | Extent chain for object %ld is not correctly linked.
1118 | 17 | Database %.*s is full. Cannot allocate space for object %.*s. All available pages are held by other transactions. Try your command again.
1201 | 20 | Page_lock was called with illegal mode %d.
1202 | 20 | Table_lock was called with illegal mode %d.
1203 | 20 | Caller of lock manager is incorrectly trying to unlock an unlocked object. spid=%d locktype=%d dbid=%d lockid=%ld.
1204 | 19 | SQL Server has run out of LOCKS. Re-run your command when there are fewer active users, or ask your System Administrator to reconfigure SQL Server with more LOCKS.
1205 | 13 | Your server command (process id #%d) was deadlocked with another process and has been chosen as deadlock victim. Re-run your command.
1206 | 20 | Locksleep was called with incorrect process id. Process %d is trying to sleep on itself
1207 | 20 | Locksleep called with bad process id %d
1208 | 20 | Extent_lock was called with illegal mode %d.
1209 | 20 | Internal lock routine called with illegal mode %d
1210 | 20 | No matching xdes found for dbid %d. Lock was requested for objid %ld, by process %d. Lock requested was %s.
1211 | 13 | Process %d was chosen as deadlock victim with P_BACKOUT bit set.
1501 | 20 | Sort failure
1503 | 20 | Sort failure: too many sort keeps (%d)
1505 | 14 | Create unique index aborted on duplicate key. Primary key is '%S_KEY'
1507 | 10 | Warning: deleted duplicate row. Primary key is '%S_KEY'
1508 | 14 | Create index aborted on duplicate rows. Primary key is '%S_KEY'
1509 | 20 | Row compare failure
1510 | 17 | Sort failed: Out of space or locks in database '%.*s'
1511 | 20 | Sort cannot be reconciled with transaction log
1513 | 20 | Reuse of extent failed in sort
1514 | 21 | Page allocated to sort found to be busy. Page number %ld. %S_BUF.
1515 | 20 | Bad session descriptor for sort
1519 | 20 | An attempt was made to keep a sort buffer in a slot where a buffer was already kept. Buffer pointer: 0x%lx Slot: %d.
1520 | 18 | Sort failed because dpages in the Sysindexes row for table '%.*s' in database '%.*s' had an incorrect value. Please run DBCC CHECKTABLE on this table to correct the value, then re-run your commmand.
1521 | 18 | Sort failed because a table in tempdb used for the processing of the query had a bad data page count. Tempdb should not have been damaged.
1522 | 20 | Sort failure. Prevented overwriting of allocation page in database '%.*s' by aborting sort.
1523 | 20 | Sort failure. Prevented incorrect extent deallocation by aborting sort.
1525 | 21 | Sort Failure. Rollforward of sort encountered sort descriptor timestamps out of sequence. Old timestamp in log: %04x %08lx. New timestamp in log: %04x %08lx. Timestamp in sort descriptor: %04x %08lx.
1528 | 21 | Character data comparison failure. An unrecognized Sort-Map-Element type (%d) was found in the server-wide default sort table at SMEL entry [%d].
1529 | 21 | Character data comparison failure. A list of Sort-Map-Elements from the server-wide default sort table does not end properly. This list begins at SMEL entry [%d].
1530 | 16 | Create index with sorted_data was aborted because of row out of order. Primary key of first out of order row is '%S_KEY'
1531 | 16 | The sorted_data option cannot be used for a nonclustered index if the keys are not unique within the table. Create index was aborted because of duplicate keys. Primary key is '%S_KEY'.
1601 | 21 | No resources available to start '%s' process. Use sp_configure to increase the number of user connections.
1602 | 21 | Unable to initialize network %d
1603 | 21 | Process priority %d invalid or no process slots available
1604 | 21 | Process not runnable or kpid %d not within range
1605 | 21 | Failed to open virtual socket for new connections
1606 | 21 | Failed to initialize network receive buffer
1607 | 21 | Failed to initialize network send buffer
1608 | 21 | A network error was encountered while sending results to the front end. Check the SQL Server errorlog for more information.
1609 | 21 | Kpid %d out of range
1610 | 21 | Could not kill process %d
1611 | 21 | Could not install quit function
1612 | 21 | Could not install attention function
1613 | 21 | Could not close network %d connection for server process %d.
1614 | 21 | Could not yield process
1615 | 21 | Process unable to sleep
1616 | 21 | Failed to flush receive stream buffer
1617 | 21 | Could not infect process %d
1619 | 21 | Could not open TEMPDB, unable to continue.
1620 | 21 | Failure to open master db for the first time
1621 | 18 | Type '%c' not allowed before login.
1622 | 18 | Type '%c' not implemented.
1701 | 16 | Creating table '%.*s' failed because row size would be %d. This exceeds the maximum allowable size of a row in a table, %d.
1702 | 16 | Create table failed because column '%.*s' in table '%.*s' exceeds the maximum of 250 columns.
1703 | 17 | Failed to allocate disk space for a work table in database '%.*s'. You may be able to free up space by using the DUMP TRANsaction command, or you may want to extend the size of the database by using the ALTER DATABASE command.
1704 | 16 | Only the SA can create the system table '%.*s'.
1705 | 16 | Must create system table '%.*s' in the Master Database.
1706 | 16 | System table '%.*s' was not created, because ad-hoc updates to system catalogs are not enabled.
1707 | 18 | Could not create system table '%.*s'.
1708 | 15 | The total row size, %d, for table '%.*s' exceeds the maximum number of bytes per row, %d.
1750 | 10 | Unable to create constraint. See previous errors.
1752 | 16 | Unable to create DEFAULT for column '%.*s' as it is not a valid column in table '%.*s'.
1753 | 16 | Column '%.*s.%.*s' is not of same length as referencing column '%.*s.%.*s' in foreign key '%.*s'.
1754 | 16 | DEFAULTS cannot be created on columns with an IDENTITY attribute. Table '%.*s', column '%.*s'.
1755 | 16 | DEFAULTS cannot be created on columns of type TIMESTAMP. Table '%.*s', column '%.*s'.
1756 | 10 | Skipping foreign key constraint '%.*s' definition for temporary table.
1757 | 10 | Unable to create DEFAULT constraint. See previous errors.
1758 | 20 | Unable to update category field for ADD constraint.
1759 | 16 | Invalid column '%.*s' specified in constraint definition.
1760 | 16 | Constraints of type %s cannot be created on columns of type %s.
1761 | 16 | Foreign key '%.*s' references invalid database '%.*s'.
1762 | 16 | '%.*s' is not a valid constraint.
1763 | 16 | Cross database foreign key references are not supported. Foreign key '%.*s'.
1764 | 20 | Unable to update category field for %s table.
1765 | 20 | %s
1766 | 16 | Foreign key references to temporary tables are not supported. Foreign key '%.*s'.
1767 | 16 | Foreign key '%.*s' references invalid table '%.*s'.
1768 | 16 | Foreign key '%.*s' references object '%.*s' which is not a user table.
1769 | 16 | Foreign key '%.*s' references invalid column '%.*s' in referencing table '%.*s'.
1770 | 16 | Foreign key '%.*s' references invalid column '%.*s' in referenced table '%.*s'.
1771 | 16 | Foreign key '%.*s' references object '%.*s' which is not a table.
1772 | 16 | Foreign key '%.*s' defines invalid relationship between a user table and system table.
1773 | 16 | Foreign key '%.*s' has implicit reference to object '%.*s' which does not have a PRIMARY KEY defined on it.
1774 | 16 | Number of columns in referencing column list for foreign key '%.*s' does not match those of the PRIMARY KEY in the referenced table '%.*s'.
1775 | 16 | Number of columns in referencing column list for foreign key '%.*s' does not match those of the referenced key in the referenced table '%.*s'.
1776 | 16 | There are no primary or candidate keys in the referenced table '%.*s' that match the referencing column list in the foreign key '%.*s'.
1777 | 14 | User does not have correct permissions on referenced table '%.*s' to create foreign key '%.*s'.
1778 | 16 | Column '%.*s.%.*s' is not of same type as referencing column '%.*s.%.*s' in foreign key '%.*s'.
1779 | 16 | Table '%.*s' already has a PRIMARY KEY defined on it.
1780 | 20 | Could not find column '%d' in SYSCOLUMNS for object id '%d' in dbid '%d'.
1781 | 16 | Column already has a DEFAULT bound to it.
1782 | 20 | Unable to update syscolumns to bind constraint based DEFAULT.
1783 | 20 | Unable to open table '%s' in dbid '%d' for constraint processing.
1784 | 20 | Unable to open system table '%s' in dbid '%d' for constraint processing. Ensure that this database has been correctly upgraded.
1801 | 16 | Database '%.*s' already exists
1802 | 11 | CREATE DATABASE failed. Some disk names listed in command were not found. Check that names exist and are spelled correctly before re-running
1803 | 17 | CREATE DATABASE failed. Could not allocate enough disk space for a new database on the disks named in the command. Total space allocated must be at least %d Mbytes (%ld 2048-byte pages) to accommodate copy of Model Database.
1804 | 10 | There is no disk named '%.*s'. Checking other disk names.
1805 | 10 | CREATE DATABASE: allocating %ld pages on disk '%.*s'
1807 | 17 | MODEL database in use, cannot create new database. Check with your system administrator before re-running CREATE DATABASE
1808 | 21 | Crdb_disk : default disk not found. Cannot complete create/alter database command
1809 | 14 | CREATE DATABASE must be preceded by a 'USE master' command. Check with your DBO (or System Administrator) if you do not have permission to USE master.
1810 | 16 | CREATE DATABASE failed because of incorrect size parameter(s). Total number of megabytes specified must be at least %d megabytes so that the Model Database can be copied to the new database.
1811 | 16 | '%.*s' is the wrong type of device for CREATE or ALTER database. Please check Sysdevices. The CREATE or ALTER is aborted.
1813 | 16 | Cannot open new database '%.*s'. CREATE DATABASE is aborted.
1814 | 10 | Problem creating Temporary Database - if out of space, please extend and reboot. If some other problem, please contact Technical Support.
1816 | 16 | CREATE DATABASE failed because the log device '%.*s' has no space available.
1819 | 16 | Could not create database '%.*s'.
1901 | 16 | Column '%.*s' -- Can't create index on a column of BIT data type.
1902 | 16 | Cannot create more than one clustered index on table '%.*s'. Drop the existing clustered index '%.*s' before creating another
1903 | 16 | %d is the maximum allowable size of an index. Composite index specified is %d bytes.
1904 | 16 | Cannot specify more than %d column names for index key list. %d specified.
1905 | 21 | Could not find 'zero' row for index '%.*s' the table in Sysindexes.
1906 | 11 | Cannot create an index on table '%.*s', because this table does not exist in database '%.*s'.
1907 | 16 | Create index on non-empty table not supported yet
1908 | 16 | Too many parameters -- symbol table overflow.
1909 | 16 | Can't use duplicate column names in index key list. Column name '%.*s' listed more than once.
1910 | 16 | Cannot create more than %d indexes on one table.
1911 | 16 | Column name '%.*s' does not exist in target table.
1913 | 16 | There is already an index on table '%.*s' named '%.*s'
1914 | 16 | Cannot create index on object '%.*s' because it is not a user table.
1915 | 16 | Only the owner of table '%.*s' or the System Administrator may create an index on it.
1916 | 16 | CREATE INDEX options %s and %s are mutually exclusive.
1918 | 10 | Non-clustered index (index id = %d) is being rebuilt.
1919 | 16 | Column '%.*s' -- Can't create index on a column of TEXT or IMAGE data type.
2001 | 10 | Cannot use duplicate parameter names. Parameter name '%.*s' listed more than once.
2002 | 10 | Cannot use variable '%.*s' without first declaring it.
2004 | 16 | Procedure '%.*s' has already been created with group number %d - create procedure with an unused group number
2007 | 11 | Cannot add rows to Sysdepends for the current stored procedure because it depends on the missing object '%.*s'. The stored procedure will still be created.
2008 | 16 | The object '%.*s' is not a procedure so you cannot create another procedure under that group name.
2103 | 16 | Cannot create a trigger on a view, name: %.*s
2106 | 11 | Cannot create a trigger on table '%.*s', because this table does not exist in database '%.*s'.
2108 | 16 | Cannot CREATE TRIGGER on table '%.*s',because you can only create a trigger on a table in the current database.
2109 | 16 | Cannot CREATE TRIGGER on table '%.*s', that accesses 'inserted' or 'deleted' because the table was created with the no_log option
2201 | 16 | Could not open file/device %s OS/2 errno=%d. Check mode of db file.
2202 | 21 | Could not translate virtual read address to device and seek vaddr=0x%x.
2203 | 24 | Could not seek to vaddr 0x%x for read. Fd=%d errno =%d.
2204 | 24 | Could not read complete record. Count=%d fd=%d errno =%d.,
2205 | 21 | Could not translate virtual write address to device and seek vaddr=0x%x.
2206 | 24 | Could not seek to vaddr 0x%x for write. Fd=%d errno =%d.
2207 | 24 | Could not write complete record. Count=%d fd=%d errno =%d.
2208 | 21 | Tried to read unopened device vaddr=0x%x.
2209 | 21 | Tried to write unopened device vaddr=0x%x.
2210 | 16 | Tried to write database without using -w or -W flag.
2301 | 19 | Operating System allocation call failed.
2501 | 16 | Table named %.*s not found; check Sysobjects
2502 | 16 | Table Corrupt: A page is linked in more than one chain; check this page:page number=%ld allocation status=%d
2503 | 16 | Table Corrupt: Page linkage is not consistent; check the following pages: (current page#=%ld; page# pointing to this page=%ld; previous page# indicated in this page=%ld)
2504 | 16 | Table Corrupt: The index id in alloc page does not match the index id in Sysindexes (alloc page#=%ld; extent id=%ld; index id in alloc=%d; index id in Sysindexes=%d)
2505 | 16 | Table Corrupt: Free offset in page header is not reasonable; free offset should be >= 32 and <= 2048; check this page and offset (page#=%ld freeoffset on the page header=%d)
2506 | 16 | Table Corrupt: The values in adjust table should be in ascending order starting from the end of the table (page#=%ld row#=%d); check adjust table in this row
2507 | 16 | Table Corrupt: Offset table is incorrect (page#=%ld row#=%d offset in offset table is=%d correct offset is=%d)
2508 | 16 | Table Corrupt: Row length is incorrect (page#=%ld row#=%d minimum row length=%d row length=%d)
2509 | 16 | Table Corrupt: The row number and offset of each row in the page should have a matching entry in row number table; check this page (page#=%ld row#=%d offset in row number table=%d)
2510 | 16 | Table Corrupt: Keys do not match between leaf page %ld and data page %ld; check row # %d on the data page
2511 | 16 | Table Corrupt: Keys in %S_MSG should be in ascending order; check page number %ld
2512 | 16 | Table Corrupt: The specified row number %d in index page %ld cannot be found on data page %ld
2513 | 16 | Table Corrupt: Object id %ld (object name = %.*s) does not match between %.*s and %.*s
2514 | 16 | Table Corrupt: Type id %ld (type name = %.*s) does not match between %.*s and %.*s
2516 | 16 | Table Corrupt: Segment number %d does not match between %.*s and %.*s
2517 | 16 | Table Corrupt: Procedure id %d (procedure name = %.*s) does not match between %.*s and %.*s
2518 | 16 | Database Corrupt: Incorrect last checkpoint in Syslogs
2519 | 16 | Database Corrupt: The last checkpoint in Sysdatabases is incorrect. Syslogs recorded a different checkpoint
2520 | 16 | Database named %.*s not found; check Sysdatabases
2521 | 16 | Table Corrupt: Page is linked but not allocated; check the following pages and table: alloc page#=%ld extent id=%ld logical page#=%ld object id in extent=%ld (object name = %.*s) index id in extent=%d
2522 | 16 | Table Corrupt: The object id %ld (object name = %.*s) in page# %ld is different from the object id %ld (object name = %.*s) in Sysindexes
2523 | 16 | Table Corrupt: Page number %ld is out of range for this database %.*s. The maximum page number in this database is %ld
2524 | 16 | Table Corrupt: Row length is inconsistent between the computed row length and the recorded row length on page; check the following page and row: pageno=%ld row#=%d computed row length=%d row length on page=%d
2525 | 16 | Table Corrupt: Object id wrong; tables: alloc page %ld extent id=%ld l page#=%ld objid in ext=%ld (name = %.*s) objid in page=%ld (name = %.*s)objid in sysindexes=%ld (name = %.*s)
2526 | 16 | Incorrect DBCC command. Please check the Commands Reference Manual for the correct DBCC syntax and options.
2527 | 10 | DBCC detected internal database inconsistancy; see your System Administrator.
2528 | 10 | DBCC execution completed. If DBCC printed error messages, see your System Administrator.
2529 | 16 | Table Corrupt: Page %ld not found
2531 | 16 | Table Corrupt: Index id on extent should be 0; check the following page and ids: alloc page=%ld extent=%ld index id on extent=%d
2532 | 16 | Table Corrupt: No Syslogs entry in Sysindexes.
2533 | 16 | Table Corrupt: Incorrect index key length %d in internal (sarg) structure.
2534 | 16 | Table Corrupt: No keys found on index page %ld. Offset for the free space: (freeoff=%ld)
2535 | 16 | Table Corrupt: Page# %ld belongs to object id %ld (object name = %.*s) not object id %ld (object name = %.*s)
2536 | 10 | Checking %.*s
2537 | 10 | Checking %ld
2538 | 10 | Alloc page %ld (# of extent=%ld used pages=%ld ref pages=%ld)
2539 | 10 | Total (# of extent=%ld used pages=%ld ref pages=%ld) in this database
2540 | 16 | Table Corrupt: Page is allocated but not linked; check the following pages and ids: allocation pg#=%ld extent id=%ld logical pg#=%ld object id on extent=%ld (object name = %.*s) indid on extent=%ld
2541 | 16 | Table Corrupt: object id does not match between extent in allocation page and Sysindexes; check the following extent: alloc pg#=%ld extent#=%ld object id on extent=%ld (object name = %.*s) object id in Sysindexes=%ld (object name = %.*s)
2542 | 16 | Table Corrupt: Extent is linked in more than one chain. Check the following allocation page and extent: alloc pg#=%ld extent#=%ld status=%d
2543 | 16 | Table Corrupt: Extent structures are linked incorrectly; check the following extent: alloc pg#=%ld extent#=%ld previous extent# on this extent=%ld previous extent should be=%ld
2544 | 16 | Table Corrupt: Extent id %ld on allocation pg# %ld had object id %ld (object name = %.*s) on but used bit off
2545 | 16 | Table Corrupt: Extent#=%ld on allocation pg#=%ld was used but object id was 0,
2546 | 16 | Table Corrupt: Extent id %ld on allocation pg# %ld has objid %ld and used bit on, but reference bit off.
2547 | 16 | Table Corrupt: Segment number %d specified for use in the segment map in Sysusages has no entry in Syssegments. The entry in Sysusages is for dbid %d (db name = %.*s), with a virtual starting address of %ld.
2548 | 16 | There is no default segment specified in Syssegments.
2549 | 16 | There is more than one default segment specified in Syssegments.
2550 | 16 | Missing segment in Sysusages segmap.
2551 | 10 | The following segments have been defined for database %d (database name %.*s).
2552 | 10 | virtual start addr size segments
2553 | 10 | -------------------- ------ --------------------------
2554 | 10 | %20ld %ld
2555 | 10 | %d
2556 | 20 | Page #%lx of Sysindexes in database %d not found in cache after read.
2557 | 16 | Must be owner of object '%.*s' to run DBCC %s on it.
2558 | 16 | Extent not within segment: Object %ld, indid %d includes extents on allocation page %ld which is not in segment %d.
2559 | 16 | Data page number %ld is empty but is not the first page. Status = 0x%x.
2560 | 16 | Incorrect parameter passed to DBCC command.
2561 | 16 | Unable to open log for database %d.
2562 | 16 | %s cannot access object '%.*s' because it is not a table.
2563 | 14 | Only the DBO of database %.*s may run the DBCC CHECKCATALOG command.
2564 | 14 | Only the DBO of database %.*s may run the DBCC CHECKDB command.
2565 | 14 | Only the DBO of database %.*s may run the DBCC CHECKALLOC command.
2567 | 14 | Only the DBO of database %.*s may run the DBCC DBREPAIR command.
2568 | 16 | Page %ld is out of range for this database
2570 | 10 | Warning - Page %ld has DEALLOC bit on - indid %d, status 0x%x
2571 | 10 | Only the System Administrator may use the DBCC command '%.*s'.
2572 | 10 | Database '%.*s' is not in single user mode - may find spurious allocation problems due to transactions in progress.
2573 | 16 | Database '%.*s' is not marked suspect. You cannot drop it with DBCC.
2574 | 16 | Index page number %ld is empty. Status = 0x%x.
2575 | 16 | The last page %ld in Sysindexes for table '%.*s' has next page # %ld in its page header. The next page # should be NULL. Please check Sysindexes.
2576 | 16 | The %S_MSG page %ld specified in Sysindexes for table '%.*s' can not be found. Please check Sysindexes.
2577 | 16 | The root page %ld in Sysindexes for table '%.*s' has next page # %ld and previous page # %ld in its page header. Both the next page # and the previous page # should be NULL. Please check Sysindexes.
2578 | 16 | The first page %ld in Sysindexes for table '%.*s' has previous page # %ld in its page header. The previous page # should be NULL. Please check Sysindexes.
2579 | 10 | The total number of data pages in this table is %ld.
2580 | 16 | The clustered index page (%S_PAGE) has an unexpected key pointer to an overflow data page (%S_PAGE). Please check page status.
2581 | 16 | Data page (%S_PAGE) indicates that an overflow page is linked to it; however, the next page (%S_PAGE) has not been marked as an overflow page. Please check page status.
2582 | 16 | Data page (%S_PAGE) has been marked as an overflow page; however, the previous page (%S_PAGE) does not indicate that there is an overflow page linked to it.
2584 | 16 | The last key in the previous page (%S_PAGE) is equal to the first key in the current page (%S_PAGE); however, the status of current page does not indicate that it is an overflow page.
2585 | 16 | The last key in the previouse page (%S_PAGE) is equal to the first key in the current page (%S_PAGE); however, the status of previous page indicates that there is a disconnected overflow page.
2586 | 16 | The last key in the previouse page (%S_PAGE) is equal to the first key in the current page (%S_PAGE); however, the status of previous page indicates that there is no overflow page.
2587 | 16 | The last key in the previouse page (%S_PAGE) is not equal to the first key in the current page (%S_PAGE); the current page is an overflow page; however, the status of previous page indicates that there is no disconnected overflow page.
2588 | 16 | Page %d was expected to be the first page of a TEXT/IMAGE value.
2589 | 16 | Object '%.*s' must have its status updated in Sysobjects, to reflect the intent of repairing the index on it.
2590 | 16 | DBCC option available for system tables only.
2591 | 16 | Could not find index row which has id %d for table '%.*s'.
2592 | 10 | %s index successfully restored for object '%.*s' in the '%.*s' database.
2593 | 10 | There are %ld rows in %ld pages for object '%.*s'.
2594 | 16 | Invalid index id specified (index id = %d).
2595 | 16 | Database '%.*s' must be set to single user mode before executing this command.
2596 | 16 | %S_PAGE has an incorrect pgfreeoff value of %d. The offset should be %d.
2597 | 16 | The database is not open. Please issue a 'use %.*s' and re-run the DBCC command.
2598 | 16 | Indexes on Sysobjects and Sysindexes cannot be recreated.
2601 | 14 | Attempt to insert duplicate key row in object '%.*s' with unique index '%.*s'
2603 | 21 | No space left on logical page %ld of index %d for object '%.*s' when inserting row on index page - this situation should have been taken care of while traversing the index
2610 | 22 | Could not find leaf row in nonclustered index '%.*s' that corresponds to data row from logical data page %ld, row offset %d during update index attempt after data page split.
2613 | 20 | Attempt to remove resource lock on buffer holding logical page %d failed - the buffer was not resource locked.
2615 | 14 | Attempt to insert duplicate row in table '%.*s' with index '%.*s' in database '%.*s'. Could drop and recreate index with ignore duprow or allow duprow.
2616 | 20 | Buffer holding logical page %d cannot move to slot 1 since buffer holding logical page %d is already there.
2617 | 20 | Buffer holding logical page %d not found in keep pool in SDES for object '%.*s'
2618 | 20 | Couldn't find dupkey group starting at offset %d on page 0x%x.
2619 | 20 | Keys did not match overflow page when inserting row at end of page that has overflow page that is not disconnected.
2620 | 21 | The offset of the row number at offset %d does not match the entry in the offset table of the following page: %S_PAGE.
2621 | 20 | Process %d already has the buffer we are using for an allocation resource locked: %S_PAGE.
2622 | 21 | Insufficient room on this page to insert a row of length %d. %S_PAGE.
2623 | 21 | The PG_DEALLOC bit is on in this page at runtime - should have been turned off by deallocating page in recovery. %S_PAGE.
2624 | 21 | Insert into table %S_DES fails because rowlength %d is less than minlen %d.
2625 | 20 | Deadlock encountered in log allocation for database '%.*s'. This state should not be reached.
2626 | 21 | Illegal attempt to insert duplicate key row in the clustered index for object '%.*s' in database '%.*s'.
2627 | 14 | Violation of %s constraint '%.*s': Attempt to insert duplicate key in object '%.*s'.
2701 | 10 | Database name '%.*s' ignored, referencing object in Tempdb.
2702 | 16 | Database '%.*s' does not exist.
2703 | 16 | Segment '%.*s' does not exist.
2705 | 16 | Column names in each table must be unique. Column name '%.*s' in table '%.*s' is specified more than once.
2706 | 11 | Table '%.*s' does not exist.
2710 | 16 | You are not the owner specified for the object named '%.*s' in this command (CREATE, ALTER, TRUNCATE, UPDATE STATISTICS, or BULK INSERT). The database owner can use the SETUSER command to assume the identity of another user.
2714 | 16 | There is already an object named '%.*s' in the database.
2715 | 16 | Column or parameter #%d: Can't find type '%.*s'.
2716 | 16 | Column or parameter #%d: -- can't specify a column width on type '%.*s'.
2717 | 16 | Column or parameter #%d: -- specified column width too large for type '%.*s'.
2718 | 16 | Column or parameter #%d: -- can't specify Null values on a column of type BIT.
2721 | 11 | Could not find a default segment to create the table on. Ask your System administrator to specify a default segment in Syssegments.
2724 | 10 | Parameter '%.*s' has an invalid data type.
2727 | 11 | Cannot find index '%.*s'.
2728 | 21 | Could not find Sysobjects row for table '%.*s'.
2729 | 16 | Object '%.*s' group number 1 already exists in the database. Choose another procedure name
2730 | 11 | Cannot create procedure '%.*s' with a group number of %d because a procedure with the same name and a group number of 1 does not currently exist in the database. Must CREATE PROCEDURE '%.*s';1 first.
2731 | 16 | Column or parameter #%d: -- can't specify column width of zero for '%.*s'.
2732 | 16 | User error number %ld is invalid. Number must be between %ld and %ld.
2734 | 16 | User name %.*s does not exist in Sysusers.
2735 | 16 | Object text is too long - can only support 255 rows in Syscomments. Shorten the object text or split into multiple objects. Text which caused overflow starts at: '%.*s'.
2736 | 16 | Owner name that was specified is a group name. Objects cannot be owned by groups.
2737 | 16 | Message passed to %s must be of type CHAR or VARCHAR.
2738 | 16 | A table can only have one timestamp column. Since table '%.*s' already has one, you can't add the column '%.*s'.
2739 | 16 | TEXT and IMAGE datatypes are invalid for local variables.
2740 | 16 | SET LANGUAGE failed because '%.*s' is not an official language name or a language alias on this SQL Server.
2741 | 16 | SET DATEFORMAT date order '%.*s' is invalid.
2742 | 16 | SET DATEFIRST %d is out of range.
2743 | 16 | %s command requires %S_MSG parameter.
2744 | 16 | Multiple identity columns specified for table '%.*s', only one identity column per table
2745 | 10 | Process %d has raised user error %d, severity %d. SQL Server is terminating this process.
2746 | 16 | Cannot specify user error format string with length exceeding %d bytes.
2747 | 16 | Too many substitution parameters for raiserror. Cannot exceed %d substitution parameters.
2748 | 16 | Cannot specify %s datatype(raiserror parameter %d) as substitution parameter for raiserror.
2749 | 16 | Identity column '%.*s' must be of type int, smallint, tinyint, decimal or numeric with scale of 0 and constrained to be non-nullable.
2750 | 16 | Column or parameter #%d: -- specified column precision %d is greater than the maximum precision of %d.
2751 | 16 | Column or parameter #%d: -- specified column scale %d is greater than the specified precision of %d.
2752 | 16 | Identity column '%.*s' contains invalid SEED.
2753 | 16 | Identity column '%.*s' contains invalid INCREMENT.
2754 | 16 | Error severity greater than %d can be specified only by System Administrator by using the WITH LOG option.
2755 | 16 | SET DEADLOCK_PRIORITY option '%.*s' is invalid.
2756 | 16 | Invalid value %d for State; Valid range is from %d to %d.
2757 | 16 | Raiserror failed due to invalid parameter substitution(s) for error %d, severity %d, state %d.
2758 | 16 | %s could not locate entry for error %d in Sysmessages.
2802 | 20 | Both the tree and plan pointer are set; Ambiguous procedure.
2804 | 20 | Stored procedure '%.*s' is out of sync with its own procedure header.
2805 | 20 | Bad pointer 0x%lx encountered while remapping stored procedure '%.*s'. Must re-create procedure.
2806 | 20 | Stored procedure '%.*s' is corrupted. Must re-create procedure.
2807 | 18 | Process %d could not unlock stored procedure '%.*s' because the procedure is not currently locked by that process.
2808 | 18 | Incorrect object structure returned from getobject.
2809 | 18 | The request for %S_MSG '%.*s' failed because '%.*s' is a %S_MSG object.
2810 | 18 | Cache reports negative usage count for procedure '%.*s'.
2811 | 18 | Cannot create procedure dbid %d, objid %d, with a group number of %d.
2812 | 16 | Stored procedure '%.*s' not found.
2813 | 20 | Procedure %.*s in procedure buffer 0x%lx not properly linked with procedure header 0x%lx.
2814 | 20 | Procedure %.*s in procedure buffer 0x%lx does not contain the same object id as procedure header 0x%lx.
2815 | 20 | Procedure %.*s in procedure buffer 0x%lx contains page address 0x%lx which is not aligned on a 2K boundary.
2816 | 20 | Procedure %.*s in procedure buffer 0x%lx contains page address 0x%lx which is not within any memory map.
2817 | 20 | Procedure %.*s in procedure buffer 0x%lx contains page address 0x%lx which should be allocated.
2818 | 20 | You must provide both name and object id in order to install a procedure.
2819 | 20 | You must provide both name and object id in order to remove a procedure.
2821 | 16 | You must drop and recreate procedure %.*s.
2822 | 20 | Bad version number encountered for procedure %.*s.
2823 | 20 | Process %d tried to remove a PROC_BUF 0x%lx named '%.*s' that it does not hold in the hold procedure linked list.
2824 | 19 | Process %d cannot hold PROC_BUF 0x%lx named '%.*s' because it holds another PROC_BUF 0x%lx named '%.*s'. A process can only hold one view, rule, or default at a time.
2825 | 20 | Process %d tried to remove a PROC_BUF 0x%lx named '%.*s' that it does not hold.
2826 | 20 | Process %d has held the PROC_BUF 0x%lx named '%.*s' in the hold procedure linked list already; Check your procedure cache.
2827 | 20 | Procedure '%.*s' in procedure buffer 0x%lx is not properly hashed.
3001 | 21 | Internal error. Could not find index for system catalog '%.*s', unable to dump database.
3002 | 23 | Attempt to dump database %.*s found logical page %ld when logical page %ld expected.
3004 | 10 | %ld uninitialized pages encountered while dumping database %.*s. Run DBCC CHECKALLOC on this database for more information, then call technical support if there are any errors.
3005 | 16 | DUMP DATABASE has been interrupted by a USER ATTENTION signal.
3101 | 16 | Database in use. System Administrator must have exclusive use of database to run load.
3102 | 16 | Specified file '%.*s' is not in valid dump database format.
3103 | 10 | Unexpected end-of-dump while loading database, attempting to continue. Please verify database integrity.
3104 | 16 | LOAD DATABASE encountered page with invalid logical page number 0x%lx.
3105 | 16 | Data on dump will not fit into current database. Need %ld Mbyte database.
3106 | 16 | Specified file '%.*s' is in an obsolete dump database format: version %d, expected version %d.
3107 | 20 | Page #0x%lx of Sysindexes in database %d not found in cache after read.
3108 | 16 | LOAD DATABASE must be used in single user mode if trying to restore the Master database.
3109 | 16 | This dump was created from the Master database. A dump from Master can only be loaded as part of the Restore Master procedure.
3110 | 14 | You must be the DBO of database %.*s or the SA to run LOAD DATABASE.
3111 | 16 | This dump was not created from the Master database. Master can only be loaded from a dump of the Master database.
3112 | 16 | Cannot load any database other than Master when server in single-user mode.
3113 | 21 | Database %.*s does not have an entry in Sysusers for the DBO.
3114 | 21 | Database %.*s does not have an entry in Sysdatabases.
3115 | 10 | User %.*s in database %.*s has suid %d, which is the same as the suid of the DBO (as defined in Sysdatabases). User %.*s will be given suid %d.
3116 | 10 | When all load transactions have been completed for database %.*s, user %.*s should be given a unique suid.
3117 | 10 | Database %.*s already has a user with suid %d. Please call Technical Support.
3118 | 16 | LOAD DATABASE has been interrupted by a USER ATTENTION signal. A LOAD DATABASE must be completed in this database before it will be accessible.
3120 | 16 | The database you are attempting to LOAD was DUMPed under a different sort order ID (%d) than the one currently running on this server (%d), and at least one of them is a non-binary sort order.
3121 | 16 | The %sCLUSTERED index %s.%s (objid = %ld, indid = %d) may be invalid since it uses CHAR or VARCHAR columns in its key, and was created under a different sort order ID (%d) than the one currently running on this server (%d).
3122 | 16 | This master database dump was created from a 4.2x server and cannot be loaded.
3123 | 16 | Multipart database names ('%.*s') are illegal for LOAD DATABASE.
3124 | 16 | Must be an System Administrator to perform LOAD HEADERONLY.
3125 | 16 | No devices specified for LOAD HEADERONLY.
3201 | 16 | Can't open dump device '%.*s', device error or device off line. Please consult the SQL Server error log for more details.
3202 | 16 | Write on dump device '%.*s' failed, vsn=%ld return=%d status=%ld. Please consult the SQL Server error log for more details.
3203 | 16 | Read on dump device '%.*s' failed, vsn=%ld return=%d status=%ld. Please consult the SQL Server error log for more details.
3204 | 16 | Operator aborted Dump or Load.
3205 | 16 | Too many dump devices specified for dump/load; only %d allowed.
3206 | 16 | No entry in Sysdevices for dump device name '%.*s'. Update Sysdevices and re-run command.
3207 | 16 | DUMP or LOAD via the network is not currently supported. Re-run your command specifying a dump device.
3208 | 16 | Unexpected end of file while reading beginning of dump. Please confirm that dump media contains a valid SQL Server dump. The SQL Server error log may contain more information on the problem.
3209 | 16 | '%.*s' is not a DUMP or LOAD device. Please check Sysdevices.
3210 | 16 | Read via host failed, vsn=%ld return=%d status=%ld. Please consult the SQL Server error log for more detail.
3211 | 10 | %d percent %s
3212 | 16 | The load requires %d dump devices and %d have been specified.
3213 | 10 | %d volume(s) of the current stripe set have been read; Mount the next %d volume(s).
3214 | 16 | The volume on %.*s does not belong to the current stripe set.
3215 | 16 | Number of stripe dump devices(%d) can be atmost one more than the system config parameter 'backup threads' (%d); reconfigure 'backup threads' to be at least %d, and restart the server to try again.
3216 | 16 | %s expects '%s' type; '%s' type has been specified and is invalid.
3217 | 16 | Invalid value '%s' specified for %s.
3218 | 16 | Dump was done from a server with Processor type %d and cannot be loaded in a server with Processor type %d.
3219 | 16 | The stripeset tape in device '%.*s' has already been loaded.
3301 | 21 | Invalid log record found in Syslogs (logop %d)
3303 | 21 | Failed to find SAVEPT in log for xact %S_RID, current number is %d, looking for %d
3305 | 21 | Page %ld in database '%.*s' read in during runtime or load xact was uninitialized.
3306 | 21 | Process %d was expected to hold logical lock on page %ld instead of process %d.
3307 | 21 | Process %d was expected to hold logical lock on page %ld.
3308 | 21 | Page %ld was expected to have %s lock on it.
3309 | 21 | While in backout, process %d was chosen as deadlock victim while waiting for process %d to release lock on page %ld.
3310 | 21 | Cannot find log record with RID: (%ld, %d).
3311 | 22 | No space left on page %ld to move data of %d length.
3312 | 22 | Free offset %d is invalid on page %ld.
3313 | 10 | Error while redoing log row in database '%.*s'. %S_RID.
3314 | 10 | Error while undoing log row in database '%.*s'. %S_RID.
3401 | 21 | Rec_init: getnext SCAN_RID of last checkpoint failed on Rid from Sysdatabases. %S_RID.
3403 | 22 | Rec_init: Found that page %d had non-log object id %d while checking Syslogs allocation.
3404 | 21 | Rec_complete: Could not open controlling database (id %d) of controlling database in multi-db transaction.
3405 | 10 | Recovering database '%.*s'
3406 | 10 | %d transactions rolled forward in dbid %d.
3407 | 10 | %d transactions rolled back in dbid %d.
3408 | 10 | Recovery complete.
3409 | 10 | Roll forward transaction '%s' in dbid %d.
3410 | 10 | Roll back transaction '%s' -- was aborted in dbid %d.
3411 | 10 | Roll back transaction '%s' -- no 'end transaction' in dbid %d.
3412 | 21 | Database %d, table %ld. Attempt to mark table as suspect. Getnext SCAN_CLUST on Sysobjects.objid failed.
3413 | 21 | Database %d. Attempt to mark database as suspect failed. Getnext NC scan on Sysdatabases.dbid failed.
3414 | 10 | Database '%.*s' (dbid %d): Recovery failed. Please contact Technical Support for further instructions.
3417 | 21 | Cannot recover the master database, exiting.
3418 | 21 | Not enough descriptors to open model.
3419 | 16 | Unable to proceed with the recovery of dbid <%d> because of previous errors. Continuing with the next database.
3421 | 21 | Unable to recover database '%.*s' because of a failure to initialize the global timestamp. This indicates that a problem exists in the log for the current database. Please contact Technical Support for assistance.
3423 | 21 | Error recovering database '%.*s' - could not find expected BEGIN TRANSACTION record at location: %S_RID.
3424 | 21 | No more room in transaction table for transaction (%ld, %d).
3425 | 21 | Transaction (%ld, %d) not found in transaction table.
3426 | 10 | Could not make log consistent during special recovery of database %d. Please run dbcc save_rebuild_log utility if you wish to attempt to create a new log for this database.
3429 | 21 | Error recovering database '%.*s' - could not connect to commit service to check completion status of xact: %S_RID.
3430 | 16 | Could not add a checkpoint record during special recovery of database %d. If you intend to do updates in this database, first free up space by running DUMP TRANasction WITH NO_LOG, and then checkpoint the database.
3432 | 16 | Warning: Syslanguages is missing.
3433 | 16 | Name is truncated to '%.*s'. The maximum name length is %d.
3434 | 20 | Cannot change sortorder. Server shutting down. Restart to continue with sortorder unchanged.
3435 | 20 | Sortorder cannot be changed because user objects or user databases exist.
3436 | 20 | Cannot rebuild index %d for the '%.*s' table in the '%.*s' database.
3501 | 21 | Could not get Sysdatabases row for database '%d' at checkpoint time %S_RID.
3502 | 21 | No checkpoint records found in Syslogs for database '%.*s'
3504 | 21 | Sysindexes page # 0x%lx in database '%.*s' is not in buffer cache at checkpoint after getindex call.
3505 | 14 | Only the DBO of database %.*s may run the checkpoint command.
3508 | 25 | Attempt to set '%.*s' database to single user mode failed because the usage count is %ld. Make sure that no other users are currently using this database and rerun CHECKPOINT.
3509 | 14 | Attempt to set database '%.*s' to read only user mode failed because transaction %d:%d is active. Make sure that no other users are currently using this database and rerun CHECKPOINT.
3604 | 10 | Duplicate key was ignored.
3605 | 10 | Duplicate row was ignored.
3606 | 10 | Arithmetic overflow occurred.
3607 | 10 | Divide by zero occurred.
3608 | 10 | Null value used in an expression
3609 | 10 | Attempt to update a column in the fabricated row of an inner table in an outer join.
3612 | 10 | %sSQL Server Execution Times:%s cpu time = %lu ms. elapsed time = %lu ms.
3613 | 10 | SQL Server Parse and Compile Time:%s cpu time = %lu ms.
3615 | 10 | Table: %.*s scan count %d, logical reads: %d, physical reads: %d
3616 | 22 | Non-leaf page %d in table %d, index %d is empty - please rebuild the index.
3618 | 10 | Transaction has been aborted.
3619 | 10 | Unable to write CHECKPOINT record in database %d because the log is out of space.
3620 | 10 | Automatic checkpointing is disabled in database '%.*s' because the log is out of space. It will continue when the DBO successfully checkpoints the database. Please free up some space or extend the database and then run CHECKPOINT.
3621 | 10 | Command has been aborted.
3622 | 10 | Domain error occurred.
3623 | 10 | A transaction on a no_log table was undone. Check the errorlog file in the SQL Server directory for details.
3701 | 11 | Cannot drop the %S_MSG '%.*s', because it doesn't exist in the system catalogs.
3702 | 16 | Cannot drop the %S_MSG '%.*s' because it is currently in use.
3703 | 11 | Cannot drop the %S_MSG with object-id %ld in database %d, because it doesn't exist in the system catalogs.
3704 | 16 | Cannot drop the %S_MSG '%.*s' because you are not the owner or System Administrator.
3705 | 16 | Cannot use DROP %s with '%.*s' because '%.*s' is a %S_MSG. Use DROP %s.
3706 | 11 | DES not found while dropping %s '%.*s'.
3708 | 16 | Cannot drop the %S_MSG '%.*s' because it is a system %S_MSG.
3709 | 16 | Cannot drop '%.*s' because you are not currently in the master database.
3716 | 16 | The %S_MSG '%.*s' cannot be dropped because it is bound to one or more %S_MSG.
3718 | 11 | Could not drop index '%.*s' because the table/clustered index entry cannot be found in the Sysindexes system catalog.
3723 | 16 | Explicit DROP INDEX not allowed on index '%.*s'. It is being used for %s constraint enforcement.
3724 | 16 | Cannot drop the %S_MSG '%.*s' because it is published for replication.
3725 | 16 | Constraint '%.*s' is being referenced by table '%.*s', foreign key constraint '%.*s'.
3726 | 16 | Could not drop object '%.*s'. It is being referenced by a foreign key constraint.
3727 | 10 | Unable to drop constraint. See previous errors.
3728 | 16 | '%.*s' is not a constraint.
3729 | 20 | Unable to open table '%.*s' in dbid '%d'.
3730 | 20 | Unable to locate entry in %s for constraint '%.*s'.
3731 | 16 | '%.*s' is not a valid object.
3732 | 10 | %s
3733 | 16 | Constraint '%.*s' does not belong to table '%.*s'.
3734 | 20 | Unable to update category field for DROP constraint.
3735 | 20 | Primary key or unique constraint '%.*s' returned invalid indid:%d from sysconstraints.
3901 | 17 | This transaction has referenced too many databases. The maximum allowed is %d. The transaction must be split into smaller sections.
3902 | 13 | The commit transaction request has no corresponding BEGIN TRANSACTION.
3903 | 13 | The rollback transaction request has no corresponding BEGIN TRANSACTION.
3904 | 21 | Can't unsplit logical page %ld in object '%.*s' in database '%.*s' - both pages together contain more data than will fit on one page.
3905 | 21 | Can't unsplit logical page %ld in object '%.*s' in database '%.*s' - row number %d is used on both pages.
3906 | 16 | Attempt to BEGIN TRANsaction in database '%.*s' failed because database is READ ONLY.
3907 | 21 | Failed to receive results from PROBE. The distributed transaction named %.*s has not been committed and data may be inconsistent across databases.
3908 | 16 | Attempt to BEGIN TRANsaction in database '%.*s' failed because database is in BYPASS RECOVERY mode.
4001 | 11 | Cannot open default database '%.*s'
4002 | 14 | Login failed
4013 | 14 | Login failed - not a secure SQL Server.
4016 | 16 | Language name in login record '%.*s' is not an official name on this SQL Server. Using default '%.*s' from Syslogins instead.
4017 | 16 | Neither language name in login record '%.*s' nor language name in Syslogins '%.*s' is an official language name on this SQL Server. Using server-wide default '%.*s' instead.
4018 | 16 | Your default language name from Syslogins '%.*s' is not an official language name on this SQL Server. Using server-wide default '%.*s' instead.
4019 | 16 | Default date order '%.*s' for language '%.*s' is invalid. Using 'mdy' instead.
4027 | 16 | Mount tape for %s of database '%s'.
4028 | 10 | End of tape has been reached, remove tape '%s' and mount next tape for %s of database '%s'.
4029 | 10 | Database '%s'%s(%d pages) dumped to file <%d> on tape '%s'.
4030 | 16 | Tape '%s' expires on day '%s' year '%s' and cannot be overwritten.
4031 | 16 | Creation date on tape '%s'(%s) does not match that of first volume(%s).
4032 | 16 | Cannot find file %d on tape '%s'.
4033 | 16 | File <%d> on tape '%s' is not a SQL Server %s dump.
4034 | 16 | Warning, file <%d> on tape '%s' was dumped from database '%s'.
4035 | 10 | Database '%s'%s(%d pages) dumped to file <%d> on device '%s'.
4036 | 16 | Diskdump '%s'expires on day '%s' year '%s' and cannot be overwritten.
4037 | 16 | User specified volume id '%s' does not match the volume id '%s' of the device '%.*s'.
4038 | 16 | Cannot find file %d on device '%s'.
4039 | 10 | Warning, file <%d> on device '%s' was dumped from database '%s'.
4040 | 16 | File <%d> on device '%s' is not a SQL Server %s dump.
4041 | 16 | Device '%s' has a stripe volume version; use INIT option for non-stripe dumps.
4042 | 16 | Device '%s' has a non stripe volume version; use INIT option for stripe dumps.
4043 | 16 | Device '%.*s' has file number mismatch <%d> with stripe file number <%d>.
4044 | 10 | Warning: EXPIREDATE or RETAINDAYS is enforced only for the first dump in the volume.
4202 | 21 | Could not find BEGINXACT record in log while finding truncation page during dump transaction in database '%.*s'.
4203 | 21 | Could not find checkpoint record after truncate page in dump transaction in database '%.*s'
4204 | 10 | Unable to continue logged version of DUMP TRANsaction. Please free up some space in database %d or use the NO_LOG option.
4205 | 16 | Syslogs does not exist in its own segment in database '%d' with segmap '%ld' with logical start page number of '%ld'. You may not use DUMP TRAN in this case, use DUMP DATABASE instead.
4206 | 16 | You cannot run DUMP TRANsaction WITH NO_LOG inside a user transaction.
4207 | 16 | DUMP TRANsaction is not allowed while the select into/bulk copy option is enabled or if a non-logged operation has occurred: use DUMP DATABASE, or disable the option with sp_dboption.
4208 | 16 | DUMP TRANsaction is not allowed while the trunc. log on chkpt. option is enabled: use DUMP DATABASE, or disable the option with sp_dboption.
4209 | 16 | DUMP TRANsaction is not allowed because log was truncated or DUMP DATABASE was never run. Must run DUMP DATABASE.
4210 | 16 | While attempting DUMP TRANsaction WITH NO_TRUNCATE, couldn't find database %.*s.
4211 | 23 | Couldn't complete DUMP TRANsaction WITH NO_TRUNCATE on database '%.*s', because the log pointer in Sysdatabases (page number %ld) is not accurate.
4301 | 16 | Database in use. System Administrator must have exclusive use of DB to load transaction
4302 | 16 | Specified file '%.*s' is not in valid dump transaction format.
4305 | 16 | Specified file '%.*s' is out of sequence. Current time stamp is %S_DATE while dump was from %S_DATE.
4306 | 16 | There was activity on database since last load, unable to load. Must restart load sequence with the load database to continue.
4307 | 16 | Specified file '%.*s' is not properly terminated.
4308 | 16 | Premature end of file, unable to load.
4309 | 16 | Loaded log page #%ld not free or allocated to log. File may be corrupted or internal error detected.
4310 | 16 | Specified file '%.*s' is not in valid DUMP TRANsaction format.
4311 | 16 | Specified file '%.*s' is in an obsolete DUMP TRANsaction format.
4312 | 16 | You must be the DBO of database %.*s or the SA to run LOAD TRANsaction.
4313 | 16 | Recreate index failed for table %ld, index %d. The table has been left in an inconsistent state, and the index is missing, so LOAD TRANSACTION errors may result. Run DBCC CHECKTABLE on the table if LOAD TRANSACTION succeeds.
4314 | 20 | Cannot find table %ld to recreate index %d.
4315 | 20 | Log scan for recreate index failed.
4316 | 16 | Can only LOAD TRANsaction in master if SQL Server is in single-user mode.
4317 | 16 | Multipart database names ('%.*s') are illegal for LOAD TRANSACTION.
4401 | 16 | View '%.*s' no longer exists.
4402 | 16 | Infinite loop in view definition. Cannot resolve the view definitions in the query to the underlying tables.
4403 | 16 | View '%.*s' is not updatable because it contains aggregates.
4404 | 16 | View '%.*s' is not updatable because the definition contains DISTINCT.
4405 | 16 | View '%.*s' is not updatable because the FROM clause names multiple tables.
4406 | 16 | View '%.*s' is not updatable because a field of the view is derived or constant.
4408 | 19 | The query and the views in it exceed the limit of %d tables.
4409 | 20 | The columns in the query definition and the view definition do not match.
4412 | 16 | View '%.*s's definition contains '%.*s', which is a temporary object. Views can only be based on permanent objects.
4413 | 16 | View resolution could not succeed because the previously mentioned objects, upon which the view directly or indirectly relies, do not currently exist. These objects need to be recreated for the view to be usable.
4414 | 16 | Unable to allocate ancillary table for view resolution. Maximum number of tables in a query (%d) exceeded.
4415 | 16 | View '%.*s' is not updatable because either it was created WITH CHECK OPTION or it spans a view created WITH CHECK OPTION and the target table is referenced multiple times in the resultant query.
4501 | 16 | View '%.*s' has more columns defined than column names given.
4502 | 16 | View '%.*s' has more column names specified than columns defined.
4503 | 20 | The create view tree has a resdom with no right hand side. View '%.*s', resdom '%.*s'.
4504 | 16 | CREATE TABLE failed because there was not enough space to allocate memory for the table.
4505 | 16 | CREATE VIEW failed because column '%.*s' in view '%.*s' exceeds the maximum of 250 columns.
4506 | 10 | Column names in each view must be unique. Column name '%.*s' in view '%.*s' is specified more than once.
4507 | 16 | Column '%.*s' specifies storage type %d, which does not currently exist.
4508 | 16 | Views are not allowed on temporary tables. Table names that begin with '#' denote temporary tables.
4509 | 10 | Column names in each view must be unique. An unnamed column is specified more than once in view '%.*s'.
4510 | 16 | Create view failed because WITH CHECK OPTION was specified and the view is not updatable.
4601 | 14 | Only owner <%.*s> of object <%.*s>,in database %.*s can GRANT/REVOKE this permission.
4602 | 14 | Only the System Administrator may GRANT or REVOKE the CREATE DATABASE permission.
4603 | 14 | Only owner of current database may GRANT/REVOKE this permission.
4604 | 16 | There is no such user %.*s.
4606 | 16 | GRANTed/REVOKEd privilege %s not compatible with object.
4607 | 16 | Privilege %s may not be GRANTed or REVOKEd.
4608 | 16 | Only the System Administrator may GRANT/REVOKE ALTER DATABASE permission, and only to/from users with CREATE DATABASE permission.
4609 | 16 | You cannot specify a column list with INSERT or DELETE.
4610 | 16 | You may only GRANT or REVOKE permission on objects in the current database.
4701 | 11 | Cannot truncate table '%.*s', because this table does not exist in database '%.*s'.
4706 | 17 | Could not truncate table '%.*s' because there is not enough room in the log to record the deallocation of all of the index and data pages.
4708 | 16 | Could not truncate object '%.*s' because it is not a table.
4709 | 16 | You are not allowed to truncate the system table '%.*s'.
4710 | 16 | Cannot truncate table '%.*s' because you are not the owner or System Administrator.
4711 | 16 | Cannot truncate table '%.*s'because it is published for replication.
4712 | 16 | Cannot truncate table '%.*s' because it is being referenced by a foreign key constraint.
4801 | 20 | Bulk_main: opentable on BULK INSERT table failed. Dbid=%d name='%.*s'.
4802 | 21 | Bulk_main: getindex of primary index row failed on BULK INSERT table
4804 | 21 | Premature end-of-message while reading current row from host. Host program may have died.
4805 | 17 | The front end tool you are using does not support the feature of bulk insert from host, please use the proper tools for this command.
4806 | 10 | Warning, reverting to slow bulk copy on table '%.*s' because BULKCOPY option not set in database '%.*s'.
4808 | 10 | The bulk copy of this table has been aborted because the CHECKPOINT record could not be written in the log. Please free up space in the database.
4810 | 16 | Expected TEXT token in data stream for bulk copy of text data.
4811 | 16 | Expected column offset in data stream for bulk copy of text data.
4812 | 16 | Expected row offset in data stream for bulk copy of text data.
4813 | 16 | Expected text length in data stream for bulk copy of text data.
4814 | 16 | Cannot perform an unlogged bulk copy into table '%.*s' because it is published for replication.
4901 | 16 | ALTER TABLE only allows columns to be added which can contain nulls. Column '%.*s' cannot be added to table '%.*s' because it does not allow nulls.
4902 | 11 | Cannot alter table '%.*s', because this table does not exist in database '%.*s'.
4905 | 21 | ALTER TABLE failed because page %d of the system catalog Sysindexes in database '%.*s' is not in the cache.
4906 | 16 | ALTER TABLE failed because adding all of the new columns to table '%.*s' would make the size of a row %d. %d is the maximum allowable size of a row in a table.
4909 | 16 | Can't alter %.*s because it is not a table.
4910 | 16 | Can't alter table '%.*s' because you are not the owner or System Administrator.
4912 | 16 | The alter table statement contains multiple identity columns, alter table '%.*s' failed
4913 | 16 | Table '%.*s' already contains an identity column, cannot add new identity column via alter table
4914 | 16 | The number of existing rows (%ld) exceeds the maximum value for the specified datatype, cannot add new identity column to '%.*s'
4915 | 16 | Maximum row width exceeded when adding identity column '%.*s' to table '%.*s'
5001 | 16 | User must be in Master Database.
5002 | 16 | Database %.*s does not exist; check Sysdatabases
5004 | 16 | ALTER DATABASE failed. The size request must be positive.
5005 | 10 | Extending database by %ld pages on disk %.*s
5006 | 16 | Could not find enough space on disks to extend database %.*s
5008 | 16 | System does not support Deextend Database currently
5009 | 16 | ALTER DATABASE failed. Some disk names listed in command were not found. Check that names exist and are spelled correctly before re-running command.
5011 | 14 | Only the owner of database %.*s or the System Administrator may ALTER it.
5013 | 16 | Cannot extend the MASTER database onto any device other than 'master'. The ALTER DATABASE was aborted.
5015 | 16 | ALTER DATABASE failed. The total size specified must be 1 megabyte or greater.
5016 | 16 | Incorrect database name or device name(s).
5017 | 16 | ALTER DATABASE failed. Database %.*s not created with 'for load' option.
5018 | 16 | The size of tempdb in RAM has exceeded the limit. The sum of 'memory size' and 'tempdb in ram' (configurable options) cannot exceed 2046 Megs.
5101 | 15 | Must give parameters for 'DISK %s' command. Usage: %s
5102 | 15 | No such command: 'DISK %.*s'
5103 | 16 | Illegal disk address range. The sum of VSTART and SIZE must be less than 16777216 (0x1000000)
5104 | 16 | Device number %ld already used.
5105 | 16 | Device activation error. The physical filename '%.*s' may be incorrect
5106 | 15 | Parameter '%s' requires value of type '%s'
5107 | 15 | Value is wrong type for parameter '%s' (requires type '%s')
5108 | 15 | Parameter '%s' does not take a value
5109 | 16 | No such parameter: '%.*s'
5114 | 20 | Could not yield
5115 | 16 | I/O error during disk initialization. PHYSNAME '%.*s' may be incorrect or %ld (VSTART SIZE) may exceed the size of the device or permissions may be wrong for the device.
5116 | 14 | Permission denied. Only the System Administrator may run DISK commands.
5117 | 16 | Unable to run DISK command. Must be in master database to run this command.
5118 | 16 | Unable to run DISK REFIT. SQL Server must be booted with the -m option. Please see your System Administration guide about the Restore Master procedure.
5119 | 18 | Unable to reserve a buffer, aborting DISK REFIT command. Please retry Restore Master procedure.
5120 | 10 | Bad segment map (%d) in Sysusages for row with Dbid = %d, Logical Start = 0x%lx, Virtual Start = 0x%lx, and Size = 0x%lx. Recommend you patch this value with correct information after Disk Refit completes.
5121 | 10 | Warning: Disk Refit may not have the correct segment map information in Sysusages. Please review these after the command completes to verify their accuracy.
5122 | 10 | The disk size must be >= 512
5123 | 16 | DISK INIT encountered an error while attempting to open/create the physical file. Please consult the SQL Server error log (in the SQL Server boot directory) for more details.
5124 | 10 | Activating disk '%.*s'
5125 | 10 | Failed to complete unmirror of logical device '%.*s' after recovery of the master database.
5126 | 16 | The logical device '%.*s' does not exist in SYSDEVICES
5127 | 16 | The device '%.*s' is already mirrored and mirroring is enabled.
5128 | 16 | The device '%.*s' is already mirrored but mirroring is disabled. Use the DISK REMIRROR command to enable mirroring or unmirror the device
5129 | 16 | Syntax error detected in the value for parameter 'mirror'. You must provide a valid physical device/file name for this parameter.
5130 | 16 | The value for parameter 'mirror' translates to the same name as that for the primary device. Use another physical device for the mirror.
5131 | 16 | The device '%.*s' is not currently mirrored.
5132 | 10 | DISK MIRROR encountered an error while attempting to create the physical file '%.*s'. Please consult the SQL Server error log for more details.
5133 | 10 | Unable to start i/o to '%.*s'. Please consult the SQL Server error log for details.
5134 | 10 | Dynamic mirroring failed for logical device '%.*s'. Check the SQL Server error log for more information.
5135 | 10 | Starting Dynamic Mirroring of %ld pages for logical device '%.*s'.
5136 | 10 | %ld pages mirrored...
5137 | 10 | Failed to mirror device '%.*s'.
5138 | 10 | Failed to unmirror device '%.*s'.
5139 | 10 | Failed to remirror device '%.*s'.
5140 | 10 | Creating the physical file for the mirror...
5141 | 17 | Unable to start Dynamic Mirroring because an i/o buffer is not currently available. Try the command again later.
5142 | 16 | Mirroring for device '%.*s' is not currently enabled.
5143 | 10 | The remaining %ld pages are currently unallocated and will be mirrored as they are allocated.
5144 | 16 | You can't remove the secondary physical device for virtual device '%.*s' since it is currently the only operational device. Use the SIDE=PRIMARY qualifier for the DISK UNMIRROR COMMAND.
5145 | 16 | Error re-initializing device '%.*s'. Check SQL Server errorlog for more information.
5146 | 16 | The %s of %d is out of range. It must be between %d and %d.
5147 | 10 | Device size set to %ld blocks.
5148 | 16 | Disk Resize can be used only to expand non-RAM devices.
5149 | 16 | Disk Resize encountered an error while attempting to expand the physical file. Please consult the SQL Server error log for more details
5150 | 16 | Cannot find device '%.*s' in sysdevices.
5151 | 16 | Cannot explicitly open or close the master device.
5152 | 16 | Failed to close device '%.*s', see errorlog for details.
5153 | 16 | Failed to open device '%.*s', see errorlog for details.
5154 | 16 | Device '%.*s' is not open.
5155 | 16 | Device '%.*s' is already open.
5156 | 16 | Usage: DBCC DEVCONTROL(devname,ONLINE|OFFLINE)
5157 | 16 | IO error in writelog during backout.
5158 | 10 | Warning, media in device '%.*s' may have been changed.
5159 | 16 | OS Error %.*s on device '%.*s' during %s
5160 | 16 | Cannot take '%.*s' offline because usecount=%d.
5161 | 16 | Database '%.*s' is marked offline.
5162 | 16 | Cannot find '%.*s' in sysdatabases.
5163 | 16 | Cannot open '%.*s' to take offline.
5164 | 16 | Usage: DBCC DBCONTROL(dbname,ONLINE|OFFLINE)
5165 | 16 | Cannot explicitly open or close master database.
5166 | 16 | Database '%.*s' is not offline.
5167 | 16 | Database '%.*s' is already offline.
5701 | 10 | Changed database context to '%.*s'.
5702 | 10 | The SQL Server is terminating this process.
5703 | 10 | Changed language setting to '%.*s'.
5803 | 10 | Unknown config number in Sysconfigures, config = %d.
5804 | 16 | Too few databases specified, minimum = %d
5805 | 16 | Too few locks specified, minimum = %d
5806 | 16 | Too few descriptors specified, minimum = %d
5807 | 16 | Do not recommend recovery intervals above %d minutes - use override option to force this configuration
5808 | 16 | Do not recommend ad hoc updates to system catalogues, use override option to force this configuration
5809 | 16 | Do not recommend average time slices above %d milliseconds, use override option to force this configuration
5810 | 16 | Legal values for fill factor is 0 to 100.
5811 | 16 | Legal values for percent allocated to procedure cache is 1 to 99.
5812 | 14 | Permission denied. Only the System Administrator may run reconfigure.
5813 | 16 | Unable to run with specified memory size of %ld. Please see the System Administration Guide for more information on how to calculate this number.
5816 | 16 | Legal values for the number of remote logins are 0 or positive numbers.
5817 | 16 | Legal values for the number of remote sites are 0 or positive numbers.
5818 | 16 | Legal values for the number of remote connections are 0 or positive numbers.
5819 | 16 | Legal values for the number of pre-read packets per remote connection are 0 or positive numbers.
5820 | 16 | Number of remote logins should be greater than the number of remote sites.
5821 | 16 | Number of remote connections should be greater than the number of remote sites.
5822 | 16 | Version number should be between 0 and 10000.
5823 | 16 | Cannot reconfigure server to use sort order ID %d, because the row for that sort order does not exist in Syscharsets.
5824 | 16 | Cannot reconfigure server to use sort order ID %d, because the row for its underlying character set (ID %d) does not exist in Syscharsets.
5825 | 16 | Cannot reconfigure the server's sort order since the Syscharsets table does not exist. You must upgrade your server prior to attempting this.
5826 | 10 | You have just reconfigured SQL Server's default sort order. System table indexes will be rebuilt when you reboot the SQL server.
5827 | 10 | In changing the default sort order, you have also reconfigured SQL Server's default character set.
5828 | 16 | User connections are limited to %d.
5901 | 20 | Was unable to get an alarm, the background checkpoint process is unable to run
5902 | 20 | Serious kernel error reported on upsleep call, unwilling to continue. Aborting the background checkpoint process.
5903 | 16 | Unable to open database with id = %d, suspect inconsistency in sysdatabases table.
5904 | 17 | Background checkpoint process suspended until locks are available.
6001 | 10 | SHUTDOWN is waiting for %d process(es) to complete.
6002 | 10 | A SHUTDOWN command is in progress. Please log off.
6003 | 10 | This process terminated by SHUTDOWN command.
6004 | 10 | The SHUTDOWN command may only be used by the system administrator.
6005 | 10 | A SHUTDOWN is in progress.
6006 | 10 | Server SHUTDOWN by request.
6101 | 16 | Process '%d' is not a valid process number. Choose a number between 1 and '%d'.
6102 | 14 | Only the System Administrator may use the KILL command.
6103 | 17 | Unable to do cleanup for the killed process; received Msg %d.
6104 | 16 | You cannot use KILL to kill your own process.
6106 | 16 | Process '%d' is not an active process number.
6107 | 14 | Only User processes can be KILLed.
6201 | 10 | STEP %d
6202 | 10 | The type of query is SELECT (into a worktable)
6203 | 10 | The type of query is %s
6204 | 10 | The update mode is direct
6205 | 10 | The update mode is deferred
6206 | 10 | %*sGROUP BY
6207 | 10 | %*sVector Aggregate
6208 | 10 | Scalar Aggregate
6209 | 10 | This step involves sorting
6210 | 10 | Worktable created for ORDER BY
6211 | 10 | Worktable created for DISTINCT
6212 | 10 | Worktable created for REFORMATTING
6213 | 10 | Worktable created for SELECT INTO
6214 | 10 | %*sTO TABLE
6215 | 10 | %*sFROM TABLE
6216 | 10 | %*sWorktable %d
6217 | 10 | %*s%.*s %.*s
6219 | 10 | %*sNested iteration
6220 | 10 | %*sEXISTS TABLE : nested iteration
6221 | 10 | Using GETSORTED Table Scan
6222 | 10 | %*sUsing Dynamic Index
6223 | 10 | %*sTable Scan
6224 | 10 | %*sUsing Clustered Index
6225 | 10 | %*sIndex : %.*s
6226 | 10 | %*sIndex name not found
6227 | 10 | %*sSUBQUERY : nested iteration
6228 | 10 | %*sAND EXISTS : nested iteration
6229 | 10 | %*sAND NOT EXISTS : nested iteration
6230 | 10 | %*sOR EXISTS : nested iteration
6231 | 10 | %*sOR NOT EXISTS : nested iteration
6232 | 10 | %*sRow estimate: %s
6233 | 10 | %*sCost estimate: %s
6234 | 10 | %*sJOINS WITH
6235 | 10 | WITH CHECK OPTION
6401 | 16 | Cannot rollback %.*s - no transaction or savepoint of that name found.
6402 | 20 | Inconsistency in rollback logic. ROLLBACK finds no matching SAVE TRANsaction or BEGIN TRANsaction. ROLLBACK aborted.
6403 | 20 | No matching savexact record found when rolling back the subordinate transaction %.*s.
6501 | 21 | Logical page 0x%x in database '%.*s' missing from buffer cache after fetching the index row.
6701 | 16 | Could not open dbid %d, object %ld.
6901 | 21 | Overflow on High component of timestamp occurred in database %d. Database table possibly corrupt.
6902 | 21 | Page timestamp value falls between the old and new timestamps from log. Page #=%ld, object id = %ld, page timestamp=%04x %08lx. Log: old timestamp=%04x %08lx, new timestamp=%04x %08lx.
6903 | 21 | High order of timestamp indicates that timestamp structure may be incorrect.
6904 | 21 | Mismatch between database table passed and the one found in the system structure when requesting new database timestamp. Database id passed in : %d. System database id : %d
7101 | 17 | Unable to allocate new text value, dbid %d.
7102 | 19 | Unexpected end-of-message found while reading from network.
7103 | 22 | Read of text value failed for text pointer %lx%lx.
7104 | 22 | Can't open the object containing text pointer %lx%lx.
7105 | 22 | Page %ld for text value does not exist.
7106 | 22 | Row %d for text value does not exist.
7107 | 22 | Text pointer %lx%lx invalid. On page %d, row %d doesn't contain text value.
7108 | 20 | Process %d already has the buffer we are using for an allocation resource locked: %S_PAGE.
7109 | 22 | Unexpected log record of type %d found while processing TEXT/IMAGE data.
7111 | 17 | Can't log text value because log is out of space.
7112 | 17 | Deadlock occurred while trying to lock page %ld, which is held by SQL Server process %d.
7113 | 22 | Data size mismatch detected when transferring TEXT/IMAGE value. First fragment page number: %ld.
7114 | 22 | Page %ld is not a valid text page.
7115 | 25 | Page %ld expected to be first fragment value
7116 | 25 | Offset %d is not in range of available text data.
7117 | 16 | Length %d is not in range of available text data.
7118 | 16 | Object id %ld on page %ld is not the one expected which is %ld.
7120 | 22 | Log record %ld:%d was not found in the LOG.
7121 | 22 | Free offset %d is invalid on page %ld.
7122 | 20 | Invalid source identified during TEXT/IMAGE transfer. Source id is: %d.
7123 | 16 | Invalid text pointer value %s.
7124 | 16 | The offset and length specified in the READTEXT command is greater than the actual data length of %ld.
7125 | 16 | Text pointer value conflicts with the column name specified.
7126 | 16 | Text pointer value references a data page with an invalid text status.
7127 | 16 | Text pointer value references a data page with an invalid time stamp.
7128 | 16 | Text pointer value references a data page which is no longer allocated.
7129 | 16 | Synchronization time stamp does not agree with text data page value.
7130 | 16 | %s with no log is not valid at this time. Use sp_dboption to set the 'select into/bulk copy' option on for database %s.
7131 | 16 | Invalid table and column name specified in textvalid function.
7132 | 16 | Selection of TEXT and IMAGE datatypes require DBLIB 4.0 or greater.
7133 | 16 | NULL textptr passed to %s function.
7134 | 16 | The text table and the table referenced by the text pointer disagree.
7135 | 16 | Deletion length %ld is not in the range of available text data
7201 | 17 | Can't open a connection to site '%.*s' because there are no remote sites available. Rerun when there are fewer active remote sites, or ask your System Administrator to reconfigure SQL Server with more 'remote sites'.
7202 | 17 | Can't open a connection to site '%.*s' because there are no available PSS structures.
7203 | 17 | Can't open a connection to site '%.*s' because SQL Server is not configured for enough user connections. See the error log file in the SQL Server boot directory.
7204 | 18 | Can't open a connection to site '%.*s' because the site is already active.
7205 | 18 | Can't open a connection to site '%.*s'. See the error log file in the SQL Server boot directory.
7206 | 17 | Can't open a connection to site '%.*s' because all channel numbers are in use.
7207 | 17 | Can't open a connection to site '%.*s' because there are no remote connections available. Rerun when there are fewer remote users and/or fewer local users making remote accesses, or ask your SA to reconfigure SQL Server with more 'remote connections'.
7208 | 17 | Can't open a connection to site '%.*s' because there are no remote logins available. Rerun when there are fewer local users making remote accesses, or ask your System Administrator to reconfigure SQL Server with more 'remote logins'.
7209 | 17 | Cannot open a connection to site '%.*s' because %S_MSG buffer could not be initialized.
7210 | 18 | Can't open a connection to site '%.*s' because 'set up channel' message could not be sent.
7211 | 18 | Can't open a connection to site '%.*s' because 'set up channel' message was not acknowledged.
7212 | 11 | Can't close connection %d on site '%.*s' because it is not active.
7213 | 18 | Can't remove site '%.*s' from list of active sites because it is missing.
7214 | 11 | No site name received in server login packet. Server login rejected.
7215 | 18 | Can't send to site '%.*s'.
7216 | 18 | Can't read from site '%.*s'.
7217 | 18 | Echo failed from site '%.*s'.
7218 | 11 | Site '%.*s' not found in Sysservers.
7219 | 11 | Site %d not found in Sysservers.
7220 | 11 | Site '%s' not found in interfaces file.
7221 | 14 | Login to site '%.*s' failed.
7222 | 18 | Received bad token 0x%x from site '%.*s'.
7223 | 16 | Cannot %S_MSG site '%.*s'.
7224 | 16 | Unexpected end-of-message encountered in RPC response from site '%.*s'.
7225 | 16 | Unknown datatype token %d '%s' encountered.
7226 | 16 | Alternate row received for id %d with no corresponding format information.
7227 | 17 | Can't open a connection to site '%.*s' because SQL Server is not configured for remote access. Ask your System Administrator to reconfigure SQL Server to allow remote access.
7901 | 16 | Page %ld was expected to be the first page of a TEXT/IMAGE value.
7902 | 16 | Data size mismatch occurred while checking TEXT/IMAGE values. The first page for this value is: %ld. There were %ld bytes found, which is different from the expected data length of %ld bytes.
7903 | 16 | Page %ld was expected to be a TEXT/IMAGE page. This occurred when link number %ld was examined.
7904 | 10 | The total number of TEXT/IMAGE pages in this table is %ld.
7905 | 10 | The number of rows in Sysindexes for this table was %ld. It has been corrected to %ld.
7906 | 10 | The number of data pages in Sysindexes for this table was %ld. It has been corrected to %ld.
7907 | 16 | The status in the first page (%ld) of the no_log table %.*s and the status in the sysobjects row, do not match.
7908 | 10 | The table %.*s was created with the no_log option.
7909 | 10 | A transaction involving the no_log table %.*s was undone. This may have left the table in an inconsistent state. Rebuild the table.
7910 | 16 | Page %ld allocated (Alloc page: %ld Extent ID: %ld Alloc mask: 0x%x)
7911 | 16 | Page %ld deallocated (Alloc page: %ld Extent ID: %ld Alloc mask: 0x%x)
7912 | 16 | EXTID:%ld (Alloc page: %ld) is initialized. Extent follows:
7913 | 16 | NEXT=%ld PREV=%ld OBJID=%ld ALLOC=0x%x DEALL=0x%x INDID=%d STATUS=0x%x
7914 | 16 | Allocation page %ld Extid %ld is not referenced, but there are referenced pages within this extent. Contact Tech Support for object %ld.
7915 | 16 | Allocation page %ld extid %ld is referenced, but there are no referenced pages within this extent. Contact Tech Support for object %ld.
7916 | 16 | Total (# alloc pages= %ld, # of alloc pages modified=%ld)
7917 | 16 | Total (# pages allocated=%ld pages deallocated=%ld extents deleted=%ld)
7918 | 16 | Alloc page %ld (pgs allocated=%ld pgs deallocated=%ld extents deleted=%ld)
7919 | 16 | Fix_al not processed. Database needs to be in SINGLE USER mode.
7920 | 16 | Processed %ld entries in the Sysindexes for dbid %d.
7921 | 16 | Found %ld bad entries in the Sysindexes.
7922 | 16 | *****************************************************
7923 | 16 | TABLE: %.*sOBJID = %ld
7924 | 16 | INDID=%ld FIRST=%ld ROOT=%ld DPAGES=%ld SORT=%d
7925 | 16 | Indid: %d. %ld Index Pages in %ld extents.
7926 | 16 | Data level: %d. %ld Data Pages in %ld extents.
7927 | 16 | TOTAL # of extents = %ld
7928 | 16 | Index %.*s is not consistent; found %ld leaf rows. Drop and recreate the index.
7929 | 16 | Table has %ld data rows.
7930 | 16 | Table Corrupt: keys in left child is not less than the parent key; check left child page %ld.
7931 | 16 | Table Corrupt: keys in right child is less than parent key; check right child page %ld.
7932 | 16 | The indexes for '%.*s' are already correct. They will not be rebuilt.
7933 | 16 | One or more indexes are corrupt. They will be rebuilt.
7934 | 16 | The table '%.*s' has no indexes.
7935 | 16 | REINDEX recieved an exception - command aborted.
7937 | 16 | The data in table '%.*s' is possibly corrupt - REINDEX aborted. Run DBCC CHECKTABLE and report errors to your System Administrator.
7944 | 10 | *** NOTICE: Space used on the log segment is %4.2f Mbytes, %4.2f%%.
7945 | 10 | *** NOTICE: Space free on the log segment is %4.2f Mbytes, %4.2f%%.
7946 | 10 | *** NOTICE: Notification of log space used/free cannot be reported because the log segment is not on its own device.
7947 | 16 | The sortorder and character set ID's for index %d on this table were %d:%d in Sysindexes. They have been corrected to %d:%d.
7962 | 16 | Upgrade requires the SQL Server to be booted in single user mode. Reboot the SQL Server with the -m flag
7963 | 16 | Upgrade encountered a fatal error. Please check the SQL Server errorlog
7964 | 16 | Allocation page SDES not open.
7965 | 16 | Page is not an allocation page.
7966 | 10 | WARNING: NOINDEX option of '%.*s' being used, checks on non-system indexes will be skipped
7967 | 16 | DBCC %.*s command does not support the %.*s option.
7968 | 1 | Transaction Information for database: %.*s
7969 | 1 | No active open transactions.
7970 | 1 | %sOldest active transaction:
7971 | 1 | SPID : %d
7972 | 1 | UID : %d
7973 | 1 | SUID : %d
7974 | 1 | Name : %.*s
7975 | 1 | RID : (%d , %d)
7976 | 1 | Time Stamp : %04X %08X
7977 | 1 | Start Time : %.*s
7979 | 1 | %sReplicated Transaction Information:
7980 | 1 | Oldest Distributed RID : (%d , %d)
7981 | 1 | Time Stamp : %04X %08X
7982 | 1 | Oldest Non-Distributed RID : (%d , %d)
7983 | 14 | Only the DBO of database %.*s may run the DBCC %s command
7984 | 16 | Invalid object name '%.*s'.
7985 | 16 | The object name '%.*s' contains more than the maximum number of prefixes. The maximum is %d.
7986 | 16 | WARNING: Pinning tables should be carefully considered. If a pinned table is larger or grows larger than the available data cache, the server may need to be restarted and the table unpinned.
7987 | 16 | Switch to database '%.*s' before running this command.
7988 | 16 | This command cannot be run on the MASTER database when a size parameter is specified. Use the '%s' option.
7989 | 16 | The size option cannot be specified for TEMPDB when it is on a RAM device.
7990 | 16 | Database '%.*s' has status: 0x%x which is not a normal database state. (Mask: 0x%x).
7991 | 16 | Unable to shrink database '%.*s' as it contains %d pages. Minimum pages %d.
7992 | 10 | DBCC SHRINKDB running on database '%.*s'...
7993 | 16 | Unable to shrink database '%.*s' to %d pages as it only contains %d pages.
7994 | 16 | Unable to shrink database '%.*s' to %d pages. Minimum new size %d pages.
7995 | 16 | See prior errors. DBCC operation has been aborted.
7996 | 16 | Extended stored procedures can only be created in the master database.
8002 | 15 | Parameter number %d and subsequent parameters must be passed as '@name = value'. Once the form '@name = value' has been used, all subsequent parameters must be passed in the form '@name = value'
8003 | 15 | There are too many parameters in this CREATE PROCEDURE statement. The maximum number is %d.
8004 | 16 | Received an unrecognized datatype %d from TDS datastream.
8005 | 15 | Received a procedure name length of %d. The TDS datastream is incorrect.
8006 | 16 | Maxlen %d invalid for datatype '%s'.
8101 | 16 | An explicit value for the identity column in table '%.*s' can only be specified when a column list is used and IDENTITY_INSERT is ON
8102 | 16 | Illegal attempt to update identity column '%.*s'
8103 | 16 | Table '%.*s' does not exist or cannot be opened for SET operation
8104 | 16 | Current user is not the DBO or object owner for table '%.*s', unable to perform SET operation
8105 | 16 | '%.*s' is not a user table, unable to perform SET operation
8106 | 16 | Table '%.*s' does not have the identity property, unable to perform SET operation
8107 | 16 | IDENTITY_INSERT is already ON for table '%.*s.%.*s.%.*s'.%sUnable to perform SET operation for table '%.*s'.
8108 | 16 | Attempting to add identity column to table '%.*s', via select into, which already has column '%.*s' that inherits the identity property.
8109 | 16 | Attempting to add multiple identity columns to table '%.*s', via select into.
8110 | 16 | Attempting to add multiple primary key constraints to table '%.*s'.
8111 | 16 | Attempting to define PRIMARY KEY constraint on nullable column in table '%.*s'.
8112 | 16 | Attempting to add more than one clustered index for constraints on table '%.*s'.
8113 | 16 | Unable to recompile '%.*s', '%s %.*s' is illegal in an open transaction.
8114 | 16 | Error converting type %s to type %s.
8115 | 16 | Arithmetic overflow error converting %s to type %s.
8116 | 16 | Argument type %s is invalid for argument %d of %s function.
8117 | 16 | Operand data type %s is invalid for %s operator.
8118 | 16 | Column '%.*s.%.*s' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.
8119 | 16 | Column '%.*s.%.*s' is invalid in the HAVING clause because it is not contained in an aggregate function and there is no GROUP BY clause.
8120 | 16 | Column '%.*s.%.*s' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
8121 | 16 | Column '%.*s.%.*s' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.
8122 | 16 | Only the first query in the UNION statement is allowed to have a select with assignment.
8123 | 16 | A correlated expression is invalid because it is not in a GROUP BY clause.
8124 | 16 | Multiple columns specified in an aggregated expression containing an outer reference. If an expression being aggregated contains an outer reference then that outer reference must be the only column reference in the expression.
8125 | 16 | An aggregated expression containing an outer reference must be contained in either the select list or a subquery of the HAVING clause of the query whose FROM clause contains the table containing the column being aggregated.
8126 | 16 | Column name '%.*s.%.*s' is invalid in the ORDER BY clause because it is not contained in an aggregate function and there is no GROUP BY clause.
8127 | 16 | Column name '%.*s.%.*s' is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause.
8129 | 16 | Shrinking of database devices is not allowed in the current version. The new disk size must be greater than %d.
8130 | 16 | Device is not a database device. Only database devices can be expanded.
8131 | 16 | Error occurred allocating resource during expansion of device TEMP_DB. Please consult the event log for details.
8132 | 16 | The number of expansions of the device TEMP_DB has exceeded the system limit. In order to expand the device shutdown and restart the server.
8133 | 16 | All the result expressions in a CASE specification must not be NULL.
8134 | 16 | Divide by zero error encountered
8135 | 16 | Table level constraint does not specify column list, table '%.*s'.
8136 | 16 | Duplicate columns specified in %s constraint key list, table '%.*s'.
8137 | 16 | Foreign key reference is missing target table name, table '%.*s'.
8138 | 16 | More than 16 columns specified in foreign key column list, table '%.*s'.
8139 | 16 | Number of referencing columns in foreign key differs from number of referenced columns, table '%.*s'.
8140 | 16 | More than one key specified in column level %s constraint, table '%.*s'.
8141 | 16 | Column %s constraint for column '%.*s' references another column, table '%.*s'.
8142 | 16 | Subqueries are not supported in %s constraints, table '%.*s'.
8143 | 16 | Parameter %.*s was supplied multiple times.
8144 | 16 | Too many arguments supplied for procedure %.*s.
8145 | 16 | %.*s is not a parameter for procedure %.*s.
8146 | 16 | Procedure %.*s has no parameters and arguments were supplied.
8147 | 16 | Attempt to create IDENTITY attribute on nullable column '%.*s', table '%.*s'.
8148 | 16 | More than one column %s constraint specified for column '%.*s', table '%.*s'.
8149 | 16 | Invalid column '%.*s' specified in %s definition, table '%.*s'.
8150 | 16 | Multiple NULL constraints specified for column '%.*s', table '%.*s'.
8151 | 16 | Both a primary key and unique constraint have been defined for column '%.*s', table '%.*s'. Only one is allowed.
13001 | 10 | data page
13002 | 10 | index page
13003 | 10 | leaf page
13004 | 10 | last
13005 | 10 | root
13006 | 10 | read from
13007 | 10 | send to
13008 | 10 | receive
13009 | 10 | send
13010 | 10 | read
13011 | 10 | wait
13012 | 10 | A USE DATABASE statement
13013 | 10 | a procedure or trigger
13014 | 10 | A DISTINCT clause
13015 | 10 | a view
13016 | 10 | An INTO clause
13017 | 10 | An ORDER BY clause
13018 | 10 | A COMPUTE clause
13019 | 10 | a SELECT INTO statement
13020 | 10 | option
13021 | 10 | offset option
13022 | 10 | statistics option
13023 | 10 | parameter option
13024 | 10 | built-in function name
13025 | 10 | field
13026 | 10 | parameter
13027 | 10 | convert specification
13028 | 10 | index
13029 | 10 | table
13030 | 10 | database
13031 | 10 | procedure
13032 | 10 | trigger
13033 | 10 | view
13034 | 10 | default
13035 | 10 | rule
13036 | 10 | system
13037 | 10 | unknown type
13038 | 10 | SET command
13039 | 10 | column
13040 | 10 | type
13041 | 10 | character string
13042 | 10 | integer
13043 | 10 | identifier
13044 | 10 | number
13045 | 10 | integer value
13046 | 10 | floating point value
13047 | 10 | object
13048 | 10 | column heading
13076 | 10 | an assignment
13077 | 10 | a cursor declaration
13078 | 10 | replication filter
14001 | 16 | The destination table must not be qualified.
14002 | 16 | The 'Sync' subsystem with the Task id '%ld' was not found.
14003 | 16 | You must supply a publication name.
14004 | 16 | %s must be in the current database.
14005 | 16 | Unable to drop publication. A subscription exists on it.
14006 | 16 | Unable to drop the publication.
14007 | 16 | You cannot change the destination database of a subscription unless it is inactive.
14008 | 11 | There are no publications.
14009 | 11 | There are no articles for publication '%s'.
14010 | 16 | The remote server is not defined as a subscription server.
14011 | 16 | The publication you have selected does not exist or you do not have permission to access it.
14012 | 16 | The @status value must be either 'active' or 'inactive'.
14013 | 16 | This database is not enabled for publication.
14014 | 16 | The synchronization method (@sync_method) must be either '[bcp] native' or '[bcp] character'.
14015 | 16 | The replication frequency (@repl_freq) must be either 'continuous' or 'snapshot'.
14016 | 16 | The publication '%s' already exists.
14017 | 16 | Invalid @restricted value. Valid options are 'true' or 'false'.
14018 | 16 | The publication could not be created.
14019 | 16 | The @operation must be either 'add' or 'drop'.
14020 | 16 | The column id for the specified column could not be obtained. The column was not correctly added to the article.
14021 | 16 | The column was not correctly added to the article.
14022 | 16 | The property must be 'name', 'description', 'sync_object', 'type', 'status', 'ins_cmd', 'del_cmd', 'upd_cmd', 'filter', 'dest_table', 'creation_script' or 'pre_creation_cmd'.
14023 | 16 | The type must be 'logbased', 'logbased manualfilter', 'logbased manualview', 'logbased manualboth'.
14024 | 16 | The status must be 'active' or 'inactive'.
14025 | 10 | The article was successfully updated.
14026 | 16 | The synchronization method must be '[bcp] native', '[bcp] character', or 'dump/load'.
14027 | 11 | %s does not exist in the current database.
14028 | 11 | User tables are the only objects that can be published.
14029 | 16 | The vertical partition switch must be either 'true' or 'false'.
14030 | 16 | The article '%s' already exists in publication '%s'.
14031 | 16 | User tables and views are the only valid synchronization objects.
14032 | 16 | The article name cannot be the keyword 'all'.
14034 | 16 | The publication name @publication cannot be the keyword 'all'.
14035 | 10 | Database '%s' is already enabled for publishing.
14036 | 16 | Unable to enable database for publishing.
14037 | 16 | Database '%s' is not enabled for publishing.
14038 | 16 | Unable to disable database for publishing.
14039 | 16 | Unable to construct column clause for article view. Reduce the number of columns or create the view manually.
14040 | 16 | The server '%s' is already a subscriber.
14041 | 16 | Unable to perform the command. The distribution server is not available.
14042 | 16 | Unable to be create subscriber.
14043 | 16 | %s cannot be NULL.
14044 | 16 | Owner qualified %s names are not allowed.
14045 | 16 | The task id must be unique. The specified @taskid has already been used.
14046 | 16 | Unable to drop article. A subscription exists on it.
14047 | 16 | Unable to drop %s.
14048 | 16 | The server '%s' is not a subscriber.
14049 | 16 | Stored procedures are the only objects that can be used as a filter.
14050 | 11 | You do not have a subscription on this publication/article.
14051 | 16 | The property must be 'sync_type' or 'dest_db'.
14052 | 16 | The sync_type must be 'manual', 'automatic' or 'none'.
14053 | 16 | The subscription could not be updated at this time.
14054 | 10 | The subscription was successfully updated.
14055 | 10 | There is no subscription on article %s in publication %s for subscriber %s.
14056 | 16 | The subscription could not be dropped at this time.
14057 | 16 | The subscription could not be created.
14058 | 16 | The subscription already exists.
14059 | 16 | Unable to obtain information from the distribution server.
14060 | 16 | Unable to update distribution subscriber table. The subscriber could not be removed at this time.
14061 | 16 | The pre_creation_cmd must be 'none', 'drop', 'delete', 'truncate'.
14062 | 10 | The subscriber was dropped.
14063 | 11 | The remote server does not exist or has not been designated as a valid subscriber.
14064 | 11 | There are no subscribers registered.
14065 | 16 | The status must be 'active', 'inactive', or 'subscribed'.
14066 | 16 | The previous status must be 'active', 'inactive', or 'subscribed'.
14067 | 16 | The status value is the same as the previous status value.
14068 | 16 | Unable to update sysobjects. The subscription status could not be changed.
14069 | 16 | Unable to update sysarticles. The subscription status could not be changed.
14070 | 16 | Unable to update the distribution database subscription table. The subscription status could not be changed.
14071 | 16 | This distributor information could not be obtained.
14072 | 16 | The publication you have selected is restricted. Contact your system administrator or database owner to obtain permission to subscribe to this publication. The subscription was not created.
14073 | 16 | This procedure must be executed from the subscriber.
14074 | 16 | The server '%s' is already listed as a publisher.
14075 | 16 | The publisher could not be created at this time.
14076 | 16 | Unable to grant replication login privilege to '%s'.
14077 | 10 | The publication was successfully updated.
14078 | 16 | The property must be 'name', 'description', 'taskid', 'sync_method', 'status', 'repl_freq', or 'restricted'.
14079 | 16 | Do not qualify the destination table name with a database. Use the 'dest_db' property of sp_changesubscription to specify a destination database.
14080 | 11 | The remote server does not exist or has not been designated as a valid publisher.
14081 | 16 | @replicated must be either 'true' or 'false'.
14082 | 10 | The object was successfully marked as a replicated object.
14083 | 16 | The object was not successfully (un)marked as a replicated object.
14085 | 16 | The subscriber information could not be obtained from the distributor.
14086 | 16 | '%s' is not a valid @subscriber_db.
14087 | 16 | No completed transactions found.
14088 | 16 | The table '%s' must have a primary key in order to be published.
14089 | 10 | '%ld' completed transactions for subscriber '%s' were removed from the distribution database.
14090 | 16 | A distribution server already exists.
14091 | 16 | The @type parameter passed to sp_helpreplicationdb must be either 'pub' or 'sub'.
14092 | 16 | Unable to change article. A subscription exists on it.
14093 | 16 | You must be System Administrator (SA) or the Database Owner (dbo) or a Replication Subscriber (repl_subscriber) to execute this stored procedure.
14150 | 10 | Replication-%s: Task '%s' succeeded. %s
14151 | 20 | Replication-%s: Task '%s' failed. %s
14152 | 18 | Replication-%s: Task '%s' scheduled for retry after %d attempt(s). '%s'
14153 | 10 | Replication-%s: Task '%s' detected the potential for missing jobs on '%s'.
14200 | 16 | Invalid frequency type.
14201 | 16 | Invalid frequency subtype.
14202 | 16 | Frequency interval invalid for this frequencytype; consult your documentation.
14203 | 16 | Invalid frequency relative interval; consult your documentation.
14204 | 16 | Active end date cannot be less than active start date.
14205 | 16 | Active end time cannot be less than active start time.
14206 | 16 | Next run date must be between active start date and active end date.
14207 | 16 | Next run time must be between active start time and active end time.
14208 | 16 | You must specify a task name.
14209 | 16 | Server '%s' is not a registered remote server.
14210 | 16 | Task '%s' already exists.
14211 | 16 | Database '%s' not found.
14212 | 16 | Operator '%s' not found.
14213 | 16 | Run priority must one of: -15 (idle), -2 (lowest), -1(low), 0 (normal), 1 (high), 2 (highest), 15 (time critical).
14214 | 16 | Invalid log history completion level.
14215 | 16 | Invalid email completion level.
14216 | 16 | Invalid task id.
14217 | 16 | You must be the sa or logged in as the owner of this task to update it.
14218 | 16 | Invalid task name.
14219 | 16 | You must be the sa or the owner of this task to drop it.
14220 | 16 | Login '%s' not found.
14221 | 16 | Administrator '%s' not found.
14222 | 16 | Task '%s' not found.
14223 | 16 | Task id '%ld' not found.
14224 | 16 | You must be the sa, or specify a task for which you are the owner, to purge task histories.
14225 | 16 | You must specify an Administrator name.
14226 | 16 | Administrator '%s' already exists.
14227 | 16 | You must specify an email address and/or a pager number for an administrator.
14228 | 16 | Invalid pager start time.
14229 | 16 | Invalid pager end time.
14230 | 16 | Pager end time must be later than pager end time.
14231 | 16 | Pager days must be one or more of Sunday (day 1) thru Saturday (day 7).
14232 | 16 | You must be the sa to add, drop, or update administrators.
14233 | 16 | Invalid admin id.
14234 | 16 | Administrator '%s' is the Email Admin for one or more Tasks. You must reassign those Tasks before dropping the Administrator.
14235 | 16 | Administrator '%s' is the Email or Page Admin for one or more Alerts. You must reassign those Alerts before dropping the Administrator.
14236 | 16 | Invalid active end date.
14237 | 16 | Invalid active end time of day.
14238 | 16 | Invalid active start date.
14239 | 16 | Invalid active start time of day.
14240 | 16 | Invalid next run date.
14241 | 16 | Invalid next run time.
14244 | 16 | You must be sa to reassign tasks.
14245 | 16 | You must specify the task name or a login name to reassign or drop tasks.
14246 | 16 | You must specify the name or id of the task to be updated.
14247 | 16 | The username (%s) you have specified is not your username (%s) in the %s database. Only the SA or the DBO of %s may do this.
14500 | 16 | You must supply either a zero (or NULL) for @message_id and a non-zero non-null value for @severity, or a zero (or NULL) for @severity and a non-zero non-null value for @message_id.
14501 | 16 | The @task_name parameter you have supplied does not exist in systasks.
14502 | 16 | The @severity parameter you have supplied is not valid.
14503 | 16 | The @include_event_description_in parameter must be EMAIL, PAGER, BOTH or NONE.
14504 | 16 | The @delay_between_responses parameter must be greater than or equal to 0.
14505 | 16 | The @occurrence_count parameter must be greater than 0 or equal to 0.
14506 | 16 | An Alert for this @message_id - or @severity - with the same @event_description_keyword and @database_name values already exists (id = %s).
14507 | 16 | The @alert_name parameter you have supplied does not exist in sysalerts.
14508 | 16 | The @operator_name parameter you have supplied does not exist in sysoperators.
14509 | 16 | This Notification does not exist in sysnotifications.
14510 | 16 | The @object_type parameter must be either ALERTS or OPERATORS.
14511 | 16 | The @enum_type parameter must be either ALL, ACTUAL or TARGET.
14512 | 16 | The @notification_method parameter must be either EMAIL, PAGER or BOTH.
14513 | 16 | This Operator already exists.
14514 | 16 | The @pager_days parameter you have supplied is invalid.
14515 | 16 | This Notification already exists.
14516 | 16 | The @enabled parameter must be either 0 or 1.
14517 | 16 | The @notification_method parameter must be EMAIL, PAGER or BOTH.
14518 | 16 | The @message_id parameter you have supplied is not valid.
14519 | 16 | The @target_name parameter must be supplied when specifying an @enum_type of TARGET.
14520 | 16 | The @target_name parameter should not be supplied when specifying an @enum_type of ALL or ACTUAL.
14521 | 16 | The @target_name parameter does not exist in sys%s.
14522 | 16 | The @weekday_pager_start_time parameter is invalid (must be in HHMMSS format).
14523 | 16 | The @weekday_pager_end_time parameter is invalid (must be in HHMMSS format).
14524 | 16 | The @saturday_pager_start_time parameter is invalid (must be in HHMMSS format).
14525 | 16 | The @saturday_pager_end_time parameter is invalid (must be in HHMMSS format).
14526 | 16 | The @sunday_pager_start_time parameter is invalid (must be in HHMMSS format).
14527 | 16 | The @sunday_pager_end_time parameter is invalid (must be in HHMMSS format).
14528 | 16 | The @name or @new_name parameter you have supplied is not unique.
14529 | 16 | The @new_name parameter you have supplied is not unique.
14530 | 16 | %s is the Fail-Safe Operator. You must make another operator the Fail-Safe operator before %s can be dropped.
14531 | 16 | The @task_name parameter you have supplied is not an On-Demand task. Only On-Demand tasks may be fired in response to an Alert.
15000 | 16 | You must be System Administrator (SA) or the Database Owner (dbo) to execute this stored procedure.
15001 | 16 | %s does not exist.
15002 | 16 | The procedure '%s' cannot be executed from within a transaction.
15003 | 16 | You must be System Administrator (SA) to execute this stored procedure.
15004 | 16 | Name cannot be NULL.
15005 | 16 | '%s' is not a valid name since it begins with an invalid character.
15006 | 16 | '%s' is not a valid name since it contains invalid characters.
15007 | 16 | The login '%s' does not exist.
15008 | 16 | User '%s' does not exist in the current database.
15009 | 16 | The object '%s' does not exist in database '%s'.
15010 | 16 | The database '%s' does not exist. Use sp_helpdb to show available databases.
15011 | 16 | Database option '%s' does not exist.
15012 | 16 | The device '%s' does not exist. Use sp_helpdevice to show available devices.
15013 | 16 | The device option '%s' does not exist or is not a settable option.
15014 | 16 | The group '%s' does not exist in the current database.
15015 | 16 | The server '%s' does not exist. Use sp_helpserver to show available servers.
15016 | 16 | The default '%s' does not exist.
15017 | 16 | The rule '%s' does not exist.
15018 | 16 | The segment '%s' does not exist.
15019 | 16 | The extended stored procedure '%s' does not exist.
15020 | 16 | The stored procedure '%s' does not exist in the current database.
15021 | 16 | The report '%s' does not exist in the current database.
15022 | 16 | The specified user name is already aliased.
15023 | 16 | User '%s' already exists in the current database.
15024 | 16 | The group '%s' already exists in the current database.
15025 | 16 | The login '%s' already exists.
15026 | 16 | Logical device '%s' already exists.
15027 | 16 | The segment '%s' already exists.
15028 | 16 | The server '%s' already exists.
15029 | 16 | The type '%s' already exists in the current database.
15030 | 16 | Physical device '%s' already exists.
15031 | 16 | The object '%s' already exists in the current database.
15032 | 16 | The database '%s' already exists.
15033 | 16 | '%s' is not a valid official language name.
15034 | 16 | The alias '%s' already exists in Syslanguages.
15035 | 16 | '%s' is not a database device.
15036 | 16 | The datatype '%s' does not exist.
15037 | 16 | The physical datatype '%s' does not allow NULLs.
15038 | 16 | User-defined datatypes based on the 'timestamp' datatype are not allowed.
15039 | 16 | The language '%s' already exists in Syslanguages.
15040 | 16 | User defined error messages must have a number > 50000.
15041 | 16 | User defined error messages must have a severity between 1 and 25.
15042 | 16 | Only the System Administrator (SA) may add messages with severity > 18 or which set the WITH_LOG option to 'true'.
15043 | 16 | You must specify 'REPLACE' to overwrite an existing message.
15044 | 16 | '%s' is an unknown device type. Use 'disk', 'tape', 'diskette' or 'pipe'.
15045 | 16 | Logical name may not be NULL.
15046 | 16 | Physical name may not be NULL.
15047 | 16 | The only legal options for a tape device are 'skip' and 'noskip'.
15048 | 16 | '%s' is not a valid database device type. Please enter either 'system' or 'data'.
15049 | 16 | Database already exists, specify 'data' instead of 'system' as the database device type to install additional data devices for an existing database.
15050 | 16 | No such database. You must first create the database by defining its system device.
15051 | 16 | The database size must be at least 1 Meg per device.
15052 | 16 | A new location for the system device must be provided when installing the system database device.
15053 | 16 | Objects exist which are not owned by the dbo.
15054 | 16 | No more available device numbers.
15055 | 16 | File '%s' cannot be opened.
15056 | 16 | Error inserting into table '%s'. Database fragment not installed.
15057 | 16 | List of %s name contains spaces, which are not allowed.
15058 | 16 | List of %s has too few names.
15059 | 16 | List of %s has too many names.
15060 | 16 | List of %s names contains name(s) which have '%s' non-alphabetic characters.
15061 | 16 | WARNING: physical device name '%s' is not unique.
15062 | 16 | The 'guest' user may not be mapped to a login name.
15063 | 16 | Login already has an account under a different user name.
15064 | 16 | Primary Key constraints do not have space allocated.
15065 | 16 | All user ids have been assigned.
15066 | 16 | There is already a default-name mapping of a remote login from remote server '%s'.
15067 | 16 | '%s' isn't a local user -- remote login denied.
15068 | 16 | There is already a remote user named '%s' for remote server '%s'.
15069 | 16 | One or more users is using the database. Cannot complete requested operation.
15070 | 16 | The 'repl_subscriber' user may only be mapped to the 'repl_subscriber' login.
15071 | 16 | usage: sp_addmessage <msgnum>,<severity>,<msgtext> [,REPLACE]
15072 | 16 | Usage: sp_addremotelogin remoteserver [, loginame [,remotename]]
15073 | 16 | The device '%s' is not used by database '%s'.
15074 | 16 | '%s' is reserved exclusively as a log device.
15075 | 16 | The maximum number of segments for the current database are already defined.
15076 | 16 | Default and table or user datatype must be in the 'current' database.
15077 | 16 | Rule and table or usertype must be in the 'current' database.
15078 | 16 | Table or view name must be in the 'current' database.
15079 | 10 | Queries processed: %d.
15080 | 17 | Failure using SQLMapi, check SQL Server error log.
15081 | 16 | The dependent table or view does not exist in the current database.
15082 | 16 | Name must be in the 'current' database.
15083 | 16 | Report must be in the 'current' database.
15084 | 16 | Column or user datatype must be in the 'current' database.
15085 | 16 | Usage: sp_addtype name, 'datatype' [,null | nonull]
15086 | 16 | Illegal precision specified -- must be between 1 and 38.
15087 | 16 | Illegal scale specified -- must be less than precision and positive.
15088 | 16 | Physical type is fixed length. You cannot specify the length.
15089 | 16 | Usage: sp_addserver servername [, 'local']
15090 | 16 | There is already a local server.
15091 | 16 | You must specify a length with this physical type.
15092 | 16 | Illegal length specified -- must be between 1 and 255.
15093 | 16 | '%s' is not a valid date order.
15094 | 16 | '%s' is not a valid first day.
15095 | 16 | Insert into 'syslanguages' failed. Language not added.
15096 | 16 | Only the System Administrator (SA) or '%s' can change '%s's default language.
15097 | 16 | Can't drop '%s' because there are associated entries in master.dbo.sysmessages. Run sp_droplanguage with dropmessages flag.
15098 | 16 | The only legal value for @dropmessages is 'dropmessages'.
15099 | 16 | Update of 'syslanguages' failed. Language alias not changed.
15100 | 16 | Usage: sp_bindefault defaultname, objectname [, 'futureonly']
15101 | 16 | You cannot bind a default to a column of datatype 'timestamp'.
15102 | 16 | You cannot bind a default to an identity column.
15103 | 16 | You cannot bind a default to a column that was created with or altered to have a default value.
15104 | 16 | You do not own a table named '%s' that has a column named '%s'.
15105 | 16 | You do not own a datatype with that name.
15106 | 16 | Usage: bindrule rulename, objectname [, 'futureonly']
15107 | 16 | You cannot bind a rule to a column of datatype 'text', 'image', or 'timestamp'.
15108 | 16 | Only the System Administrator (SA) can change the owner of a database.
15109 | 16 | The owner of the 'master' database may not be changed.
15110 | 16 | The proposed new db owner already is a user in the database.
15111 | 16 | The proposed new db owner already is aliased in the database.
15112 | 16 | First table in the common key does not exist.
15113 | 16 | Second table in the common key does not exist.
15114 | 16 | Only the table owner may define its common keys.
15115 | 16 | The tables have no such first column or the columns are of different types.
15116 | 16 | The tables have no such second column or the columns are of different types.
15117 | 16 | The tables have no such third column or the columns are of different types.
15118 | 16 | The tables have no such fourth column or the columns are of different types.
15119 | 16 | The tables have no such fifth column or the columns are of different types.
15120 | 16 | The tables have no such sixth column or the columns are of different types.
15121 | 16 | The tables have no such seventh column or the columns are of different types.
15122 | 16 | The tables have no such eighth column or the columns are of different types.
15123 | 16 | The configuration option does not exist.
15124 | 16 | The configuration option '%s' is not unique.
15125 | 16 | Only the System Administrator (SA) may change configuration parameters.
15126 | 16 | You cannot set the number of devices to be less than the number of devices already defined in sysdevices.
15127 | 16 | You cannot set the default language to a language ID that is not defined in Syslanguages.
15128 | 16 | You cannot set the kernel language to a language ID that is not defined in Syslanguages.
15129 | 16 | '%d' is not a valid value for configuration option '%s'.
15130 | 16 | usage: sp_dbinstall <dbname>,<logical devname>,<physical devname>,<size>,{'system' | 'data'},['new location']
15131 | 16 | usage: sp_dbremove <dbname> [,dropdev]
15132 | 16 | You cannot change someone else's default database.
15133 | 16 | Cannot change settings for 'master' device.
15134 | 16 | No alias for specified user exists.
15135 | 16 | Device option '%s' is not unique.
15136 | 16 | usage: sp_devoption [devname, optname, {true | false}]
15137 | 16 | Only the System Administrator (SA) may set device options.
15138 | 16 | Cannot set device to 'read only' because it is used by non 'read only' database(s). Use sp_dboption to set database options.
15139 | 16 | The device is a RAM disk and cannot be used as a default device.
15140 | 16 | Usage: sp_diskdefault logicalname {defaulton | defaultoff}.
15141 | 16 | Cannot drop device since it is being used by one or more databases.
15142 | 16 | Cannot drop the group 'public'.
15143 | 16 | '%s' is not a valid option for @updateusage. Please enter either 'true' or 'false'.
15144 | 16 | Group has members. It must be empty before it can be dropped.
15145 | 16 | Usage: sp_dropkey {primary | foreign | common}, tabname [,deptabname]. Type must be 'primary', 'foreign', or 'common'.
15146 | 16 | You must be the owner of the table or view to drop its key.
15147 | 16 | No primary key for the table or view exists.
15148 | 16 | You need to supply the dependent table or view as the third parameter.
15149 | 16 | No foreign key for the table or view exists.
15150 | 16 | No common keys exist between the two tables or views supplied.
15151 | 16 | Foreign key table does not exist.
15152 | 16 | Primary key table does not exist.
15153 | 16 | Only the owner of the table may define a foreign key.
15154 | 16 | The table has no such first column.
15155 | 16 | The table has no such second column.
15156 | 16 | The table has no such third column.
15157 | 16 | The table has no such fourth column.
15158 | 16 | The table has no such fifth column.
15159 | 16 | The table has no such sixth column.
15160 | 16 | The table has no such seventh column.
15161 | 16 | The table has no such eighth column.
15162 | 16 | Primary key does not exist with the same number of columns as the foreign key.
15163 | 16 | Primary key does not exist.
15164 | 16 | Datatypes of the first column in the keys are different.
15165 | 16 | Datatypes of the second column in the keys are different.
15166 | 16 | Datatypes of the third column in the keys are different.
15167 | 16 | Datatypes of the fourth column in the keys are different.
15168 | 16 | Datatypes of the fifth column in the keys are different.
15169 | 16 | Datatypes of the sixth column in the keys are different.
15170 | 16 | Datatypes of the seventh column in the keys are different.
15171 | 16 | Datatypes of the eighth column in the keys are different.
15172 | 16 | Only the owner of the table may define a primary key.
15173 | 16 | Primary key already exists on table -- drop key first.
15174 | 16 | Login '%s' owns one or more database(s). Change the owner of the following database(s) before dropping login:
15175 | 16 | Login '%s' is mapped to user: '%s' in database '%s'. Drop user before dropping login.
15176 | 16 | Login '%s' is aliased to user: '%s' in database '%s'. Drop alias before dropping login.
15177 | 16 | usage: sp_dropmessage <msg number>.
15178 | 16 | Cannot drop a message with a number < 50000.
15179 | 16 | Message number %u does not exist.
15180 | 16 | Type is being used. You cannot drop it.
15181 | 16 | You cannot drop the 'database owner'.
15182 | 16 | You cannot drop the 'guest' user from master or tempdb.
15183 | 16 | The user owns objects in the database and cannot be dropped.
15184 | 16 | The user owns datatypes in the database and cannot be dropped.
15185 | 16 | There is no remote user '%s' mapped to local user '%s' from the remote server '%s'.
15186 | 16 | Cannot drop segment '%s' completely.
15187 | 16 | The segment '%s' is being used.
15188 | 16 | Segment '%s' does not reference device '%s'.
15189 | 16 | There is only one unique device mapping for the segment '%s' -- use sp_dropsegment with no device argument.
15190 | 16 | There are still remote logins for the server '%s'.
15191 | 16 | Usage: sp_dropserver server [, droplogins]
15192 | 16 | Can't make the only segment on original device log-only.
15193 | 16 | This procedure can be used on system tables only.
15194 | 16 | Cannot re-create index on this table.
15195 | 16 | The first table does not exist.
15196 | 16 | The second table does not exist.
15197 | 16 | There is no text for object '%s'
15198 | 16 | The name supplied is not a user, group, or aliased.
15199 | 16 | Only the System Administrator (SA) or the Database Owner (dbo) may move the syslogs table.
15200 | 16 | There are no remote servers defined.
15201 | 16 | There are no remote logins for the remote server '%s'.
15202 | 16 | There are no remote logins defined.
15203 | 16 | There are no remote logins for '%s'.
15204 | 16 | There are no remote logins for '%s' on remote server '%s'.
15205 | 16 | There are no servers defined.
15206 | 16 | Invalid Remote Server Option: '%s'
15207 | 16 | usage: sp_makestartup <procname>
15208 | 16 | The specified procedure must be owned by the SA.
15209 | 16 | Procedure expects parameters. Cannot be used as a startup stored procedure.
15210 | 16 | Only System Administrator (SA) can use loginame option -- password not changed.
15211 | 16 | Old (current) password incorrect for user -- password not changed.
15212 | 16 | Use sp_logdevice to move syslogs table.
15213 | 16 | You cannot move system tables.
15214 | 16 | You do not own a table named '%s'.
15215 | 16 | There is no index named '%s' for table '%s'.
15216 | 16 | '%s' is not a valid option for @delfile.
15217 | 16 | '%s' is a system table. sp_recompile cannot be used on system tables.
15218 | 16 | Object '%s' is not a table.
15219 | 16 | You do not own table '%s'. Only the System Administrator (SA) or the table's owner may perform this action.
15220 | 16 | Usage: sp_remoteoption [remoteserver, loginame, remotename, optname, {true | false}]
15221 | 16 | Remote login option does not exist or cannot be set by user. Run sp_remoteoption with no parameters to see options.
15222 | 16 | Remote login option '%s' is not unique.
15223 | 16 | A column named '%s' already exists in table '%s'.
15224 | 16 | An index named '%s' already exists in table '%s'.
15225 | 16 | Object name beginning with '#' is not allowed.
15226 | 16 | Only the System Administrator (SA) can change the name of a database.
15227 | 16 | The database '%s' cannot be renamed.
15228 | 16 | The System Administrator (SA) must set database '%s' to single-user mode with sp_dboption before it can be renamed.
15229 | 16 | usage: sp_serveroption [server, optname, {true | false}]
15230 | 16 | Server option does not exist or cannot be set by user. Run sp_serveroption with no parameters to see options.
15231 | 16 | Server option '%s' is not unique.
15232 | 16 | Only the System Administrator (SA) may set server options.
15233 | 16 | There is already a server network name '%s'.
15234 | 16 | Object is stored in 'sysprocedures' and has no space allocated directly.
15235 | 16 | Views do not have space allocated.
15236 | 16 | Column '%s' has no default.
15237 | 16 | User datatype '%s' has no default.
15238 | 16 | Column '%s' has no rule.
15239 | 16 | User datatype '%s' has no rule.
15240 | 16 | usage: sp_unmakestartup <procname>
15241 | 16 | usage: sp_dboption [dbname, optname, {true | false}]
15242 | 16 | Database option '%s' is not unique.
15243 | 16 | The option '%s' cannot be changed for the 'master' database.
15244 | 16 | Only the System Administrator (SA) or the owner of the database may set db options.
15245 | 16 | 'DBCC DBCONTROL' error. Database not placed offline.
15246 | 16 | Cannot bring database online due to problem opening device '%s'.
15247 | 16 | The object name '%s' is ambiguous. Table '%s' has both a column and an index named '%s'. Please specify either 'COLUMN' or 'INDEX' after the new name.
15248 | 16 | You cannot specify '%s' unless renaming a column or index.
15249 | 16 | '%s' is an invalid option for object type. Please enter either 'COLUMN' or 'INDEX'.
15250 | 16 | Database name component of object qualifier must be name of current database.
15251 | 16 | Illegal '%s' specified -- must be %s.
15252 | 16 | PK table name or FK table name must be given.
15253 | 16 | '%s' is not a column in table '%s'.
15254 | 16 | Non dbo/guest users exist in database. Please drop them before removing database.
15255 | 16 | '%s' is not a valid value for @autofix. The only valid option is 'auto'.
15256 | 16 | usage: sp_certify_removable <dbname> [,'auto']
15257 | 16 | You cannot be USEing the database that you are attempting to certify.
15258 | 16 | The database must be owned by the System Administrator before it can be removed.
15259 | 16 | The database must occupy at least three database devices (one each for the 'system' and 'log' segments and one or more for the 'data' segment(s)) before it can be removed.
15260 | 16 | The database has cannot be removed since it has noncontiguous fragments on one or more devices.
15261 | 16 | usage: sp_create_removable <dbname>,<syslogical>,<sysphysical>, <syssize>,<loglogical>,<logphysical>, <logsize>,<datalogical1>,<dataphysical1>, <datasize1> [,<datalogical2>,<dataphysical2>,<datasize2>... <datalogical16>,<dataphysical16>,<datasize16>]
15262 | 16 | Invalid device size entered. Database devices must be at least 1 Meg. in size.
15263 | 16 | Could not create the '%s' device. See the errorlog for details.
15264 | 16 | Could not create the '%s' portion of the database.
15265 | 16 | Could not update sysusages.segmap.
15266 | 16 | Cannot make '%s' database removable.
15267 | 16 | You must supply a physical device for logical data device '%s'.
15268 | 16 | You must supply a size for logical data device '%s'.
15269 | 16 | Logical data device '%s' not created.
15270 | 16 | You may not specify a length for user types based on the 'sysname' type.
15271 | 16 | Invalid @with_log value. Valid options are 'true' or 'false'.
15272 | 16 | Procedure '%s' is not a valid startup procedure since startup procedures must be in the 'master' database.
15273 | 16 | Cannot make '%s' a startup procedure since startup procedures must be in the 'master' database and the current database is '%s'.
15274 | 16 | Procedure '%s' is not a valid startup procedure since startup procedures must be in the 'master' database and the current database is '%s'.
15275 | 16 | Foreign Key constraints do not have space allocated.
16901 | 10 | %s:This feature has not been implemented yet.
16902 | 10 | %s: The parameter %s is invalid.
16903 | 10 | %s procedure called with incorrect number of parameters.
16904 | 10 | The cursor handle is invalid.
16905 | 10 | The cursor is already open.
16906 | 10 | The cursor is not declared.
16907 | 10 | %s is not allowed in cursor statements.
16909 | 10 | %s: The cursor identifier value provided (%d) is not valid.
16910 | 10 | %s: The fetch type %s can only be used with keyset driven cursors.
16911 | 10 | %s: The fetch type %s cannot be used with forward only cursors.
16912 | 10 | %s: This fetch type requires a rownumber.
16914 | 10 | %s procedure called with too many parameters.
16915 | 10 | A cursor with the name '%s' already exists.
16916 | 10 | A cursor with the name '%s' does not exist.
16917 | 10 | Cursor is not open.
16919 | 10 | Cannot open cursor--referenced object (NAME NOT RECOVERABLE) dropped already.
16920 | 10 | Stored procedure defining the cursor does not have a select statement.
16921 | 10 | Cursorfetch: Must declare variable '%s'.
16922 | 10 | Cursorfetch: Variable type of '%s' does not match that of selected column in the cursor.
16923 | 10 | Cursorfetch: Maximum length of '%s' is incompatible with that of selected column in the cursor.
16924 | 10 | Cursorfetch: Number of variables declared in the INTO list must match that of selected columns.
16925 | 10 | The fetch type %s cannot be used with dynamic cursors.
16926 | 10 | sp_cursoroption: The column id (%d) does not correspond to a TEXT or IMAGE column.
16927 | 10 | sp_cursoroption: The cursor already has a name.
16928 | 10 | The column name '%s' specified in the FOR UPDATE list is invalid or ambiguous.
16929 | 10 | Cursor is read only.
16930 | 10 | Requested row is not in the fetch buffer.
16931 | 10 | There are no rows in the current fetch buffer.
16932 | 10 | Cursor has a 'FOR UPDATE' list and the requested column to be updated is not in this list.
16933 | 10 | The cursor does not include the table being modified.
16934 | 10 | Optimistic concurrency check failed, the row was modified outside of this cursor.
16935 | 10 | No values parameters were specified for the sp_cursor-%s command.
16936 | 10 | Cannot open cursor-referenced object '%s' (ID %d) during %s.
16937 | 10 | Cannot open a cursor on a stored procedure that has anything other than a single select statement in it.
16938 | 10 | sp_cursoropen: The statement parameter can only be a single select or a single stored procedure.
16939 | 10 | Process has isolation level set to 0 (uncommitted reads), which can only support READ ONLY cursors.
16940 | 10 | Table optimizer hint '%s' is not allowed with READ ONLY cursors.
16941 | 10 | Cursor updates are not allowed on tables opened with NOLOCK option.
16942 | 10 | Asyncronous keyset generation failed, the cursor has been deallocated.
16943 | 10 | Cursor open failed because the size of the keyset row exceeded maximum allowed row size.
16944 | 10 | The unique index used for the table needs to have smaller number of keys or keys with smaller sizes.
16945 | 10 | Cursor open failed because the size of the table row is too large for optimistic checking based on values.
16946 | 10 | Try using locking, readonly or timestamp based optimistic checking for concurrency control on the table.

(1880 row(s) affected)


Chapter 27 DB-Library Error Messages

DB-Library Error Messages

This appendix describes all DB-Library error messages and severity levels. The information in this appendix is divided into two tables. The table in the following section lists the errors alphabetically, along with their severities. The table in the "Error Severities" section summarizes the error severity levels. Number values corresponding to the errors are passed to the currently installed, user-supplied error handler. For information about creating error handlers, see the description for dberrhandle in Microsoft SQL Server Programming DB-Library for C. To access these error definitions, include the SQLFRONT.H and SQLDB.H header files in your program.


Errors

The following error values are defined in the header file SQLFRONT.H. Note that errors with a severity of EXCOMM also have a network-related error message appended to the dberrstr value. In addition, EXCOMM errors have network-specific error information in oserr and oserrstr.

Error no. | Error/ Error severity | Description
10000 | SQLEMEM EXRESOURCE | Unable to allocate sufficient memory.
10001 | SQLENULL EXPROGRAM | NULL DBPROCESS pointer encountered.
10002 | sqlenlog exconsistency | NULL LOGINREC pointer encountered.
10003 | SQLEPWD EXUSER | Login incorrect.
10004 | SQLECONN EXCOMM | Unable to connect: SQL Server is unavailable or does not exist.
10005 | SQLEDDNE EXINFO | DBPROCESS is dead or not enabled.
10006 | SQLENULLO EXCONSISTENCY | Attempt to login with NULL LOGINREC.
10007 | SQLESMSG EXSERVER | General SQL Server error: Check messages from SQL Server.
10008 | SQLEBTOK EXCOMM | Bad token from SQL Server: Datastream processing out of synchronization.
10009 | SQLENSPE EXPROGRAM | General nonspecific DB-Library error.
10010 | SQLEREAD EXCOMM | Read from SQL Server failed.
10011 | SQLECNOR EXPROGRAM | Column number out of range.
10012 | SQLETSIT EXINFO | Attempt to call dbtsput with an invalid timestamp.
10013 | SQLEPARM EXCONSISTENCY | Invalid parameter in DB-Library function reference.
10014 | SQLEAUTN EXPROGRAM | Attempt to update the timestamp of a table with no timestamp column.
10015 | SQLECOFL EXCONVERSION | Data conversion resulted in overflow.
10016 | SQLERDCN EXCONVERSION | Requested data conversion does not exist.
10017 | SQLEICN EXPROGRAM | Invalid value for computeid or invalid compute column number.
10018 | SQLECLOS EXCOMM | Error in closing network connection.
10019 | SQLENTXT EXPROGRAM | Attempt to get text point/timestamp from a nontext column.
10020 | SQLEDNTI EXPROGRAM | Attempt to use dbtxtsput to put a new text timestamp into a column whose datatype is neither SQLTEXT nor SQLIMAGE.
10021 | SQLETMTD EXPROGRAM | Attempt to send too much TEXT data through dbmoretext.
10022 | SQLEASEC EXPROGRAM | Attempt to send an empty command buffer to the SQL Server.
10023 | SQLENTLL EXUSER | Name too long for LOGINREC field.
10024 | SQLETIME EXTIME | SQL Server connection timed out.
10025 | SQLEWRIT EXCOMM | Write to SQL Server failed.
10026 | SQLEMODE EXCOMM | Network connection not in correct mode ¾ invalid SQL Server connection.
10027 | SQLEOOB EXCOMM | Error in sending out-of-band data to SQL Server.
10028 | SQLEITIM EXPROGRAM | Illegal timeout value specified.
10029 | SQLEDBPS EXRESOURCE | Maximum number of DBPROCESSes already allocated.
10030 | SQLEIOPT EXPROGRAM | Attempt to use invalid dboption.
10031 | SQLEASNL EXPROGRAM | Attempt to set fields in a null LOGINREC.
10032 | SQLEASUL EXPROGRAM | Attempt to set unknown LOGINREC field.
10033 | SQLENPRM EXPROGRAM | NULL parameter not allowed for this dboption.
10034 | SQLEDBOP EXPROGRAM | Invalid or out of range dbn parameter.
10035 | SQLENSIP EXPROGRAM | Negative starting index passed to dbstrcpy.
10036 | SQLECNULL EXPROGRAM | NULL destination variable not allowed.
10037 | SQLESEOF EXCOMM | Unexpected EOF from SQL Server.
10038 | SQLERPND EXPROGRAM | Attempt to initiate a new SQL Server operation with results pending.
10039 | SQLECSYN EXCONVERSION | Attempt to convert data stopped by syntax error in source field.
10040 | SQLENONET EXCOMM | DB-Library network communications layer not loaded.
10041 | SQLEBTYP EXPROGRAM | Unknown bind type passed to DB-Library function.
10042 | SQLEABNC EXPROGRAM | Attempt to bind to a nonexistent column.
10043 | SQLEABMT EXPROGRAM | User attempted a dbbind with mismatched column and variable types.
10044 | SQLEABNP EXPROGRAM | Attempt to bind using NULL pointers.
10045 | SQLEBNCR EXPROGRAM | Attempt to bind user variable to a nonexistent compute row.
10046 | SQLEAAMT EXPROGRAM | User attempted a dbaltbind with mismatched column and variable types.
10047 | SQLENXID EXNONFATAL | The server did not grant us a distributed-transaction ID.
10048 | SQLEIFNB EXPROGRAM | Illegal field number passed to bcp_control.
10049 | SQLEKBCO EXINFO | 1000 rows successfully bulk copied to host file.
10050 | SQLEBBCI EXINFO | Batch successfully bulk copied to SQL Server.
10051 | SQLEKBCI EXINFO | 1000 rows sent to SQL Server.
10052 | SQLEBCWE EXNONFATAL | I/O error while writing bcp datafile.
10053 | SQLEBCNN EXUSER | Attempt to bulk copy a null value into a server column that does not accept null values.
10054 | SQLEBCOR EXCONSISTENCY | Attempt to bulk copy an oversized row to SQL Server.
10055 | SQLEBCPI EXPROGRAM | Call bcp_init before any other bcp routines.
10056 | SQLEBCPN EXPROGRAM | Use bcp_bind, bcp_collen, and bcp_colptr only after calling bcp_init with the copy direction set to DB_IN.
10057 | SQLEBCPB EXPROGRAM | Do not use bcp_bind after bcp_init has been passed a non-null input filename.
10058 | SQLEVDPT EXUSER | For bulk copy, all variable-length data must have either a length-prefix or a terminator specified.
10059 | SQLEBIVI EXPROGRAM | Use bcp_columns and bcp_colfmt only after bcp_init has been passed a valid input file.
10060 | SQLEBCBC EXPROGRAM | Call bcp_columns before bcp_colfmt.
10061 | SQLEBCFO EXUSER | Host files must contain at least one column: bcp.
10062 | SQLEBCVH EXPROGRAM | Call bcp_exec only after bcp_init has been passed a valid host file.
10063 | SQLEBCUO EXRESOURCE | Unable to open host datafile: bcp.
10064 | SQLEBUOE EXRESOURCE | Unable to open error file: bcp.
10065 | SQLEBWEF EXNONFATAL | I/O error while writing bcp error file.
10066 | SQLEBTMT EXPROGRAM | Attempt to send too much text data with bcp_moretext.
10067 | SQLEBEOF EXNONFATAL | Unexpected EOF encountered in bcp datafile.
10068 | SQLEBCSI EXCONSISTENCY | Host-file columns may be skipped only when copying into the server.
10069 | SQLEPNUL EXCONSISTENCY | NULL program pointer encountered.
10070 | SQLEBSKERR EXCONSISTENCY | Cannot seek in data file.
10071 | SQLEBDIO EXPROGRAM | Bad bulk-copy direction.
10072 | SQLEBCNT EXUSER | Attempt to use bulk copy with a nonexistent server table.
10073 | SQLEMDBP EXPROGRAM | Attempt to set maximum number of DPPROCESS lower than 1.
10075 | SQLCRSINV EXPROGRAM | Invalid cursor statement.
10076 | SQLCRSCMD EXPROGRAM | Attempt to call cursor functions when there are commands waiting to be executed.
10077 | SQLCRSNOIND EXINFO | One of the tables involved in the cursor statement does not have a unique index.
10078 | SQLCRSDIS EXPROGRAM | Cursor statement contains one of the disallowed phrases COMPUTE, UNION, FOR BROWSE, or SELECT INTO.
10079 | SQLCRSAGR EXPROGRAM | Aggregate functions are not allowed in a cursor statement.
10080 | SQLCRSORD EXPROGRAM | Only fully keyset driven cursors can have ORDER BY, GROUP BY, or HAVING PHRASES.
10081 | SQLCRSMEM EXPROGRAM | Keyset or window scroll size exceeds the memory limitations of this machine.
10082 | SQLCRSBSKEY EXPROGRAM | Keyset cannot be scrolled backward in mixed cursors with a previous fetch type.
10083 | SQLCRSNORES EXINFO | Cursor statement generated no results.
10084 | SQLCRSVIEW EXPROGRAM | A view cannot be joined with another table or a view in a cursor statement.
10085 | SQLCRSBUFR EXPROGRAM | Row buffering should not be turned on when using cursor functions.
10086 | SQLCRSFROWN EXINFO | Row number to be fetched is outside valid range.
10087 | SQLCRSBROL EXPROGRAM | Backward scrolling cannot be used in a forward scrolling cursor.
10088 | SQLCRSFRAND EXPROGRAM | Fetch types RANDOM and RELATIVE can only be used within the keyset of keyset driven cursors.
10089 | SQLCRSFLAST EXPROGRAM | Fetch type LAST requires fully keyset driven cursors.
10090 | SQLCRSRO EXPROGRAM | Data locking or modifications cannot be made in a READONLY cursor.
10091 | SQLCRSTAB EXPROGRAM | Table name must be determined in operations involving data locking or modifications.
10092 | SQLCRSUPDTAB EXPROGRAM | Update or insert operations using bind variables require single table cursors.
10093 | SQLCRSUPDNB EXPROGRAM | Update or insert operations cannot use bind variables when binding type is NOBIND.
10094 | SQLCRSVIIND EXPROGRAM | The view used in the cursor statement does not include all the unique index columns of the underlying tables.
10095 | SQLCRSNOUPD EXINFO | Update or delete operation did not affect any rows.
10096 | SQLCRSOS2 EXPROGRAM | Cursors are not supported for this server.
10097 | SQLEBCSA EXPROGRAM | The BCP hostfile %s contains only %ld rows. Skipping all of these rows is not allowed.
10098 | SQLCRSRO EXPROGRAM | Data locking or modifications cannot be made in a READONLY cursor.
10099 | SQLEBCNE EXPROGRAM | The table %s contains only %ld rows. Copying up to row %ld is not possible.
10100 | SQLEBCSK EXPROGRAM | The table %s contains only %ld rows. Skipping all of these rows is not allowed.
10101 | SQLEUVBF EXPROGRAM | Attempt to read unknown version of bcp format file.
10102 | SQLEBIHC EXPROGRAM | Incorrect host-column number found in bcp format file.
10103 | SQLEBWFF EXRESOURCE | I/O error while reading bcp format file.
10104 | SQLNUMVAL EXPROGRAM | The data stored in the DBNUMERIC/DBDECIMAL structure is invalid.
10105 | SQLEOLDVR EXPROGRAM | The SQL Server's TDS is obsolete with this version of DB-Library.


Error Severities

The following table lists all error severities with their numerical equivalents and an explanation of the type of error. When an error occurs or when a message is sent, these numerical equivalents are passed to the currently installed, user-supplied error handler.

Error severity levels are defined in the SQLFRONT.H header file. Your program must include SQLFRONT.H if it refers to these severity levels.

Error severity | Severity number | Description
EXINFO | 1 | Informational, nonerror.
EXUSER | 2 | User error.
EXNONFATAL | 3 | Nonfatal error.
EXCONVERSION | 4 | Error in DB-Library data conversion.
EXSERVER | 5 | The server has returned an error flag.
EXTIME | 6 | Timeout period exceeded while waiting for a response from the server ¾ the DBPROCESS is still alive.
EXPROGRAM | 7 | Coding error in user program.
EXRESOURCE | 8 | Running out of resources ¾ the DBPROCESS may be dead.
EXCOMM | 9 | Failure in communication with server ¾ the DBPROCESS is dead.
EXFATAL | 10 | Fatal error ¾ the DBPROCESS is dead.
EXCONSISTENCY | 11 | Internal software error ¾ notify your primary support provider.


Error 10008 (DB-Library)

DB-Library Severity Level 9

Message Text

Bad token from SQL Server: Datastream processing out of synchronization.

Explanation

This error occurs when DB-Library cannot interpret the tabular data stream (TDS) sent from SQL Server. A DB-Library application communicates with SQL Server across the network using a TDS. The TDS is a specification for the communication of data and other messages between SQL Server and the DB-Library client. The network libraries used by SQL Server and the DB-Library client provide the interface for the transmission of TDS over a particular network protocol. The network protocol used is independent from the TDS as long as there is an appropriate interface network library that supports the network protocol, whether it is a named pipe connection or a socket connection. Each DB-Library application automatically parses this TDS to extract useful information (for example, query results rows), or to generate requests of or responses to SQL Server in a format that is mutually understood.

There are two main causes for this error:

  • The data sent by SQL Server over the network named pipe or socket has been corrupted. This is almost always caused by a network problem involving either network hardware or software.
  • The network can generate errors or messages unknown to DB-Library; as a consequence, this error can be generated.

Action

Inspect the Windows NT Event Viewer system and application logs. These logs may provide information that indicates whether the problem is related to the server network protocol, the network card, or the system configuration. Review the SQL Server-specific entries in the application log or the SQL Server error log for relevant network-related errors that correspond in time with the occurrence of the 10008 error seen on the client. If this review does not provide enough information to resolve the problem, special network monitoring tools and a review of the client's configuration may be necessary.

If the problem persists, contact your primary network support provider for assistance.

Programmers using the SQL Server Programmer's Toolkit (for DB-Library) can handle error 10008 by adding conditional statements to test for the occurrence of this error. When error 10008 is seen in the DB-Library error handler, additional processing can include closing the current DBPROCESS connection, opening a new connection, and then resending the query. For details, see Microsoft SQL Server Programming DB-Library for C and Microsoft SQL Server Programming DB-Library for Visual Basic.


Error 10018 (DB-Library)

DB-Library Severity Level 9

Message Text

Error in closing the network connection.

Explanation

This error occurs when the client attempted to close a network connection and the network software returned a failure code. DB-Library may also return a network-specific error code that your network provider may find useful in diagnosing the problem. This error usually indicates a problem with the network, system configuration, or software, rather than a problem with SQL Server.

Action

Inspect the Windows NT Event Viewer system and application logs. These logs may provide information that indicates whether or not the problem is related to the server network protocol, the network card, or the system configuration. Review the SQL Server-specific entries in the application log or in the SQL Server error log for relevant network-related errors that correspond in time with the occurrence of the 10018 error seen on the client. If this review does not provide enough information to resolve the problem, special network monitoring tools and a review of the client's configuration may be needed.

If the problem persists contact your primary network support provider for assistance.


Error 10024 (DB-Library)

DB-Library Severity Level 6

Message Text

SQL Server connection timed out.

Explanation

This error message is returned from DB-Library when the query time-out setting for the application's connection to SQL Server is too low. The query is terminated when it takes longer to complete than the time allocated.

Action

Check the application for configuration settings, and increase the query time-out setting. If this is a custom application, you can adjust the query time-out setting by using the bdsettime() function in C or the SqlSetTime% function in Visual Basic.


Error 10025 (DB-Library)

DB-Library Severity Level 9

Message Text

Write to SQL Server failed.

Explanation

This error occurs due to a failure of a client-initiated write operation over a network connection to SQL Server. DB-Library may also return a network-specific error code that your network support provider may find useful in diagnosing the problem. This message occurs when the network connection between the client and the server is broken. It may also be associated with SQL Server error 1608.

Action

Inspect the Windows NT Event Viewer system and application logs. These logs may provide information that indicates whether or not the problem is related to the server network protocol, the network card, or the system configuration. Review the SQL Server-specific entries in the application log or in the SQL Server error log for relevant network-related errors that correspond in time with the occurrence of the 10025 error seen on the client. If this review does not provide enough information to resolve the problem, special network monitoring tools and a review of the client's configuration may be needed.

If the problem persists contact your primary network support provider for assistance.


Error 10053 (DB-Library)

DB-Library
Severity Level 2

Message Text

Attempt to bulk copy a null value into a server column that does not accept null values.

Explanation

This error occurs when you attempt to bulk copy a null value into a table column that does not accept null values. This most often occurs when the column is changed from NULL to NOT NULL after previous bulk copies.

Action

If the source file being bulk copied is character data, the file can be edited and the column value changed to an appropriate value for the column definition. You can also change the current definition of the table or create a separate table with a column definition that allows null values.


Error 10054 (DB-Library)

DB-Library Severity Level 11

Message Text

Attempt to bulk copy an oversized row to SQL Server.

Explanation

This error occurs during a bulk copy operation when a row or rows in the source data file do not match the row as defined for the destination database table. It can occur due to a missing end-of-line marker. It can also occur if there are more column delimiters in the source data file than currently exist in the destination database table. This error can also occur if the source data file is corrupt.

Action

Verify that the source data file matches the column definitions for the database table. Or create a new table to match the current data file, bulk copy the data into the database and then manipulate the data using Transact-SQL statements.

You can manipulate either the source data file or create a format file to facilitate the data transfer. You can manipulate character-based data files by using a text editing tool that will accommodate the data file size and will not add special hidden characters during a save operation. The editing tool can then be used to manipulate the source data file by adding or deleting characters as necessary so that the source data file matches the table definition. You can also create a format file. The generated format file can be manipulated by a text editing tool and changed so that character positions/columns in the source data file are ignored. Native format files are more difficult to manipulate.

The alternatives to manipulating the native format source data file and/or a format file are limited due to the storage of datatypes other than character in a binary type format. It is fairly difficult to manipulate this file type with any editing tool, and it is more difficult to generate and manipulate a format file. You can use the /F or the /L command-line flags to specify the first and last row in the source data file that is to be bulk copied into SQL Server. If the source data file contains a few oversized rows, these flags can be used to bulk copy up to the oversized row followed by a bulk copy operation from the row following the oversized row to the end of the data file.

For more information on BCP, see the Microsoft SQL Server Transact-SQL Reference and the Microsoft SQL Server Administrator's Companion. If you are unable to resolve this error, contact your primary support provider for assistance.


Chapter 28 ODBC Messages

ODBC Messages

SQLError returns SQLSTATE values as defined by the X/Open and SQL Access Group SQL CAE specification (1992). SQLSTATE values are strings that contain five characters. The following table lists SQLSTATE values that a driver can return for SQLError.

The character string value returned for an SQLSTATE consists of a two character class value followed by a three character subclass value. A class value of 01 indicates a warning and is accompanied by a return code of SQL_SUCCESS_WITH_INFO. Class values other than 01, except for the class IM, indicate an error and are accompanied by a return code of SQL_ERROR. The class IM is specific to warnings and errors that derive from the implementation of ODBC itself. The subclass value 000 in any class is for implementation defined conditions within the given class. The assignment of class and subclass values is defined by ANSI SQL-92.

Note

Although successful execution of a function is normally indicated by a return value of SQL_SUCCESS, the SQLSTATE 00000 also indicates success.

SQLSTATE | ODBC API (Driver Manager) Error
00000 | Success
01000 | General warning
01002 | Disconnect error
01004 | Data truncated
01006 | Privilege not revoked
01S00 | Invalid connection string attribute
01S01 | Error in row
01S02 | Option value changed
01S03 | No rows updated or deleted
01S04 | More than one row updated or deleted
01S05 | Cancel treated as FreeStmt/Close
01S06 | Attempt to fetch before the result returned the first rowset
07001 | Wrong number of parameters
07006 | Restricted data type attribute violation
07S01 | Invalid use of default paramater
08001 | Unable to connect to data source
08002 | Connection in use
08003 | Connection not open
08004 | Data source rejected establishment of connection
08007 | Connection failure during transaction
08S01 | Communication link failure
21S01 | Insert value list does not match column list
21S02 | Degree of derived table does not match column list
22001 | String data right truncation
22002 | Indicator variable required but not supplied
22003 | Numeric value out of range
22005 | Error in assignment
22008 | Datetime field overflow
22012 | Division by zero
22026 | String data, length mismatch
23000 | Integrity constraint violation
24000 | Invalid cursor state
25000 | Invalid transaction state
28000 | Invalid authorization specification
34000 | Invalid cursor name
37000 | Syntax error or access violation
3C000 | Duplicate cursor name
40001 | Serialization failure
42000 | Syntax error or access violation
70100 | Operation aborted
IM001 | Driver does not support this function
IM002 | Data source name not found and no default driver specified
IM003 | Specified driver could not be loaded
IM004 | Driver's SQLAllocEnv failed
IM005 | Driver's SQLAllocConnect failed
IM006 | Driver's SQLSetConnectOption failed
IM007 | No data source or driver specified; dialog prohibited
IM008 | Dialog failed
IM009 | Unable to load translation DLL
IM010 | Data source name too long
IM011 | Driver name too long
IM012 | DRIVER keyword syntax error
IM013 | Trace file error
S0001 | Base table or view already exists
S0002 | Base table not found
S0011 | Index already exists
S0012 | Index not found
S0021 | Column already exists
S0022 | Column not found
S0023 | No default for column
S1000 | General error
S1001 | Memory allocation failure
S1002 | Invalid column number
S1003 | Program type out of range
S1004 | SQL data type out of range
S1008 | Operation canceled
S1009 | Invalid argument value
S1010 | Function sequence error
S1011 | Operation invalid at this time
S1012 | Invalid transaction operation code specified
S1015 | No cursor name available
S1090 | Invalid string or buffer length
S1091 | Descriptor type out of range
S1092 | Option type out of range
S1093 | Invalid parameter number
S1094 | Invalid scale value
S1095 | Function type out of range
S1096 | Information type out of range
S1097 | Column type out of range
S1098 | Scope type out of range
S1099 | Nullable type out of range
S1100 | Uniqueness option type out of range
S1101 | Accuracy option type out of range
S1103 | Direction option out of range
S1104 | Invalid precision value
S1105 | Invalid parameter type
S1106 | Fetch type out of range
S1107 | Row value out of range
S1108 | Concurrency option out of range
S1109 | Invalid cursor position
S1110 | Invalid driver completion
S1111 | Invalid bookmark value
S1C00 | Driver not capable
S1DE0 | No data at execution values pending
S1T00 | Timeout expired

The ODBC SQL Server Driver version 2.5 can return error messages for certain SQLSTATE values, as shown in the following table:

SQLSTATE | SQL SERVER DRIVER ERROR
01000 | The ODBC catalog stored procedures installed on server %s are version %s; version %02d.%02d.%4.4d or later is required to ensure proper operation. Please contact your system administrator.
01000 | Ongoing transaction has been committed
01000 | Access to database specified in the odbc.ini file has been denied. Default used.
01000 | Language specified in the odbc.ini file is not supported. Default used.
01000 | Procedure executed with 'EXEC'. No output parameters returned.
01S02 | Packet size change not honored by server, server size used
22008 | Invalid date
22008 | Invalid time
22008 | Invalid timestamp
28000 | Invalid authorization specification; Access to selected database has been denied
28000 | Invalid authorization specification; Language specified is not supported
IM006 | Packet size change not supported by server, default used
IM009 | Translation module is not valid
S1000 | The stored procedure required to complete this operation could not be found on the server (they were supplied with the ODBC setup disk for the SQL Server driver). Please contact your system administrator.
S1000 | Unknown token received from SQL Server
S1000 | Operation not allowed while results are pending
S1000 | Unable to load communication module. Driver has not been correctly installed.
S1000 | Communication module is not valid. Driver has not been correctly installed.
S1000 | Warning: Partial insert/update. The insert/update of a text or image column(s) did not succeed.
S1000 | Connection is busy with results for another hstmt
S1000 | Failure during closing of connection
S1000 | Protocol error in TDS stream
S1000 | TDS buffer length too large
S1000 | Non-default parameter not allowed after default parameter


Appendixes

The appendixes provide supplemental information.

Appendix A, Interoperation with Microsoft SQL Server 4.2, discusses the simultaneous operation in an enterprise of Microsoft SQL Server 6.0 and Microsoft SQL Server version 4.2.

Appendix B, Estimating Database Size, contains formulas and examples that show how to estimate the size of tables and indexes in a database.

Appendix C, System Tables Diagram, presents a chart of the relationships between the SQL Server system tables.

Appendix D, RAID Technology, discusses using drive subsystems to tune a database server for optimal performance.

Appendix E, Backup and Recovery Guidelines for Production Environments, discusses backup and recovery of SQL Server databases running in production environments.

Appendix F, Accessibility for People with Disabilities, provides information about products and service that make Microsoft Windows NT, Windows, and SQL Server more accessible for people with disabilities.


Appendix A Interoperation with Microsoft SQL Server 4.2

Interoperation with Microsoft SQL Server 4.2

In most ways, SQL Server 6.0 servers and clients interoperate normally with SQL Server 4.2 servers and clients. This appendix discusses interoperation issues and exceptions.

Note The information in this appendix addresses administration and connectivity topics. For information about language, statement, query, and other compatibility issues between SQL Server 6.0 and SQL Server 4.2 databases, see the compatibility information provided in the Microsoft SQL Server Transact-SQL Reference.

For more information, choose one of the following topics.

Servers and Clients

Using SQL Administrator and SQL Object Manager

Running SQLOLE42.SQL

SQL Enterprise Manager Capabilities

Running SQL Server 4.2 Alongside 6.0

Loading SQL Server 4.2 Databases

Data Transfer

Using Extended Stored Procedures

Support for New SQL Server 6.0 Features


Servers and Clients

Both types of client can connect to both types of server. SQL Server 6.0 clients can connect to SQL Server 6.0 and 4.2 servers, and SQL Server 4.2 clients can connect to SQL Server 6.0 and 4.2 servers.

To a SQL Server 4.2 server, a SQL Server 6.0 client appears to be a 4.2 client. To a SQL Server 6.0 server, a SQL Server 4.2 client appears and behaves as a SQL Server 4.2 client. A SQL Server 4.2 client does not support new SQL Server 6.0 features. For example, the decimal datatype is converted to float. For more information, see Support for New Features, later in this appendix.

SQL Server 6.0 and SQL Server 4.2 servers may be set up as remote servers to each other. Server-to-Server RPC operates normally between SQL Server 6.0 and SQL Server 4.2 servers.

ODBC connections between 6.0 and 4.2 function normally.


Using SQL Administrator and SQL Object Manager

SQL Administrator and SQL Object Manager are no longer provided. They have been superseded by SQL Enterprise Manager.

Servers or clients that still have old copies of SQL Administrator or SQL Object Manager can still use those tools to administer a SQL Server 6.0 server, but only after that server has run two scripts¾ADMIN60.SQL and OBJECT60.SQL¾that upgrade its stored procedures to allow SQL Administrator and SQL Object Manager to administer it. However, you will notice a few differences when using these tools to administer a SQL Server 6.0 server, as compared to administering a SQL Server 4.2 server.

When an existing SQL Server 4.2 server is upgraded to SQL Server 6.0, the old copies of SQL Administrator or SQL Object Manager are left in place, and the necessary upgrade scripts are automatically run by the setup program. You do not need to take any action to allow an upgraded server to be managed by those tools.

For new SQL Server 6.0 installations, the two upgrade scripts must be run if other servers or clients that still have SQL Administrator and SQL Object Manager installed will be used to administer the new SQL Server 6.0 server.

To allow users of SQL Administrator and SQL Object Manager to administer a new SQL Server 6.0 server
  1. From the Microsoft SQL Server 6.0 program group, start ISQL/w and connect to the new SQL Server 6.0 server.

    Or start SQL Enterprise Manager, select the new SQL Server 6.0 server from the Server Manager window, and from the Tools menu, choose Query Analyzer.

  2. To allow this server to be administered by the SQL Administrator utility, from the \SQL60\INSTALL directory, open and run the script ADMIN60.SQL.
  3. To allow this server to be administered by the SQL Object Manager utility, from the \SQL60\INSTALL directory, open and run the script OBJECT60.SQL.


Running SQLOLE42.SQL

Before you can administer a SQL Server version 4.2 server from SQL Enterprise Manager, you must run the SQLOLE42.SQL script on the SQL Server version 4.2 server. SQLOLE42.SQL is a Transact-SQL script that creates SQL-DMO stored procedures for SQL Server 4.2 servers. (You must install these on a SQL Server 4.2 server before SQL-DMO objects can connect to that server.)

The appropriate SQLOLE42.SQL file can be found in the distribution directory (\ALPHA, \I386, or \MIPS) containing the software compatible with the hardware platform’s processor architecture.


SQL Enterprise Manager Capabilities

The following table indicates which SQL Enterprise Manager commands can be used to administer SQL Server 6.0 and SQL Server 4.2 servers.

Menu | Command | 6.0 | 4.2 | Comment
File | all commands | X | X |
View | all commands | X | X |
Server | Register Server | X | X |
 | Server Groups | X | X |
 | Alerts | X |  |
 | Configurations | X |  |
 | Replication Options | X |  |
 | Current Activity | X |  |
 | Error Log | X |  |
 | Replication Configuration | X |  |
Tools | Task Scheduling | X |  |
 | Query Analyzer | X | X |
 | Backup/Restore | X | X | SQL Server 4.2 servers cannot use backup/restore features that are new for SQL Server 6.0.
 | Set Server/Database | X | X |
 | Preferences/Configure | X | X |
Manage | Logins | X | X |
 | Devices | X | X |
 | Databases | X | X |
 | Replication | X |  |
 | Users | X | X |
 | Groups | X | X |
 | Tables | X | X | Constraints for declarative referential integrity are not supported for SQL Server 4.2 servers.
 | Indexes | X | X |
 | Triggers | X | X |
 | Stored Procedures | X | X |
 | Views | X | X |
 | Rules | X | X |
 | Defaults | X | X |
 | User Defined Datatypes | X | X |
Object | Permissions | X | X | REFERENCES permission is not supported for SQL Server 4.2 servers.
 | Dependencies | X | X |
 | Generate SQL Scripts | X | X | "Table DRI" checkbox is disabled for SQL Server 4.2 servers.
 | Drop | X | X |
 | Rename | X | X |
Window | all commands | X | X |
Help | all commands | X | X |

Also, the Server States indicators in the Server Manager window will not display for SQL Server 4.2 servers. The Stoplight icon will only display gray (not red, green, or yellow), and the Connect indicator (the red zigzag) will not appear.


Running SQL Server 4.2 Alongside 6.0

When running both SQL Server 4.2 and SQL Server 6.0 servers at the same time on the same computer, to be supported by the graphical tools, the servers must use different names. For example, if you want to use SQL Transfer Manager to transfer data between the two, each must use a different server name.

You change a server name by using sp_addserver with the local option. For example:

sp_addserver POODLE, local

This changes the server name in the master.dbo.sysservers table and sets the @@servername global variable. The server must be restarted for the change to take effect.

Note The server name is only an issue if the two SQL Server installations are run simultaneously. You can have SQL Server 4.2 and SQL Server 6.0 installed on the same computer and have both use the same server name, as long as you run them one at a time.

For information about setting up a side-by-side installation, see Microsoft SQL Server Setup. For instructions on using sp_addserver, see the Microsoft SQL Server Transact-SQL Reference.


Loading SQL Server 4.2 Databases

You can dump a SQL Server 4.2 user database and load it on a SQL Server 6.0 server (although you cannot do this for master.) However, this capability is one-way only, as you cannot dump a SQL Server 6.0 database and load it on a SQL Server 4.2 server.

When loading a SQL Server 4.2 user database on a SQL Server 6.0 server, all necessary comments must exist in syscomments. SQL Server cannot upgrade all objects from SQL Server 4.2 databases to SQL Server 6.0 if you have deleted data from the text column in the syscomments table.

Also, you may encounter conflicts with the new SQL Server 6.0 keywords. If you do, after loading the database, you can change the conflicting table or object name and alter the applications that access those objects so that they use the new names. For a list of the new keywords, see the Microsoft SQL Server Transact-SQL Reference.

Note For information about language, statement, query, and other compatibility issues between SQL Server 6.0 and SQL Server 4.2 databases, see the compatibility information provided in the Microsoft SQL Server Transact-SQL Reference.


Data Transfer

You can use bcp to transfer a native or character format file from SQL Server 4.2 into a SQL Server 6.0 table of the same definition. You can also transfer in the other direction, but if you are bulk copying a table with the new SQL Server 6.0 datatypes into a SQL Server 4.2 table, you must use character mode bcp. The destination table would use only SQL Server 4.2 datatypes. Identity column values and the identity property are not transferred.

You can use SQL Transfer Manager to transfer objects and data between SQL Server version 4.2 and SQL Server version 6.0. When moving objects data from SQL Server 4.2 to SQL Server 6.0, some stored procedures or views may contain Transact-SQL statements that are no longer accepted in version 6.0, and some 4.2 object names may now be reserved words in 6.0. In these cases, the transfer will fail for these objects and will not complete correctly for objects that depend on them. For more information, see the compatibility information in the Microsoft SQL Server Transact-SQL Reference.

When using SQL Transfer Manager to transfer objects and data from SQL Server 6.0 to SQL Server 4.2, you cannot include 6.0-specific datatypes in the source objects, and 6.0-specific schema additions such as identity columns and declarative referential integrity will not be included in the transfer.

For more information about using SQL Transfer Manager and bcp, see Chapter 11, Exporting and Importing Data.

Note For a list of new SQL Server 6.0 keywords and for other information about language, statement, query, and other compatibility issues between SQL Server 6.0 and SQL Server 4.2 databases, see the compatibility information in the Microsoft SQL Server Transact-SQL Reference.


Using Extended Stored Procedures

If you are using extended stored procedure .DLLs written for previous versions of Microsoft SQL Server, you will need to rebuild those extended stored procedures by using the new SQL Server .DLLs. For more information, see Microsoft SQL Server Programming Open Data Services.


Support for New SQL Server 6.0 Features

Support for New Features

For a summary of new SQL Server 6.0 features, see the Release Notes provided with SQL Server Books Online.

As should be expected, SQL Server 4.2 servers do not support new SQL Server 6.0 features such as constraints, new keywords, the identity property, the decimal, numeric, float(b), and double precision datatypes, expanded ANSI SQL support and language enhancements, server cursors, constraints, and so on. For information on these features, see the Microsoft SQL Server Transact-SQL Reference.

SQL Server 4.2 servers are not supported as replication participants. They cannot act as publication servers or distribution servers and are not supported subscribers.


Appendix B Estimating Database Size

Estimating Database Size

This appendix contains formulas and examples that show how to estimate the size of tables and indexes in a database.

The following examples are used:

  • Calculating the size of a 9,000,000-row table with a clustered index.
  • Calculating the size of a 9,000,000-row table with a nonclustered index.

Since the amount of overhead in tables containing variable-length fields is greater, two sets of formulas are presented in each example ¾ one for fixed-length fields and one for variable-length fields.

To calculate the size of a database, add the number of bytes of data and associated overhead and divide that number by the number of bytes available on a data page. Each 2K data page uses 32 bytes of overhead, so there are 2016 (2048 - 32) bytes available for data on each data page.

For best accuracy, round down divisions that calculate the number of rows per page, and round up divisions that calculate the number of pages.

If you are using FILL FACTOR in your CREATE INDEX statement, it will change some of the equations. For more information, see Other Factors, later in this appendix.

If a table includes text or image datatypes, use 16K (the size of the text pointer that is stored in the row) as indicated in the following examples, and see Using Average Sizes for text/image Data Pages, later in this appendix.

The following are the storage sizes for SQL Server datatypes:

Datatype | Size
char | Defined size
varchar | Data size
binary | Defined size
varbinary | Data size
int | 4
smallint | 2
tinyint | 1
float | 8
float(b) | 4 (for precision of 1-7), 8 (for precision of 8-15)
double precision | 8
real | 4
money | 8
smallmoney | 4
datetime | 8
smalldatetime | 4
bit | 1
decimal | 2-17 bytes, depending on precision (see the following table)
numeric | 2-17 bytes, depending on precision (see the following table)
text | 16 bytes + 2K per initialized column
image | 16 bytes + 2K per initialized column
timestamp | 8

Note Any columns defined to accept NULL values must be considered variable-length columns, since they involve the overhead associated with the variable-length columns.

The decimal and numeric datatypes have a maximum precision of 38. Based on the precision specified, a length is computed and used as the size of the array to store the datatype. The following table shows the mapping from precision to length.

Precision | Size (bytes)
0 - 2 | 2
3 - 4 | 3
5 - 7 | 4
8 - 9 | 5
10 - 12 | 6
13 - 14 | 7
15 - 16 | 8
17 - 19 | 9
20 - 21 | 10
22 - 24 | 11
25 - 26 | 12
27 - 28 | 13
29 - 31 | 14
32 - 33 | 15
34 - 36 | 16
37 - 38 | 17

All calculations in the following examples are based on the maximum size for varchar and varbinary data ¾ the defined size of the columns. They also assume that columns were defined as NOT NULL. If you want to use average values for variable-length columns, see Using Average Sizes for Variable Fields, later in this appendix.


Calculating the Size of a Table with a Clustered Index

The steps in this section show how to calculate the size of a table with a clustered index.

For an example of how to use the formulas presented in this section, see Calculating the Size of a 9,000,000-Row Table with a Clustered Index, later in this appendix.


Step 1: Calculate the Data Row Size

Calculation of data row size is slightly different depending on whether the row stores any variable-length columns. Use the first formula if all the columns are fixed-length and defined as NOT NULL. Use the second formula if the row contains variable-length columns or if the columns are defined as NULL.

For fixed-length columns, calculate:

2 + (Sum of bytes in all fixed-length columns) = Data Row Size

For fixed- and variable-length columns, calculate:

2 + (Sum of bytes in all fixed-length columns) + (Sum of bytes in all variable- length columns) = Subtotal

Subtotal ((Subtotal / 256) + 1) + (Number of variable-length columns + 1) + 2 = Data Row Size

The values 1 and 2 in the previous equations are overhead that SQL Server uses for internal storage.


Step 2: Calculate the Number of Data Pages

Calculate the number of data pages:

2016 / (Data row size) = Number of data rows per page

(Number of rows) / (Number of data rows per page) = Number of data pages required


Step 3: Calculate the Size of Clustered Index Rows

Calculating the size of clustered index rows depends on whether the keys are fixed- or variable-length. Use the first formula if all keys are fixed-length. Use the second formula if keys include variable-length columns.

For fixed-length columns, calculate:

5 + (Sum of bytes in the fixed-length index keys) = Clustered row size

For fixed- and variable-length columns, calculate:

5 + (Sum of bytes in the fixed-length index keys) + (Sum of bytes in variable-length index keys) = Subtotal

(Subtotal) ((Subtotal / 256) + 1) + (Number of variable-length columns + 1) + 2 = Clustered index row size

The values 5 and 2 in the previous equations are overhead that SQL Server uses for internal storage.


Step 4: Calculate the Number of Clustered Index Pages

After you have calculated the row size of the clustered index, you can calculate the number of pages for the clustered index.

(2016 / Clustered index row size) - 2 = Number of clustered index rows per page

(Number of data pages) / (Number of clustered index rows per page) = Number of index pages at level 0

If the result is greater than 1, repeat the following division step, using the quotient as the next dividend, until the quotient equals 1. When the quotient equals 1, you have reached the root level of the index.

(Number of index pages at the last level) / (Number of clustered index rows per page) = Number of index pages at next level


Step 5: Calculate the Total Number of Pages

Calculate the total number of data pages:

(Number of data pages) + (Number of index pages at level 0) + (Number of index pages at next level) + (Number of index pages at next level) [...] = Total number of data pages


Calculating the Size of a 9,000,000-Row Table with a Clustered Index

The following example calculates the size (in 2K pages) of the data and clustered index for a table containing:

  • 9,000,000 rows
  • Sum of bytes in fixed-length columns = 100
  • Sum of bytes in two variable-length columns = 50
  • Clustered key, fixed-length = 4 bytes

Follow these steps:

  1. Calculate the data row size:
4 | (Overhead)
+ 100 | Sum of bytes in all fixed-length columns
+ 50 | Sum of bytes in all variable-length columns
___ |
154 | Subtotal
154 | Subtotal
+ 1 | (Subtotal / 256) 1 (Overhead)
+ 3 | Number of variable-length columns 1
+ 2 | (Overhead)
___ |
160 | Data row size

  2. Calculate the number of data pages:

    2016/160 = 12 Data rows per page

    9,000,000/12 = 750,000 Data pages

  3. Calculate the size of clustered index rows:
5 | Overhead
+ 4 | Sum of bytes in the fixed-length index keys
___ |
9 | Clustered index row size

  4. Calculate the number of clustered index pages:

    (2016 / 9) - 2 = 222 Clustered index rows per page

    750,000 / 222 = 3378 Index pages (Level 0)

    3378 / 222 = 15 Index pages (Level 1)

    15 / 222 = 1 Index page (Level 2)

  5. Calculate the total number of pages:
Totals: | Pages | Rows
Level 2 (root) | 1 | 15
Level 1 | 15 | 3,378
Level 0 | 3,378 | 750,000
Data | 750,000 | 9,000,000
 | ¾---- |
Total number of 2K pages | 753,394 |


Calculating the Size of a Nonclustered Index

The steps in this section show how to calculate the size of a nonclustered index.


Step 1: Calculate the Size of the Leaf Index Row

Calculating of the size of nonclustered index rows depends on whether the keys are fixed- or variable-length. Use the first formula if all of the keys are fixed-length. Use the second formula if keys include variable-length columns.

Calculate the size of nonclustered leaf rows with fixed-length keys only:

7 + (Sum of fixed-length keys) = Size of leaf index row

Calculate the size of nonclustered leaf rows with variable-length keys:

9 + (Sum of length of fixed-length keys) + (Sum of length of variable-length keys) (Number of variable-length keys) + 1 = Subtotal

(Subtotal) + ((Subtotal / 256) + 1) = (Size of leaf index row)

The values 7 and 9 in the previous equations are overhead that SQL Server uses for internal storage.


Step 2: Calculate the Number of Leaf Pages in the Index

Calculate the number of leaf pages:

2016 / (Size of leaf index row) = Number of leaf rows per page

(Number of rows in table) / (Number of leaf rows per page) = Number of leaf pages


Step 3: Calculate the Size of the Nonleaf Rows

Calculate the size of nonleaf rows:

(Size of leaf index row) + 4 = Size of nonleaf row

The value 4 in the previous equation is overhead that SQL Server uses for internal storage.


Step 4: Calculate the Number of Nonleaf Pages

Calculate the number of nonleaf pages:

(2016 / Size of nonleaf row) - 2 = Number of nonleaf index rows per page

(Number of leaf pages / Number of nonleaf index rows per page) = Number of index pages at Level 1

If the result is greater than 1, repeat the following division step, using the quotient as the next dividend, until the quotient is equal to 1. When the quotient is equal to 1, you have reached the root level of the index.

(Number of index pages at last level / Number of nonleaf index rows per page) = Number of index pages at next level


Step 5: Calculate the Total Number of Nonleaf Index Pages

(Number of index pages at Level 0) + (Number of index pages at next level) + (Number of index pages at next level) + (Number of index pages at next level) + (Number of index pages at next level) [...] = (Total number of 2K data pages used)


Calculating the Size of a 9,000,000-Row Table with a Nonclustered Index

The following example calculates the size of a nonclustered index on the 9,000,000-row table used in "Calculating the Size of a 9,000,000-Row Table with a Clustered Index," earlier in this appendix. There are two keys, one fixed- and one variable-length. The table contains the following:

  • 9,000,000 rows
  • Sum of bytes of fixed-length columns = 100
  • Sum of bytes of two variable-length columns = 50
  • Nonclustered key, fixed-length = 4 bytes
  • Variable-length, 20 bytes, 1 key

Follow these steps:

  1. Calculate the size of the leaf index row:
9 | Overhead
+ 4 | Sum of length of fixed-length keys
+ 20 | Sum of length of variable-length keys
+ 2 | Number of variable-length keys + 1
---- |
35 | Subtotal
35 | Subtotal
+ 1 | (Subtotal/256) + 1
---- |
36 | Size of Leaf Index Row

  2. Calculate the number of leaf pages in the index:

    2016/36 = 56 Nonclustered leaf rows per page

    9,000,000/56 = 160,715 Leaf pages

  3. Calculate the size of the nonleaf rows:

    36 + 4 = 40 Size of nonleaf index row

  4. Calculate the number of nonleaf pages:

    (2016/40) - 2 = 48 Nonleaf index rows per page

    160,715/48 = 3348 Index pages, Level 1
    3348/48 = 69 Index pages, Level 2
    69/48 = 2 Index pages, Level 3
    2/48 = 1 Index page, Level 4

  5. Calculate the total number of nonleaf index pages:
Totals: | Pages | Rows
Level 4 (Root) | 1 | 2
Level 3 | 2 | 69
Level 2 | 69 | 3,348
Level 1 | 3,348 | 60,715
Level 0 (Leaf) | 160,715 | 9,000,000
 | ------ |
Total number of 2K pages | 164,135 |


Other Factors

There are other factors to take into account when you calculate the database size. The FILL FACTOR has an effect on the calculations for clustered index pages, distribution pages, and data pages, and using an average size for variable fields affects the calculations presented in the preceding examples. The following sections provide more information about these topics and calculations for using average sizes for variable fields.


Using a FILL FACTOR Value of 100 Percent

Normally, the index management process leaves room for two additional rows on each index page. When you set FILL FACTOR to 100 percent, it no longer leaves room for these rows. The only effect on these calculations is on calculating the number of clustered index pages (Step 4) and calculating the number of nonleaf pages (Step 4). Both of these calculations subtract 2 from the number of rows per page. When using a FILL FACTOR of 100 percent, do not subtract 2 from the number of rows per page.


Using Different FILL FACTOR Values

Other values for FILL FACTOR reduce the number of rows per page on data pages and leaf index pages. To compute the correct values when using FILL FACTOR, multiply the size of the available data page (2016) by the FILL FACTOR. For example, if your FILL FACTOR is 75 percent, your data page would hold 1512 bytes. Use this value in place of 2016 in Step 2 for both clustered and nonclustered index calculations.


Using Distribution Pages

Distribution pages are created when you create an index on existing data and when you run UPDATE STATISTICS. A distribution page occupies one full data page.

The UPDATE STATISTICS statement adds one distribution page per index on which statistics have been created. If you UPDATE STATISTICS for an entire table, add one page for each index on the table. If you UPDATE STATISTICS for only one index, add 1.


Using Average Sizes for Variable Fields

These calculations use the maximum size of the variable-length fields. If you know the average size of the fields, you can use this value in Steps 1 and 4 for calculating table size, and the value in Step 1 for calculating the nonclustered index size. You'll need slightly different formulas for clustered and nonclustered indexes.

For Clustered Indexes

In "Step 1: Calculate the Data Row Size," use the sum of the average length of the variable-length columns instead of the sum of the defined length of the variable-length columns to determine the average data row size:

4 + (Sum of bytes in all fixed-length columns) + (Sum of bytes of the average length of variable-length columns) = Subtotal

In "Step 2: Calculate the Number of Data Pages," use the average data row size from the first formula:

2016 / (Average data row size) = Number of data rows per page

In "Step 3: Calculate the Size of Clustered Index Rows," you must perform the addition twice. The first time, calculate the maximum index row size, using the given formula. The second time, calculate the average index row size, substituting the sum of the average number of bytes in the variable-length index keys for the sum of the defined number of bytes in the variable-length index keys:

5 + (Sum of bytes in the fixed-length index keys) + (Sum of bytes in variable length keys) = Subtotal

Subtotal + ((Subtotal / 256) + 1) + 2 = Maximum index row size

In "Step 4: Calculate the Number of Clustered Index Pages," substitute the following formula for the first formula, using the two different length values you calculated in the previous equation:

(2016 - (2 * Maximum index row size)) / Average index row size = Number of clustered index rows per page

For Nonclustered Indexes

In "Step 1: Calculate the Size of the Leaf Index Row," you must perform the addition twice. The first time, calculate the maximum leaf index row size, using the given formula. The second time, calculate the average leaf index row size, substituting the average number of bytes in the variable-length index keys for the sum of bytes in the variable-length index keys:

5 + (Sum of bytes in the fixed-length index keys) + (Sum of the average number of bytes in variable-length index keys) = Subtotal

Subtotal + ((Subtotal / 256) + 1) + 2 = Average index row size

In "Step 2: Calculate the Number of Leaf Pages in the Index," use the average leaf index row size in the first division procedure:

2016 / (Average leaf index row size) = Number of leaf rows per page

In "Step 3: Calculate the Size of the Nonleaf Rows," use the average leaf index row size:

(Average leaf index row) + 4 = Size of nonleaf row

In "Step 4: Calculate the Number of Nonleaf Pages," substitute the following formula for the first formula, using the maximum and average row sizes calculated in Step 1:

(2016 - (2 * Maximum index row size)) / Average index row size = Number of nonleaf index rows per page


Using Average Sizes for Very Small Rows

SQL Server can store as many as 256 data or index rows on a page. If your rows are extremely short, the minimum number of data pages are:

Number of rows / 256 = Number of data pages required


Using Average Sizes for text/image Data Pages

Each text or image column stores a 16-byte pointer in the data row, with the datatype varchar(16). Each text or image column that is initialized requires at least 2K bytes (1 data page) of storage space.

Text and image columns are designed to store implicit null values, meaning that the text pointer in the data row remains null and there is no text page initialized for the value, saving 2K of storage space.

If a text or image column is defined to allow null values and the row is created with an INSERT statement that includes NULL for the text or image column, the column is not initialized, and the storage is not allocated.

If a text or image column is changed in any way with UPDATE, then the text page is allocated. Of course, inserts or updates that place actual data in a column initialize the page.

The text chains that store text and image data have 112 bytes of overhead per page. Use the following formula to calculate the number of text chain pages that a particular entry will use:

Data length / 1800 = Number of 2K pages

The result should be rounded up in all cases; for example, a data length of 1800 bytes requires two 2K pages.


Appendix C System Tables Diagram

System Tables Diagram


Appendix D RAID Technology

RAID Technology

This appendix contains information reprinted from a White Paper, Configuring Compaq RAID Technology for Database Servers, Document Number 267A/0294, from Compaq® Computer Corporation. Copyright 1994, 1995 Compaq Computer Corporation. All Rights Reserved. Reproduced with permission.

Note The information presented in this appendix, although generally useful to SQL Server 6.0 users, references a particular vendor's hardware technology. However, Microsoft SQL Server 6.0 is compatible with a broad range of computer hardware. For information about compatible equipment, see the Microsoft Windows NT Hardware Compatibility List.


Configuring Compaq RAID Technology for Database Servers

The purpose of this document is to provide the reader general guidelines to use when determining the best SMART Array Controller configuration for their particular database server needs. Although absolute performance cannot be precisely predicted, you will have the information needed to make informed configuration choices given your performance, fault-tolerance, and cost constraints.

Drive subsystem performance is one of the most important aspects of tuning a database server for optimal performance. Compaq has designed disk controllers utilizing RAID technology to provide businesses with the best balance of performance, reliability, and availability. RAID technology provides a system with more consistent performance, higher levels of fault-tolerance, and easier fault-recovery than traditional non-RAID systems.

Even though a myriad of artificial benchmarks can be and have been contrived showing non-RAID systems outperforming RAID systems, we have not seen a case of this being true in a production environment. I/O performance is basically limited by the physics of the mechanical nature of disk drives, not I/O buses. Therefore, the configuration and tuning of a system should be focused on getting the most out of each drive and having an appropriate number of drives on a system. When properly configured the I/O subsystem should not be the limiting factor in overall system performance.

The reader should be generally familiar with RAID technology, Compaq drive subsystem terminology, and the use of Compaq System Configuration utilities. Compaq has other publications covering these and related topics listed below:

Compaq SMART Controller User's Guide (142136-001)

Drive Array Advanced Diagnostics User's Guide (137331-001)

SMART Controller Addendum 137536-001 to Manual 137331-001


Database I/O Overview

To correctly configure the disk subsystem of a database server a basic understanding of database access patterns and methods is required. This section provides a high level overview of the database process and typical patterns of common application types. This information will be referenced throughout the remainder of this paper.


Database I/O Schemes

Database systems store data in a logical collection of disk files or disk partitions. The physically atomic unit of a database file is referred to as a database page. The typical size of a database page is 2KB and most databases don't allow the user to change this size. Oracle does, however, allow the administrator to define the page size at database creation time. The default page size of Oracle for NetWare is 4KB and the default page size of Oracle for UNIX, Microsoft NT, and OS/2 is 2KB. Changing the page size from the default has rarely demonstrated any measurable performance gains.

Physical reads and writes of the data are done by the database page. Therefore, disk requests are usually 2KB. There are some exceptions to this on large table scans. If the database system detects that a long scan will be done it will often read in larger blocks, but this feature doesn't usually change the tuning process.

The process of executing I/O routines is similar across most database systems. Reads of database pages are done by database process(es) or thread(s) for the application. Many read operations can usually be conducted in parallel and each is independent of each other. Writes of data pages, on the other hand, are not initiated by a user application. When an application updates or inserts new data, the change is actually put into the database cache by the application's database process. Some time later an independent database function will clean the dirty data pages from memory. These writes will usually occur as a large batch of asynchronous writes. How this is initiated and its frequency is beyond the scope of this paper. The point is that write operations are not usually a steady stream of single page writes, but periodic, heavy bursts of write operations. In contrast to the data pages, writes of transaction log pages is a very steady stream of single pages writes. These occur during update and insert operations and again is controlled by a background database process.


Application Types

By examining different database applications and database functions, the fundamental I/O profile used to access the disk can be determined. What this determines is whether a particular dataset will be accessed either sequentially or randomly. The key high-level application types include transaction processing, decision support systems, and batch processing. In this section we will examine the various access patterns on the database files and later apply these patterns to how the drives eventually get configured. The distinct file types to be examined are data and index files, transaction logs, and import/export files.

Transaction Processing (OLTP)

OLTP is usually characterized as many users acting on a small subset of data throughout the database. The I/O profile resulting from this load is very heavy random reads and writes across the data and index files. The transaction logs, however, are hit with a heavy stream of sequential write operations of 2K or less.

Decision Support System (DSS)

DSS is characteristic of multiple users executing complicated joins and aggregations on large sets of data. Even though many of the operations could use some sequential processing, contention with other users and join and indexing operation result in a fairly random access pattern to the data and index files. Usually, if the database is dedicated to DSS no updates will be done to the database during heavy query load. In this case, no I/O will occur on the transaction logs. If on-line updates are applied to the database, it must be remembered when configuring the drive subsystem that log file response time may still be important to the overall performance of the system.

Batch Processing

Batch processing is the most likely application to produce significant sequential I/O on the data files. The types of activities referred to here often occur after hours and usually in isolation of other activities. Batch processing involves database dumps, database loads, detail report processing, and index creation.


Array Configuration Guidelines

The key issues when configuring a drive array system are how it is configured into logical volumes and how many physical disk drives are in the volumes. In this section we will cover these topics.


Volume Configuration

The most confusing decision when configuring a system is how an array of physical drives should be partitioned into logical volumes. In reality this is a very easy step in the configuration process, once the methodology is understood. The key is to let an array do what it is intended to do, that is, distribute I/O requests among all available drives.

The basic principles:

  1. Put all randomly accessed data on a single volume.
  2. Isolate purely sequential I/O to avoid excessive head movement.

Group Randomly Accessed Data

Looking back at the environment definitions covered earlier, most data access on database servers is basically random. When the goal is to optimize these application classes, database data and index files should be grouped onto a single array volume for each disk array controller in a machine. For example, if an OLTP database contains a number of large tables and their associated indexes totaling 5GB, these should all be put on a single volume of six 1GB drives. This guarantees that all drives will have approximately equal I/O load during normal operation of the system. This load balancing is done by the disk controller, due to the low-level striping of files across all disks in the volume, with no additional effort required by the System Administrator or DBA.

In contrast, techniques that have been carried over from traditional, non-array systems include the separation of data and index files to separate physical drives and separation of large data tables to their own dedicated drives. The reason for this was to allow simultaneous access to multiple drives. The problem with these techniques is that it puts the burden of load balancing upon the System Administrator. By carefully studying the applications accessing the database, the data can be distributed in such a manner so that each drive receives an approximately equal number of disk requests. Unfortunately, two assumptions are made that are difficult to achieve. Those are that the System Administrator and DBA can determine the actual I/O profile of an application and, that once determined, the I/O profile will remain constant throughout a day's processing and over the life of the application. For example, an application will often use different tables at different times of the day. Table A may have heavy access in the morning as a business gets started for the day. As the day wears on, most access may move over to Table B. If these tables were separated on different physical disks, the application would overload the disk with Table A in the morning and overload the disk with Table B later. However, with an array controller these two tables would be put on the same logical volume spread across multiple drives allowing all drives to share equally in the I/O load throughout the day. Another example to further demonstrate this concept is data growth. Again using Table A and Table B, when the database is initially deployed Table A and B are approximately the same size and receive the same number of I/O requests. At that time, it makes sense for each table to be on its own drive. Over time, Table B grows by 10 percent per month in both size and I/O requests. After just 9 months Table B has doubled in access frequency and is now a bottleneck to system performance. If both these tables are put on a single array volume this table growth is shared among all drives on the volume, thus avoiding the disk bottleneck.

The case covered thus far applies when all disks are attached to a single controller. Obviously when the amount of data and indexes exceeds the capacity of a single controller you will have multiple volumes in the system. At this point you have three options for distributing the data across the controllers.

  1. Use an operating system facility to stripe the volume across controllers.
  2. Use the database facilities to stripe the data across the controllers.
  3. Segment different data to each controller.

There is no best solution to this situation. It is a matter of preference to the Administrator. General trade-offs of each are listed below to help you make your own decision. The degree of each of these may vary depending upon operating system and database software chosen. The pros and cons of each option are shown in Table 1.

Use an operating system facility to stripe the volume across controllers.
Pros | Cons
Ease of space management as database grows | More difficult volume management
Ease of backup with everything on one file system | Very long tape recovery times of volume
 | Performance penalty associated with file system striping

Use the database facilities to stripe the data across the controllers.
Pros | Cons
Little to no negative performance impact | Most complicated database configuration process
Ease of space management as database grows | More complicated backup/recovery process

Segment different data to each controller.
Pros | Cons
Best performance when balanced properly | Requirement of administrator to understand access patterns
Fastest, easiest tape recovery of volume |
Fastest tape backup, allows multiple tape usage |

Table 1: Multiple Controller Options

Isolate Sequentially Accessed Data

Even though most data in a database server is read and/or written randomly, there are several cases of sequential access. During a long sequential read or write process, if the drive head can stay on the same physical disk track, performance will be dramatically better than if the head must continually seek between tracks. This principle is the same for traditional, non-array controllers and array controllers.

Actually, the largest single time component in reading or writing a block of data on a disk is the time required to move the drive head between tracks. The best drives on the market today range from 8 to 10 milliseconds (ms) average seek time and many drives you may be using from just a couple of years ago could be as high as 16 or 19 ms for an average seek time. The remaining activities in an I/O routine include: the database makes a request from the operating system, the operating system requests the data from the controller, the controller processes the request and makes the request from the drive, the block rotates under the drive head, the data is transferred to the controller, back to the operating system, and finally the application. All of this takes only 10 to 15 ms, depending upon the particular controller, operating system, and database. Obviously, minimizing seek time, where able, has a significant benefit.

So much for low-level numbers, what does this mean to your application and how do you take advantage of it. There are three basic database operations that are characteristically sequential: transaction logging, bulk loading and unloading of the database, and batch reporting or updating requiring table scans. In many cases involving sequential I/O, the operations associated with it will not be the primary function of the system, but may be the most important aspect for your tuning due to nightly batch windows or backup time constraints. If the typical random access to the data will be relatively light or done by few users, you may want to give priority to tuning sequential operations over random I/O distribution.

The transaction log is the most obvious sequential I/O routine. In any update environment the transaction log is sequentially written from beginning to end. You should isolate the log file from any other system I/O activities during heavy update activity. However, a typical log file's space requirement may not need the space of an entire physical disk. You can usually share a single large disk between the log file and other files on the system which are not active during heavy update activities. Examples of items which coexist well with the log file include the operating system, database executables, database dump files, etc.

Bulk loads and batch updates are often associated with decision support systems. The typical scenario involves extracting large volumes of data from production transaction processing systems on a pre-defined schedule, such as daily or weekly. The data is then moved to the DSS server and loaded into a database. Performance of this load operation can be very critical due to nightly time constraints. Optimization of this process is very different from the typical system. In contrast to the random nature of most multi-user systems, a batch load or update can have up to 4 concurrent sequential operations. These operations include reading the input file, writing the database data file, writing the database index file, and writing the transaction log. To optimize the load time of the data each of these file types should be isolated to their own logical volumes. In contrast, pure optimization for daily multi-user decision support would put ALL of the above files on a single, large volume to allow concurrent access of all drives on the server by all read operations. The performance impact on daily access of optimization for load times should be less than 20%. However, the gain in load time can be over 200% which is often well worth the small random access penalty.

For example, assume you have a decision support system which is refreshed nightly, Table 2 gives application characteristics and an optimal configuration for loading the database.

Data File | Space Requirement | Disk Volume | Drive Count | Drive Size
DB Log & OS | 500MB | Volume 1 | 1 | 1GB
DB Data File | 2.5GB | Volume 2 | 3 | 1GB
DB Index File | 1GB | Volume 3 | 2 | 1GB
Extract File | 1.5GB | Volume 4 | 1 | 2GB

Table 2: Batch Processing Example

The final general application classes which rely on sequential I/O performance include batch reporting and database dumps. These are fairly simple operations to optimize and there are only a couple of concepts to keep in mind. The profile of reporting and unloading is sequential table scans with some resulting output being written to a non-database file. In the case of a detailed analysis report, a report file of several megabytes may be spooled to a large disk file. The database dump sequentially reads tables writing the results to either a tape device or disk file. When the output is written to a disk file on the server, the target disk should be a different physical volume from the source of the data. If this is the only activity at the time the volume used for the log file is a good target, otherwise, another volume should be added to the system of sufficient size to accommodate the output file.


Fault-Tolerance Evaluation

There are several fault-tolerance options to a System Administrator depending upon the integrity requirements, the availability requirements, and the recovery issues of the application being deployed. The Compaq SMART Array Controller RAID levels relevant to this discussion include 0, 1, & 5. RAID-0 simply refers to data striping multiple disks into a single logical volume and has no fault-tolerance. RAID-1 and RAID-5 are both fault-tolerant, but require a different amount of drives to accomplish the fault-tolerance. RAID-1 or drive mirroring uses 50% of the drives in a volume for the fault-tolerance. RAID-5 requires only a single drive worth of the volume's total capacity for the fault-tolerance. For example, if a RAID-5 volume is configured with 6 1GB drives, the usable capacity of the volume is 5GB. With RAID-1 this same 5GB's of usable space requires 10 1GB drives. Which level of RAID to use is completely dependent on the individual situation. No one alternative is best for every application. Some applications may need complete redundancy and the System Administrator is willing to pay for it; while others may be willing to risk some down time for a more cost-effective implementation. In addition, the I/O loads generated by a particular application may fit very well in the performance constraints of RAID-5; while other applications will suffer serious performance penalties with RAID-5. This section explains some of the trade-offs associated with each alternative and possible performance implications, but it is up to the implementor to evaluate each alternative's applicability to their environment.


Data Protection Levels

Data protection here refers to the degree the database integrity is protected from a physical disk failure. Which scheme is chosen is determined by the degree to which the organization can afford down time and/or data loss. Obviously the higher the degree of protection, the higher the cost of the system. However, the cost of a few thousand dollars of redundant disks may be much less than the cost of a system being down. This comparison does not compare fault-tolerant mode RAID-1 with RAID-5, but just trade-offs of using fault-tolerance or not. The next section discusses the issues around the choice of RAID level.

The most secure option is to configure the entire drive subsystem to run in a fault-tolerant mode. In this case, no single disk failure will stop the system or risk any loss of data. If the drive subsystem supports hot-swap drives, such as the SMART Controller with a ProLiant system, the system will not need to be brought down for repairs. If the system doesn't support this feature, down time will need to be scheduled. Most business critical applications, particularly OLTP systems, use this level of fault-tolerance.

The second option uses fault-tolerance on some volumes, but leaves others unprotected from a single disk failure. This involves putting all database transaction logs, critical database system tables, the operating system, and boot partition on a volume with some form of fault-tolerance. The remainder of the system is configured with volumes using no fault-tolerance. These volumes contain general data tables, index structures, and other non-critical database objects such as temporary space. If a protected drive fails the system continues to run in the same manner as described in the previous configuration. If an unprotected drive fails the system will eventually error and the current instance of the database will be lost. At this point the system is brought down and repaired, the database is restored from a previous backup, and the database restored to the instant of failure by rolling forward committed transactions from the protected transaction logs. The reason for protecting the operating system and system tables of the database is to ease and speed the recovery process. If the operating system or system catalogs are lost, the database can still be recovered, however, the process is more complicated and takes much longer.

The final configuration option is to run with the disk subsystem completely unprotected. In this situation, any disk failure will usually result in the requirement to restore the full database from a previous backup or reload the database if loaded from an ASCII dump of another system. All updates done since the backup or original load are lost and are NOT recoverable. This may be acceptable for many types of operations, such as static weekly loads of a decision support system.


RAID Level Considerations

In order to protect a database from a drive failure, a SMART Array Controller volume may be configured with either RAID-1 or RAID-5. Compaq array controllers even allow RAID levels to be mixed on a single controller when system requirements need varying levels of performance and protection. As is usually the case, no single configuration fits all application scenarios. This discussion gives a system administrator and DBA the information needed to make an educated decision regarding the appropriate choice of RAID configurations depending on an application's specific characteristics.

Cost/Performance Trade-offs

In general RAID-5 provides a more cost effective solution compared to RAID-1, particularly when I/O performance requirements are well below the performance capabilities of the configured drives. The larger the capacity requirements the more pronounced the cost advantage becomes. For example, in a configuration which needs only 1GB a RAID-5 solution could be 3 550MB drives and the RAID-1 solution would be 2 1GB drives. There is very little difference between these two configurations' prices. However, if looking at a 14 GB system, RAID-5 could be done with 8 2GB drives as opposed to 14 2GB drives for the RAID-1 configuration.

Even though RAID-5 often has a cost advantage, RAID-1 has its own advantages for price/performance and increased fault-tolerance. If the application(s) using a database server have high I/O requirements, RAID-1 will provide significantly better performance at the same user capacity due to the increased number of drives. To increase the performance of the RAID-5 volume requires increasing the number of drives on the volume and therefore the capacity over what the application really needs. As will become evident from the examples in the next section, RAID-1 and RAID-5 may have the same price/performance costs on high I/O systems.

Another advantage of RAID-1 over RAID-5 is its ability to tolerate more than a single drive failure. This can occur and the server continue running as long as the multiple failed drives are not the pair mirroring each other. For example, if a RAID-1 volume consists of 4 drives mirrored to 4 drives, the first drive of the first set of drives could fail and before that drive is replaced any other drive, except for the first drive in the second set, could also fail and the system will continue to operate. In contrast, on a RAID-5 volume only a single drive can fail and if a second drive fails before the drive is replaced and recovered the data will be lost.

Failed State Considerations

Obviously, the only configurations where this is relevant is RAID-1 and RAID-5. The performance degradation for RAID-1 should be negligible since the only difference is that one less drive is available for read operations. However, under RAID-5 a more significant penalty may be incurred. The reason for the degradation is that for every read or write request to the failed drive, an I/O operation against all other drives in the volume is required. In most database systems the sustainable load will drop until the drive is replaced and the rebuild process is complete.

Recovery Time

Approximately 20 to 30 minutes per GB are required to recover from a drive failure if the system is idle. If the system is in use during the drive rebuild, recovery time may be very dependent on the level of activity. Most systems should recover in nearly the same time with moderate activity as with no load, particularly RAID-1. RAID-5 is much more sensitive to system load during the recovery period due to the considerably heavier I/O requirements of the failed system as described previously. Take this recovery time and failed-state performance into account when deciding between RAID-1 and RAID-5.


Physical Disk Requirements

Once you understand the target environment, the volume configuration guidelines, and the fault-tolerance requirements the next step is determining how many disks to distribute the data across and which type of disks are required. The goal is to use the lowest cost/megabyte drives, usually the largest drives available, while having enough drives to satisfy the physical I/O rate required by the application. The information presented here will help in meeting this goal.

The number and type of disk drives required by a disk subsystem volume is dependent upon the throughput requirements of the environment and the total amount of data on the server. Throughput requirements are composed of two characteristics, the degree of concurrency among user requests and the request rate from the application. Concurrency and request rate are distinct, but related concepts. Concurrency refers to the number of physical requests that are in the process of being executed by the disk controller(s). The degree of concurrency is primarily influenced by the number of users on the system and the frequency of requests from those users. Request rate is the absolute number of reads and writes per unit of time, usually expressed as I/O's per second. Usually, the higher the concurrency level, the higher the request rate. Yet, fairly high request rates can be generated by a single batch process with no concurrent requests. Of course, the number of physical disk requests that actually occur will depend upon the size of the database relative to the amount of disk cache and the resulting cache hit rate. The worst case scenario would result in as many concurrent disk requests as simultaneous user requests.

The reason for understanding the application I/O request rate is that multiple I/O requests can typically be processed in parallel if the data is distributed across multiple disk drives. Therefore, even though large drives are usually "faster" than smaller drives, this performance difference cannot offset the advantage of two drives' ability to respond to multiple requests in parallel. The target number of drives in a server should be approximately equal to the sustained or average number of simultaneous I/O requests, with three drives being a typical minimum for the data and index files.

The following evaluation process determines the number of drives required by a volume containing data accessed randomly by multiple users. Repeat this process for each volume to be used on a database server. In the case of high transaction rate systems, this process may yield too many drives to fit on a single controller, at which point the drives can be split into multiple, equal volumes across controllers. For systems or volumes using purely sequential I/O or having no concurrent disk requests, i.e. only one or two users on the system at a time, strict calculations for the number of drives is not required. For this case, use the fastest drives available and as many as required to meet the space requirements of the system.

The steps used to determine the optimal number of drives are summarized here followed by a detailed explanation of each step and several case studies:

  1. Determine typical I/O request rate by analyzing transaction I/O requirements and typical transaction rates of the target application(s).
  2. Using Chart 1, determine the minimum number of drives required to fall within or below the 35 to 45 I/O's per second rates of typical disk drives.
  3. Add at least an additional 20% space for growth and administration to the database size.
  4. Divide drive requirements based on RAID usage into total space requirements to determine which drive size to use.

The first step in calculating the number and size of drives to use is determining the request rate of the application. Without this information it is not possible to make an accurate estimation of the number and type of drives to use. The following equations provide rough estimates to the number of I/O requests generated by an application. Due to optimization routines in the controller to reduce the total I/O requests, these equations do not yield exact loads. They do, however, provide a tool for making conservative comparisons of the load the drives may be required to sustain under alternative RAID configurations. The RAID-5 equation component of (4*writes) implies that each database write incurs 4 physical I/O's, 2 reads and 2 writes; it is not meant to imply 4 physical write operations for each database write operation.

Application I/O Requests per Second =

RAID-0:(reads/transaction writes/transaction ) * transactions/second
RAID-1:(reads/transaction 2*writes/transaction ) * transactions/second
RAID-5:(reads/transaction 4*writes/transaction ) * transactions/second

The next step in the process is determining how many drives are required to support the application's I/O demands. Advertised I/O rates of today's typical 500MB through 2GB drives can exceed 70 I/O's per second. However, these results are achieved with pure saturation testing without regard for request latency. Empirical testing has shown that these same disks sustain between 35 and 45 random database requests per second without incurring costly latency delays. Using this range you can determine the approximate number of physical disks which should be configured on the server and what size those drives can be.

Chart 1 displays two lines which equate to 35 I/O's per second for the lower line and 45 I/O's per second for the upper line. This chart is used in conjunction with the previously discussed equations to determine the number of physical disks required by an application. Locate on the Y-axis the number of I/O's per second required by the application. Move across the graph locating the intersection of the application I/O rate and the 35 to 45 I/O per second area. The number of drives is then determined by locating the drive count on the horizontal axis. The more conservative the implementation desired, the lower the I/O rates per drive that will be required. Also, if using RAID-1 an even number of drives is required. If the result is an odd number of drives, round up to the next even number. When throughput requirements are more than the chart indicates, continue adding controllers and drives until the required throughput is achieved.

Chart 1: SMART Array Drive I/O Rate Capacities

Finally, the total space requirements for the database and support files, combined with the throughput requirements and fault-tolerance, determine the size of disks which will provide an optimal solution. When calculating total space requirements, add an additional 20% free space above the actual data requirements for growth and miscellaneous overhead. Again, a set of equations provide the answer to the appropriate size drive.

Drive size requirements based on total space needs and fault-tolerance:

RAID-0: [total space / number of drives] Rounded up to next drive size
RAID-1: [total space / (number of drives / 2)] Rounded up to next drive size
RAID-5: [total space / (number of drives - number of controller volumes)] Rounded up to next drive size

Several examples are presented which illustrate the use of this process. All RAID levels are presented for each case. Some cases still require a judgment call by the implementor to choose the number of drives or drive sizes, but the alternatives are drastically narrowed. The alternatives chosen are conservative configurations and the reason for the choice, if not a single alternative, is explained.

Case 1: Complex transaction processing system requiring multiple queries per update.

Reads: | 100/transaction
Writes: | 5/transaction
Transaction rate: | 2/second
Space requirements: | 3GB Database 20% Free space = 3.6GB

RAID-0:(100 5) * 2 = 205 I/O's / Second

205 I/O's / Second => 5 or 6 Drives

3.6 / 6 = .6 => Round up to next drive size => 1GB Drives

A conservative implementation yields 6 1GB drives for the data volume.

RAID-1:(100 (2*5)) * 2 = 220 I/O's / Second

220 I/O's / Second => 6 or 8 Drives

3.6 / (8 / 2) = .9 => Round up to next drive size => 1GB Drives

A conservative implementation yields 8 1GB drives for the data volume. The alternative of using 6 drives was not chosen due to possibly lower performance and 2GB drives would be required to meet space requirements. Using 2GB drives would yield a higher cost system in addition to lower performance.

RAID-5:(100 (4*5)) * 2 = 240 I/O's / Second

240 I/O's / Second => 6 or 7 Drives

3.6 / (7 - 1) = .6 => Round up to next drive size => 1GB Drives

A conservative implementation yields 7 1GB drives for the data volume.

Case 2: High-end OLTP system with several hundred users and a large database.

Reads: | 20/transaction
Writes: | 8/transaction
Transaction rate: | 15/second
Space requirements: | 10GB Database 20% Free space = 12GB

RAID-0:(20 8) * 15 = 420 I/O's / Second

420 I/O's / Second => 10 to 12 Drives

12 / 12 = 1.0 => Round up to next drive size => 1GB Drives

12 1GB drives for the data volume was chosen for this case. As in an earlier example, if 10 drives would have been used, 2GB drives would be required yielding a more expensive, lower performance system. The up side of 2GB drives would have been more available space for growth.

RAID-1:(20 (2*8)) * 15 = 540 I/O's / Second

540 I/O's / Second => 12 to 14 Drives

12 / (14 / 2) = 1.7 => Round up to next drive size => 2GB Drives

14 2GB drives are required for the data volume.

RAID-5:(20 (4*8)) * 15 = 780 I/O's / Second

780 I/O's / Second => 18 to 22 Drives

12 / (22 - 2) = .60 => Round up to next drive size => 1GB Drives

For this system, two controllers with 11 drives each using RAID-5 would be recommended. Notice in this example the value '2' was subtracted from the drive count instead of 1 as used previously. This is required when the drive count exceeds the capacity of a single volume or controller. Each volume will be using n+1 parity, therefore, 1 must be subtracted for each volume to determine usable space.

In this case, due to the very high I/O rates, RAID-1 and RAID-5 have similar costs. The reason is that the RAID-5 implementation requires many drive above the absolute space requirements to achieve acceptable performance levels. The RAID-1 solution, on the other hand, fits the space requirements much closer.

Case 3: Complex decision support with several simultaneous users.

Reads: | 1000/transaction
Writes: | 10/transaction (temporary space for sorting & grouping)
Peak transaction rate: | 3/minute or 0.05/second
Space requirements: | 5GB Database 20% Free space = 6GB

RAID-0:(1000 10) * 0.05 = 50.5 I/O's / Second

50.5 I/O's / Second => 2 Drives

6 / 2 = 3 => Largest drive currently available => 2GB Drives

3 2GB drives are required for the data volume due to space requirements.

RAID-1:(1000 (2*10)) * 0.05 = 51 I/O's / Second

51 I/O's / Second => 2 Drives

6 / (2 / 2) = 6 => Largest drive currently available => 2GB Drives

6 2GB drives are required for the data volume due to space requirements.

RAID-5:(1000 (4*10)) * 0.05 = 52 I/O's / Second

52 I/O's / Second => 2 Drives

6 / (2 - 1) = 6 => Largest drive currently available => 2GB Drives

4 2GB drives are required for the data volume due to space requirements.

The general conclusion from this discussion is that more, smaller disks are best for high user, high I/O, high concurrency systems and fewer, larger disks work best for environments with one/few users, high I/O, low concurrency requirements.


Conclusion

Configuration of the drive subsystem is the most critical part of setting up a database server for optimal operation. We have tried to give you the tools to make an intelligent decision regarding the choice of the best configuration for your servers. The key concepts presented in this paper are: distribute I/O requests over an appropriate number of drives, carefully chose a fault-tolerance option, and RAID technology provides the best choice for critical, high-performance database servers.

Finally, not all systems react the same due to differences among application profiles. The information provided in this paper has been based on five years of experience with array systems, both in Compaq labs and in customer situations. However, your environment requires testing of these concepts before implementing a system in production. Any paper that would claim otherwise should be viewed with a high degree of skepticism.


Appendix E Backup and Recovery Guidelines for Production Environments

Backup and Recovery Guidelines for Production Environments

Microsoft SQL Server is a powerful multiuser relational database management system designed to support high-volume transaction processing, as well as decision-support applications. SQL Server provides data processing capabilities (reliability, data integrity, performance, security) that meet or exceed those found in production-oriented minicomputer- and mainframe-based database management systems. Because of its power and stability, Microsoft SQL Server is widely used in many diverse production environments.

This appendix provides guidelines for proper backup and recovery of SQL Server databases running in production environments.


Backup Strategies

Why Back Up?

Planning a Backup Strategy

Where and When to Back Up

Testing a Backup Strategy


Why Back Up?

Today's hardware and software components are many times more reliable than those of the not-so-distant past; however, they will never be perfect, and there is always the chance of having some type of failure. It is therefore prudent to always have some type of "safety net" in place at all times, so that if a situation arises that results in the loss or damage of online data, production can be restored quickly with minimal or no loss of data. When people think of situations that could result in the loss of data, they typically think of disk crashes. There are, however, other situations that can have the same end result but are not as often considered when planning for recovery. Some of these problems include:

  • Disk subsystem failure
  • Systems software failure
  • Accidental or malicious use of deletion statements (for example, delete from prod_table, drop database customers, format c:, and so on)
  • Accidental or malicious use of updating statements (for example, expecting to update one row in a table but not qualifying the WHERE clause, so all rows are updated)
  • Destructive viruses
  • Natural disasters (fire, flood, earthquake, and so on)
  • Theft

As the remainder of this appendix will show, Microsoft SQL Server provides many fast and reliable ways to back up your data. To ensure that your data is safeguarded, you need to define a solid backup strategy.


Planning a Backup Strategy

You should have a solid backup plan in place before any application is ever moved from a development/test environment into a production environment. In addition, just as you would never put an untested application into production, you should never go into production without testing your backup strategy. It is always a good idea to include backup strategy planning as a key component of any project. In some cases, the backup strategy may even have a large impact on the design of the application. In planning the backup strategy for a given application, answer the following questions before launching the application into production:

  • How often should the backups be done?
  • What will be backed up at various times (for example, full database dumps versus transaction log dumps)?
  • To what medium will the backups go (tape or disk)?
  • Will the backups be done online (while users are working) or after-hours?
  • Will the backups be done manually or by an automatic scheduling facility?
  • If the backups are automated, how will it be verified that they actually occurred without error?
  • How long will the backups be saved before reusing the medium is reused?
  • Assuming failure, how long will it take to restore to the last backup? Is that an acceptable amount of downtime? If not, what is?
  • Is there a mechanism in place to ensure that the backups are good, that they can be reapplied if necessary?
  • Where will the backups be stored, and do the necessary people have access to them?
  • Who is responsible for seeing that the backups are done and done correctly?
  • If the system administrator is gone, is there someone else who knows the proper passwords and procedures to do backups and if necessary restore the backups?

This, of course, is not a complete list of all the questions you should think about in planning your backup strategy. You will need to answer these questions for every SQL Server environment, and there may be many other questions specific to your particular environment.


Where and When to Back Up

It is best to keep live data and the backups on separate computers or, better yet, in different buildings. If the databases and/or logs are dumped to physical disk devices, it is often optimal from a performance standpoint to dump them to local hard drives on the server, as opposed to drives on some other computer on the network. However, from that point they should be copied to tape or to another server, so that the data and backups are not on the same computer. For convenience, most people choose to have their backups close at hand so that they can quickly get to them if needed. If this is done, keep another copy somewhere offsite (such as a bank safety deposit box) so that in the event of damage to the building, the backup of the data will remain safe.

The frequency and type of backups you do will generally depend on two factors: the acceptable amount of work that can be lost due to media or other failure, and the volume of transactions that occur on the SQL Server. For many sites, databases are dumped weekly and transaction logs are dumped daily. This can vary widely, however. For systems that have little update activity and that are used primarily for decision support, only weekly database dumps might be needed. For other high-volume online transaction processing (OLTP) environments, databases might be dumped daily and the transaction logs dumped hourly. The strategy chosen should be one that best fits your environment while providing adequate insurance of recovering needed data.

If dumps are performed online, they should be scheduled for times when the server is not being heavily updated, because the dumps will slow SQL Server somewhat. In addition, the dumps should be issued on a fixed schedule. By using a fixed schedule, users will always know when the dump is occurring and can expect a slight delay in performance, or they can plan to do other non–SQL Server related work during that time.

Mirroring adds another level of data protection. With mirroring enabled, data that is written to a database is automatically duplicated on a separate device or drive. Should a media failure occur on either, the damaged device or drive is unmirrored, and the undamaged device or drive automatically takes over writing all transactions. Depending on the number of disks and disk controllers present in the computer, it is possible to have a configuration in which any one disk can fail and SQL Server will continue to run uninterrupted. Combining mirroring along with a regular backup schedule can help ensure a high level of redundancy and minimize the risk of data loss. For information about Windows NT–based mirroring, SQL Server-based device mirroring, and other methods of implementing redundancy, see Chapter 7, Managing Drives.


Testing a Backup Strategy

Once a backup strategy has been designed, it should be thoroughly tested. In testing the strategy, as many failures as possible should be simulated so you can be sure that there are no vulnerable areas that could jeopardize the recovery of data. For example, you could implement very redundant device and disk mirroring with multiple disks in a computer, so that should any one disk drive fail, you can continue operation uninterrupted. This is a good plan, but it does not eliminate the need to do backups. Asking the question "Will this be sufficient in the event of theft of the computer?" would show that this is a vulnerable area.

Testing a backup strategy will also demonstrate how much time is required to restore the databases from backups. If that amount of time is unacceptable, you may want to reevaluate the frequency with which the databases and transaction logs are being dumped, or you may want to look at the feasibility of maintaining a "warm" backup server. (For more information, see Managing a Backup Server, later in this appendix.)


Database Dumping and Loading

Managing Database Dump Files

Database Consistency Checking

Loading Database Dumps


Managing Database Dump Files

SQL Server databases can be dumped to disks or tape drives. It is a good idea to keep not only the most current dump, but the previous n dumps as well (n depends on what you judge to be necessary). To illustrate the need for this, assume that some failure occurred that resulted in your need to reload the database from a dump. If only the most current dump was kept and something destroyed that dump, you would have to attempt to reconstruct your data from scratch. Or say that a user accidentally issues a misqualified update or delete statement against one or more tables. This can result in the incorrect modification or loss of large amounts of data, which could go undetected for several days, weeks, or more. By keeping a succession of previous dumps, you have multiple "safety nets" in place for recovery.

If you dump your database or transaction logs to the same disk or tape dump device each time, the current dump can overwrite the existing dump file or be appended. SQL Server 6.0 allows you to specify whether the new dump should overwrite or be appended to the existing contents of the disk or tape dump device. This allows you, for example, to circulate tapes for reuse in a least-recently-used fashion. SQL Server provides an expiration parameter that helps to ensure that a new dump does not overwrite an existing dump too soon. SQL Enterprise Manager can be used to specify the number of days, or a specific date, that must pass before an existing dump can be overwritten by a new one.

When a database is dumped, SQL Server dumps not only the data portion but also the transaction log for that database. The transaction log must be included in the dump so that when the database is later loaded, transactions that were in progress during the dump can be properly rolled back. Because the transaction log is dumped with the database, the resulting dump file may be larger than the data portion of the database. For example, assume that you have a 100-MB database with a 25-MB transaction log. If both the database and log are nearly full, the dump file would be approximately 125 MB when the database is dumped. Be sure to allow enough room on the media you are dumping to for both the data and log portions of the database being dumped.

The size of the dump file will always be the correct size of the amount of data in the dump. For example, assume again that you dump a database to the DB_DUMP device and the resulting DBDUMP.DAT file is 100 MB. If you then dump a 5-MB database to the same device, the size of the DBDUMP.DAT file will have a size of 5 MB (or less, depending on the amount of data in the database).


Database Consistency Checking

Regardless of the frequency of the database dumps, it is highly recommended that you always run DBCC CHECKDB, DBCC CHECKALLOC, DBCC TEXTALLOC, and DBCC CHECKCATALOG on a database either just before or just after dumping it, to check the logical and physical consistency of the database. Because transactions can occur during or after the DBCC but before the dump, you may want to first dump the database and then run the DBCCs to ensure that the database was consistent at the time it was dumped. If a database or transaction log that contains errors is dumped, the errors will still exist when the database is reloaded. Under some conditions, this can even prevent successful reloading. There are two important reasons to run DBCC statements on a database when no users are currently using the database. First, if users are actively updating the database while DBCC is running, it can report spurious errors, which can be misleading. Second, because DBCC performs numerous checks on the data pages in the database, it can have a noticeable impact on performance if users are trying to query the database while DBCC is running.

For databases with a large amount of data (for example, in excess of 5 GB), the DBCC statements may take several hours to run, which can hamper the feasibility of running DBCCs on a production server. SQL Server on Windows NT–based computers addresses this by including the no_index option with DBCC statements. When using the no_index option, SQL Server checks only the consistency of the data pages and clustered index pages for each user table, not the non-clustered index pages, which can dramatically reduce the time necessary to run DBCC. It is still advisable, however, to periodically run full DBCCs on the database to ensure consistency of the non-clustered indexes as well. The syntax for this option is to include the no_index keyword after the DBCC statement. For example, DBCC CHECKDB (pubs, no_index) and DBCC CHECKTABLE (inventory, no_index) perform all the consistency checks on the data pages but skip the checks on any nonclustered indexes.

You can create Transact-SQL scripts containing DBCC checks and use SQL Enterprise Manager to schedule these scripts to run during periods of low activity.

Another solution to running DBCCs on large amounts of production data is to have a backup server running. In this configuration, database and transaction logs can be dumped from the production server and loaded onto the backup server. The DBCCs can then be run on the backup server without negatively affecting the performance of the production server. This is also a good safety net in the event that a hardware or other failure causes the production server to become unavailable for a long period of time. In this case, the backup server can quickly become the new production server, resulting in very little disturbance to users. The rapidly declining cost of PC hardware makes this option much more feasible than with the mini/mainframe platforms. (Managing a backup server is discussed in detail later in this appendix.)

Occasionally, when dumping a database you will receive SQL Server error 3004, stating:

%Id uninitialized pages encountered while dumping database <%.*s>. Run DBCC CHECKALLOC on this database for more information, then call technical support if there are any errors.

This error occurs if a problem is detected while doing an online dump. The dump procedure takes a snapshot of the database in order to begin the dump. Because some transactions may have allocated pages but not yet initialized them at the time the snapshot was taken, the dump procedure raises this informational message simply as a precaution.

If you encounter this message, the proper procedure, as the error states, is to run DBCC CHECKALLOC on that database, ensuring that no users are currently using the database while DBCC is executing. Under most circumstances, CHECKALLOC will not return any errors, and the previous 3004 error can safely be ignored. If CHECKALLOC does report other errors, however, you should contact your primary support provider for further instructions.

If DBCC CHECKALLOC is run with active users, you may see spurious 2525 or 2541 errors.


Loading Database Dumps

You need to consider several things when loading a database from a dump. First, the target database needs to be at least as large as the database that was dumped. Attempting to load a dump into a database that is smaller than the database that the dump came from will result in a SQL Server 3105 error, stating:

Data on dump will not fit into current database. Need xx Mbyte database.

In this message, xx is the size of the original database. You can, however, load a dump into a target database that is larger than the original database.

Also consider whether the database will be loaded on the same server from which it was dumped, or if there is a potential for it to be loaded onto a different server. If the database may be dumped and loaded between servers, the code page and sort order between the servers must match. You cannot load a database on a SQL Server that is running with a code page or sort order different from the SQL Server where the dump was from.

SQL Server 6.0 provides a tool, SQL Transfer Manager, which uses a graphical interface to allow you to easily transfer some or all of the data from one server to another. This is useful when the servers are using different sort orders or code pages, or when they are using different hardware architectures (for example, to move data from a SQL Server running on an Intel®-based computer to SQL Server running on a RISC-based computer). If your environment has multiple SQL Servers, it is recommended that they all be configured with the same code page and sort orders.

If a database needs to be re-created and loaded from a previous dump, it is important that the database is re-created in exactly the same way that it was created. That is, the device usage, log space allocation, and segment definitions in the new database must be identical to how they were when the database was dumped. This information is kept in the sysusages table in the master database, so you should always dump the master database whenever a change to a database is made that records anything in master (such as an ALTER DATABASE or DISK INIT command). In addition, if you save the scripts you used to create the initial database, re-creating it will simply be a matter of rerunning those scripts.

If a dump is loaded into a database that has data, log, or segment mappings different from the original database, DBCC CHECKALLOC may report SQL Server error 2558, stating:

Extent not within segment: Object <object id>, indid <index id> includes extents on allocation page <page number> which is not in segment <segment number>.

This error can indicate that there are data pages allocated in portions of the database intended for log pages, or log pages allocated in portions intended for data. In the first case (data pages in log space), the effect is that less space is available for the transaction log to grow. The second case (log pages in data space) is less serious, because the data space being used by log pages will eventually be freed up when the log is truncated with the DUMP TRANSACTION statement.


Transaction Log Dumping and Loading

Creating and Sizing Transaction Logs

Frequency of Transaction Log Dumps

Transaction Log Sequencing

Effect of "trunc. log on chkpt." on Transaction Logs

Effect of "select into/bulk copy" on Transaction Logs

Dumping a Full Transaction Log

Loading Transaction Logs


Creating and Sizing Transaction Logs

SQL Server's ability to do online incremental backups (transaction log dumps) provides a very effective mechanism for up-to-the-minute recovery of data. If your environment will be implementing both database and transaction log dumps as a means of backup, it is important to have a well-planned procedure in place and tested prior to going into production. This section contains some tips and guidelines for managing transaction logs.

In order for a transaction log to be dumped to a physical dump device, the log must reside on its own device. This can be accomplished using SQL Enterprise Manager or the LOG ON clause of the CREATE DATABASE statement when the database is initially created. Or, after the database has been created, it can be altered onto a new device, and the sp_logdevice system procedure can be executed to move the log to the new device. Ideally, every database should have its log on a separate device. Exceptions are small databases that are dumped often enough to negate the need for transaction log dumps, or are "test" databases whose contents are not needed or can be easily rebuilt, such as the pubs database. The other exception is the master database, which must have the data and log portions on the MASTER device.

The first step in managing transaction logs is to estimate how large to make the log. The size will be dependent on the volume of transactions in the database and the frequency with which the log is dumped. After a transaction log is dumped to a physical dump device, the inactive portion of the log (the portion from the beginning of the log to the first noncommitted transaction) is automatically truncated to free up new space for the log to reuse. As a general rule, creating a log that is approximately 10–25 percent of the size of the database is a good place to start—depending on your environment, you may require a log that is significantly larger or smaller than that amount. It is best to simulate the volume and types of transactions that will be expected when the system is in production. If the log fills up or comes close to filling up before the scheduled transaction log dump occurs, you should either enlarge the size of the log or decrease the time between transaction log dumps.


Frequency of Transaction Log Dumps

When deciding how frequently to dump the transaction log between database dumps, there are a couple of important points to consider. In the following example, assume that a production application dumps the database at midnight every Friday and that transaction log dumps are performed every hour from 8 a.m. to 5 p.m. Monday through Friday (10 log dumps per day). If a failure occurs at 4:30 p.m. on Friday, resulting in the need to recover from backups, the previous Friday's database dump would need to be loaded, followed by 49 transaction log loads.

Although doing online log dumps results in a smaller performance hit to the SQL Server compared to database dumps, loading that many transaction logs can take a significant amount of time, resulting in a longer period of downtime. A better approach is to do nightly database dumps and still do hourly transaction log dumps during the day. Assuming the same scenario of a failure at 4:30 p.m. Friday, only Thursday night's database dump would need to be loaded, followed by the 9 hourly transaction log dumps from 8 a.m. through 4 p.m. on Friday.

Also consider that the larger the number of log dumps, the bigger the risk of something happening to one of them. If any one transaction log dump is misplaced or deleted, or if the transaction log is truncated, no further transaction logs past that point can be loaded. Think of individual transaction logs as the pairs of teeth in a zipper. If one set of teeth is missing, you can only zip the zipper up to that point—likewise, you can't skip over a missing transaction log.


Transaction Log Sequencing

SQL Server keeps track of the order of transaction log dumps via a method that can be thought of as similar to a sequence number. The sequence number is incremented every time a DUMP TRANSACTION statement is issued, regardless of whether the log is being dumped to a physical dump device or whether it is being truncated by using either the WITH TRUNCATE_ONLY or the WITH NO_LOG clause. When restoring transaction logs, they must be loaded in the same order in which they were dumped, and their sequence numbers must be in monotonically increasing numbers.

In the following example, assume again that a database is dumped at midnight each night and that the transaction log is dumped to a separate disk device every hour from 8 a.m. to 5 p.m. The 8 a.m. dump would have a sequence number of 1, the 9 a.m. dump would have a sequence number of 2, and so on. Suppose that the transaction log completely fills up at 9:30 a.m., such that it must be dumped (truncated) using the WITH NO_LOG option. When the 10 a.m. transaction log dump is attempted, it will fail with an error message indicating that the log has previously been truncated. You must do a database dump before doing any additional log dumps.

If you load transaction logs, but you skip one (for example, if you load logs 1, 2, and then 4), the load will be rejected and error 4305 will be raised, stating:

Specified file 'dumpfile' is out of sequence. Current time stamp is '<some date and time>' while dump was from '<some other date and time>'.


Effect of "trunc. log on chkpt." on Transaction Logs

Two database options have an important effect on transaction logs: trunc. log on chkpt. and select into/bulkcopy. The trunc. log on chkpt. option automatically performs a DUMP TRANSACTION <database> WITH TRUNCATE_ONLY statement every time the SQL Server checkpoint handler wakes up (which depends on the value for the recovery interval configuration option). Setting this option for a database is useful primarily in a development environment when backups of the transaction log are not wanted. However, whether this option is set, you can rely only on recovering from your database dumps, not from your log dumps. When this option is set, SQL Server prohibits a transaction log dump to a physical dump device—attempting to do so will yield SQL Server error 4208, stating:

DUMP TRANsaction is not allowed while the trunc. log on chkpt. option is enabled: use DUMP DATABASE, or disable the option with sp_dboption.

For databases that do not have the log on a separate device, there is no harm in having the trunc. log on chkpt. option set. If the log is located on the same device as the data, SQL Server disallows the dumping of the transaction log to a physical device (only DUMP DATABASE is allowed for backing them up), so sequencing of the transaction log is not an issue.


Effect of "select into/bulkcopy" on Transaction Logs

The select into/bulkcopy option must be set in a database when you want to do non-logged operations such as SELECT INTO or fast bulk copy (bcp).

SQL Server (version 4.2 and later) allow transaction logs to be dumped while this option is turned on, provided that no non-logged activity has taken place since the last database dump. SQL Server detects whether any non-logged operations have been performed in a database. If an attempt is made to dump the transaction log to a physical dump device and it detects that non-logged operations have been done, it raises a version of the 4207 error, stating:

DUMP TRANsaction is not allowed while the select into/bulk copy option is enabled or if a non-logged operation has occurred: use DUMP DATABASE, or disable the option with sp_dboption.

As the error states, it is necessary to turn off the select into/bulkcopy option and dump the database before transaction log dumps can be issued.


Dumping a Full Transaction Log

It is possible for a database's transaction log to become so full that there is no room left to log new transactions. When this occurs, SQL Server will report error 1105, stating:

Can't allocate space for object 'syslogs' in database <database name> because the 'logsegment' segment is full. If you ran out of space in Syslogs, dump the transaction log. Otherwise, use ALTER DATABASE or sp_extendsegment to increase the size of the segment.

In most cases, the log can be dumped to a physical dump device, which will free up new space in the log. When the transaction log is dumped, SQL Server first writes a checkpoint record in the log in order to get a snapshot of which transactions are currently open. It then proceeds to write out the pages of the log and then remove the inactive portion of the log.

If the log is so full that there is not even enough room left to write the checkpoint record, the only option available is to issue a DUMP TRANSACTION database_name WITH NO_LOG statement. This statement truncates the inactive portion of the log without writing the initial checkpoint record and without logging any of the truncation operation. Because the log is not written to a physical dump device, it is not recoverable. It is therefore imperative that the database be dumped immediately so that future transaction log dumps will be recoverable. If you encounter this situation regularly, you should increase the size of the log or increase the frequency of your log dumps.

SQL Server 6.0 includes enhancements that can help prevent a transaction log from ever filling completely. Through its close integration with the Windows NT Performance Monitor, the percentage of log space used for each database can be continuously monitored. Using Performance Monitor alerts, the database administrator can have Performance Monitor automatically run a batch file to dump the transaction log when the percentage of log space used hits a predefined threshold. Using this approach, along with the automated scheduled backup, alerting, and email and page notification capabilities of SQL Enterprise Manager, the database administrator's task of managing backups has been greatly simplified and automated.


Loading Transaction Logs

If a situation arises that requires you to recover from database and transaction log dumps, the load procedure needs to be completed in one continuous step. That is, the database should first be loaded, followed by each of the transaction logs, with no activity taking place in between each load. However, users can be actively doing updates in other databases. If any updates take place in the target database before all the logs have been loaded, when the next log load is attempted, SQL Server will raise error 4306, stating:

There was activity on database since last load, unable to load. Must restart load sequence with the load database to continue.

As the error indicates, you must start back at the beginning by loading the database dump, followed by all the log dumps. For this reason, it is often advisable to start SQL Server in single-user mode when loading a database. In single-user mode, only one user at a time is allowed access to SQL Server, and this should be the person loading the database.

Alternatively, SQL Server could be started normally, but SQL Enterprise Manager or sp_dboption could be used to turn on the single user option for the database being loaded. This allows users to freely access other databases on the server but allows only one person to access the database being loaded (this should be the person performing the load).

Caution Shutting down and restarting SQL Server during a load sequence can lead to error 4306, because the SHUTDOWN statement puts a checkpoint record in each database, and each database is checkpointed when SQL Server is restarted.


Managing a Backup Server

Purpose of a Backup Server

Setting Up a Backup Server

Summary


Purpose of a Backup Server

If a disk drive or other failure results in the computer being unusable for a time, it can be a relief to know that you have reliable backups of your data. However, making the necessary repairs and reloading the dumps of the database and logs can take considerable time. A very cost-effective alternative to this is to maintain a "warm" backup server at all times.

SQL Server includes features that make it very easy to have another server standing by in case something should happen to the primary production server. Assume that you have two servers: Primary is the primary production SQL Server and Standby is another server on the network, also running SQL Server, with devices, databases, logins, and user accounts set up identically to those on Primary. Each time a database is dumped from Primary, you will immediately load it onto Standby. Likewise, you will immediately load each transaction log dump from Primary onto Standby. (It is still recommended as a further precaution that these dumps also be copied off to tape or some other medium and stored.) Should a problem arise on Primary that will require significant downtime, Primary can be taken offline and Standby's server name changed to Primary.

If you use this approach, the only downtime will be the few minutes necessary to take Primary offline and to change Standby's name—no user applications will need to change, and the data on the server will be current through the last transaction log dump made from the old Primary server.


Setting Up a Backup Server

To accomplish a backup server setup, there are a couple of changes that need to be made to the databases on Standby. After initially creating the databases on Standby, the two database options read only and no chkpt on recovery need to be set for each database that will be maintained. As stated earlier, when loading a database and transaction logs, no update activity can take place in the database until all logs have been loaded. These two options help to reduce the risk of having any activity between log loads. When SQL Server is started, a checkpoint record is written in each database after it has been recovered. Setting the no chkpt on recovery option prevents SQL Server from writing this checkpoint, so that if the Standby server goes down, after SQL Server is restarted the databases will still show that no activity has taken place, and transaction logs can continue to be loaded from the Primary server.

If SQL Server is manually stopped by using the SHUTDOWN statement, the shutdown procedure waits for all active processes to complete and checkpoints each database before stopping. The writing of this checkpoint prevents any further transaction log loads, because there would have been an update made to the database. Setting the read only option not only prevents users from performing any write activity in a database, it also causes SQL Server to bypass writing a checkpoint record in the database when a SHUTDOWN statement is issued. When these two options are set for the databases on Standby, database and transaction logs should be able to continue loading regardless of how the Standby server goes down. Note that if the Standby server is needed to replace Primary, you must turn off the no chkpt on recovery and read only options before users can resume updating.

The replication capabilities of Microsoft SQL Server 6.0 can be used to establish and maintain one or more backup servers. For information about replication, see Part 6, Replication.


Summary

Microsoft SQL Server offers unparalleled performance and integrity for a PC-based relational database management system, with a robust set of data integrity features, including online database and transaction log backups, and automatic roll forward/rollback recovery. SQL Server is an ideal platform for large production applications, whether they be high-volume transaction-processing systems or decision-support environments.

As with any software application, it is expected that all proper precautions be taken to avoid loss of data, whether due to hardware, software, or user error. Before using any SQL Server application for production, you should have a solid and well-tested backup strategy in place, so that in the event of any type of failure, production can be restored with minimal downtime and little or no loss of data.


Appendix F Accessibility for People with Disabilities

Accessibility for People with Disabilities

Microsoft is committed to making its products and services easier for everyone to use. This appendix provides information about the following products and services, which make Microsoft Windows and Microsoft SQL Server 6.0 more accessible for people with disabilities:

  • Microsoft services for people who are deaf or hard-of-hearing.
  • Access Pack for Microsoft Windows, a software utility that makes using Microsoft Windows easier for people with motion or hearing disabilities.
  • Keyboard layouts designed for people who type with one hand or a wand.
  • Microsoft software documentation on audio cassettes and floppy disks.
  • Products for people who are blind or have low vision.
  • Hints for customizing Microsoft Windows.
  • Other products and services for people with disabilities.

Note The information in this section applies only to users who purchased Windows in the United States. If you purchased Windows outside the United States, your Windows package contains a subsidiary information card listing Microsoft support services telephone numbers and addresses. You can contact your subsidiary to find out whether the type of products and services described in this appendix are available in your area.


Microsoft Services for People Who Are Deaf or Hard-of-Hearing

Through a text telephone (TT/TDD) service, Microsoft provides people who are deaf or hard-of-hearing with complete access to Microsoft product and customer support services.

You can contact Microsoft Sales Information Center on a text telephone by dialing (800) 892-5234 between 6:30 a.m. and 5:30 p.m. Pacific time. For technical assistance, you can contact Microsoft Product Support Services on a text telephone at (425) 635-4948 between 6:00 a.m. and 6:00 p.m. Pacific time. Microsoft support services are subject to Microsoft prices, terms, and conditions in place at the time the service is used.


Access Pack for Microsoft Windows

Microsoft distributes Access Pack for Microsoft Windows, which provides people with motion or hearing disabilities better access to computers running Microsoft Windows. Access Pack for Microsoft Windows contains several features that:

  • Allow single-finger typing of SHIFT, CTRL, and ALT key combinations.
  • Ignore accidental keystrokes.
  • Adjust the rate at which a character is repeated when you hold down a key, or turn off character repeating entirely.
  • Prevent extra characters if you unintentionally press a key more than once.
  • Enable you to control the mouse cursor by using the keyboard.
  • Enable you to control the computer keyboard and mouse by using an alternate input device.
  • Provide a visual cue when the computer beeps or makes other sounds.

Access Pack for Microsoft Windows is included on the Microsoft Windows Driver Library in the file ACCESS.EXE. If you have a modem, you can download Microsoft Windows Driver Library components, including the following, from network services:

  • CompuServe®
  • GEnie™
  • Microsoft OnLine
  • Microsoft Download Service (MSDL), which you can reach by calling (425) 936-6735 any time except between 1:00 a.m. and 2:30 a.m. Pacific time. Use the following communications settings:

    For this settingSpecify

    Baud rate1200, 2400, or 9600
    ParityNone
    Data bits8
    Stop bits1

  • Various user-group bulletin boards (such as the bulletin-board services on the Association of PC User Groups network)

People within the United States who do not have a modem can order the Access Pack for Microsoft Windows on disks by calling Microsoft Product Support Services at (425) 637-7098 or (425) 635-4948 (text telephone).


Keyboard Layouts for Single-Handed Users

Microsoft distributes Dvorak keyboard layouts that make the most frequently typed characters on a keyboard more accessible to people who have difficulty using the standard "QWERTY" layout. There are three Dvorak layouts: one for two-handed users, one for people who type with their left hand only, and one for people who type with their right hand only. The left-handed or right-handed keyboard layouts can also be used by people who type with a single finger or a wand. You do not need to purchase any special equipment in order to use these features.

Microsoft Windows already supports the two-handed Dvorak layout, which can be useful for coping with or avoiding types of repetitive-motion injuries associated with typing. To get this layout, choose International from the Windows Control Panel. The two layouts for people who type with one hand are distributed as Microsoft Application Note GA0650. This note is also contained in file GA0650.ZIP on most network services or GA0650.EXE on the Microsoft Download Service. For instructions on obtaining this application note, see the preceding section, "Access Pack for Microsoft Windows."


Microsoft Documentation on Audio Cassettes and Floppy Disks

People who have difficulty reading or handling printed documentation can obtain most Microsoft publications from Recording for the Blind, Inc. Recording for the Blind distributes these documents to registered members of their distribution service either on audio cassettes or on floppy disks. The Recording for the Blind collection contains more than 80,000 titles, including Microsoft product documentation and books from Microsoft Press. You can contact Recording for the Blind at the following address or phone numbers:

Recording for the Blind, Inc.
20 Roszel Road
Princeton, NJ 08540 		Phone :
Phone outside the U.S.:
Fax: 		(800) 221-4792
(609) 452-0606
(609) 987-8116


Products for People Who Are Blind or Have Low Vision

There are numerous products available to help people who are blind or have low vision use Microsoft Windows. For people with low vision, there are screen-enlargement utilities, and for people who cannot use visual information, there are screen readers that provide alternative output by synthesized voice or refreshable Braille displays. In addition, people with low vision can customize the Microsoft Windows display to suit their needs.

For more information on the various products available, see "Getting More Information" later in this appendix. For more information about customizing Microsoft Windows for people with low vision, see "Customizing Windows," next.


Customizing Windows

There are many ways you can adjust the appearance and behavior of Microsoft Windows to suit varying eyesight and motor skills without requiring any additional software or hardware. These include ways to adjust the appearance as well as the behavior of the mouse and keyboard. The specific methods available depend on which operating system you are using. Application notes are available describing the specific methods available for each operating system.

For information relating to customizing Windows 3.0 for people with disabilities, see Application Note WW0786; for Windows 3.1, Application Note WW0787; for Windows for Workgroups 3.1, Application Note WG0788; for Windows NT 3.1, Application Note WN0789. For information on obtaining application notes, see "Access Pack for Microsoft Windows," earlier in this appendix.


Getting More Information

For more information on Microsoft products and services for people with disabilities, contact Microsoft Sales Information Center at (800) 426-9400 (voice) or (800) 892-5234 (text telephone).

The Trace R&D Center at the University of Wisconsin–Madison produces a book and a compact disc that describe products that help people with disabilities use computers. The book, titled Trace ResourceBook, provides descriptions and photographs of about 2,000 products. The compact disc, titled Co-Net CD, provides a database of more than 17,000 products and other information for people with disabilities. It is issued twice a year.

You can contact the Trace R&D Center at the following address or telephone numbers:

Trace R&D Center
S-151 Waisman Center
1500 Highland Avenue
Madison, WI 53705-2280 		Voice telephone:
Text telephone:
Fax: 		(608) 263-2309
(608) 263-5408
(608) 262-8848

For general information and recommendations on how computers can help specific people, you should consult a trained evaluator who can best match your needs with the available solutions. An assistive technology program in your area will provide referrals to programs and services that are available to you. To locate the assistive technology program nearest you, you can contact:

National Information System
Center for Developmental
Disabilities
Benson Building
University of South Carolina
Columbia, SC 29208 		Voice/text telephone outside South Carolina:
Voice/text telephone inside South Carolina:
Voice/text telephone outside the U.S.:
Fax:
(800) 922-9234, ext. 301

(800) 922-1107

(803) 777-6222
(803) 777-6058


About the Database Developer's Companion

The Microsoft SQL Server Database Developer's Companion explains how to use Transact-SQL™, the enhanced version of SQL (structured query language), and SQL Enterprise Manager to access and optimize databases created with SQL Server.

Although this book is written for database developers, it does not specifically explain how to design and develop databases. It assumes that you are familiar with basic database concepts and are acquainted with concepts of database administration. (For more information about database administration, see the Microsoft SQL Server Administrator's Companion.) This book also assumes that you are familiar with the Microsoft® Windows®, the Microsoft® Windows NT™, and/or the MS-DOS® operating systems.

This book uses many examples to illustrate database fundamentals. Most examples refer to the pubs sample database. The pubs sample database is included as a learning tool; it is created when SQL Server is installed. To use the sample database, your system must have access to the pubs database. If you have a localized version of SQL Server and want to try the examples, drop the localized version of pubs and install the U.S. English version of pubs. To install the U.S. English version of pubs, run the INSTPUBS.SQL script with the isql command-line utility. This script can be found in the INSTALL directory of SQL Server. Also, as you execute the examples in this book, you alter the pubs database, which can change the output you receive from some of the example queries. You can reinstall the original pubs database at any time by running the INSTPUBS.SQL script.

To run the INSTPUBS.SQL script, from an operating-system prompt, type:

isql /Usa /P password /S server -i\sql60\install\instpubs.sql

Note You can create the queries in this book by using isql, ISQL/w, the query analyzer in SQL Enterprise Manager, or any number of other (third-party or custom-built) tools.

For details on isql, see the isql command-line utility in the Microsoft SQL Server Transact-SQL Reference. For details on ISQL/w, see the Utilities and Executables topic in the Microsoft SQL Server Transact-SQL Reference. For details on SQL Enterprise Manager, see the SQL Enterprise Manager online Help.


Finding Further Information

In addition to the administration information in this book, additional information about using SQL Server 6.0 is available from the following sources, as well as from the Microsoft® Development Library and Microsoft® TechNet.

The Microsoft Developer Network provides in-depth information for developers. With Level 1 of the Developer Network, you get four quarterly releases of the Development Library, packed with inside information on programming for Microsoft Windows and Windows NT, plus other program benefits. With Level 2 of the Developer Network, you'll receive all the Level 1 benefits plus quarterly releases of the Development Platform, containing the latest Windows and Windows NT Workstation operating systems and API-level SDKs and DDKs from Microsoft. For ordering information, call (800) 759-5474.

Microsoft TechNet is the front-line resource for fast complete answers to technical questions on Microsoft desktop and system products. Through two monthly CDs, you get everything from crucial data on client/server and workgroup computing, systems platforms, and database products to the latest applications support for Microsoft Windows and the Apple® Macintosh®. For ordering information, call your reseller or (800) 344-2121.

Online Help

To access online Help while using SQL Server, choose the Help button or press f1 from within SQL Enterprise Manager or ISQL/w. To access context-sensitive Transact-SQL Help from SQL Enterprise Manager or ISQL/w, press shift f1. From within isql, execute the sp_helpsql system stored procedure.

SQL Server Books Online

The setup program gives you the option of installing Microsoft SQL Server Books Online. If you choose this option, setup adds the Books Online icon to the Microsoft SQL Server 6.0 program group. By choosing this icon, you can access online versions of the SQL Server documentation.

Important SQL Server Books Online contains the most up-to-date information about SQL Server 6.0, including information that changed or was unavailable when the SQL Server 6.0 books were printed.

Microsoft SQL Server System Administrator's Companion
Incorporates configuration, administration, and troubleshooting topics. Describes server and client configuration. Explains system administration tasks, such as managing devices and databases, backing up and recovering data, performing replication, scheduling tasks, managing security, and monitoring performance. Describes error conditions and gives troubleshooting procedures.
Microsoft SQL Server Database Developer's Companion
The online version of this book provides an overview of Transact-SQL, which is an enhanced version of SQL (structured query language). Discusses managing data and database objects, such as tables, views, indexes, stored procedures, defaults, rules, constraints, and user-defined datatypes.
Microsoft SQL Server Transact-SQL Reference
Explains how to use Transact-SQL statements and other features to access databases, and provides syntax and descriptions for Transact-SQL statements, system procedures, utility programs, and system tables.
Microsoft SQL Server Setup
Provides instructions for installing SQL Server 6.0 servers and clients.
Microsoft SQL Server Programming SQL Distributed Management Objects
Provides syntax and reference information for the SQL Distributed Management Objects, which are 32-bit OLE Automation objects for the Microsoft Windows 95 and Windows NT operating systems. These objects, properties, methods, and collections are used to write scripts and programs that can administer multiple SQL Servers distributed across a network.
Microsoft SQL Server Programming DB-Library for C
Provides syntax and reference information for the DB-Library™ application programming interface (API), which is used to write C/C++ client programs for the Microsoft Windows, Microsoft Windows 95, Windows NT, and MS-DOS operating systems.
Microsoft SQL Server Programming DB-Library for Visual Basic
Provides syntax and reference information for the DB-Library API, which is used to write Microsoft® Visual Basic® programming system-based client programs for the Windows operating system.
Microsoft SQL Server Programming Open Data Services
Provides syntax and reference information for the Microsoft Open Data Services API, which is used to write C/C++ server and gateway programs for the Windows NT operating system.


Overview

In a multiuser environment such as Microsoft SQL Server, the database developer usually works as a member of a team that includes a system administrator and other database developers.


The Database Developer

The database developer designs SQL Server databases, creates and manages objects in databases, accesses data in databases, and optimizes databases for best performance.


Designing Databases

The developer typically designs a new database. The developer decides what tables are required, which data goes in each table, who should have access to the table, and so on. When the design is complete, the developer or administrator can create the database.


Creating and Managing Database Objects

The developer typically creates and manages objects in a database. These objects include tables, views, indexes, constraints defaults, triggers, and procedures. For details on these objects, see Working with Tables.

Note In some cases, the database developer is not the owner of a database. However, with permission from the database owner, a developer can create objects in the database.

The developer who creates an object owns the object and can explicitly grant permission to others to use the object. By default, even the database owner cannot use the object unless the object's owner grants the appropriate permission. For details on permissions, see the Microsoft SQL Server Administrator's Companion.


Accessing Data in Databases

The developer can access and manipulate data in databases. For example, the developer might add data to a database or update data in a database. And the developer can retrieve data by using queries, as described throughout Chapter 4, "Retrieving Data with Queries."


Optimizing Databases

Periodically, the developer might optimize databases for performance. For example, the developer might check the consistency of databases and might set various database options to maximize the performance of a database.


The System Administrator

The SQL Server system administrator has a different role from the database developer. The system administrator is responsible for setting up and maintaining SQL Server. Administering SQL Server includes such tasks as:

  • Installing SQL Server
  • Creating devices and databases
  • Managing and monitoring the use of disk space, memory, and connections
  • Authorizing SQL Server login IDs and granting permissions to them
  • Backing up and restoring databases
  • Diagnosing system problems
  • Fine-tuning SQL Server to achieve the best performance

Additionally, a system administrator, like a database developer, can create objects in any database and can add, change, or delete data in any database.

With SQL Server, the system administrator has absolute power and can do anything. SQL Server does not check for permissions before the administrator does something. Additionally, the system administrator can issue commands and system procedures that no one else can issue (and that cannot be transferred to others).

Where appropriate, the system administrator can transfer some responsibilities to other users. For more information about responsibilities that can be transferred, see the Microsoft SQL Server Administrator's Companion.

The system administrator is the owner of the master database. This database is considered the system catalog, because it stores information about the user databases and the operation of SQL Server as a whole. Additionally, the system administrator is the owner of other databases while they are in use by the administrator.

For more information about the system administrator and administering SQL Server, see the Microsoft SQL Server Administrator's Companion.


Chapter 2 Working with Tables

Working with Tables

Tables are database objects that contain all the data in a database. In tables, data is organized in a row-and-column format similar to a spreadsheet. Each row represents a unique record, and each column represents an attribute of the record.

When you design a database, you decide what tables you need, what type of data goes in each table, who can access each table, and so on. As you create and work with tables, you continue to make more detailed decisions about them.

The following sections introduce other database objects used with tables and describe the ways you can use these objects to create and work with tables.


Understanding Database Objects

To create and work with tables, you use a variety of database objects, including datatypes, constraints, defaults, rules, triggers, keys, and indexes. This section describes these objects, and later sections explain how to use them.


Datatypes

You assign to each column a datatype, which defines the data values allowed for that column. For example, if you want to include only names in a column, you would assign to that column a character datatype. Or, if you want a column to contain only telephone numbers, you would assign to the column a numeric datatype.

To define a column's datatype, you can use the SQL Server - supplied datatypes, or you can create your own datatypes when the system datatypes do not meet your needs. For details on system datatypes, see the Datatypes topic in the Microsoft SQL Server Transact-SQL Reference; for details on user-defined datatypes, see Using Datatypes to Enforce Data Integrity.


Constraints

Constraints are application rules that SQL Server enforces for you. Constraints limit the possible values that users can enter into a column or columns. They provide following advantages:

  • You can associate multiple constraints with a column, and you can associate a constraint with multiple columns.
  • You create constraints when you create a table with the CREATE TABLE statement. You don't have to bind constraints manually, as you do with defaults.
  • Constraints conform to the ANSI standard for creating and altering tables; they are not Transact-SQL extensions.
  • You can use constraints to enforce referential integrity. Referential integrity is the process of preserving defined relationships between tables when you enter or delete records in those tables.

For details on constraints, see Using Constraints to Enforce Data Integrity.


Defaults

In SQL Server, each column in a record must contain some value ¾ even if that value is NULL. You determine whether a column can accept null values by the datatype, default, or constraint you specify.

Defaults specify the value that SQL Server will insert when a user does not enter a value (in either a NULL or NOT NULL column). For example, in a table with a column called price, if the user does not know the price of an item, you can instruct SQL Server to enter "???" or "fill in later."

The easiest way to specify defaults is to define DEFAULT constraints when you create a table.

You can also create defaults and then bind them to columns or to user-defined datatypes so that whenever no entry is entered into that column or whenever a column is assigned that user-defined datatype, the default automatically takes effect. For details on creating defaults, see the CREATE DEFAULT statement in the Microsoft SQL Server Transact-SQL Reference.


Rules

Rules are database objects that specify the acceptable values that can be inserted into a particular column. Rules are bound to a column or to a user-defined datatype. A column or user-defined datatype can have only one rule associated with it. (Note that using constraints is the preferred way of restricting column data because multiple constraints can be defined on a column or on multiple columns.)

For example, in a table with a column called phone_number, you could define a rule that specifies that the column accepts only 10-digit entries. For details on creating rules, see the CREATE RULE statement in the Microsoft SQL Server Transact-SQL Reference.


Triggers

A trigger is a stored procedure that is automatically invoked whenever a specified event (INSERT, UPDATE, or DELETE) modifies a table. A trigger can query other tables and it can include complex Transact-SQL statements.

Triggers are primarily useful for enforcing complex business rules or requirements, such as whether to insert an order based on a customer's current account status.

Triggers are also useful for enforcing referential integrity, preserving the defined relationships between tables when you enter or delete records in those tables. (Note that the best way to enforce referential integrity is to define FOREIGN KEY constraints. For details, see Using Constraints to Enforce Data Integrity.

For details on triggers and stored procedures, see Using Stored Procedures and Triggers.


Keys

A table often has a column or combination of columns whose values uniquely identify each row in the table. This column (or columns) is called the primary key of the table. The primary key cannot be null.

You can create a primary key by defining a PRIMARY KEY constraint when you create or alter a table (see "Creating Tables" and "Altering Tables," later in this chapter).

As shown here, the au_id and title_id columns in the titleauthor table together form a composite primary key for the titleauthor table.

You can define a PRIMARY KEY constraint for a table, and the constraint will automatically create an index. This index enforces uniqueness in the table and permits fast access to data when you use the primary key in queries.

A foreign key is a column or combination of columns whose values match the primary key of another table. A foreign key doesn't have to be unique. However, foreign key values must be copies of the primary key values: no value in the foreign key except NULL can exist unless the same value exists in the primary key. A foreign key can be NULL, but if any part of a composite foreign key is NULL, the entire foreign key must be NULL. You can create a foreign key by defining a FOREIGN KEY constraint when you create or alter a table see Creating Tables and Altering Tables.

You can join tables by using their primary and foreign keys. For example, in the pubs database the title_id column is the primary key of the titles table and the foreign key of the titleauthor, sales, and roysched tables. Accordingly, you can use title_id to join the titles table with the titleauthor, sales, or roysched tables. For details on joins, see Retrieving Data with Queries.


Indexes

An index is a table structure that SQL Server uses to provide fast access to rows of a table based on the values of one or more columns. An index contains data values and pointers to the rows where those values occur.

In the following illustration, for example, the employee table in the pubs database has an index on the employee ID (emp_id) column.

SQL Server uses an index as you use the index of a book. SQL Server searches the index to find a particular value and then follows the pointer to locate the row containing the value. For example, in the preceeding illustration, SQL Server locates the record containing "VPA30890F " by searching the index for "VPA30890F."

For details on creating indexes, see Using Indexes.


Data Integrity

Enforcing data integrity involves preserving the consistency and correctness of the data stored in a database by validating the contents of individual fields, verifying field values with respect to one another, validating data in one file or table as compared to another file or table, and verifying that a database is successfully and accurately updated for each transaction. An important step in planning tables is deciding how to enforce the integrity of their data.

Data integrity falls into four categories: entity integrity, domain integrity, referential integrity, and user-defined integrity.

Earlier releases of SQL Server enforced data integrity by using user-defined datatypes, defaults, rules, triggers, and stored procedures. SQL Server 6.0 supports a variety of table-definition extensions that achieve the same results without requiring separate objects (rules and defaults) or additional steps to "bind" these objects to various columns or user-defined datatypes.

Integrity type | Former options | SQL Server 6.0 options
Entity | Unique indexes | PRIMARY KEY UNIQUE KEY IDENTITY property
Domain | Datatypes, Defaults, Rules | DEFAULT constraint FOREIGN KEY constraint CHECK constraint
Referential | Triggers | FOREIGN KEY constraint CHECK constraint
User-defined | Rules, Triggers Stored procedures | All column- and table-level constraints in CREATE TABLE


Entity Integrity

Entity integrity defines a row as a unique entity for a particular table. Entity integrity usually enforces the primary key of a table (through indexes, UNIQUE constraints, or PRIMARY KEY constraints).


Domain Integrity

Domain integrity refers to the range (domain) of valid entries for a given column. You can enforce domain integrity by restricting the type (through datatypes), the format (through CHECK constraints and rules), or the range of possible values (through FOREIGN KEY constraints, CHECK constraints, and rules).


Referential Integrity

Referential integrity preserves the defined relationships between tables when records are entered or deleted. In SQL Server, referential integrity is based on foreign to primary key or unique key relationships. Referential integrity ensures that key values are consistent. Such consistency requires that there be no references to nonexistent values, and that if a key value changes, all references to it change consistently throughout the database.

When you enforce referential integrity, SQL Server prevents users from:

  • Adding records to a related table when there is no associated record in the primary table.
  • Changing values in a primary table that would result in "orphaned" records in a related table.
  • Deleting records from a primary table when there are matching related records.

For example, with the sales and titles tables in the pubs database, referential integrity is based on the relationship between the foreign key (title_id) in the sales table and the primary key (title_id) in the titles table, as shown in the following illustration:


User-defined Integrity

User-defined integrity allows you to define specific business rules that don't fall into one of the other integrity categories. All of the integrity categories support user-defined integrity.


Using Datatypes to Enforce Data Integrity

You can use system datatypes (supplied by SQL Server ) and user-defined datatypes (custom datatypes based on system datatypes) to enforce data integrity.

You create user-defined datatypes with the sp_addtype system stored procedure. When you create user-defined datatypes, you supply three parameters: the name of the datatype, the system datatype upon which the new datatype is based, and the datatype's nullability (whether it allows null values ¾ if defined explicitly, NULL or NOT NULL). When nullability is not explicitly defined, it will be assigned based on the ANSI null default setting for the database or connection.

Note Most examples refer to the pubs sample database. The pubs sample database is included as a learning tool; it is created when the server is installed. To use the sample database, your system must have access to the pubs database. If you have a localized version of SQL Server and want to try the examples, drop the localized version of pubs and install the U.S. English version of pubs. To install the U.S. English version of pubs, run the INSTPUBS.SQL script with the isql command-line utility. This script can be found in the INSTALL directory of SQL Server. Also if other users have executed the examples in this chapter, it is likely that the pubs database has been altered. This will change the output you see from some of the examples. You can reinstall the original pubs database at any time by running the INSTPUBS.SQL script.

To run the INSTPUBS.SQL script, from an operating-system prompt, type:

isql /Usa /P password /S server -i\sql60\install\instpubs.sql

For details about isql, see the isql command-line utility in the Microsoft SQL Server Transact-SQL Reference.


Creating User-defined Datatypes

You create user-defined datatypes based on SQL Server-supplied datatypes.

Note To use a user-defined datatype in more than one database, create it in the model database. The user-defined datatype definition then becomes known to all databases created after the change to the model database.

To create a user-defined datatype
  • From the Manage menu in SQL Enterprise Manager, choose User-Defined Datatypes, and then create the datatype in the Manage User-Defined Datatypes dialog box.

    (For details, search for "user defined datatypes" in SQL Enterprise Manager Help.)

Or

  • Execute the sp_addtype system stored procedure.

    For example:

    sp_addtype ssn, 'varchar(11)', 'NOT NULL'

    creates a user-defined datatype called ssn (social security number) that is based on the SQL Server-supplied varchar datatype. The ssn datatype will be used for columns holding 11-digit social security numbers (xxx-xx-xxxx). That column cannot be NULL.

    (For details, see the sp_addtype system stored procedure in the Microsoft SQL Server Transact-SQL Reference.)


Dropping User-defined Datatypes

You remove user-defined datatypes from a database by dropping them.

To drop a user-defined datatype
  • From the Manage menu in SQL Enterprise Manager, choose User-Defined Datatypes, select the datatype you want to drop, and then click the Drop button.

    (For details, search for "user defined datatypes" in SQL Enterprise Manager Help.)

Or

  • Execute the sp_droptype system stored procedure.

    For example:

    sp_droptype ssn

    drops the ssn (social security number) datatype created in the preceding example.

    (For details, see the sp_droptype system stored procedure in the Microsoft SQL Server Transact-SQL Reference.)

Note You cannot drop a user-defined datatype if it is used within a table definition or if a rule or default is bound to it.


Sample User-defined Datatypes

The pubs sample database contains some user-defined datatypes.

In each of the following examples, the user-defined datatype definition explicitly defines the nullability. Quotation marks are used when a parameter contains blanks or punctuation marks. Note that these user-defined datatypes already exist in pubs, so these procedures cannot be added here.

sp_addtype id, 'varchar(11)', 'NOT NULL'
sp_addtype tid, 'varchar(6)', 'NOT NULL'
sp_addtype empid, 'char(9)', 'NOT NULL'

In each case, nullability has been explicitly defined. Each of these datatypes will be used multiple times throughout the sample database.


Using Constraints to Enforce Data Integrity

Constraints enforce data integrity on a column (column-level constraints) or on a table (table-level constraints, usually multicolumn constraints). You define constraints by using SQL Enterprise Manager or by using the CREATE TABLE statement. You add and drop constraints by using the ALTER TABLE statement.

SQL Server provides CHECK, DEFAULT, FOREIGN KEY, PRIMARY KEY, and UNIQUE constraints.


CHECK Constraints

CHECK constraints specify data values that are acceptable in one or more columns. You can also apply multiple CHECK constraints to a single column. When a table is dropped, all CHECK constraints are also dropped.

When you apply a constraint, it is automatically bound to the specified column. CHECK constraints can coexist with a rule on a column.

To create a CHECK constraint
  • In SQL Enterprise Manager's Server Manager window, double-click the appropriate table, choose the Advanced Features button, and then choose the Check Constraints tab.

    (For details, search for "constraints" in SQL Enterprise Manager Help.)

Or

  • Use the CREATE TABLE or ALTER TABLE statement. (Examples are shown in the following section.)

    (For details, see the CREATE TABLE and ALTER TABLE statements in the Microsoft SQL Server Transact-SQL Reference.)


Sample CHECK Constraints

The following CHECK constraint, used in the pubs sample database, is applied to the au_id column of the authors table. This constraint enforces an alphanumeric entry with the format of ###-##-#### (used in Social Security numbers).

ALTER TABLE authors
ADD
CONSTRAINT ckau_id CHECK (au_id LIKE '[0-9][0-9][0-9]-[0-9][0-9]-
    [0-9][0-9][0-9][0-9]')

The following CHECK constraint allows entries for pub_id in the publishers table to adhere to a specific entry in a list or adhere to a 4-digit pattern.

ALTER TABLE publishers
ADD
CONSTRAINT ckpub_id CHECK (pub_id IN ('1389', '0736', '0877', '1622',
    '1756')
OR pub_id LIKE '99[0-9][0-9]')

The following CHECK constraint shows a table-level constraint. In this example, a user is required to enter a maximum salary, a base pay, and a maximum yearly bonus. The maximum salary (max_salary) must be greater than or equal to the sum of the base pay (base_salary) and maximum yearly bonus (yearly_bonus). Because this constraint references more than one column, it is defined at a table level, using the actual names of the columns within the constraint definition. Note that this example is not part of the pubs database.

CONSTRAINT total_pay CHECK (max_salary >= base_salary  yearly_bonus)


DEFAULT Constraints

To supply a value (when a user does not enter one in a column), define a DEFAULT constraint or a default on the column. DEFAULT constraints are defined with the CREATE TABLE or ALTER TABLE statement. Defaults are created with the CREATE DEFAULT statement and bound with the sp_bindefault system stored procedure. Unlike defaults, DEFAULT constraints do not need a separate binding step.

When you insert a row with the INSERT statement, you can specify default values for one or all columns in the row by using the DEFAULT or DEFAULT VALUES options.

To create a DEFAULT constraint
  • In SQL Enterprise Manager's Server Manager window, double-click the appropriate table, choose the Advanced Features button, and then enter the appropriate default in the Default column.

    (For details, search for "constraints" in SQL Enterprise Manager Help.)

Or

  • Use the CREATE TABLE or ALTER TABLE statement.

    For example:

    ALTER TABLE authors
ADD
DEFAULT 'UNKNOWN' for au_frame

    add the word "UNKNOWN" anytime no entry is made in the au_frame column.

    (For details, see the CREATE TABLE and ALTER TABLE statements in the Microsoft SQL Server Transact-SQL Reference.)

For details on INSERT, see the INSERT statement in the Microsoft SQL Server Transact-SQL Reference.


Working with Defaults and Null Values

If you specify NOT NULL when you create a column but do not create a default for the column, SQL Server returns an error message whenever anyone inserts a row and fails to make an explicit entry in that column.

When you use the INSERT statement to specify default values for columns, you get the following results:

  • If a DEFAULT constraint or default for a column does not exist, but the column allows null values, NULL will be inserted.
  • If any column of the table does not have a DEFAULT constraint or default and does not allow NULL, an error will be returned.

When you drop a default for a NULL column, SQL Server inserts NULL in that position whenever you add rows without entering a value for that column. When you drop a default for a NOT NULL column, you get an error message when rows are added but no value for that column is entered.

The following table illustrates the relationship between the existence of a DEFAULT constraint or default and the definition of a column as NULL or NOT NULL. The entries in the table show the result:

Column definition | No entry, no default | No entry, default | Enter NULL, no default | Enter NULL, default
NULL | NULL | Default | NULL | NULL
NOT NULL | Error | Default | Error | Error

For more information about null values, see Null Valuesin the Microsoft SQL Server Transact-SQL Reference.


FOREIGN KEY Constraints

FOREIGN KEY constraints work in conjunction with PRIMARY KEY or UNIQUE key constraints to enforce referential integrity among specified tables.

To create a FOREIGN KEY constraint
  • In SQL Enterprise Manager's Server Manager window, double-click the appropriate table, choose the Advanced Features button, and then choose the Foreign Keys tab.

    (For details, search for "constraints" in SQL Enterprise Manager Help.)

Or

  • Use the CREATE TABLE or ALTER TABLE statement.

    For example:

    ALTER TABLE titles
ADD
CONSTRAINT FK_pub_id FOREIGN KEY (pub_id) REFERENCES publishers (pub_id)

    adds a FOREIGN KEY constraint to the titles table on the pub_id column.

    (For details, see the CREATE TABLE and ALTER TABLE statements in the Microsoft SQL Server Transact-SQL Reference.)


PRIMARY KEY Constraints

You can use PRIMARY KEY constraints to enforce entity integrity as well as referential integrity. A PRIMARY KEY constraint ensures that no duplicate values are entered, that NULL values are not allowed, and that an index is created to enhance performance.

To create a PRIMARY KEY constraint
  • In SQL Enterprise Manager's Server Manager window, double-click the appropriate table, choose the Advanced Features button, and then choose the Primary Key/Identity tab.

    (For details, search for "constraints" in SQL Enterprise Manager Help.)

OR

  • Use the CREATE TABLE or ALTER TABLE statement.

    For example:

    ALTER TABLE authors
ADD
CONSTRAINT UPKCL_auidind PRIMARY KEY CLUSTERED (au_id)

    adds a PRIMARY KEY constraint on the au_id column. Note that this table already has a primary key defined on it.

    (For details, see the CREATE TABLE and ALTER TABLE statements in the Microsoft SQL Server Transact-SQL Reference.)


UNIQUE Constraints

You can use UNIQUE constraints to enforce entity integrity on a non-primary key. Using a UNIQUE constraint also ensures that no duplicate values are entered.

To create a UNIQUE constraint
  • In SQL Enterprise Manager's Server Manager window, double-click the appropriate table, choose the Advanced Features button, and then choose the Unique Constraints tab.

    (For details, search for "constraints" in SQL Enterprise Manager Help.)

Or

  • Use the CREATE TABLE or ALTER TABLE statement.

    For example:

    ALTER TABLE stores
ADD
CONSTRAINT UNC_name_city UNIQUE NONCLUSTERED (stor_name, city)

    adds a UNIQUE constraint on the stor_name and city columns.

    (For details, see the CREATE TABLE and ALTER TABLE statements in the Microsoft SQL Server Transact-SQL Reference.)


Dropping Constraints

You can remove constraints from a table definition by dropping them.

To drop a constraint
  • In SQL Enterprise Manager's Server Manager window, double-click the appropriate table, choose the Advanced Features button, choose the tab representing the type of constraint you want to drop, select the constraint from the drop-down list, and then choose the Remove button.

    (For details, search for "constraints" in SQL Enterprise Manager Help.)

Or

  • Use the ALTER TABLE statement.

    For example:

    ALTER TABLE authors
DROP CONSTRAINT UPKCL_auidind

    drops the constraint created earlier in the example in "PRIMARY KEY constraints."

    (For details, see the ALTER TABLE statement in the Microsoft SQL Server Transact-SQL Reference.)


Displaying Information About Constraints

To list the constraints used in a table, use the sp_helpconstraint system stored procedure. For example, to see a report about the titles table:

sp_helpconstraint titles

Object Name
-----------
titles

constraint_type

constraint_name

---------------

---------------

PRIMARY KEY (clustered)

UPKCL_titleidind

FOREIGN KEY

FK__titles__pub_id__0E4E2B2E

DEFAULT on column type

DF__titles__type__0D5A06F5

DEFAULT on column pubdate

DF__titles__pubdate__0F424F67

constraint_keys

---------------

title_id

pub_id

REFERENCES pubs.dbo.publishers (pub_id)

('UNDECIDED')

(getdate())

Table is referenced by
----------------------------------------------------
pubs.dbo.titleauthor: FK__titleauth__title__14070484
pubs.dbo.sales: FK__sales__title_id__1BA8264C
pubs.dbo.roysched: FK__roysched__title___1E8492F7


Planning Tables

The most efficient way to create a table is to define everything you need in the table at once, including its data restrictions and additional components. However, you could also create a basic table, add some data to it, and then work with it for a while. This approach gives you a chance to see what types of transactions are most common and what types of data are frequently entered ¾ before you commit to a firm design by adding constraints, indexes, defaults, rules, and other objects.

It is a good idea to outline your plans on paper before actually creating a table and its objects.

To plan a table
  1. Decide what type of data the table will contain.
  2. Decide what columns you need in the table and the datatype (and length, if required) for each column.
  3. Decide which columns should accept null values.
  4. Decide whether to use constraints and/or defaults and rules and, if so, where.
  5. Decide what types of indexes you need, where you need the indexes, and which columns should be the primary and foreign keys.


Creating Tables

You can create permanent tables or temporary tables. SQL Server supports two types of temporary tables: local and global. A local temporary table is visible only to the connection that created it. A global temporary table is available to all connections. Local temporary tables are automatically dropped at the end of the current session. Global temporary tables are dropped at the end of the last session using the table (normally, this is when the session that created the table ends). For details on temporary tables, see the CREATE TABLE statement in the Microsoft SQL Server Transact-SQL Reference.

When you create a table, you name its columns and supply a datatype for each column. You also specify whether or not a particular column can hold null values.

To create a table
  1. Create user-defined datatypes before you define the table in which you want to use them.
  2. Create the table with constraints and defaults by using the CREATE TABLE statement. (Any defaults or rules on a user-defined datatype used in a CREATE TABLE statement are automatically in effect.)
  3. Create triggers with the CREATE TRIGGER statement.
  4. Create views with the CREATE VIEW statement. (For details, see "Using Views," later in this chapter.)
  5. Create the table:
    • In SQL Enterprise Manager's Server Manager window, select the database in which you want to create the table, select Tables or Objects, click the right mouse button, and then choose New Table.

      (For details, search for "table" in SQL Enterprise Manager Help.)

    Or

    • Use the CREATE TABLE statement.

      (For details, see the CREATE TABLE statement in the Microsoft SQL Server Transact-SQL Reference.)

    Or

    • Use the INTO option of the SELECT statement.

      (For details, see the SELECT statement in the Microsoft SQL Server Transact-SQL Reference.)

You can define up to 250 columns per table. Table and column names must follow the rules for identifiers; they must be unique within a given table, but you can use the same column name in different tables in the same database. You must define a datatype for each column.

Although table names must be unique for each user, different users can create tables with the same name. For example, a user named Jonah and one named Sally can both create a table named info. Users with permission on both of those tables must qualify the tables as jonah.info and sally.info. Sally must qualify all references to Jonah's info table as jonah.info, but she can refer to her own simply as info.


Sample CREATE TABLE Statement

This is the CREATE TABLE statement for the titles table in the pubs database. It is part of the pubs script (INSTPUBS.SQL, located in the SQL Server INSTALL directory).

CREATE TABLE titles
(
    title_id        tid
        CONSTRAINT UPKCL_titleidind PRIMARY KEY CLUSTERED,
    title   varchar(80)     NOT NULL,
    type    char(12)        NOT NULL
        DEFAULT ('UNDECIDED'),
    pub_id  char(4) NULL
        REFERENCES publishers(pub_id),
    price   money   NULL,
    advance money   NULL,
    royalty int     NULL,
    ytd_sales       int     NULL,
    notes   varchar(200)    NULL,
    pubdate datetime        NOT NULL
        DEFAULT (GETDATE())


Dropping Tables

When you no longer need a table, you can remove it from the database by dropping it.

To drop a table
  • In SQL Enterprise Manager's Server Manager window, select the table you want to drop, click the right mouse button, and then choose Drop.

    (For details, search for "table" in SQL Enterprise Manager Help.)

Or

  • Use the DROP TABLE statement.

    For example:

    DROP TABLE authors

    drops the authors table from the pubs sample database. It is recommended that you not drop tables from the pubs sample database. If you do delete a table, you can always reinstall pubs (INSTPUBS.SQL, the pubs script, is located in the SQL Server INSTALL directory).

    (For details, see the DROP TABLE statement in the Microsoft SQL Server Transact-SQL Reference.)

Note You cannot drop any of the system tables in the master database or a user database.

SQL Server removes the specified table from the database, together with its contents and all the indexes and permissions associated with it. Rules or defaults bound to the table are no longer bound but are otherwise unaffected.


Renaming Tables

If you need to change the name of a table, you can rename it.

To rename a table
  • Execute the sp_rename system stored procedure.

    For example:

    sp_rename titles, books

    renames the titles table to the books table.

    To change back to titles, run:

    sp_rename books, titles

You can also use sp_rename to rename other database objects ¾ views, indexes, rules, defaults, procedures, and triggers. You must be the owner of an object to rename it.

Procedures, triggers, and views that depend on a renamed object (table) work fine until they are recompiled. When the procedure, trigger, or view that depends on a renamed object is recompiled by SQL Server, it will no longer work.

To avoid this problem, the user must change the procedure, trigger, or view text to reflect the new name of the object on which it depends. The old object name appears in query results until the procedure, trigger, or view has been changed and recompiled. The safest course is to change the definitions of any dependent objects when you execute sp_rename.

When you rename a table, the name of the table is changed in the sysobjects system table.


Altering Tables

After you create a table, you might want to change its structure by adding columns, adding record keys, or changing constraints. To change a table, you alter its definition.

To alter a table definition
  • In SQL Enterprise Manager's Server Manager window, double-click the appropriate table, and then make the appropriate changes.

    (For details, search for "table" in SQL Enterprise Manager Help.)

Or

  • Use the ALTER TABLE statement.

    For example:

    ALTER TABLE publishers
ADD
COUNTRY varchar(30) NULL
DEFAULT('USA')

    adds the country column to the pubs database. (Note that this column already exists in the SQL Server 6.0 pubs database.)

    (For details, see the ALTER TABLE statement in the Microsoft SQL Server Transact-SQL Reference.)


Using Indexes

An index provides fast access to rows of a table based on the values of one or more columns. An index greatly speeds the execution of SQL statements with search conditions that refer to the indexed columns.

Using indexes is appropriate for columns that are used frequently in search conditions. Using indexes is also appropriate in tables for which queries are more frequent than inserts and updates.

SQL Server provides two types of indexes: clustered and nonclustered.

  • A clustered index is one in which the logical (indexed) order of the key values is the same as the physical order in which the corresponding rows (that contain the key values) exist in the table. A table can contain only one clustered index.
  • A nonclustered index is one in which the logical order of the index does not match the physical order of the rows on disk. Clustered indexes usually provide faster access to data than nonclustered indexes.


Creating Indexes

SQL Server automatically creates an index for the PRIMARY KEY and UNIQUE constraints. If you want other indexes, you must create them.

To create an index
  • In SQL Enterprise Manager's Server Manager window, select the appropriate table, click the right mouse button, and then choose Indexes.

    (For details, search for "indexes" in SQL Enterprise Manager Help.)

Or

  • Use the CREATE INDEX statement.

    For example:

    CREATE UNIQUE CLUSTERED INDEX au_id_ind
ON authors (au_id)

    creates an index on the au_id column of the authors table to enforce uniqueness.

    (For details, see the CREATE INDEX statement in the Microsoft SQL Server Transact-SQL Reference.)


Displaying Information About Indexes

To see the indexes that exist on a table, use the sp_helpindex system procedure. A maximum of eight indexes will be displayed. The sysindexes system table contains information about all indexes.

Here's a sample report about the authors table:

sp_helpindex authors

index_name

index_description

index_keys

-------------

-------------------------------

-----------------

UPKCL_auidind

clustered, unique, primary key
located on default

au_id

aunmind

nonclustered located on default

au_lname,
au_fname

(1 row(s) affected)

When used with the table name, the sp_help system procedure also reports indexes on a specific table.


Dropping Indexes

When you no longer need an index, you can remove it from a database and reclaim its storage space by dropping it. For example, consider dropping an index if you do not use it for most or all of your queries.

Note Only the owner of the index can drop it. The owner cannot transfer drop permission to other users.

To drop an index
  • In SQL Enterprise Manager's Server Manager window, select the appropriate table, click the right mouse button, choose Indexes, select the index from the Index drop-down list, and then choose the Remove button.

    (For details, search for "indexes" in SQL Enterprise Manager Help.)

Or

  • Use the DROP INDEX statement.

    For example:

    DROP INDEX authors.au_id_ind

    drops the au_id_ind index from the authors table.

    (For details, see the DROP INDEX statement in the Microsoft SQL Server Transact-SQL Reference.)


Using Views

A view is a virtual table whose contents are defined by a query. A query is a set of instructions that retrieves and displays data from a database. In SQL Server, you create a query using the SELECT statement.

A view looks like a real table ¾ with a set of named columns and rows of data. However, a view does not exist as a stored set of data values in a database. Instead, the rows and columns of data in a view come from base tables and are produced by the query that defines the view.

Here is a view based on two tables:

Views provide security by controlling the data users can see. Views allow users to work with a database in the form they are used to, even when changes occur to the structure of the database.

A view looks exactly like any other database table. You can display it and operate on it almost as you can any other table. Transact-SQL enhances standard SQL so that there are no restrictions on querying through views and few restrictions on modifying them.

The definition of a view (the base tables from which it is derived) is stored in the database. The data that you view is stored in only one place: in the base tables. No separate copies of data are associated with this stored definition.

When you modify the data you see in a view, you are actually changing data in the underlying base tables. Changes to data in the underlying base tables are automatically reflected in the views derived from them.


Planning Views

Before you create views, consider how you want to use them. You can use views to focus, simplify, and customize each user's perception of the database.


Using Views to Focus on Specific Data

Views allow users to focus on specific data that interests them and on the specific tasks for which they are responsible. Data that is not necessary or useful can be left out of the view.


Using Views to Simplify Data Manipulation

Views can simplify not only users' perception of the data but also their manipulation of it. You can define frequently used joins, projections, and selections as views so that users don't have to specify all the conditions and qualifications each time a further operation on that data is performed. (For details about joins, projections, and selections, see Retrieving Data with Queries.)


Using Views to Customize Data

Views allow different users to see data in different ways, even when they're using the same data at the same time. This advantage is particularly important when users with many different interests and skill levels share the same database.


Using Views to Export Data

Using views, you can export data to other applications. For example, suppose you want to use stores and sales tables to analyze sales data by stores in Microsoft® Excel. To do this, you can create a view based on the stores and sales tables. Then you can export the data defined by the view by using the bulk copy program utility (bcp).

For more information on exporting data, see Importing and Exporting Data in Working with Data. For details on bcp, see the Microsoft SQL Server Administrator's Companion and the bcp command-line utility in the Microsoft SQL Server Transact-SQL Reference.


Using Views for Security

By using the CREATE VIEW statement with the WITH CHECK OPTION, you can ensure that users query and modify only the data they can see. This option forces all data modification statements executed against the view to adhere to the criteria set within the SELECT statement defining the view. When a row is modified through a view, the WITH CHECK OPTION guarantees that the data will remain visible through the view after the modification has been committed.

Using the GRANT and REVOKE statements, you can restrict each user's database access to specific database objects¾including views. If the view and all the tables and views from which it was derived are owned by the same user, that owner can grant permission to others to use the view, and that owner can deny access to the view's underlying tables and views. This is a simple but effective security mechanism.

By defining different views and selectively granting permissions on them, you can limit a user's (or any combination of users') access to specific subsets of data. To provide security, you might confine a user's access to:

  • A subset of the rows of a base table (a value-dependent subset).

    For example, in the pubs sample database, you might define a view that contains only the rows for business and psychology books, keeping information about other types of books hidden from some users.

  • A subset of the columns of a base table (a value-independent subset).

    For example, you might define a view that contains all the rows of the titles table but omit the royalty and advance columns since that financial information is confidential.

  • A row-and-column subset of a base table.
  • The rows that qualify for a join of more than one base table.

    For example, you might define a view that joins the titles, authors, and titleauthor tables to display the names of the authors and the books they have written. This view would hide personal data about authors and financial information about the books.

  • A statistical summary of data in a base table.

    For example, through a view called category_price, users can access only the average price of each type of book.

  • A subset of another view or of some combination of views and base tables.

    For example, through a view called hiprice_computer, users can access the title and price of computer books that meet the qualifications in the view definition of hiprice.

To create a view, a user must be granted CREATE VIEW permission by the database owner and must have appropriate permissions on any tables or views referenced in the view definition.

As the owner of an object on which other users have created views, you must be aware of who can see what data through which views. Consider this situation: the database owner has granted Harold CREATE VIEW permission, and a user named Margaret has granted Harold permission to select from a table she owns. Given these permissions, Harold can create a view that selects all columns and rows from Margaret's table. However, if Margaret subsequently revokes permission for Harold to select from her table, he can still look at her data through the view he has created.


Creating Views

You can create a view with SQL Enterprise Manager or by using the CREATE VIEW statement.

To create a view
  • From the Manage menu in SQL Enterprise Manager, choose Views, and then select New from the Views drop-down list.

    (For details, search for "view" in SQL Enterprise Manager Help.)

Or

  • Use the CREATE VIEW statement.

    For example:

    CREATE VIEW titles_view
AS
SELECT title, type, price, pubdate
FROM titles

    creates a simple view called titles_view, consisting of the title, type, price, and pubdate columns from the titles table. You'll receive a message stating that the command did not return any data, and it did not return any rows. This is fine. The view has been created.

    (For details, see the CREATE VIEW statement in the Microsoft SQL Server Transact-SQL Reference.)

Before you create a view, consider the following guidelines:

  • You can create views only in the current database.
  • View names must follow the rules for identifiers and must be unique for each user.
  • You can build views on other views and on procedures that reference views.
  • You cannot associate rules, defaults, or triggers with views.
  • You cannot build indexes on views.
  • You cannot create temporary views, and you cannot create views on temporary tables.
  • You do not need to specify column names with the CREATE VIEW statement. SQL Server gives the columns of the view the same names and datatypes as the columns referred to in the select list of the SELECT statement. The select list can be a full or partial list of the column names in the base tables.
  • You can specify column names; you must specify column names in the CREATE VIEW statement for every column in the view if:
    • Any of the view's columns are derived from an arithmetic expression, a built-in function, or a constant.
    • Two or more of the view's columns would otherwise have the same name (usually because the view definition includes a join and the columns being joined have the same name).
    • You want to give any column in the view a name different from the column from which it is derived. (You can also rename columns in the SELECT statement.) Whether or not you rename a view column, it inherits the datatype of the column from which it is derived.


Restrictions for Modifying Data Through Views

When you write a data modification statement for a view, SQL Server checks to make sure that none of the restrictions or integrity rules are violated.

Why can you update some views but not others? You can best understand the restrictions by examining the following examples.


Computed Columns in View Definition

The first restriction applies to columns of views that are derived from computed columns or built-in functions, for example, the amt_due column in the accounts view shown here is a computed column:

CREATE VIEW accounts (title, advance, amt_due)
AS SELECT title_id, advance, (price * royalty/100) * ytd_sales
FROM titles
WHERE price > $15
AND advance > $5000

These are the rows visible through accounts:

SELECT * FROM accounts

title

advance

amt_due

--------

--------

---------

PC1035

7,000.00

32,240.16

PC8888

8,000.00

8,190.00

PS1372

7,000.00

809.63

TC3218

7,000.00

785.63

(4 row(s) affected)

Updates and inserts to the amt_due column are not allowed because there is no way to deduce the underlying values for price, royalty, or ytd_sales from any value you enter in amt_due column.


GROUP BY or Aggregates in View Definition

The second restriction applies to all columns in views whose definition includes a GROUP BY or aggregate clause. Here is a view defined with a GROUP BY clause and the rows seen through it:

CREATE VIEW categories (category, average_price)

AS SELECT type, AVG(price)

FROM titles

GROUP BY type

SELECT * FROM categories

category

average_price

--------

-------------

business

13.73

mod_cook

11.49

popular_comp

21.48

psychology

13.50

trad_cook

15.96

UNDECIDED

NULL

(6 row(s) affected)

It does not make sense to insert rows into the categories view. To what group of underlying rows would an inserted row belong? Updates on the average_price column cannot be allowed because there is no way to know from any value entered there how the underlying prices should be changed.


Null Values in Underlying Objects

The third restriction applies to INSERT statements if there are some NOT NULL columns in the tables from which the view is derived.

For example, suppose null values are not allowed in a column of a table underlying a view. Normally, when you insert new rows through a view, any columns in underlying tables that don't have defaults and that are not included in the view are given null values. If null values are not allowed in one or more of these columns and they do not have defaults, no inserts are allowed through the view.

For example:

CREATE VIEW titlesview
AS SELECT title_id, price, ytd_sales
FROM titles
WHERE type = 'business'

You'll receive a message stating that the command did not return any data, and it did not return any rows. This is fine. The view has been created.

Null values are not allowed in the title column of the underlying table titles, so no INSERT statements can be allowed through titlesview. Although the title column doesn't even exist in the view, its prohibition of null values makes any inserts into the view illegal.

Similarly, if the title_id column has a unique index, updates or inserts that would duplicate any values in the underlying table are rejected, even if the entry doesn't duplicate any value in the view.


Changing More than One Underlying Object

The fourth restriction is that updates and inserts through views are not permitted if the statement would modify columns that are derived from more than one object. Updates and inserts on more than one object at a time are never allowed.

However, SQL Server allows view modification statements. For example, you can modify one underlying object of a view that contains columns from more than one underlying object.

For example, if a view contains three columns from the titles table and two columns from the publishers table, you can do an update operation on the view that changes only the columns from titles or only the columns from publishers. However, you cannot do an update on the view that changes one column from titles and one column from publishers.


Renaming Views

You can rename a view, subject to the following guidelines:

  • The view to be renamed must be in the current database.
  • The new name must follow the rules for identifiers.
  • You can rename only views that you own.
  • The database owner can change the name of any user's view.
To rename a view
  • Execute the sp_rename system procedure.

    For example:

    sp_rename accounts, owing

    renames the accounts view the owing view.

    (For details, see the sp_rename system stored procedure in the Microsoft SQL Server Transact-SQL Reference.)


Chapter 3 Working with Data

Working with Data

After you've created tables, you'll want to put data into the tables and work with the data. You can change data, remove data, or add more data. You can also import and export data to and from other applications.

In SQL Server, you work with data by using data modification statements. You add data with the INSERT statement, change data with the UPDATE, WRITETEXT, or UPDATETEXT statements, and remove data with the DELETE or TRUNCATE TABLE statements.

Each SQL Server statement is by default a transaction. You can process transactions individually or collectively. For example, to add five rows to a table, you can issue five INSERT statements separately, or you can group them into a single transaction.


Planning Additions or Changes to Data

To work with data in a database, you need to plan for additions and changes. You need to consider who should change the data, what permissions they need to change it, and how to ensure the integrity of the data.


Granting Permissions

Data modification statements are not necessarily available to everyone. The database owner and the owners of database objects can use the GRANT and REVOKE statements to determine who can use which data modification statements.

Permissions can be granted to individual users, to groups, or to the group public to use any combination of the data modification statements. (For more information about permissions, see the Microsoft SQL Server Administrator's Companion.)


Ensuring Data Integrity

To ensure the integrity of a database, you can restrict the data entered into the tables of the database. For example, you can require integer data in one column of a table and character data in another. To restrict the data entered, you can use system datatypes, user-defined datatypes, constraints, defaults, or the IDENTITY property.

For details on system and user-defined datatypes, see Working with Tables, and the Datatypes topic in the Microsoft SQL Server Transact-SQL Reference.

For details on constraints and defaults, see the CREATE TABLE and ALTER TABLE statements in the Microsoft SQL Server Transact-SQL Reference.

For details on the IDENTITY property, see the CREATE TABLE statement in the Microsoft SQL Server Transact-SQL Reference.

Keeping data consistent in a database is important. If you change data in one table without changing related data in other tables, problems can develop. For example, if you discover in the pubs sample database that the au_id entry for Sylvia Panteley is incorrect and change it in the authors table, you must also change it in the titleauthor table (and in any other table in the database with a column containing that value). If you don't, you'll never be able to find information about Sylvia Panteley.

Keeping data modifications consistent throughout a database enforces referential integrity. This means that the integrity of cross-table references is maintained. You can maintain referential integrity by using constraints (see Working with Tables). Another way is to create and use stored procedures called triggers (see Using Stored Procedures and Triggers).

When you change data in a database, a copy of the old and new state of each row affected by data modification statements (except UPDATETEXT and WRITETEXT) is written to the transaction log. This means that if you begin a transaction by executing a BEGIN TRANSACTION statement, and then decide not to permanently make the change and so roll back the transaction, the data can be restored to its previous condition.

The default mode of operation for UPDATETEXT and WRITETEXT does not log the transactions. This avoids filling up the transaction log with the extremely long blocks of data that text and image columns can contain. To log changes made with these statements, you must use the WITH LOG option.

Note Changes made on a remote SQL Server (one that the user is not directly connected to) by means of a remote procedure cannot be rolled back.


Adding, Changing, or Removing Data

In SQL Server, you can add, remove, or change data by using the INSERT, DELETE, TRUNCATE TABLE, UPDATE, UPDATETEXT, and WRITETEXT data modification statements.

  • INSERT adds a new row to a table.
  • DELETE removes one or more rows; TRUNCATE TABLE removes all rows of a table.
  • UPDATE changes rows.
  • UPDATETEXT and WRITETEXT change text and image data without writing lengthy changes in the system's transaction log.

You can also add data to a table by transferring it from a file using the bulk copy program, bcp. (For information about bcp, see the Microsoft SQL Server Administrator's Companion and the bcp command-line utility in the Microsoft SQL Server Transact-SQL Reference.)

You can modify (INSERT, UPDATE, or DELETE) data in only one table per statement. Transact-SQL lets you base your modifications on data in other tables, even those in other databases.

The data modification statements work on views as well as on tables, with some restrictions. For details, see Using Views in Working with Tables.

Note Most examples in this book refer to the pubs sample database. The pubs sample database is included as a learning tool; it is created when the server is installed. To use the sample database, your system must have access to the pubs database. If you have a localized version of SQL Server and want to try the examples, drop the localized version of pubs and install the U.S. English version of pubs. To install the U.S. English version of pubs, run the INSTPUBS.SQL script with the isql command-line utility. This script can be found in the INSTALL directory of SQL Server. Also, if other users have executed the examples in this chapter, it is likely that the pubs database has been altered. This will change the output you see from some of the examples. You can reinstall the original pubs database at any time by running the INSTPUBS.SQL script.

To run the INSTPUBS.SQL script, from an operating-system prompt, type:

isql /Usa /P password /S server -i\sql60\install\instpubs.sql

For details about isql, see the isql command-line utility in the Microsoft SQL Server Transact-SQL Reference.


Adding New Rows with INSERT

Use the INSERT statement to add rows to a database with the VALUES keyword or with a SELECT statement.

The VALUES keyword is used to specify values for some or all columns in a new row. This is the simplified syntax for the INSERT statement using the VALUES keyword:

INSERT table_name
VALUES (constant1, constant2, ...)

You can also use a SELECT statement in an INSERT statement to insert values selected from one or more other tables or views. This is the simplified syntax:

INSERT table_name
SELECT column_list
FROM table_list
WHERE search_conditions

For details on the INSERT statement, see the INSERT statement in the Microsoft SQL Server Transact-SQL Reference.


INSERT Examples

The following sections provide examples of the variations of the INSERT statement.


Inserting Data into All Columns

This INSERT statement adds a new row to the titles table of the pubs database, giving a value for each column in the row:

INSERT titles
    VALUES ('BU2222', 'Faster!', 'business', '1389',
        NULL, NULL, NULL, NULL, 'ok', '06/14/95')

Notice that the data values are in the same order as the column names in the original CREATE TABLE statement (that is, first the ID number, then the name, the city, and finally the state). The VALUES data is surrounded by parentheses and all character data is enclosed in single quotation marks. Use a separate INSERT statement for each row that you add.


Inserting Data into Some Columns

You can add data to some, but not all, of the columns in a row by specifying only those columns and the data for those columns. All the columns that are not in the column list must be defined to allow null values. The skipped columns can also accept defaults. If you skip a column that has a DEFAULT constraint, the default is used. You can use the DEFAULT keyword to instruct SQL Server to use the default value for a named column. (For details on defaults and null values, see Working with Tables and the INSERT statement in the Microsoft SQL Server Transact-SQL Reference.)

For example, this statement adds data to only two columns in the stores table in the pubs database:

INSERT INTO stores (stor_id, stor_name)
VALUES ('1229', 'Mary''s Books')

This form of the statement can also be used to skip over timestamp data.

The order in which you list the column names must match the order in which you list the values. This example produces the same results as the preceding one:

INSERT INTO stores (stor_name, stor_id)
VALUES('Mary''s Books', '1229')

Either of the INSERT statements puts 1756 in the pub_id column and The Health Center in the pub_name column. (Note that because the pub_id column in publishers has a unique index, you can't execute both of these example INSERT statements; the second attempt to insert a pub_id value of 1756 produces an error message.)


Adding New Rows with SELECT

To add values into a table from one or more other tables, use a SELECT clause in the INSERT statement. The SELECT clause can insert values into some or all columns in a row.

Inserting values into only some columns can come in handy when you want to take some values from an existing table. Then you can use UPDATE to add the values for other columns.

Before inserting values for some (but not all) of the columns in a table, be sure that a default exists or NULL has been specified for the columns in which you are not inserting values. Otherwise, you will get an error message.

When you insert rows from one table into another, the two tables must have compatible structures ¾ that is, the relevant columns must be of the same datatype or have datatypes that SQL Server automatically converts between.

If the columns in both tables are in the same order in their CREATE TABLE statements, you don't need to specify column names in either table. Suppose that the newauthors table contains some rows of author information in the same format as the authors table. This example adds all the rows in newauthors to authors:

INSERT authors
SELECT *
FROM newauthors

However, because the columns in the two tables are likely not listed in the same sequence in their respective CREATE TABLE statements, you can use either the INSERT or the SELECT statement to order the columns so that they match.

For example, say that the CREATE TABLE statement for the authors table contains the columns au_id, au_fname, au_lname, and address in that order, and the newauthors table contains au_id, address, au_lname, and au_fname. You must make the column sequence match in the INSERT statement. You can do this in either of these two ways:

INSERT authors (au_id, address, au_lname, au_fname)
SELECT * FROM newauthors

Or

INSERT authors
SELECT au_id, au_fname, au_lname, address
FROM newauthors

If the column sequence in the two tables fails to match, SQL Server cannot complete the INSERT operation or completes it incorrectly, putting data in the wrong column. For example, you might get address data in the au_lname column.

Computed Columns

You can use computed columns in a SELECT statement inside an INSERT statement. For example, imagine that a table named tmp contains some new rows for the titles table with some out-of-date data (the price figures need to be doubled). A statement that would increase the prices and insert the tmp rows into titles looks like this:

INSERT titles
SELECT title_id, title, type, pub_id, price * 2,
advance, royalty, ytd_sales, notes, pubdate
FROM tmp

When you perform computations on a column, you cannot use the SELECT * syntax. Each column must be named individually in the select list.

Inserting Data from the Same Table

You can insert data into a table based on other data in the same table. Essentially, this means copying all or part of a row.

For example, you can insert a new row in the publishers table that is based on the values in an already existing row in the same table. (Be sure you follow the rule on the pub_id column for legal entries.) Here's how:

INSERT publishers
SELECT '9980', 'test', city, state, country
FROM publishers
WHERE pub_name = 'New Moon Books'

(1 row affected)

SELECT * FROM publishers

pub_id

pub_name

city

state

country

------

-----------------------

-----------

-----

--------
0736

New Moon Books

Boston

MA

USA

0877

Binnet & Hardley

Washington

DC

USA

1389

Algodata Infosystems

Berkeley

CA

USA
1622

Five Lakes Publishing

Chicago

IL

USA

1756

Ramona Publishers

Dallas

TX

USA

9901

GGG&G

München

(null)

Germany

9952

Scootney Books

New York

NY

USA
9999

Lucerne Publishing

Paris

(null)

France

(8 row(s) affected)

Similar to the INSERT...SELECT capability, INSERT INTO allows you to create a new table entirely and populate it with the results set of the SELECT statement. For details, see the INSERT statement in the Microsoft SQL Server Transact-SQL Reference.


Changing Existing Data with UPDATE

Use the UPDATE statement to change single rows, groups of rows, or all the rows in a table. As in all data modification statements, you can change the data in only one table at a time.

The UPDATE statement specifies which row(s) to change and gives the new data. The new data can be a constant or expression that you specify, or it can be data from other tables.

Note The UPDATE statement is logged; if you are changing large blocks of text or image data, use the UPDATETEXT or WRITETEXT statement, which, by default, is not logged. For more information, see Changing Data with WRITETEXT.

If an UPDATE statement violates an integrity constraint (if one of the values being added is the wrong datatype, or it violates a constraint that has been defined for one of the columns or datatypes involved), the update does not take place and an error message is displayed.

For details on the UPDATE statement, see the UPDATE statement in the Microsoft SQL Server Transact-SQL Reference.


UPDATE Examples

For example, Reginald Blotchet-Halls decides to change his name to Goodbody Health. Here's how to change his row in the authors table:

UPDATE authors
SET au_lname = 'Health', au_fname = 'Goodbody'
WHERE au_lname = 'Blotchet-Halls'

This example that updates the ytd_sales column of the titles table to reflect the most recent sales recorded in the sales table:

UPDATE titles
SET ytd_sales = ytd_sales  qty
FROM titles, sales
WHERE titles.title_id = sales.title_id
    AND sales.ord_date in (SELECT MAX(sales.ord_date) FROM sales)

The preceding example assumes that only one set of sales is recorded for a given title on a given date and that updates are up to date. If this is not the case (if more than one sale for a given title can be recorded on the same day), then this example does not work correctly. It executes without error, but each title is updated with only one sale, regardless of how many sales actually occurred on that day. This is because a single UPDATE statement never updates the same row twice.

In the situation in which more than one sale for a given title can occur on the same day, all the sales for each title must be aggregated together within the UPDATE statement, as shown here:

UPDATE titles
SET ytd_sales = (SELECT SUM(qty)
    FROM sales
    WHERE sales.title_id = titles.title_id
        AND sales.ord_date IN (SELECT MAX(ord_date) FROM sales))
FROM titles, sales


The SET Clause

The SET clause specifies the column(s) to be changed and the changed value(s). The WHERE clause determines which row or rows are updated. Note that if you don't specify a WHERE clause, the specified columns of all rows are updated with the values given in the SET clause.

For example, if all the publishing houses in the publishers table move their head offices to Atlanta, Georgia, this is how to update the table:

UPDATE publishers
SET city = 'Atlanta', state = 'GA'

In the same way, you can change the names of all the publishers to NULL with this statement:

UPDATE publishers
SET pub_name = null

You can also use computed column values in an update. To double all the prices in the titles table, use this statement:

UPDATE titles
SET price = price * 2

Since there is no WHERE clause, the change in prices is applied to every row in the table.


The WHERE Clause

The WHERE clause specifies which rows are to be updated. For example, in the unlikely event that northern California is renamed Pacifica (abbreviated PC) and the people of Oakland vote to change the name of their city to Bay City, here is how to update the authors table for all former Oakland residents whose addresses are now out of date:

UPDATE authors
SET state = 'PC', city = 'Bay City'
WHERE state = 'CA' AND city = 'Oakland'


The FROM Clause

Use the FROM clause to pull data from one or more tables into the table you're updating. When author Dirk Stringer gets a contract, a title identification number is assigned to his book, The Psychology of Computer Cooking, in the titles table. You can modify his row in the titleauthor table by adding a title identification number for him:

UPDATE titleauthor
SET title_id = titles.title_id
FROM titles, authors, titleauthor
WHERE titles.title = 'Net Etiquette'
AND au_lname = 'Locksley'
AND authors.au_id = titleauthor.au_id
AND titles.title_id = titleauthor.title_id

Note that an UPDATE without the au_id join changes all the title_ids in the titleauthor table to the same identification number as the one for The Psychology of Computer Cooking.


Changing Data with WRITETEXT

To update text or image values, use the WRITETEXT statement. By default, WRITETEXT statements (using text or image data) are not logged, so that the transaction log will not fill up with large amounts of data.

Note The system administrator must use the sp_dboption system procedure to set select into/bulk copy to true for the WRITETEXT statement to be used in its default, nonlogged state.

The WRITETEXT statement completely overwrites any existing data in the column it affects. For WRITETEXT to work, the column must already contain a valid text pointer. There are two ways to create a text pointer:

  • Insert actual data into the text or image column.
  • Update the column with data or with NULL.

Important After a WRITETEXT operation that does not include the WITH LOG option, a DUMP TRANSACTION operation will not archive changes made to a text or image column, because these changes were not recorded in the transaction log. In this situation, the only way to archive such changes is to use the DUMP DATABASE statement.

Because an initialized text column uses at least one page (2K) of storage, even to store a couple of words, SQL Server saves space by not initializing text columns when explicit or implicit null values are placed in text columns with INSERT. For example:

INSERT publishers
VALUES ('9925', 'New Publisher', 'Redmond', 'WA', 'USA')
go
INSERT pub_info
VALUES ('9925', NULL, NULL)
go

After an INSERT operation, such as the one in the preceding example, you can use this UPDATE statement to initialize the text column:

UPDATE pub_info
SET pr_info = null
WHERE pub_id = '9925'

Once you have initialized the pointer, you can use WRITETEXT. This example adds text to an existing row in the publishers table:

DECLARE @val varbinary(16)
SELECT @val = textptr(pr_info) FROM pub_info
WHERE pub_id = '9925'
WRITETEXT pub_info.pr_info @val WITH LOG
'Information about New Publisher.'

This example puts the text pointer into the local variable @val. Then WRITETEXT places the new text string into the row pointed to by @val.

For details on WRITETEXT, see the WRITETEXT statement in the Microsoft SQL Server Transact-SQL Reference.


Changing Data with UPDATETEXT

Instead of using the WRITETEXT statement to update a text or image field, you can use the UPDATETEXT statement. UPDATETEXT is more flexible than WRITETEXT, because it changes only a portion of a text or image value in place (WRITETEXT updates and replaces an entire text or image field).

For details on UPDATETEXT, see the UPDATETEXT statement in the Microsoft SQL Server Transact-SQL Reference.


Using Cursors to Change or Remove Data

Some applications need to work a row at a time with the results of a query. But relational databases like SQL Server are "set oriented," not "record oriented." Cursors can bridge this apparent mismatch. Applications can retrieve rows one at a time by using a cursor. A cursor is essentially a defined result set within which applications manipulate data row by row.

In a cursor, you can update or delete the current row by using an UPDATE or DELETE statement that includes a WHERE CURRENT OF clause. Changes made with this clause affect only the single row on which the cursor is positioned. In the case of a cursor based on a join, only the table_name specified in the DELETE or UPDATE statement is modified. Other tables participating in the cursor are not affected. For details on the UPDATE and DELETE statements, see the UPDATE and DELETE statements in the Microsoft SQL Server Transact-SQL Reference. For information about joins, see Retrieving Data with Queries.

For more information about cursors, see the Cursors topic in the Microsoft SQL Server Transact-SQL Reference. For details about cursors and locking, see Optimizing Performance.


Removing Data with DELETE

Like the INSERT and UPDATE statements, the DELETE statement works for single-row as well as multiple-row operations. As with the other data modification statements, you can delete rows based on data in other tables.


DELETE Example

Suppose that a complex corporate deal results in the acquisition of all the Bay City (formerly Oakland) authors and their books by another publisher. You need to remove all these books from the titles table right away, but you don't know their titles or identification numbers. The only information you have is the authors' names and addresses.

You can delete the rows in the titles table by finding the author identification numbers for the rows that have San Francisco as the city in the authors table, and then using these numbers to find the title identification numbers of the books in the titleauthor table. In other words, a three-way join is required to find the rows you want to delete in the titles table.

The three tables are all included in the FROM clause of the DELETE statement. However, only the rows in the titles table that fulfill the conditions of the WHERE clause are deleted. You must perform separate deletes to remove relevant rows in tables other than titles.

Here's the statement you need:

DELETE titles
FROM authors, titles, titleauthor
WHERE titles.title_id = titleauthor.title_id
    AND authors.au_id = titleauthor.au_id
    AND city = 'San Francisco'

Note The primary key/foreign key relationship between titleauthor and authors/titles in the pubs database prevents you from actually performing this deletion because the foreign key won't allow you to delete any titles that have sales recorded in the sales table. To run this example, the referenced sales data must first be deleted.

For details, see the DELETE statement in the Microsoft SQL Server Transact-SQL Reference.


Removing All Rows with TRUNCATE TABLE

TRUNCATE TABLE is a fast, nonlogged method of deleting all rows in a table. It is almost always faster than a DELETE statement with no conditions, because DELETE logs each change, and TRUNCATE TABLE logs only the deallocation of whole data pages. TRUNCATE TABLE immediately frees all the space occupied by that table's data and indexes. The distribution pages for all indexes are also freed.

As with DELETE, a table emptied with the TRUNCATE TABLE statement remains in the database (along with its indexes and other associated objects) unless you enter a DROP TABLE statement.

Permission to use the TRUNCATE TABLE statement, like DROP TABLE, defaults to the table owner and cannot be transferred.

A TRUNCATE TABLE statement does not fire a DELETE trigger. For details on triggers, see Using Stored Procedures and Triggers. For details on the TRUNCATE TABLE statement, see the TRUNCATE TABLE statement in the Microsoft SQL Server Transact-SQL Reference.

Because TRUNCATE TABLE a nonlogged operation, it is recommended that you dump the database using the DUMP DATABASE statement after using TRUNCATE TABLE.


Importing and Exporting Data

With the bulk copy program (bcp), you can easily import data from other applications or export data to those applications. For example, you can import data from Microsoft® Visual FoxPro™, or you can export a view based on several tables for use in other SQL Servers or for analysis in Microsoft Excel.

The bulk copy program (bcp) copies SQL Server data to or from an operating-system file in a user-specified format.

The bcp utility is most frequently used to transfer data into a SQL Server database from another program, usually another database management system. The data to be transferred must be put into an operating-system file or onto a diskette with a backup facility provided by the old program.

The bcp utility is also used for temporary transfers of data for use with other programs¾for example, with spreadsheet programs. The data is moved from SQL Server into an operating-system file or onto a diskette; from there, the other program can import the data.

SQL Server can accept data in any ASCII or binary format as long as the terminators (the characters used to separate columns and rows) can be described. The table structures need not be identical. Data copied into SQL Server is appended to any existing contents of a table; data copied to a file overwrites any previous contents of the file.

To use bcp, a user must have a SQL Server login account and the appropriate permissions on the database tables, views, and operating-system files.

For details on bcp, see the Microsoft SQL Server Administrator's Companion and the bcp command-line utility in the Microsoft SQL Server Transact-SQL Reference.


Processing Transactions in Batches

You can submit SQL statements to SQL Server one at a time, entering statements and receiving results interactively. Or you can submit multiple SQL statements as a batch, interactively or in a file.

A batch of SQL statements is terminated by an end-of-batch signal that instructs SQL Server to go ahead and execute the statements. The end-of-batch signal used here¾for the stand-alone isql utility¾ is the GO statement on a line by itself.

Technically speaking, a single SQL statement can constitute a batch, but it is more common to think of a batch as containing multiple SQL statements. Frequently, a batch of statements is written to a file before being submitted to isql. The file can contain multiple batches, each separated by the GO statement.

For details on batches, see Batches in the Microsoft SQL Server Transact-SQL Reference.


Batches Submitted as Files

A batch is a set of SQL statements submitted together and executed as a group. A script is often a series of batches submitted one after the other. A batch is compiled only once as a whole and is terminated by an end-of-batch signal. Because of this, certain restrictions on batch size exist.

You can submit one or more batches of SQL statements to isql from an operating-system file. A file can include more than one batch ¾ more than one collection of SQL statements¾each terminated by the GO end-of-batch signal.

For details, see Batches in the Microsoft SQL Server Transact-SQL Reference.

The following excerpt of INSTPUBS.SQL script, located in the SQL Server INSTALL directory, contains the following batches that help to create the pubs sample database (note that comments have been removed):

SET NOCOUNT ON
SET DATEFORMAT mdy
USE master
go

CREATE TABLE #dbdev_temp
(
    name_var        varchar(30)     NOT NULL,
    type    varchar(10)     NOT NULL
)
go

INSERT #dbdev_temp VALUES('pubs', 'dbname')
INSERT #dbdev_temp VALUES('master', 'devname')
go

DECLARE @dbname_var     varchar(30)
SELECT @dbname_var = name_var FROM #dbdev_temp WHERE type = 'dbname'
IF EXISTS (SELECT * FROM master.dbo.sysdatabases
    WHERE name = @dbname_var)
BEGIN
    EXECUTE ('DROP DATABASE '  @dbname_var)
END
go

DECLARE @dbname_var     varchar(30),
    @devname_var    varchar(30)
SELECT @dbname_var = name_var FROM #dbdev_temp WHERE type = 'dbname'
SELECT @devname_var = name_var FROM #dbdev_temp WHERE type = 'devname'
EXECUTE ('PRINT "Creating the publishers database as '  @dbname_var
             ' on the '  @devname_var  ' device."')
EXECUTE ('CREATE DATABASE '  @dbname_var  ' ON '  @devname_var  ' = 3')
go

DECLARE @dbname_var     varchar(30)
SELECT @dbname_var = name_var FROM #dbdev_temp WHERE type = 'dbname'
EXECUTE ('USE '  @dbname_var)
go

DECLARE @dbname_var     varchar(30)
SELECT @dbname_var = name_var FROM #dbdev_temp WHERE type = 'dbname'
IF ((db_id() <> db_id(@dbname_var)) OR (db_id(@dbname_var) IS NULL) OR (db_id() = db_id('master')))
    RAISERROR ('The publishers database was not created. See the Errorlog or
Event Viewer for more details.',20,0) WITH LOG
go

EXECUTE ('USE master')
DECLARE @dbname_var     varchar(30)
SELECT @dbname_var = name_var FROM #dbdev_temp WHERE type = 'dbname'
EXECUTE ('sp_dboption '''  @dbname_var  ''', ''trunc. log on chkpt.'', true')
EXECUTE ('USE '  @dbname_var)
go

EXECUTE sp_addtype id, 'varchar(11)', 'NOT NULL'
EXECUTE sp_addtype tid, 'varchar(6)', 'NOT NULL'
EXECUTE sp_addtype empid, 'char(9)', 'NOT NULL'
go

CREATE TABLE authors
(
    au_id   id
    CHECK (au_id like '[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]')
    CONSTRAINT UPKCL_auidind PRIMARY KEY CLUSTERED,
    au_lname        varchar(40)     NOT NULL,
    au_fname        varchar(20)     NOT NULL,
    phone   char(12)        NOT NULL
        DEFAULT ('UNKNOWN'),
    address varchar(40)     NULL,
    city    varchar(20)     NULL,
    state   char(2) NULL,
    zip     char(5) NULL
        CHECK (zip like '[0-9][0-9][0-9][0-9][0-9]'),
    contract        bit     NOT NULL
)
go
.
.
.


Using Control-of-Flow Language

Transact-SQL provides special keywords called control-of-flow language that allow you to control the flow of execution of SQL statements, statement blocks, and stored procedures. These keywords can be used in ad hoc SQL statements, in batches, and in stored procedures.

Without control-of-flow language, separate SQL statements are performed sequentially, as they occur. Control-of-flow language permits statements to be connected, related to each other, and made interdependent using programming-like constructs.

These are the control-of-flow keywords:

Keyword | Description
BEGIN...END | Defines a statement block.
GOTO label | Continues processing at the statement following the label as defined by label.
IF...ELSE | Defines conditional and, optionally, alternate execution when a condition is false.
RETURN | Exits unconditionally.
WAITFOR | Sets a delay for statement execution.
WHILE | Repeats statements while a specific condition is true.
...BREAK | Exits the innermost WHILE loop.
...CONTINUE | Restarts a WHILE loop.

In addition to the keywords used for conditional processing and control-of-flow for SQL statements, a variety of helpful Transact-SQL extensions and ANSI-standard additions are available:

Feature | Description
CASE Expression | Allows an expression to have conditional return values. This is the ANSI SQL-92 standard CASE expression.
Comments | Inserts a comment anywhere in an SQL statement. Two commenting styles are supported: Transact-SQL style (/* and */) and ANSI-standard comment style (--).
DECLARE Statement | Declares local variables as well as cursors.
PRINT Statement | Prints a user-defined message on the user's screen.
RAISERROR Statement | Returns a sysmessages entry or a dynamically built message with user-specified severity and state. RAISERROR also sets a system flag (in the global variable @@ERROR) to record that an error condition has occurred.
Execute (@string) | Allows a command to be dynamically constructed as a character string, and then executed, without requiring any communication between client and server.

For details on control-of-flow language, see Control-of-Flow Language in the Microsoft SQL Server Transact-SQL Reference.


Chapter 4 Retrieving Data with Queries

Retrieving Data with Queries

You can retrieve data from tables and views quickly and easily by using queries. You use queries for various reasons: to answer a quick question, to organize information for a report, or to see any relevant subset of your data. Whatever your aim, SQL Server provides the tools you need to get the data you want.

Note You can create queries using isql, ISQL/w, the query analyzer SQL Enterprise Manager, or any number of other (third-party or custom-built) tools.

For details on isql, see the isql command-line utility in the Microsoft SQL Server Transact-SQL Reference. For details on ISQL/w, see Utilities and Executables in the Microsoft SQL Server Transact-SQL Reference. For details on SQL Enterprise Manager, see the SQL Enterprise Manager online Help.


Creating Basic Queries

You use the SELECT statement to choose rows and columns from tables. You can use it for selections (retrieving a subset of the rows in one or more tables), projections (retrieving a subset of the columns in one or more tables), and joins (linking rows in two or more tables to retrieve cross-table data).

This chapter discusses how to use SELECT to choose the specific columns and rows you want from a database and how to query the database using various comparison and logical operators. It also shows how to format the results of a query, including adding elementary computed values, processing and sorting results, and producing simple summary reports.


Identifiers

Every object in a database has a name. To work with an object, you must identify it by that name. In Transact-SQL, you use identifiers to specify the names of the objects you want to work with. Identifiers can have from 1 through 30 characters. The first character can be an alphabetic character (a-z or A-Z) or the symbols _ (underscore), @ (at sign), or # (pound sign). An identifier beginning with @ denotes a variable. An identifier beginning with # denotes a temporary object (table or procedure). After the first character, identifiers can include letters, digits, or the $, #, or _ symbols. For details about identifiers, see Identifiers in the Microsoft SQL Server Transact-SQL Reference.


Choosing a Database: USE

When you log in to SQL Server, you are placed into a default database (initially the master database unless otherwise specified by the system administrator). Many tools also let you specify which database to use. For example, with the pubs sample database, even if your default database is master you can use:

isql /Usa /dpubs

where

d is the database option switch.

To switch to another database, from the SQL Enterprise Manager Query window, select the database to switch to from the DB drop-down list.

Or you can use the USE statement:

USE database_name

The USE statement changes the current database context to the specified database. For example, to switch to pubs, type:

USE pubs

Note The examples in this chapter are based on the pubs sample database.

Once you have selected a database, you are ready to build a query using the SELECT statement.


SELECT Syntax

Note Most examples refer to the pubs sample database. The pubs sample database is included as a learning tool; it is created when the server is installed. To use the sample database, your system must have access to the pubs database. If you have a localized version of SQL Server and want to try the examples, drop the localized version of pubs and install the U.S. English version of pubs. To install the U.S. English version of pubs, run the INSTPUBS.SQL script with the isql command-line utility. This script can be found in the INSTALL directory of SQL Server. Also if other users have executed the examples in this chapter, it is likeley that the pubs database has been altered. This will change the output you see from some of the examples. You can reinstall the original pubs database at any time by running the INSTPUBS.SQL script.

To run the INSTPUBS.SQL script, from an operating-system prompt, type:

isql /Usa /P password /S server -i\sql60\install\instpubs.sql

For details about isql, see the isql command-line utility in the Microsoft SQL Server Transact-SQL Reference.

The SELECT statement specifies the columns you want to retrieve. The FROM clause specifies the tables where the columns are located. The WHERE clause specifies which rows in the tables you want to see.

A simplified syntax for the SELECT statement is:

SELECT select_list
FROM table_list
WHERE search_conditions

For example, the following SELECT statement finds the first and last names of writers in the authors table who live in Oakland.

SELECT au_fname, au_lname
FROM authors
WHERE city = 'Oakland'

au_fname                au_lname
---------               --------------
Marjorie                Green
Dean                    Straight
Dirk                    Stringer
Stearns                 MacFeather
Livia                   Karsen

(5 row(s) affected)

The complete syntax of the SELECT statement includes the following phrases and keywords:

SELECT [ALL | DISTINCT] select_list
[INTO [new_table_name]]
[FROM {table_name | view_name}[(optimizer_hints)]
[[, {table_name2 | view_name2}[(optimizer_hints)]
[..., {table_name16 | view_name16}[(optimizer_hints)]]]
[WHERE clause]
[GROUP BY clause]
[HAVING clause]
[ORDER BY clause]
[COMPUTE clause]
[FOR BROWSE]

The clauses in a SELECT statement must be used in the order shown here. (For example, if the statement includes a GROUP BY clause and an ORDER BY clause, the GROUP BY clause precede the ORDER BY clause.)

The names of database objects must be qualified if there is ambiguity about which object is being referred to. You can uniquely identify a table or column by specifying other names that qualify it ¾ the database name, the owner's name, and the table name or view name for a column. Each of these qualifiers is separated from the next by a period, as shown here:

database.owner.table_name.column_name

For example, if the user sharon owns the authors table in the pubs database, the unique identifier of the city column in that table is:

pubs.sharon.authors.city

Since many examples in this chapter involve single-table queries, column names in syntax models and examples are usually not qualified with the names of the tables, owners, or databases to which they belong. Although these elements are left out of the examples to promote readability, it is never wrong to include qualifiers.

Note that SELECT statement optimizer_hints are optional and delimited with a space, not a comma.

For example:

SELECT * FROM authors (HOLDLOCK TABLOCK)

You can order by either the column name, or by its ordinal number in the select list.

These two queries are equivalent:

SELECT au_frame, au_lname
FROM authors
ORDER BY au_lname

ORDER BY 2

For details about SELECT, see the SELECT statement in the Microsoft SQL Server Transact-SQL Reference.


Choosing Columns: The Select List

The select list frequently consists of a series of column names (separated by commas) or an asterisk (*, representing all columns).

The select list, however, can also include one or more expressions (separated by commas), where an expression is a constant, column name, function, subquery, or any combination of these connected by arithmetic or bitwise operators and parentheses. The select list has this syntax:

SELECT expression [, expression...]


Choosing All Columns: SELECT *

The asterisk (*) has a special meaning in SELECT statements. It represents all column names in all tables specified in the FROM clause. This is the syntax for selecting all columns in a table:

SELECT *
FROM table_name

Because SELECT * finds all columns currently in a table, changes in the structure of a table (adding, removing, or renaming columns) automatically modify the results of a SELECT * statement. Listing columns individually allows more precise control over the results. Whenever * is used, the columns in the results are displayed in the order in which they were created by the CREATE TABLE statement.

It is usually preferable to explicitly name the columns in the select list. Because an application often relies on knowing certain columns will be returned, using SELECT * might "break" an application if a new column is added to the table.

The following statement retrieves all columns in the publishers table and displays them in the order in which they were defined when the publishers table was created. Because no WHERE clause is included, this statement also retrieves every row.

SELECT *
FROM publishers

The results look like this:

pub_id pub_name                  city           state country
------ -------------------------------------------------------
0736   New Moon Books            Boston          MA    USA
0877   Binnet & Hardley          Washington      DC    USA
1389   Algodata Infosystems      Berkeley        CA    USA
1622   Five Lakes Publishing     Chicago         IL    USA
1756   Ramona Publishers         Dallas          TX    USA
9901   GGG&G                     München         (null)Germany
9952   Scootney Books            New York        NY    USA
9999   Lucerne Publishing        Paris           (null)France

(8 row(s) affected)

You get exactly the same results by listing all the column names in the table in order after the SELECT statement:

SELECT pub_id, pub_name, city, state
FROM publishers


Choosing Specific Columns

To select specific columns in a table, use this syntax:

SELECT column_name [, column_name...]
FROM table_name

Each column name must be separated from the following column name by a comma.


Specifying the Order of Columns

The order in which you list the column names determines the order in which the columns appear in the output. The following examples show how to find and display the publisher names and identification numbers from the publishers table. The first example prints pub_id first, followed by pub_name. The second example reverses that order.

SELECT pub_id, pub_name
FROM publishers

pub_id pub_name
------ ---------------------
0736   New Moon Books
0877   Binnet & Hardley
1389   Algodata Infosystems
1622   Five Lakes Publishing
1756   Ramona Publishers
9901   GGG&G
9952   Scootney Books
9999   Lucerne Publishing

(8 row(s) affected)

SELECT pub_name, pub_id
FROM publishers

pub_name             pub_id
---------------------------
New Moon Books        0736
Binnet & Hardley      0877
Algodata Infosystems  1389
Five Lakes Publishing 1622
Ramona Publishers     1756
GGG&G                 9901
Scootney Books        9952
Lucerne Publishing    9999

(8 row(s) affected)


Renaming Columns in Query Results

When query results are displayed, the name given to a column when it was created is used as the default heading. To produce more readable results, you can specify a different column heading by using either column_heading = column_name or column_name column_heading instead of using the column name in a select list.

For example, to change pub_name to Publisher in the preceding query, type either of the following statements:

SELECT Publisher = pub_name, pub_id
FROM publishers

SELECT pub_name Publisher, pub_id
FROM publishers

The results of both statements look like this:

Publisher             pub_id
---------------------------
New Moon Books        0736
Binnet & Hardley      0877
Algodata Infosystems  1389
Five Lakes Publishing 1622
Ramona Publishers     1756
GGG&G                 9901
Scootney Books        9952
Lucerne Publishing    9999

(8 row(s) affected)


Categorizing or Renaming Data in Query Results

In addition to renaming columns in a results set, you can also categorize or rename data in a results set. For example, the following query uses the CASE expression to rename book categories so that they are more understandable:

SELECT Category =
    CASE type
        WHEN 'popular_comp' THEN 'Popular Computing'
        WHEN 'mod_cook' THEN 'Modern Cooking'
        WHEN 'business' THEN 'Business'
        WHEN 'psychology' THEN 'Psychology'
        WHEN 'trad_cook' THEN 'Traditional Cooking'
        ELSE 'Not yet categorized'
    END,
'Shortened Title' = CONVERT(varchar(30), title),
Price = price
FROM titles
WHERE price IS NOT NULL
ORDER BY 1

The results look like this:

category            shortened title                Price
------------------- ------------------------------ -------
Business            Cooking with Computers: Surrep 11.95
Business            Straight Talk About Computers  19.99
Business            The Busy Executive's Database  19.99
Business            You Can Combat Computer Stress 2.99
Modern Cooking      Silicon Valley Gastronomic Tre 19.99
Modern Cooking      The Gourmet Microwave          2.99
Popular Computing   But Is It User Friendly?       22.95
Popular Computing   Secrets of Silicon Valley      20.00
Psychology          Computer Phobic AND Non-Phobic 21.59
Psychology          Emotional Security: A New Algo 7.99
Psychology          Is Anger the Enemy?            10.95
Psychology          Life Without Fear              7.00
Psychology          Prolonged Data Deprivation: Fo 19.99
Traditional Cooking Fifty Years in Buckingham Pala 11.95
Traditional Cooking Onions, Leeks, and Garlic: Coo 20.95
Traditional Cooking Sushi, Anyone?                 14.99

(16 row(s) affected)


Replacing Data in Query Results

Under conditions defined in a query, the query can replace data in a results set with other data. For example, the following query uses the CASE expression to replace certain price data with text comments:

SELECT 'Price Category' =
    CASE
        WHEN price IS NULL THEN 'Not yet priced'
        WHEN price < 10 THEN 'Very Reasonable Title'
        WHEN price >= 10 and price < 20 THEN 'Coffee Table Title'
        ELSE 'Expensive book!'
    END,
'Shortended Title' = CONVERT(varchar(20), title),
Category =
    CASE type
        WHEN 'popular_comp' THEN 'Popular Computing'
        WHEN 'mod_cook' THEN 'Modern Cooking'
        WHEN 'business' THEN 'Business'
        WHEN 'psychology' THEN 'Psychology'
        WHEN 'trad_cook' THEN 'Traditional Cooking'
        ELSE 'Not yet categorized'
    END
FROM titles
ORDER BY price

The results look like this:

Price Category        Shortended Title     Category
--------------------- -------------------- -------------------
Not yet priced        Net Etiquette        Popular Computing
Not yet priced        The Psychology of Co Not yet categorized
Very Reasonable Title The Gourmet Microwav Modern Cooking
Very Reasonable Title You Can Combat Compu Business
Very Reasonable Title Life Without Fear    Psychology
Very Reasonable Title Emotional Security:  Psychology
Coffee Table Title    Is Anger the Enemy?  Psychology
Coffee Table Title    Cooking with Compute Business
Coffee Table Title    Fifty Years in Bucki Traditional Cooking
Coffee Table Title    Sushi, Anyone?       Traditional Cooking
Coffee Table Title    Prolonged Data Depri Psychology
Coffee Table Title    Silicon Valley Gastr Modern Cooking
Coffee Table Title    Straight Talk About  Business
Coffee Table Title    The Busy Executive's Business
Expensive book!       Secrets of Silicon V Popular Computing
Expensive book!       Onions, Leeks, and G Traditional Cooking
Expensive book!       Computer Phobic AND  Psychology
Expensive book!       But Is It User Frien Popular Computing

(18 row(s) affected)


Quoted Strings in Column Headings

A column heading in a select list can contain any character, even spaces or blanks, if the column heading is enclosed in single quotation marks ('). It can have a maximum of 30 characters. A column heading not enclosed in single quotation marks must conform to the rules for identifiers.

For example:

SELECT 'Book Publisher' = pub_name
FROM publishers

The result is:

Book Publisher
---------------------
New Moon Books
Binnet & Hardley
Algodata Infosystems
Five Lakes Publishing
Ramona Publishers
GGG&G
Scootney Books
Lucerne Publishing

(8 row(s) affected)

In addition, you can use Transact-SQL reserved words in quoted column headings. For example, the following query uses the reserved word SUM as a column heading:

SELECT 'sum' = SUM(ytd_sales)
FROM titles

Note that you can use a quoted string for a column heading in a table definition (CREATE TABLE), or in SELECT INTO and CREATE VIEW statements only if the SET option QUOTED_IDENTIFIER is set to 'ON'. Otherwise, column headings in these statements must conform to the rules for identifiers.


Character Strings and Quotation Marks

Character strings and dates (char, varchar, and datetime datatypes) must be enclosed in single quotation marks (') when you enter or search for them. (Although double quotation marks are allowed, single quotation marks are preferred for compliance with ANSI standards.)

To specify other single quotation marks (or apostrophes) within a character entry, use two consecutive single quotation marks, as shown in the following example:

'I don''t understand.'

To continue a character string too long to fit on one line on your screen, enter a backslash ( \) before going to the following line.


Character Strings in Query Results

The SELECT statements in the examples you've seen so far produce results that consist of data from the tables listed in the FROM clause. Character strings can also be displayed in query results.

To display a character string in a results set, enclose the entire string in single quotation marks and separate it from other elements in the select list with commas:

SELECT 'The publisher''s name is', Publisher = pub_name
FROM publishers

Publisher

---------------------------------------------

The publisher's name is New Moon Books

The publisher's name is Binnet & Hardley

The publisher's name is Algodata Infosystems

The publisher's name is Five Lakes Publishing

The publisher's name is Ramona Publishers

The publisher's name is GGG&G

The publisher's name is Scootney Books

The publisher's name is Lucerne Publishing

(8 row(s) affected)


Computed Values in the Select List

You perform computations with data from numeric columns or on numeric constants in a select list by using arithmetic operators. Arithmetic operators let you add, subtract, multiply, and divide numeric data.


Arithmetic Operators

The following arithmetic operators are supported:

Symbol | Operation
+ | Addition
- | Subtraction
/ | Division
* | Multiplication
% | Modulo

The arithmetic operators that perform addition, subtraction, division, and multiplication can be used on any numeric column ( int, smallint, tinyint, decimal, numeric, float, real, money, or smallmoney). The modulo operator cannot be used on money columns. (A modulo is the integer that remains after two integers are divided. For example, 21 % 9 = 3, because 21 divided by 9 equals 2, with a remainder, or modulo, of 3.)

Certain arithmetic operations can also be performed on datetime and smalldatetime columns using the date functions. For details, see Functions in the Microsoft SQL Server Transact-SQL Reference.

All the arithmetic operators can be used in the select list with column names and numeric constants in any combination. The following example uses the multiplication operator to show a projected sales increase of 100 percent for all the books in the titles table:

SELECT title_id, ytd_sales, ytd_sales * 2
FROM titles

title_id ytd_sales   ytd_sales * 2
-------- ----------- -----------
BU1032   4095        8190
BU1111   3876        7752
BU2075   18722       37444
BU7832   4095        8190
MC2222   2032        4064
MC3021   22246       44492
MC3026   (null)      (null)
PC1035   8780        17560
PC8888   4095        8190
PC9999   (null)      (null)
PS1372   375         750
PS2091   2045        4090
PS2106   111         222
PS3333   4072        8144
PS7777   3336        6672
TC3218   375         750
TC4203   15096       30192
TC7777   4095        8190

(18 row(s) affected)

Notice the NULL entries in the ytd_sales and computed columns. Null values have no explicitly assigned values. When you perform any arithmetic operation on a null value, the result is NULL. (You can use the system function ISNULL() to substitute a real value for NULL. For details, see the Functions topic in the Microsoft SQL Server Transact-SQL Reference.)

To give the computed column a heading (say proj_sales):

SELECT title_id, ytd_sales, proj_sales = ytd_sales * 2
FROM titles

The column from which the computed column is generated does not have to appear in the select list. The ytd_sales column, for example, is shown in the preceding queries only for comparison with the ytd_sales * 2 column. To see just the computed values:

SELECT title_id, ytd_sales * 2
FROM titles

You can use arithmetic operators to perform computations involving one or more columns. The use of constants in arithmetic expressions is optional, as shown in this example:

SELECT title_id, ytd_sales * price

FROM titles

Computed columns can come from more than one table. The following query computes the product of the number of copies of a psychology book sold (the qty column from the sales table) and the price of the book (the price column from the titles table):

SELECT titles.title_id, stor_id, qty * price

FROM titles, sales

WHERE titles.title_id = sales.title_id

AND titles.title_id = 'PS2091'

The WHERE clause in this example is a join condition that specifies the connection between the tables listed in the FROM clause. For details about working with multitable queries, see Using Joins to Create Multitable Queries and Using Subqueries.

Datatype Precedence in Mixed-mode Arithmetic

Mixed-mode arithmetic means performing arithmetic operations on values of different datatypes (for example, int  smallint). The hierarchy of datatypes, which comes from the rank ordering of the values of the datatype codes, determines the datatype of the result. In a mixed-mode expression, the lower datatype is converted internally to the higher type. The only exception to this rule is when converting money and other number datatypes such as float, real, decimal, and numeric; money always takes precedence, even though its type is lower. The hierarchy of datatypes is shown in the systypes system table.

If, for example, sales.qty (a smallint) is multiplied by roysched.royalty (an int), the resultant datatype is int. This is because the smallint datatype code has a value of 52 and the int datatype code has a value of 56.

To obtain a list of datatypes with their type value codes from the systypes table, use the following query. Select the name of the datatype and its type code, and then use the ORDER BY statement to display the hierarchy:

SELECT name, type
FROM systypes
ORDER BY type

The results of this query differ if you have user-defined datatypes.

Arithmetic Operator Precedence

When there is more than one arithmetic operator in an expression, multiplication, division, and modulo are calculated first, followed by subtraction and addition. When all arithmetic operators in an expression have the same level of precedence, the order of execution is left to right. Expressions within parentheses take precedence over all other operations.

For example, the following SELECT statement subtracts the part of the year-to-date sales that the author receives (sales * author's royalty percentage / 100) from the total sales. The final result is the amount of money the publisher receives.

The product of ytd_sales and royalty is calculated first because the operator is multiplication. Next, the total is divided by 100. Then this result is subtracted from ytd_sales:

SELECT title_id, ytd_sales - ytd_sales * royalty / 100
FROM titles

For clarity, you can use parentheses. The following query has the same meaning and gives the same results as the preceding one:

SELECT title_id, ytd_sales - ((ytd_sales * royalty) / 100)
FROM titles

You can also use parentheses to change the order of execution. Calculations inside parentheses are evaluated first. If parentheses are nested, the most deeply nested calculation has precedence. For example, the result and meaning of the preceding query can be changed if you use parentheses to force the evaluation of subtraction before multiplication:

SELECT title_id, (ytd_sales - ytd_sales) * royalty / 100
FROM titles


Selecting text and image Values

You can use either the SELECT or READTEXT statement to select values that have the text or image datatypes.

When the select list includes text and image values, the limit on the length of the data returned depends on the setting of the @@TEXTSIZE global variable. This value (in bytes) is changed with the SET statement TEXTSIZE option, as shown here:

SET TEXTSIZE 25

The default setting for TEXTSIZE is 4096 (4K).

With a TEXTSIZE setting of 25, a SELECT statement that includes a text column displays only the first 25 characters of the data, as shown here:

SELECT pub_id, pr_info
FROM pub_info

pub_id pr_info
-------------------------------
0736   This is sample text data
0877   This is sample text data
1389   This is sample text data
1622   This is sample text data
1756   This is sample text data
9901   This is sample text data
9952   This is sample text data
9999   This is sample text data

(8 row(s) affected)

After trying this example, reset TEXTSIZE to its default value, using the following statement:

SET TEXTSIZE 0

The default display is the actual length of the data when its size is less than TEXTSIZE.

Note When you are selecting image data, the returned value includes the characters 0x, which indicate that the data is hexadecimal. These two characters are counted as part of TEXTSIZE.


Select List Examples

The select list can include * (all columns in the order in which the table was created), a list of column names in any order, character strings, column headings, and expressions, including arithmetic operators. Here are some sample select lists:

A.    SELECT titles.*
    FROM titles

B.    SELECT Name = au_fname, Surname = au_lname
    FROM authors

C.    SELECT Sales = ytd_sales, ToAuthor = (ytd_sales * royalty) / 100,
    ToPublisher = ytd_sales - (ytd_sales * royalty) / 100
    FROM titles

D.    SELECT 'Social security #', au_id
    FROM authors

E.    SELECT this_year = advance,
    next_year = advance  advance / 10,
    third_year = advance / 2, 'for book title #', title_id
    FROM titles

F.    SELECT 'Total income is', Revenue = price * ytd_sales,
    'for', Book# = title_id
    FROM titles

The select list can also include aggregate functions, which are discussed in Using Summary Queries and in Displaying Totals with GROUP BY or COMPUTE.


Eliminating Duplicates: DISTINCT

The DISTINCT keyword eliminates duplicate rows from the results of a SELECT statement. If you don't specify DISTINCT, you see all rows, including duplicates. For example, if you select all the author IDs in the titleauthor table without DISTINCT, you see the following rows:

SELECT au_id
FROM titleauthor

au_id
-----------
172-32-1176
213-46-8915
213-46-8915
238-95-7766
267-41-2394
267-41-2394
274-80-9391
409-56-7008
427-17-2319
472-27-2349
486-29-1786
486-29-1786
648-92-1872
672-71-3249
712-45-1867
722-51-5454
724-80-9391
724-80-9391
756-30-7391
807-91-6654
846-92-7186
899-46-2035
899-46-2035
998-72-3567
998-72-3567

(25 row(s) affected)

Notice that there are some duplicate listings. With DISTINCT, you can eliminate duplicates and see only the unique author IDs:

SELECT distinct au_id
FROM titleauthor

au_id
-----------
172-32-1176
213-46-8915
238-95-7766
267-41-2394
274-80-9391
409-56-7008
427-17-2319
472-27-2349
486-29-1786
648-92-1872
672-71-3249
712-45-1867
722-51-5454
724-80-9391
756-30-7391
807-91-6654
846-92-7186
899-46-2035
998-72-3567

(19 row(s) affected)

Important The output for statements involving DISTINCT depends on the sort order chosen during installation. For information about the effects of different sort orders, see Microsoft SQL Server Setup.

For the DISTINCT keyword, null values are considered to be duplicates of each other. When DISTINCT is included in a SELECT statement, only one NULL is returned in the results, no matter how many null values are encountered.

Note For compatibility with other implementations of SQL, the ALL keyword can explicitly ask for all rows. However, there is no need to use ALL because displaying all rows is the default.


Specifying Tables: The FROM Clause

The FROM clause is required in every SELECT statement involving data from tables or views. Use it to list the tables and views containing the columns included in the select list and in the WHERE clause. Separate multiple table or view names, with commas. The FROM clause uses this syntax:

SELECT select_list
FROM {table_name | viewname list} [(optimizer_hints)]

To simplify writing queries, you can give aliases to table names. Aliases are assigned in the FROM clause by specifying the alias after the table name. In the following example, the alias p is assigned to publishers:

SELECT p.pub_id, p.pub_name
FROM publishers p

Optional optimizer hints in the FROM clause allow you to customize locking for tables specified in the SELECT statement. For example, you can use the HOLDLOCK option to keep a shared lock in force until the completion of a transaction ¾ instead of releasing the lock as soon as the data is no longer needed. For details about the optimizer hints, see Optimizing Performance. Note that hints should be included inside parentheses so that they are not interpreted as an alias for a table.


Selecting Rows: The WHERE Clause

The WHERE clause in a SELECT statement specifies the criteria for which rows to retrieve. The WHERE clause has the following syntax:

SELECT select_list
FROM {table_name | viewname list} [(optimizer_hints)]
WHERE search_conditions

Search conditions, or qualifications, in the WHERE clause include:

  • Comparison operators (such as =, < >, <, and >)
    WHERE advance * 2 > ytd_sales * price
  • Ranges (BETWEEN and NOT BETWEEN)
    WHERE ytd_sales between 4095 and 12000
  • Lists (IN, NOT IN)
    WHERE state in ('CA', 'IN', 'MD')
  • Pattern matches (LIKE and NOT LIKE)
    WHERE phone not like '415%'

    Note The only WHERE conditions that you can use on text columns are LIKE and NOT LIKE or with certain string functions such as patindex().

  • Unknown values (IS NULL and IS NOT NULL)
    where advance is null
  • Combinations of these conditions (AND, OR)
    where advance < $5000 or (ytd_sales > 2000 and ytd_sales < 2500)

In addition, WHERE can introduce join conditions and subqueries. For more information, see Using Joins to Create Multitable Queries and Using Subqueries.

For a complete list of search conditions, see Search Conditions in the Microsoft SQL Server Transact-SQL Reference.


Comparison Operators

Transact-SQL uses the following comparison operators:

Operator | Meaning
= | Equal to
> | Greater than
< | Less than
>= | Greater than or equal to
<= | Less than or equal to
< > | Not equal to
!> | Not greater than
!< | Not less than

The operators have the following syntax:

WHERE expression comparison_operator expression

An expression is a constant, column name, function, subquery, or any combination of them connected by arithmetic or bitwise operators.

In comparing char and varchar data, < means earlier in the installed sort order and > means later. Installation options for case and accent sensitivity affect the comparisons. (For more information about sort orders, see Microsoft SQL Server Setup.) In comparing dates, < means earlier and > means later.

Trailing blanks are ignored in comparisons. For example, the following are equivalent.

'Dirk'
'Dirk '

When you use comparison operators, be sure to put single quotation marks around all char, varchar, text, datetime, and smalldatetime data.

The use of NOT negates an expression. The following query finds all business and psychology books that do not have an advance over $5500:

SELECT title_id, type, advance
FROM titles
WHERE (type = 'business' OR type = 'psychology')
    AND NOT advance > $5500

These are the results:

title_id

type

advance

--------

----------

--------

BU1032

business

5,000.00

BU1111

business

5,000.00

BU7832

business

5,000.00

PS2091

psychology

2,275.00

PS3333

psychology

2,000.00

PS7777

psychology

4,000.00

(6 rows affected)

Comparison Operator Examples

The following examples use SELECT statements with comparison operators:

A.    SELECT *
    FROM titleauthor
    WHERE royaltyper < 50

B.    SELECT authors.au_lname, authors.au_fname
    FROM authors
    WHERE au_lname > 'McBadden'

C.    SELECT au_id, phone
    FROM authors
    WHERE phone <> '415 658-9932'

D.    SELECT title_id, newprice = price * $1.15
    FROM pubs..titles
    WHERE advance > $5000

Important  The output for statements involving comparison operators depends on the sort order chosen during installation. For information about the effects of different sort orders, see Microsoft SQL Server Setup.


Ranges (BETWEEN and NOT BETWEEN)

The BETWEEN keyword specifies an inclusive range to search. For example, to find all books with sales between (and including) 4095 and 12,000, use this query:

SELECT title_id, ytd_sales

FROM titles

WHERE ytd_sales BETWEEN 4095 AND 12000

title_id

ytd_sales

--------

---------

BU1032

4095

BU7832

4095

PC1035

8780

PC8888

4095

TC7777

4095

(5 row(s) affected)

Notice that books with sales of 4095 are included in the results. If there were any books with sales of 12,000, they would also be included.

To specify an exclusive range, use the greater-than and less-than operators (> and <). The preceding query using the greater-than and less-than operators returns different results because these operators are not inclusive:

SELECT title_id, ytd_sales

FROM titles

WHERE ytd_sales > 4095 AND ytd_sales < 12000

title_id

ytd_sales

--------

---------

PC1035

8780

(1 row(s)  affected)

NOT BETWEEN finds all rows outside the range you specify. To find all books with sales outside the 4095 to 12,000 range:

SELECT title_id, ytd_sales

FROM titles

WHERE ytd_sales NOT BETWEEN 4095 AND 12000

title_id

ytd_sales

--------

---------

BU1111

3876

BU2075

18722

MC2222

2032

MC3021

22246

PS1372

375

PS2091

2045

PS2106

111

PS3333

4072

PS7777

3336

TC3218

375

TC4203

15096

(11 row(s) affected)

When you specify ranges, be sure to put single quotation marks around all char, varchar, text, datetime, and smalldatetime data.


Lists (IN and NOT IN)

The IN keyword allows you to select values that match any one of a list of values. For example, without IN, if you want a list of the names and states of all authors who live in California, Indiana, or Maryland, use this query:

SELECT au_lname, state
FROM authors
WHERE state = 'CA' OR state = 'IN' OR state = 'MD'

However, you get the same results with less typing if you use IN:

SELECT au_lname, state
FROM authors
WHERE state IN ('CA', 'IN', 'MD')

You get the same results from either query:

au_lname

state

--------

-----

White

CA

Green

CA

Carson

CA

O'Leary

CA

Straight

CA

Bennet

CA

Dull

CA

Gringlesby

CA

Locksley

CA

Yokomoto

CA

DeFrance

IN

Stringer

CA

MacFeather

CA

Karsen

CA

Panteley

MD

Hunter

CA

McBadden

CA

(17 row(s) affected)

The items following the IN keyword must be separated by commas and be enclosed in parentheses.

Perhaps the most important use for the IN keyword is in nested queries, also referred to as subqueries. (For a full discussion of subqueries, see Using Subqueries) The following example gives some idea of what you can do with nested queries and the IN keyword.

Suppose that you want to know the names of authors who receive less than 50 percent of the total royalties on the books they coauthor. The authors table gives author names and the titleauthor table gives royalty information. By putting the two together using IN, you can extract the information you need without listing the two tables in the same FROM clause.

The following query finds all au_ids in the titleauthor table for authors who make less than 50 percent of the royalty on any one book, and then selects from the authors table all author names with au_ids that match the results from the titleauthor query. The results show that several authors fall into the less than 50 percent category:

SELECT au_lname, au_fname
FROM authors
WHERE au_id IN
    (SELECT au_id
    FROM titleauthor
    WHERE royaltyper < 50)

au_lname

au_fname

-----------

--------

Green

Marjorie

O'Leary

Michael

Gringlesby

Burt

Yokomoto

Akiko

MacFeather

Stearns

Ringer

Anne

(6 row(s) affected)

NOT IN finds the authors who do not match the items in the values list. The following query finds the names of authors who do not make less than 50 percent of the royalties on at least one book:

SELECT au_lname, au_fname
FROM authors
WHERE au_id NOT IN
    (SELECT au_id
    FROM titleauthor
    WHERE royaltyper < 50)

au_lname

au_fname

-------------

--------

White

Johnson

Carson

Cheryl

Straight

Dean

Smith

Meander

Bennet

Abraham

Dull

Ann

Locksley

Charlene

Greene

Morningstar

Blotchet-Halls

Reginald

del Castillo

Innes

DeFrance

Michel

Stringer

Dirk

Karsen

Livia

Panteley

Sylvia

Hunter

Sheryl

McBadden

Heather

Ringer

Albert

(17 row(s) affected)

When you select values using the IN keyword, be sure to put single quotation marks around all char, varchar, text, datetime, and smalldatetime data.


Wildcards and the LIKE Clause

The LIKE keyword selects rows containing fields that match specified portions of character strings. LIKE is used with char, varchar, text, datetime, and smalldatetime data. It takes four wildcard characters, which are in the form of regular expressions:

Wildcard | Meaning
% | Any string of zero or more characters
_ | Any single character
[ ] | Any single character within the specified range (for example, [a-f]) or set (for example, [abcdef])
[^] | Any single character not within the specified range (for example, [^a - f]) or set (for example, [^abcdef])

When you use LIKE, be sure to enclose the wildcard(s) and the character string in single quotation marks. For example, using LIKE with the data in the authors table:

  • LIKE 'Mc%' searches for all names that begin with the letters "Mc" (McBadden).
  • LIKE '%inger' searches for all names that end with the letters "inger" (Ringer, Stringer).
  • LIKE '%en%' searches for all names that have the letters "en" (Bennet, Green, McBadden).
  • LIKE '_heryl' searches for all six-letter names ending with the letters "heryl" (Cheryl, Sheryl).
  • LIKE '[CK]ars[eo]n' searches for Carsen, Karsen, Carson, and Karson (Carson).
  • LIKE '[M-Z]inger' searches for all names ending with the letters "inger" that begin with any single letter from M to Z (Ringer).
  • LIKE 'M[^c]%' searches for all names beginning with the letter M that don't have the letter c as the second letter (MacFeather).

This query finds all phone numbers in the authors table that have area code 415:

SELECT phone
FROM authors
WHERE phone LIKE '415%'

You can use NOT LIKE with the same wildcards. To find all phone numbers in the authors table that have area codes other than 415, use either of these equivalent queries:

SELECT phone
FROM authors
WHERE phone NOT LIKE '415%'

SELECT phone
FROM authors
WHERE not phone LIKE '415%'

Important The output for statements involving the LIKE keyword depends on the sort order chosen during installation. For information about the effects of different sort orders, see Microsoft SQL Server Setup.

The only WHERE conditions that you can use on text columns are LIKE, IS NULL, or patindex.

Wildcards used without LIKE are interpreted as literals rather than as a pattern ¾ that is, they represent only their own values. The following query attempts to find any phone numbers that consist of the four characters 415% only. It will not find phone numbers that start with 415.

SELECT phone
FROM authors
WHERE phone = '415%'

Another important consideration in using wildcards is their effect on performance. If a wildcard begins the expression, an index cannot be used. (Just as you wouldn't know where to start in a phone book if given the name '%mith', not 'Smith'. You'd have to search the whole book!) A wildcard in or at the end of an expression does not preclude use of an index (just as in a phone book, you'd know where to search if the name was 'Samuel%', regardless of whether the names Samuels and Samuelson are both there).

You can search for the wildcard characters themselves. To use wildcards as characters in a LIKE match string rather than as wildcards, use square brackets ([ ]) to enclose %, _, and [. Use ] by itself. To search for a dash (-), rather than using it to specify a search range, use the dash as the first character inside a set of brackets.

Symbol | Meaning
LIKE '5%' | 5 followed by any string of 0 or more characters
LIKE '5[%]' | 5%
LIKE '_n' | an, in, on (and so on)
LIKE '[_]n' | _n
LIKE '[a-cdf]' | a, b, c, d, or f
LIKE '[-acdf]' | -, a, c, d, or f
LIKE '[ [ ]' | [
LIKE ']' | ]

Trailing blanks following the % wildcard in a LIKE clause are truncated to a single trailing blank. LIKE '% ', which includes two trailing blanks, matches any string containing one or more trailing blanks.

Sometimes you might want trailing blanks and trailing underscores (_) to be ignored with the LIKE pattern. To enable this functionality with LIKE, turn on trace flag 204 (at server startup, use the -T204 option), or individual users can enable this functionality by using DBCC TRACEON (204).


Unknown Values: IS NULL and IS NOT NULL

When you see NULL in a column, it means that the user or application has made no entry in that column. A data value for the column is unknown or not available.

NULL is not synonymous with zero (a numerical value) or blank (a character value). Rather, null values allow you to distinguish between a deliberate entry of zero (for numeric columns) or blank (for character columns) and a non-entry (NULL for both numeric and character columns).

NULL can be entered in a column for which null values are permitted (as specified in the CREATE TABLE statement) in three ways:

  • If no data is entered and there is no default or DEFAULT constraint on the column or datatype, SQL Server automatically enters the value NULL.
  • The user can explicitly enter the value NULL. Type NULL without quotation marks. If the word NULL is typed into a character column with quotation marks, it is treated as data, not as a null value.
  • A datatype that is a number and allows NULLs will contain NULL if the value specified causes an arithmetic overflow, unless SET ARITHABORT ON is in effect.

When null values are retrieved, the query results show the word NULL in the appropriate position. For example, the advance column of the titles table allows null values. By inspecting the data in that column, you can tell whether a book had no advance payment (zero in the advance column, as in the row for MC2222) or whether the advance amount was not known when the data was entered (NULL in the advance column, as in the row for MC3026):

SELECT title_id, type, advance

FROM titles

WHERE pub_id = '0877'

title_id

type

advance

--------

----------

-----------

MC2222

mod_cook

0.00

MC3021

mod_cook

15,000.00

MC3026

UNDECIDED

(null)

PS1372

psychology

7,000.00

TC3218

trad_cook

7,000.00

TC4203

trad_cook

4,000.00

TC7777

trad_cook

8,000.00

(7 row(s) affected)

When you compare a null value with another value, the result is never true; a null value does not match anything, not even another null value. So, for example, the following expression is false and will not return results:

ytd_sales > NULL

Null values do not match each other because there is no reason to assume that two unknown values are the same. Null values never join, not even to other null values. (For information about joining tables with null values, see Using Joins to Create Multitable Queries).

Null values are considered to be equal only for the purposes of the ORDER BY, GROUP BY, and DISTINCT keywords. Also, a unique index or UNIQUE constraint that allows NULL may contain only one row containing NULL. A subsequent row with NULL will be rejected. A primary key may not have NULL in any column that is part of the key.

Computations involving NULL evaluate to NULL because the result must be unknown if any of the factors is unknown. For example, column1  1 evaluates to NULL if column1 is NULL.

When the columns being searched include ones defined as allowing null values, you can find null or non-null values in the database with this pattern:

WHERE column_name IS [NOT] NULL

If you try to find null or non-null values in columns defined as NOT NULL, SQL Server displays an error message.

Some of the rows in the titles table contain incomplete data. For example, a book called The Psychology of Computer Cooking has been proposed and its title, title identification number, and probable publisher entered. However, since the author has no contract yet and details are undecided, null values appear in the price, advance, royalty, ytd_sales, and notes columns. Because null values don't match anything in a comparison, a query for all the title identification numbers and advances for books with moderate advances (under $5000) will not find the row for The Psychology of Computer Cooking, title_id MC3026.

SELECT title_id, advance
FROM titles
WHERE advance < $5000

title_id

advance

--------

-------------

MC2222

0.00

PS2091

2,275.00

PS3333

2,000.00

PS7777

4,000.00

TC4203

4,000.00

(5 row(s) affected)

To include books with an advance under $5000 or a null value in the advance column, use this query:

SELECT title_id, advance
FROM titles
WHERE advance < $5000
OR advance IS NULL

title_id

advance

--------

-----------

MC2222

0.00

MC3026

(null)

PC9999

(null)

PS2091

2,275.00

PS3333

2,000.00

PS7777

4,000.00

TC4203

4,000.00

(7 row(s) affected)


Logical Operators

The logical operators are AND, OR, and NOT. The logical operators AND and OR are used to connect search conditions in WHERE clauses.

AND joins two or more conditions and returns results only when all the conditions are true. For example, the following query finds only the rows in which the author's last name is Ringer and the author's first name is Anne. It will not find the row for Albert Ringer.

SELECT *
FROM authors
WHERE au_lname = 'Ringer' AND au_fname = 'Anne'

OR also connects two or more conditions, but it returns results when any of the conditions is true. The following query searches for rows containing Anne or Ann in the au_ fname column:

SELECT *
FROM authors
WHERE au_fname = 'Anne' OR au_fname = 'Ann'


Logical Operator Precedence

When more than one logical operator is used in a statement, NOT is evaluated first, then AND, and finally OR. Arithmetic (and bitwise) operators are handled before logical operators.

For example, the following query finds all business books in the titles table, no matter what their advances are, as well as all psychology books that have an advance greater than $5500:

SELECT title_id, type, advance
FROM titles
WHERE type = 'business' OR type = 'psychology'
    AND advance > $5500

title_id type         advance
-------- ------------ --------------------------
BU1032   business     5,000.00
BU1111   business     5,000.00
BU2075   business     10,125.00
BU7832   business     5,000.00
PS1372   psychology   7,000.00
PS2106   psychology   6,000.00

(6 row(s) affected)

In this example, the advance condition pertains to psychology books and not to business books because AND has precedence over OR.

You can change the meaning of the query by adding parentheses to force evaluation of the OR first. This query finds all business and psychology books that have advances over $5500:

SELECT title_id, type, advance
FROM titles
WHERE (type = 'business' OR type = 'psychology')
    AND advance > $5500

title_id     type                       advance
------------ -------------------------- -----------
business     6,281.25                   30788
mod_cook     7,500.00                   24278
popular_comp 7,500.00                   12875
psychology   4,255.00                   9939
trad_cook    6,333.33                   19566
UNDECIDED    (null)                     (null)

(6 row(s) affected)

The use of parentheses, even when not required, can improve readability of queries and reduce the chance of making a subtle mistake because of operator precedence. There is no significant performance penalty in using parentheses.

For more information, see Search Conditions in the Microsoft SQL Server Transact-SQL Reference.


Creating a New Table for Results: SELECT INTO

The SELECT INTO clause creates a new table based on the columns specified in the select list and on the rows chosen in the WHERE clause.

The SELECT INTO clause makes a permanent table only if the select into/bulkcopy database option is set. To see whether this option is set, execute the sp_helpdb system procedure. In this example, execute sp_helpdb against the pubs database:

sp_helpdb pubs

If the select into/bulkcopy option is not set, the report from sp_helpdb indicates this. Only the system administrator or the database owner can set database options.

If the select into/bulkcopy database option is set, you can use the SELECT INTO clause to create a new permanent table (without using a CREATE TABLE statement). If select into/bulkcopy is not set, SELECT INTO can be used to create only temporary tables. (The examples in this chapter assume that select into/bulkcopy is set.)

Caution Because SELECT INTO is not logged, use DUMP DATABASE to back up your database following a SELECT INTO operation. Do not use DUMP TRANSACTION because after a non-logged operation you cannot restore the log with LOAD TRANSACTION.

The new table is based on the columns you specify in the select list, the table(s) you name in the FROM clause, and the rows you choose in the WHERE clause. The name of the new table must be unique in the database and must conform to the rules for identifiers.

A SELECT INTO statement allows you to define a table and put data into it (based on existing definitions and data) without going through the usual data definition process.

The following example shows a SELECT INTO statement and its results. A table called newtable is created, using two of the columns in the four-column table publishers. Because this particular statement includes no WHERE clause, data from all rows (but only two columns, pub_id and pub_name) of publishers is copied into newtable:

SELECT pub_id, pub_name
INTO newtable
FROM publishers

Note You cannot run SELECT INTO in the pubs database, so you cannot run these examples.

The new table contains the results of the SELECT statement. It becomes part of the database, just like its parent table.

The SELECT INTO clause is useful for creating test tables and copies of existing tables, and for making several smaller tables out of one large table. You can also use SELECT INTO to create a skeleton table with no data by putting a false condition in the WHERE clause. For example:

SELECT *
INTO newtable2
FROM publishers
WHERE 1 = 2

SELECT *
FROM newtable2

pub_id

pub_name

city

state

------

--------

----

-----

Although newtable2 is created, no rows are inserted into it because 1 never equals 2.


Sorting Query Results: ORDER BY

The ORDER BY clause sorts query results by one or more columns (up to 16 columns). A sort can be ascending (ASC) or descending (DESC). If neither is specified, ASC is assumed.

Important The exact results of an ORDER BY clause depend on the sort order chosen during installation. For information about the effects of different sort orders, see Microsoft SQL Server Setup.

The following query returns results ordered by pub_id:

SELECT pub_id, type, title_id
FROM titles
ORDER BY pub_id

pub_id

type

title_id

------

------------

--------

0736

business

BU2075

0736

psychology

PS2091

0736

psychology

PS2106

0736

psychology

PS3333

0736

psychology

PS7777

0877

mod_cook

MC2222

0877

mod_cook

MC3021

0877

psychology

PS1372

0877

trad_cook

TC3218

0877

trad_cook

TC4203

0877

trad_cook

TC7777

0877

UNDECIDED

MC3026

1389

business

BU1032

1389

business

BU1111

1389

business

BU7832

1389

popular_comp

PC1035

1389

popular_comp

PC8888

1389

popular_comp

PC9999

(18 row(s) affected)

If more than one column is named in the ORDER BY clause, sorts are nested. The following statement sorts the rows in the titles table, first by publisher in descending order, and then by type in ascending order within each publisher, and finally by price (also ascending, because DESC is not specified). Null values are sorted first within any group:

SELECT pub_id, type, title_id, price
FROM titles
ORDER BY pub_id desc, type, price

The number of the position of a column in a select list can be used instead of the column name. You can mix column names and select list numbers. Both of the following statements produce the same results as the preceding one:

SELECT pub_id, type, title_id
FROM titles
ORDER BY 1 DESC, 2, 3

SELECT pub_id, type, title_id
FROM titles
ORDER BY 1 DESC, type, 3

Note  You cannot use ORDER BY on columns that have the text or image datatypes. Also, subqueries, aggregates, and constant expressions are not allowed in the ORDER BY list; however, you can use the ordinal position in the select list (for example, ORDER BY 2) for aggregates or expressions. For example:

SELECT type, sum (ytd_sales)
FROM titles
GROUP BY type
ORDER BY 2


Generating Summary Rows: COMPUTE BY

Use COMPUTE BY with row aggregate functions to produce reports that summarize values whenever the value in a specified column changes. Such reports (usually produced by a report generator) are called control-break reports, since summary values appear in the report under the control of the groupings, or breaks, you specify in the COMPUTE BY clause.

These summary values appear as additional rows in the query results, unlike the aggregate function results of a GROUP BY clause, which appear as new columns.

A COMPUTE BY clause allows you to see both detail and summary rows with one SELECT statement. You can calculate summary values for subgroups, and you can calculate more than one row aggregate function for the same group.

The COMPUTE BY clause has the following syntax:

COMPUTE row_aggregate(column_name)
[, row_aggregate(column_name)...]
[BY column_name [, column_name]...]

You can use the aggregate functions SUM, AVG, MIN, MAX, and COUNT with COMPUTE BY. SUM and AVG are used with numeric columns only.

Note You cannot use COMPUTE BY with text or image columns.

This query uses GROUP BY and aggregate functions:

SELECT type, SUM(price), SUM(advance)

FROM titles

GROUP BY type

This query uses COMPUTE BY and row aggregate functions:

SELECT type, price, advance
FROM titles
ORDER BY type
COMPUTE SUM(price), SUM(advance) BY type

type         price                      advance
------------ -------------------------- --------------------------
business     2.99                       10,125.00
business     11.95                      5,000.00
business     19.99                      5,000.00
business     19.99                      5,000.00

             sum
             ==========================
             54.92
                                        sum
                                        ==========================
                                        25,125.00

type         price                      advance
------------ -------------------------- --------------------------
mod_cook     2.99                       15,000.00
mod_cook     19.99                      0.00

             sum
             ==========================
             22.98
                                        sum
                                        ==========================
                                        15,000.00

type         price                      advance
------------ -------------------------- --------------------------
popular_comp (null)                     (null)
popular_comp 20.00                      8,000.00
popular_comp 22.95                      7,000.00

             sum
             ==========================
             42.95
                                        sum
                                        ==========================
                                        15,000.00

type         price                      advance
------------ -------------------------- --------------------------
psychology   7.00                       6,000.00
psychology   7.99                       4,000.00
psychology   10.95                      2,275.00
psychology   19.99                      2,000.00
psychology   21.59                      7,000.00

             sum
             ==========================
             67.52
                                        sum
                                        ==========================
                                        21,275.00

type         price                      advance
------------ -------------------------- --------------------------
trad_cook    11.95                      4,000.00
trad_cook    14.99                      8,000.00
trad_cook    20.95                      7,000.00

             sum
             ==========================
             47.89
                                        sum
                                        ==========================
                                        19,000.00

type         price                      advance
------------ -------------------------- --------------------------
UNDECIDED    (null)                     (null)

             sum
             ==========================
             (null)
                                        sum
                                        ==========================
                                        (null)

(24 row(s) affected)

The summary values are treated as new rows, which is why the SQL Server message says "24 rows affected". (For a complete explanation, rules, and more examples of the COMPUTE clause, see Displaying Totals with GROUP BY or COMPUTE.)


The UNION Operator

The UNION operator allows you to manipulate the results of two or more queries by combining the results of each query into a single results set. The syntax is as follows:

Query1
[UNION [ALL] QueryN ] ...
[ORDER BY clause]
[COMPUTE clause]

where Query1 is:

SELECT select_list
[INTO clause]
[FROM clause]
[WHERE clause]
[GROUP BY clause]
[HAVING clause]

and QueryN is:

SELECT select_list
[FROM clause]
[WHERE clause]
[GROUP BY clause]
[HAVING clause]

For example, suppose that you have the following tables:

table1

table2

a

b

c

d

char(4)

int

char(4)

int

-------

---

-------

---

abc

1

ghi

3

def

2

jkl

4

ghi

3

mno

5

The following query creates a UNION between the two tables:

SELECT * FROM table1
UNION
SELECT * FROM table2

This is the results set:

a

b

-------

---

abc

1

def

2

ghi

3

jkl

4

mno

5

Notice that, by default, the UNION operator removes duplicate rows from the results set. If you use the ALL option, all rows are included in the results and duplicates are not removed. Notice also that the columns in the results set have the same names as the columns in table1.

Important  The exact results of a UNION operation depend on the sort order chosen during installation. For information about the effects of different sort orders, see Microsoft SQL Server Setup.

Any number of UNION operators can appear in a Transact-SQL statement. For example:

x UNION y UNION z

By default, SQL Server evaluates a statement containing UNION operators from left to right. You can use parentheses to specify the order of evaluation. For example, the following expressions are not equivalent:

x UNION ALL (y UNION z)

(x UNION ALL y) UNION z

In the first expression, duplicates are eliminated in the union between y and z. Then, in the union between that set and x, duplicates are not eliminated. In the second expression, duplicates are included in the union between x and y but are then eliminated in the subsequent union with z. ALL has no effect on the final result of this statement.


Guidelines for Building UNION Statements

Follow these guidelines when building UNION statements:

  • All select lists in the UNION statement must have the same number of expressions (column names, arithmetic expressions, aggregate functions, and so on). The following statement is not valid because the first select list is longer than the second:
    SELECT stor_id, date, title_id FROM sales
UNION
SELECT stor_id, title_id FROM sales_east

    Note Because pubs does not actually contain a stores_east table, you cannot run the examples containing stores_east.

  • Corresponding columns in all tables, or any subset of columns used in the individual queries, must be of the same datatype, an implicit data conversion must be possible between the two datatypes, or an explicit conversion must be supplied. For example, UNION is not possible between a column of char datatype and one of int datatype unless an explicit conversion is supplied. However, a UNION is possible between a column of money datatype and one of int datatype. For details about comparing datatypes in a UNION statement, see UNION Operator in the Microsoft SQL Server Transact-SQL Reference.
  • Corresponding columns in the individual queries of a UNION statement must occur in the same order, because UNION compares the columns one to one in the order given in the individual queries. For example, suppose that you have the following tables:
table3

table4

a

b

c

a

b

int

char(4)

char(4)

char(4)

float

---

-------

-------

-------

-------

1

abc

jkl

jkl

1.000

2

def

mno

mno

5.000

3

ghi

pqr

The following query:

SELECT a, b FROM table3
UNION
SELECT b, a FROM table4

produces this results set:

a          b
--------   -----
1.000000   abc
2.000000   def
3.000000   ghi
1.000000   jkl
5.000000   mno

  •
When different datatypes are combined in a UNION statement, they are converted to the datatype with the most precision. In the preceding example, the int values are converted to float.

The following query produces an error message because the datatypes of corresponding columns are not compatible:

    SELECT b, c FROM table3
UNION
SELECT a, b FROM table4

    •

  •
The column names in the table resulting from UNION are taken from the first individual query in the UNION statement. Therefore, if you want to define a new column heading for the results set, you must do it in the first query. If you want to refer to a column in the results set by a new name (for example, in an ORDER BY statement), it must be referred to that way in the first SELECT statement, as shown in this example:
    SELECT Cities = city FROM stores
UNION
SELECT city FROM stores_east
ORDER BY Cities

    •


Using UNION with Other Transact-SQL Statements

Follow these guidelines when using UNION with other Transact-SQL statements:

  • The first query in the UNION statement can contain an INTO clause that creates a table to hold the final results set.

    The INTO clause can be used only in the first query; if it appears anywhere else, you get an error message. Also, remember that if the select into/bulkcopy option is not set, SELECT INTO can be used only to create temporary tables.

  • ORDER BY and COMPUTE clauses to define the order of the final results or to compute summary values are allowed only at the end of the UNION statement. They cannot be used within the individual queries that make up the UNION statement.
  • GROUP BY and HAVING clauses can be used within individual queries only; they cannot be used to affect the final results set.
  • The UNION operator can also be used within an INSERT statement.
  • The UNION operator cannot be used within a CREATE VIEW statement.
  • The FOR BROWSE clause cannot be used in statements involving the UNION operator.


Using Joins to Create Multitable Queries

Join operations enable you to retrieve data from two or more tables or views in the same database or in different databases in a single operation.

This section shows how to formulate several varieties of joins, including equijoins and outer joins. For details on subqueries (queries nested within other queries), which also can involve two or more tables, see Using Subqueries.


The Join Operation

Joining two or more tables is the process of comparing the data in specified columns and using the comparison results to form a new table from the rows that qualify. A join statement:

  • Specifies a column from each table.
  • Compares the values in those columns row by row.
  • Combines rows with qualifying values into new rows.

Although the comparison is usually for equality ¾ values that match exactly ¾ other types of joins can also be specified. This join example finds the names of authors and publishers located in the same city:

SELECT au_fname, au_lname, pub_name
FROM authors, publishers
WHERE authors.city = publishers.city

au_fname

au_lname

pub_name

--------

-------

--------------------

Cheryl

Carson

Algodata Infosystems

Abraham

Bennet

Algodata Infosystems

(2 row(s) affected)

Since the query draws on information contained in two separate tables, publishers and authors, a join is required to retrieve the requested information.


The Select List in Joins

A join statement, like other selection statements, starts with the keyword SELECT. The columns named after the SELECT keyword are the columns to be included in the query results, in their desired order.

In the example, the columns au_ fname, au_lname, and pub_name were not qualified by a table name since there is no ambiguity about the table to which they belong. But the city column used for the join comparison was qualified since there are columns of that name in both the publishers and authors tables. Even though neither of the city columns is printed in the results, SQL Server needs the table name to perform the comparison.

As in other SELECT statements, you can use * to specify that all columns of the tables involved in the query are to be included in the results. For example, to include all columns in publishers and authors in the preceding join query, use this SQL statement:

SELECT *
FROM authors, publishers
WHERE authors.city = publishers.city

au_id

au_lname

au_fname

phone

address

city

state

---------

--------

--------

-------

-------

--------

-----

238-95-7766

Carson

Cheryl

415 548-7723
589 Darwin Ln.

Berkeley

CA

409-56-7008

Bennet

Abraham

415 658-9932

6223 Bateman St.

Berkeley

CA

zip

contract

pub_id

pub_name

city

state

country

-----

--------

------

--------

--------

-----

-------

94705

1

1389

Algodata Infosystems

Berkeley

CA

USA

94705

1

1389

Algodata Infosystems

Berkeley

CA

USA

(2 row(s) affected)

The display shows two rows with 14 columns each. Because of the length of the rows, each takes up multiple horizontal lines in the output.

The select list (and the results) of a join need not include columns from both of the tables being joined. For example, to find the names of the authors who live in the same city as one of the publishers, your select list need not include any columns from publishers:

SELECT au_lname, au_fname
FROM authors, publishers
WHERE authors.city = publishers.city


The FROM Clause in Joins

The FROM clause of a join statement names all the tables (or views) involved in the join. FROM is the clause that actually indicates to SQL Server that a join is desired. The order in which the tables (or views) are listed in the FROM clause affects the results display only when you use * in the select list.

Although this chapter uses only tables in its examples, views can be joined in exactly the same way as tables. Table or view names can be qualified by the names of the owner and database and can be given alias names for convenience. You can specify more than two tables or views in the FROM clause. (For details, see Joining More Than Two Tables.)


The WHERE Clause in Joins

The WHERE clause specifies the connection between the tables or views named in the FROM clause and restricts the rows to be included in the results. It gives the names of the columns to be joined (qualified by table names if necessary) and the join operator, such as equality.

Important If you omit the WHERE clause in a join, you will get unexpected results. Without a WHERE clause, any of the join queries discussed so far produce 184 rows instead of 2! This situation is explained in How Joins Are Processed.

Use the following comparison operators to determine the basis on which columns will be matched:

Symbol | Meaning
= | Equal to
> | Greater than
> = | Greater than or equal to
< | Less than
< = | Less than or equal to
< > | Not equal to
! > | Not greater than
! < | Not less than

Joins that use the relational operators are collectively called theta joins. Another set of join operators is used for outer joins (discussed in detail later in this chapter). The outer join operators are *=, which includes in the results all the rows from the first table, not just the ones in which the joined columns match, and =*, which includes in the results all the rows from the second table, not just the ones in which the joined columns match.

Columns being joined need not have the same name or be the same datatype. However, if the datatypes are not identical, they must be compatible ¾ types that SQL Server automatically converts. (For details about datatype conversion, see Using Built-in Functions.)

The WHERE clause of a join statement can include other conditions in addition to the one that links columns from different tables.

Note Tables cannot be joined on text or image columns. You can, however, compare the lengths of text columns from two tables with a WHERE clause. For example:

WHERE DATALENGTH(textab_1.textcol) > DATALENGTH(texttab_2.textcol)


Joins and the Relational Model

The join operation is the hallmark of the relational model of database management. More than any other feature, the join distinguishes relational database management systems from other types.

In structured database management systems (often known as network or hierarchical systems), relationships between data are predefined. Once a database has been set up, it is difficult to make queries about unanticipated relationships among the data.

On the other hand, in a relational database management system, relationships among data are left unstated in the definition of a database. They become explicit when the data is manipulated ¾ when you query the database, not when you create it. You can ask any question that comes to mind about the data stored in the database, regardless of what was intended when the database was set up.

According to the rules of good database design (called normalization rules), each table should describe one type of entity ¾ a person, place, event, or thing. When you want to present or extract information about two or more types of entities, you use the join operation.

Joins give you unlimited flexibility in adding new types of data to your database. You can always create a new table that contains data about a different type of entity. If the new table has a column with values similar to those in some column of an existing table or tables, it can be linked to those other tables by joining.


How Joins Are Processed

Knowing how joins are processed will help you to understand them and to figure out why incorrectly stated joins can give unexpected results. This section explains conceptually how joins are processed; the actual SQL Server procedure is more sophisticated.

The first step in processing a join is to form the Cartesian product of the tables, all the possible combinations of the rows from each of the tables. The number of rows in a Cartesian product of two tables is equal to the number of rows in the first table times the number of rows in the second table.

The Cartesian product of the authors table and the publishers table is 184 (23*8) (23 authors multiplied by 8 publishers). You can see the Cartesian product with any query that includes columns from more than one table in the select list, more than one table in the FROM clause, and no WHERE clause. For example, if you omit the WHERE clause from the join of the authors and publishers tables, SQL Server combines each of the 23 authors with each of the 8 publishers and returns all 184 rows. But this Cartesian product usually does not contain any particularly useful information (unless you are explicitly looking to see every possible combination). In fact, it is misleading, since it seems to imply that every author in the database has a relationship with every publisher in the database ¾ which is not true.

That's why a join must include a WHERE clause, which specifies the columns to be matched and the basis on which to match them. (It can also include other restrictions.) Once the Cartesian product has been formed, the rows that do not satisfy the join are eliminated, using the conditions in the WHERE clause. For example, the WHERE clause, WHERE authors.city = publishers.city, eliminates from the results all rows in which the author's city is not the same as the publisher's city.


Equijoins and Natural Joins

An equijoin is a join in which the values in the columns being joined are compared for equality, and all columns in the tables being joined are included in the results.

The following query is an example of an equijoin:

SELECT *
FROM authors, publishers
WHERE authors.city = publishers.city

In the results of this statement, the city column appears twice. Since there's usually no point in repeating the same information, one of these two identical columns can be eliminated by restating the query. The result is called a natural join. You can restate the preceding query to form a natural join, as follows:

SELECT publishers.pub_id, publishers.pub_name,
    publishers.state, authors.*
FROM publishers, authors
WHERE publishers.city = authors.city

In this example, publishers.city does not appear in the results.


Joins with Additional Conditions

The WHERE clause of a join query can include additional selection criteria as well as specifying the join condition. For example, to retrieve the names and publishers of all books for which advances greater than $7500 were paid, the statement is:

SELECT title, pub_name, advance
FROM titles, publishers
WHERE titles.pub_id = publishers.pub_id
AND advance > $7500

title
pub_name

advance

-------------------------------

--------------------

----------

You Can Combat Computer Stress!

New Moon Books

10,125.00

The Gourmet Microwave

Binnet & Hardley

15,000.00

Secrets of Silicon Valley

Algodata Infosystems

8,000.00

Sushi, Anyone?

Binnet & Hardley

8,000.00

(4 row(s) affected)

Notice that the columns being joined ( pub_id) need not appear in the select list (and thus do not appear in the results).

As many selection criteria as wanted can be included in a join statement. The order of the selection criteria and the join condition is not important.


Joins Not Based on Equality

You can join values in two columns that are not equal. The following comparison operators can be used:

Symbol | Meaning
> | Greater than
> = | Greater than or equal to
< | Less than
< = | Less than or equal to
< > | Not equal to
!> | Not greater than
!< | Not lesser than

This example of a greater-than (>) join finds New Moon authors who live in states that come alphabetically after Massachusetts, where New Moon Books is located:

SELECT pub_name, publishers.state, au_lname, au_fname, authors.state
FROM publishers, authors
WHERE authors.state > publishers.state
    AND pub_name = 'New Moon Books'

pub_name

state

au_lname

au_fname

state

--------------

-----

--------------

-----------

-----

New Moon Books

MA

Greene

Morningstar
TN

New Moon Books

MA

Blotchet-Halls

Reginald

OR

New Moon Books

MA

del Castillo

Innes

MI

New Moon Books

MA

Panteley

Sylvia

MD

New Moon Books

MA

Ringer

Anne

UT

New Moon Books

MA

Ringer

Albert

UT

(6 row(s) affected)

The following example uses a greater-than-or-equal-to join (>=) and a less-than join (<) to print the royalty columns from the titles and roysched tables:

SELECT t.title_id, t.ytd_sales, r.royalty, t.royalty
FROM titles t, roysched r
WHERE t.title_id = r.title_id
AND t.ytd_sales >= r.lorange AND t.ytd_sales < r.hirange

title_id ytd_sales   royalty     royalty
-------- ----------- ----------- -----------
BU1032   15          10          10
MC3021   40          10          24
PS2091   30          10          12

(3 row(s) affected)


Self-Joins and Aliases

You compare values within a column of a table with a self-join. For example, you can use a self-join to find out which authors in Oakland, California live in the same zip code area.

Since this query involves a join of the authors table with itself, the authors table appears in two roles. To distinguish these roles, you can temporarily (and arbitrarily) give the authors table two different aliases ¾ au1 and au2 ¾ in the FROM clause. These aliases are used to qualify the column names in the rest of the query. The self-join statement looks like this:

SELECT au1.au_fname, au1.au_lname, au2.au_fname, au2.au_lname
FROM authors au1, authors au2
WHERE au1.city = 'Oakland'
    AND au1.state = 'CA'
    AND au1.zip = au2.zip

au_fname

au_lname

au_fname

au_lname

--------

--------

--------

--------

Marjorie

Green

Marjorie

Green

Dean

Straight

Dean

Straight

Dean

Straight

Dirk

Stringer

Dean

Straight

Livia

Karsen

Dirk

Stringer

Dean

Straight

Dirk

Stringer

Dirk

Stringer

Dirk

Stringer

Livia

Karsen

Stearns

MacFeather

Stearns

MacFeather

Livia

Karsen

Dean

Straight

Livia

Karsen

Dirk

Stringer

Livia

Karsen

Livia

Karsen

(11 row(s) affected)

To eliminate the rows in the results where the authors match themselves and to eliminate rows that are identical except that the order of the authors is reversed, make this change to the self-join query:

SELECT au1.au_fname, au1.au_lname, au2.au_fname, au2.au_lname
FROM authors au1, authors au2
WHERE au1.city = 'Oakland'
    AND au1.state = 'CA'
    AND au1.zip = au2.zip
    AND au1.au_id < au2.au_id

au_fname

au_lname

au_fname

au_lname

---------

--------

--------

--------

Dean

Straight

Dirk

Stringer

Dean

Straight

Livia

Karsen

Dirk

Stringer

Livia

Karsen

(3 row(s) affected)

It is now clear that Dean Straight, Dirk Stringer, and Livia Karsen all have the same zip code.


The Not-Equal Join

The not-equal join (< >) is rarely used. As a general rule, not-equal joins make sense only when used with a self-join. For example, this not-equal join and self-join are used to find the categories with two or more inexpensive (less than $15) books of different prices:

SELECT DISTINCT t1.type, t1.price
FROM titles t1, titles t2
WHERE t1.price < $15 AND t2.price < $15
    AND t1.type = t2.type
    AND t1.price <> t2.price

Note The expression NOT column_name = column_name is equivalent to column_name < > column_name.

The following example uses a not-equal join combined with a self-join to find all rows in the titleauthor table where two or more rows have the same title_id but different au_id numbers (that is, books with more than one author).

SELECT DISTINCT t1.au_id, t1.title_id
FROM titleauthor t1, titleauthor t2
WHERE t1.title_id = t2.title_id
    AND t1.au_id <> t2.au_id

au_id                title_id
-----------            --------
213-46-8915            BU1032
267-41-2394            BU1111
267-41-2394            TC7777
409-56-7008            BU1032
427-17-2319            PC8888
472-27-2349            TC7777
672-71-3249            TC7777
722-51-5454            MC3021
724-80-9391            BU1111
724-80-9391            PS1372
756-30-7391            PS1372
846-92-7186            PC8888
899-46-2035            MC3021
899-46-2035            PS2091
998-72-3567            PS2091

(15 row(s) affected)


Joining More Than Two Tables

The titleauthor table of the pubs database offers a good example of a situation in which joining more than two tables is helpful. The following query finds the titles of all books of a particular type and the names of their authors:

SELECT au_lname, au_fname, title
FROM authors, titles, titleauthor
WHERE authors.au_id = titleauthor.au_id
    AND titles.title_id = titleauthor.title_id
    AND titles.type = 'trad_cook'

au_lname

au_fname

title

--------------

---------

-----------------------------------

Panteley

Sylvia

Onions, Leeks, and Garlic: Cooking
Secrets of the Mediterranean

Blotchet-Halls

Reginald

Fifty Years in Buckingham Palace
Kitchens

O'Leary

Michael

Sushi, Anyone?

Gringlesby

Burt

Sushi, Anyone?

Yokomoto

Akiko

Sushi, Anyone?

(5 row(s) affected)

Notice that one of the tables in the FROM clause, titleauthor, does not contribute any columns to the results. Nor do the columns that are joined, au_id and title_id, appear in the results. Nonetheless, this join is possible only by using titleauthor as an intermediate table.

You can also join two or more pairs of columns in the same statement. For example, here's how to find the authors who live in the same city and state as a publisher:

SELECT au_fname, au_lname, pub_name
FROM authors, publishers
WHERE authors.city = publishers.city
    AND authors.state = publishers.state

au_fname

au_lname

pub_name

--------

--------

--------------------

Cheryl

Carson

Algodata Infosystems

Abraham

Bennet

Algodata Infosystems

(2 row(s) affected)

When there is more than one join operator in the same statement, either to join more than two tables or to join more than two pairs of columns, the join expressions can be connected with AND or with OR.


Outer Joins

In the joins discussed so far, only matching rows (rows with values in the specified columns that satisfy the join condition) are included in the results. In a sense, these join operations eliminate the information contained in the rows that do not match.

However, it is sometimes desirable to retain the nonmatching information by including nonmatching rows in the results of a join. To do this, you can use an outer join. Transact-SQL provides two outer join operators: *=, which includes all rows from the first-named table, and =*, which includes all rows from the second-named table.

Consider a join of the authors table and the publishers table on their city columns. The results show only the authors who live in cities where a publisher is located (in this case, Abraham Bennet and Cheryl Carson).

To include all authors in the results, regardless of whether a publisher is located in the same city, use an outer join. Here's what the query and results of the outer join look like:

SELECT au_fname, au_lname, pub_name
FROM authors, publishers
WHERE authors.city *= publishers.city

au_fname

au_lname

pub_name

-----------

--------------

--------------------

Johnson

White

(null)

Marjorie

Green

(null)

Cheryl

Carson

Algodata Infosystems

Michael

O'Leary

(null)

Dean

Straight

(null)

Meander

Smith

(null)

Abraham

Bennet

Algodata Infosystems

Ann

Dull

(null)

Burt

Gringlesby

(null)

Charlene

Locksley

(null)

Morningstar

Greene

(null)

Reginald

Blotchet-Halls

(null)

Akiko

Yokomoto

(null)

Innes

del Castillo

(null)

Michel

DeFrance

(null)

Dirk

Stringer

(null)

Stearns

MacFeather

(null)

Livia

Karsen

(null)

Sylvia

Panteley

(null)

Sheryl

Hunter

(null)

Heather

McBadden

(null)

Anne

Ringer

(null)

Albert

Ringer

(null)

(23 row(s) affected)

The *= operator distinguishes the outer join from an ordinary (equijoin) join. It tells SQL Server to include all rows in the authors table in the results, whether or not there is a match on the city column in the publishers table. Notice that in the results, there is no matching data for most of the authors listed, so these rows contain null values in the pub_name column.

Note  Because bit columns do not permit null values, a value of 0 appears in an outer join when there is no match for a bit column in the inner table.

The other outer join operator, =*, indicates that all rows in the second table are to be included in the results, regardless of whether there is matching data in the first table:

SELECT au_fname, au_lname, pub_name
FROM authors, publishers
WHERE authors.city =* publishers.city

An outer join can be further restricted by comparing it to a constant. This means that you can zoom in on precisely the value or values you want to see, and use the outer join to list the rows that didn't make the cut. For example, to find out which title has sold more than 50 copies, use this query:

SELECT stor_id, qty, title
FROM sales, titles
WHERE qty > 50
    AND sales.title_id = titles.title_id

stor_id

title

-------

--------------------

7066

Is Anger the Enemy?

(1 row(s) affected)

To also show the titles that didn't sell more than 50 copies in any one store, use an outer join:

SELECT stor_id, qty, title
FROM sales, titles
WHERE qty > 50
    AND sales.title_id =* titles.title_id

stor_id

title

-------

-----------------------------------------------------------

(null)

The Busy Executive's Database Guide

(null)

Cooking with Computers: Surreptitious Balance Sheets

(null)

You Can Combat Computer Stress!

(null)

Straight Talk About Computers

(null)

Silicon Valley Gastronomic Treats

(null)

The Gourmet Microwave

(null)

The Psychology of Computer Cooking

(null)

But Is It User Friendly?

(null)

Secrets of Silicon Valley

(null)

Net Etiquette

(null)

Computer Phobic and Non-Phobic Individuals: Behavior
Variations

7066

Is Anger the Enemy?

(null)

Life Without Fear

(null)

Prolonged Data Deprivation: Four Case Studies

(null)

Emotional Security: A New Algorithm

(null)

Onions, Leeks, and Garlic: Cooking Secrets of the
Mediterranean

(null)

Fifty Years in Buckingham Palace Kitchens

(null)

Sushi, Anyone?

(18 row(s) affected)

Outer Join Restrictions

Transact-SQL does not allow both nested outer joins and inner joins nested within an outer join. A table can, however, participate in an inner join and be the outer table in an outer join, as illustrated in this example:

SELECT royaltyper, au_lname, pub_name
FROM titleauthor, authors, publishers
WHERE titleauthor.au_id = authors.au_id
    AND authors.city *= publishers.city

The following shorthand can also be used to express the above example:

titleauthor = authors *= publishers

Generalizing and removing table names, this becomes:

T1 = T2 *= T3

Using this notation, the following illustration shows both legal and illegal combinations of inner and outer joins.

The following example is not valid because publishers cannot be the inner table in an outer join and still participate in an inner join:

SELECT title, au_lname, pub_name
FROM authors, publishers, titles
WHERE authors.city *= publishers.city
    AND publishers.pub_id = titles.pub_id

The qualification in the query does not restrict the number of rows returned; instead, it affects which rows contain null values. For rows that do not meet the qualification, NULL appears in the inner table's columns of those rows.


Joins and Null Values

If there are null values in the columns of the tables being joined, the null values will never match each other. You can detect the presence of null values in a column from one of the tables being joined only by using an outer join. Here are two tables, each of which has NULL in the column that will participate in the join. A left outer join (created using *=) displays the NULL in the first table:

table1

table2

a

b

c

d

-------

------

-------

------

1

one

NULL

two

NULL

three

4

four

4

join4

A left outer join on these two tables looks like this:

SELECT *
FROM table1, table2
WHERE a *= c

a         b      c        d
--------- ------ -------- ------
        1    one     NULL   NULL
     NULL  three     NULL   NULL
        4  join4        4   four

Note that the results do not make it particularly easy to distinguish a NULL in the data from a NULL that represents a failure to join. When null values are present in data being joined, it is usually preferable to omit them from the results by using a regular join.


Using Summary Queries

You can summarize data by using the GROUP BY and HAVING clauses. GROUP BY organizes data into groups; HAVING sets conditions on which groups to include in the results. These clauses should be used together; HAVING used without GROUP BY can produce confusing results.

Aggregate functions return summary values, either for the whole table or for groups within the table. For this reason they are used with GROUP BY. Aggregate functions can appear in a select list or in a HAVING clause, but not in a WHERE clause.

You can use the following aggregate functions with GROUP BY (expression in this table is almost always a column name):

Aggregate function | Result
SUM([ALL | DISTINCT] expression) | Total of the values in the numeric expression, either all or distinct
AVG([ALL | DISTINCT] expression) | Average of the values in the numeric expression, either all or distinct
COUNT([ALL | DISTINCT] expression) | Number of values in the expression, either all or distinct
COUNT(*) | Number of selected rows
MAX(expression) | Highest value in the expression
MIN(expression) | Lowest value in the expression

SUM and AVG work only with numeric values. SUM, AVG, COUNT, MAX, and MIN ignore null values, but COUNT(*) does not.

Note You cannot use GROUP BY or HAVING on columns that have the text or image datatype.

The following query finds the total year-to-date sales of each publisher in the database:

SELECT pub_id, total = SUM(ytd_sales)
FROM titles
GROUP BY pub_id

pub_id

total

------

-----

0736

28286

0877

44219

1389

24941

(3 row(s) affected)

Because of the GROUP BY clause, only one row is returned for each publisher, and it contains the sum of all sales for that publisher.

Important  The exact results of a GROUP BY clause depend on the sort order chosen during installation. For information about the effects of different sort orders, see Microsoft SQL Server Setup.

The HAVING clause sets conditions on the GROUP BY clause similarly to the way the WHERE clause interacts with the SELECT clause. The HAVING clause syntax is exactly like the WHERE clause syntax except that it can contain aggregate functions.

If, for example, you want to see the publishers who have had year-to-date sales greater than $40,000, use this query:

SELECT pud_id, total = SUM(ytd_sales)
FROM titles
GROUP BY pub_id
HAVING SUM(ytd_sales) > 40000

If, for example, you want to make sure that there are at least six books involved in the calculations for each publisher, use HAVING COUNT(*) > 5 to eliminate the publishers that return totals for fewer than six books. The query looks like this:

SELECT pub_id, total = SUM(ytd_sales)
FROM titles
GROUP BY pub_id
HAVING COUNT(*) > 5

pub_id

total

------

-----

0877

44219

1389

24941

(2 row(s) affected)

With this statement, two rows are returned. New Moon Books (0736) is eliminated.

For a detailed description of GROUP BY, HAVING, and aggregate functions, see Displaying Totals with GROUP BY or COMPUTE.


Using Subqueries

A subquery is a SELECT statement nested inside a SELECT, INSERT, UPDATE, or DELETE statement, or inside another subquery. A statement that includes a subquery operates on rows from one table based on its evaluation of the subquery's SELECT statement. The subquery SELECT statement can refer to the same table as the outer query or to a different table. In Transact-SQL, a subquery that returns a single value can also be used anywhere an expression is allowed.

SELECT statements that contain one or more subqueries are sometimes called nested queries or nested SELECT statements. The practice of nesting one SELECT statement inside another one reason for the word "structured" in structured query language (SQL).

Many SQL statements that include subqueries can be alternatively formulated as joins. Other questions can be posed only with subqueries. Some SQL users prefer subqueries to alternative formulations. Other people prefer joins. In Transact-SQL, there are usually not performance differences between a statement that includes a subquery and a semantically equivalent version that does not. However, in some cases where existence must be checked, a join will yield better performance, since otherwise the nested query must be processed for each result of the outer query in order to ensure duplicates are eliminated. In such cases, a join approach would yield better results.

This chapter introduces subquery syntax and rules and discusses keywords and comparison operators used with subqueries. It also covers correlated subqueries, subqueries that cannot be evaluated independently but that depend on the outer query for their results, and subqueries introduced with EXISTS.


Subquery Syntax

A subquery nested in the outer SELECT statement has the following SELECT syntax:

(SELECT [ALL | DISTINCT] subquery_select_list
[FROM {table_name | view_name}[optimizer_hints]
[[, {table_name2 | view_name2}[optimizer_hints]
[..., {table_name16 | view_name16}[optimizer_hints]]]
[WHERE clause]
[GROUP BY clause]
[HAVING clause])

The SELECT statement of a subquery is always enclosed in parentheses. It cannot include an ORDER BY, COMPUTE, or FOR BROWSE clause.

A subquery can be nested inside the WHERE or HAVING clause of an outer SELECT, INSERT, UPDATE, or DELETE statement, or inside another subquery. There is no limit on the level of nesting. A subquery can appear anywhere an expression can be used, as long as it returns a single value. You cannot use a subquery in an ORDER BY list.

If a table appears only in a subquery and not in the outer query, then columns from that table cannot be included in the output (the select list of the outer query).

Statements that include a subquery usually take one of these formats:

WHERE expression [NOT] IN (subquery)

WHERE expression comparison_operator [ANY | ALL] (subquery)

WHERE [NOT] EXISTS (subquery)

In some SQL statements, the subquery (also called the inner query) can be evaluated as if it were an independent query. Conceptually, the results of the subquery are substituted into the main statement or outer query (although this is not how SQL Server actually processes SQL statements with subqueries).

There are three basic types of subqueries:

  • Subqueries that operate on lists, introduced with IN or with a comparison operator modified by ANY or ALL
  • Subqueries that are introduced with an unmodified comparison operator and that must return a single value
  • Subqueries that are existence tests introduced with EXISTS


Subquery Rules

A subquery is subject to a number of restrictions:

  • The select list of a subquery introduced with a comparison operator can include only one expression or column name (except that EXISTS and IN operate on SELECT * or a list, respectively). If the WHERE clause of the outer statement includes a column name, it must be join-compatible with the column named in the subquery select list.
  • The datatypes text and image are not allowed in the select list of subqueries.
  • Because they must return a single value, subqueries introduced by an unmodified comparison operator (one not followed by the keyword ANY or ALL) cannot include GROUP BY and HAVING clauses.
  • The DISTINCT keyword cannot be used with subqueries that include a GROUP BY clause.
  • Because a subquery cannot include an ORDER BY clause, a COMPUTE clause, or an INTO keyword, it cannot manipulate its results internally. The optional DISTINCT keyword can effectively order the results of a subquery, because the system eliminates duplicates by ordering the results first.
  • A view created with a subquery cannot be updated.
  • The select list of a subquery introduced with EXISTS by convention consists of an asterisk (*) instead of the single column name. Do not specify more than one column name. The select list rules for a subquery introduced with EXISTS are identical to those for a standard select list because a subquery introduced with EXISTS constitutes an existence test and returns TRUE or FALSE rather than data.


Subquery Examples

Using subqueries saves you steps. For example, if you want to find all books that are the same price as Straight Talk About Computers, you can perform the task in two steps (or use a subquery). First, find the price of Straight Talk:

SELECT price
FROM titles
WHERE title = 'Straight Talk About Computers'

price
---------
    19.99

(1 row(s) affected)

Now use the result (the price) in a second query to find all books that cost the same as Straight Talk:

SELECT title, price
FROM titles
WHERE price = $19.99

title

price

---------------------------------------------

-------

The Busy Executive's Database Guide

19.99

Straight Talk About Computers

19.99

Silicon Valley Gastronomic Treats

19.99

Prolonged Data Deprivation: Four Case Studies

19.99

(4 row(s) affected)

By using a subquery, you can solve the problem with a single statement:

SELECT title, price
FROM titles
WHERE price =
    (SELECT price
    FROM titles
    WHERE title = 'Straight Talk About Computers')


Subqueries Introduced with IN

The result of a subquery introduced with IN (or with NOT IN, discussed later in this chapter) is a list of zero or more values. Once the subquery returns results, the outer query makes use of them.

This query finds the names of the publishers who have published business books:

SELECT pub_name
FROM publishers
WHERE pub_id IN
    (SELECT pub_id
    FROM titles
    WHERE type = 'business')

pub_name
--------------------
New Moon Books
Algodata Infosystems

(2 row(s) affected)

This statement is evaluated in two steps. First, the inner query returns the identification numbers of the publishers that have published business books (1389 and 0736). Second, these values are substituted into the outer query, which finds the names that go with the identification numbers in the publishers table. This step looks like this:

SELECT pub_name
FROM publishers
WHERE pub_id in ('1389', '0736')

Another difference in using a join rather than a subquery for this and similar problems is that the join lets you show columns from more than one table in the result. For example, if you want to include the titles of the business books in the result, you'd need to use the join version:

SELECT pub_name, title
FROM publishers, titles
WHERE publishers.pub_id = titles.pub_id
    AND type = 'business'

pub_name

title

--------------------

-------------------------------------------

Algodata Infosystems

The Busy Executive's Database Guide

Algodata Infosystems

Cooking with Computers: Surreptitious
Balance Sheets

New Moon Books

You Can Combat Computer Stress!

Algodata Infosystems

Straight Talk About Computers

(4 row(s) affected)

This query shows that the join produces 4 rows, not just 2 like the preceding subquery.

Here's another example of a statement that can be formulated with either a subquery or a join. This query finds the names of all second authors who live in California and who receive less than 30 percent of the royalties for a book:

SELECT au_lname, au_fname
FROM authors
WHERE state = 'CA'
    AND au_id IN
        (SELECT au_id
        FROM titleauthor
        WHERE royaltyper < 30
            AND au_ord = 2)

au_lname

au_fname

----------

--------

MacFeather

Stearns

(1 row(s) affected)

The inner query is evaluated, producing the ID numbers of the three authors who meet the qualification. The outer query is then evaluated. Notice that you can include more than one condition in the WHERE clause of both the inner and the outer query.

Using a join, the query is expressed like this:

SELECT au_lname, au_fname
FROM authors, titleauthor
WHERE state = 'CA'
    AND authors.au_id = titleauthor.au_id
    AND royaltyper < 30
    AND au_ord = 2

A join can always be expressed as a subquery. A subquery can often, but not always, be expressed as a join. This is because joins are symmetric¾you can join table A to B in either order and get the same answer. Obviously the same is not true if a subquery is involved.


Subqueries Introduced with NOT IN

Subqueries introduced with the keywords NOT IN also return a list of zero or more values.

This query finds the names of the publishers who have not published business books:

SELECT pub_name
FROM publishers
WHERE pub_id NOT IN
    (SELECT pub_id
    FROM titles
    WHERE type = 'business')

The query is exactly the same as the one in the preceding section except that NOT IN is substituted for IN. However, this statement cannot be converted to a join. The analogous not-equal join has a different meaning ¾ it finds the names of publishers who have published some book that is not a business book. (The difficulties with interpreting the meaning of joins not based on equality are discussed in more detail in Using Joins to Create Multitable Queries.)


Qualifying Column Names

In the preceding example, the pub_id column in the WHERE clause of the outer query is implicitly qualified by the table name in the outer query's FROM clause, publishers. The reference to pub_id in the select list of the subquery is qualified by the subquery's FROM clause ¾ that is, by the titles table.

The general rule is that column names in a statement are implicitly qualified by the table referenced in the FROM clause at the same level.

Here's what the query looks like with these implicit assumptions spelled out:

SELECT pub_name
FROM publishers
WHERE publishers.pub_id NOT IN
    (SELECT titles.pub_id
    FROM titles
    WHERE type = 'business')

It is never wrong to state the table name explicitly, and it is always possible to override implicit assumptions about table names with explicit qualifications.


Multiple Levels of Nesting

A subquery can itself include one or more subqueries. Any number of subqueries can be nested in a statement.

An example of a problem that can be solved using a statement with multiple levels of nested queries is, "Find the names of authors who have participated in writing at least one popular computer book."

SELECT au_lname, au_fname
FROM authors
WHERE au_id IN
    (SELECT au_id
    FROM titleauthor
    WHERE title_id IN
        (SELECT title_id
        FROM titles
        WHERE type = 'popular_comp'))

au_lname

au_fname

--------

-----------

Carson

Cheryl

Dull

Ann

Locksley

Charlene

Hunter

Sheryl

(4 row(s) affected)

The innermost query returns the title ID numbers PC1035, PC8888, and PC9999. The query at the next higher level is evaluated with these title IDs and returns the author ID numbers. Finally, the outer query uses the author IDs to find the names of the authors.

You can also express this query as a join:

SELECT au_lname, au_fname
FROM authors, titles, titleauthor
WHERE authors.au_id = titleauthor.au_id
    AND titles.title_id = titleauthor.title_id
    AND type = 'popular_comp'


Subqueries in UPDATE, DELETE, and INSERT Statements

Subqueries can be nested in UPDATE, DELETE, and INSERT statements, as well as in SELECT statements.

The following query doubles the price of all books published by New Moon Books. The statement updates the titles table; its subquery references the publishers table:

UPDATE titles
SET price = price * 2
WHERE pub_id in
    (SELECT pub_id
    FROM publishers
    WHERE pub_name = 'New Moon Books')

Here's an equivalent UPDATE statement using a join:

UPDATE titles
SET price = price * 2
FROM titles, publishers
WHERE titles.pub_id = publishers.pub_id
    AND pub_name = 'New Moon Books'

You can remove all records of sales of business books with this nested select statement:

DELETE sales
WHERE title_id IN
    (SELECT title_id
    FROM titles
    WHERE type = 'business')

Here's an equivalent DELETE statement using a join:

DELETE sales
FROM sales, titles
WHERE sales.title_id = titles.title_id
    AND type = 'business'


Subqueries with Aliases

Many statements in which the subquery and the outer query refer to the same table can also be stated as self-joins (joining a table to itself). For example, you can find authors who live in the same city as Livia Karsen by using a subquery:

SELECT au_lname, au_fname, city
FROM authors
WHERE city IN
    (SELECT city
    FROM authors
    WHERE au_fname = 'Livia'
        AND au_lname = 'Karsen')

au_lname

au_fname

city

----------

---------

-------

Green

Marjorie

Oakland

Straight

Dean

Oakland

Stringer

Dirk

Oakland

MacFeather

Stearns

Oakland

Karsen

Livia

Oakland

(5 row(s) affected)

Or you can use a self-join:

SELECT au1.au_lname, au1.au_fname, au1.city
FROM authors au1, authors au2
WHERE au1.city = au2.city
    AND au2.au_lname = 'Karsen'
    AND au2.au_fname = 'Livia'

From the earlier discussion of self-joins, you might recall that table aliases are required because the table being joined to itself appears in two different roles. Aliases can also be used in nested queries that refer to the same table in an inner and outer query:

SELECT au1.au_lname, au1.au_fname, au1.city
FROM authors au1
WHERE au1.city in
    (SELECT au2.city
    FROM authors au2
    WHERE au2.au_fname = 'Livia'
        AND au2.au_lname = 'Karsen')

Explicit aliases make it clear that the reference to authors in the subquery does not mean the same thing as the reference in the outer query.


Comparison Operator Subqueries

Subqueries can be introduced with one of the comparison operators =, < >, >, > =, <, ! >, ! <, or < =.

A subquery introduced with an unmodified comparison operator (a comparison operator not followed by ANY or ALL) must return a single value rather than a list of values, like subqueries introduced with IN. If such a subquery returns more than one value, SQL Server displays an error message.

However, this can be unreliable and should aften be avoided because to use a subquery introduced with an unmodified comparison operator, you must be familiar enough with your data and with the nature of the problem to know that the subquery will return exactly one value.

For example, if you suppose each publisher to be located in only one city, and you want to find the names of authors who live in the city where Algodata Infosystems is located, you can write a statement with a subquery introduced with the simple comparison operator = (equal sign):

SELECT au_lname, au_fname
FROM authors
WHERE city =
    (SELECT city
    FROM publishers
    WHERE pub_name = 'Algodata Infosystems')

au_lname        au_fname
--------        --------
Carson        Cheryl
Bennet        Abraham

(2 row(s) affected)

If, however the preceding subquery returned multiple rows, then an error message would result, stating that it was an illegal subquery. Instead of =, an IN formulation could be used (= ANY also works).

Subqueries introduced with unmodified comparison operators often include aggregate functions, since these return a single value. For example, this statement finds the names of all books priced higher than the current minimum price:

SELECT distinct title
FROM titles
WHERE price >
    (SELECT min(price)
    FROM titles)

title
----------------------------------------------------------
But Is It User Friendly?
Computer Phobic and Non-Phobic Individuals: Behavior Variations
Cooking with Computers: Surreptitious Balance Sheets
Emotional Security: A New Algorithm
Fifty Years in Buckingham Palace Kitchens
Is Anger the Enemy?
Life Without Fear
Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean
Prolonged Data Deprivation: Four Case Studies
Secrets of Silicon Valley
Silicon Valley Gastronomic Treats
Straight Talk About Computers
Sushi, Anyone?
The Busy Executive's Database Guide

(14 row(s) affected)

Because subqueries introduced with unmodified comparison operators must return a single value, they cannot include GROUP BY or HAVING clauses unless you know that the GROUP BY or HAVING clause itself returns a single value. For example, this query finds the books priced higher than the lowest priced book in the trad_cook category:

SELECT DISTINCT title
FROM titles
WHERE price >
    (SELECT min(price)
    FROM titles
    GROUP BY type
    HAVING type = 'trad_cook')


Comparison Operators Modified by ANY, SOME, or ALL

Comparison operators that introduce a subquery can be modified by the keywords ALL or ANY. SOME is an ANSI-standard keyword for ANY.

Note The =ALL construct is not supported since it would result in an error whenever the subquery resulted in multiple rows.

Subqueries introduced with a modified comparison operator return a list of zero or more values and can include a GROUP BY or HAVING clause. These subqueries can be restated with EXISTS, as discussed later in this chapter.

Using the > comparison operator as an example, >ALL means greater than every value ¾ in other words, greater than the maximum value. For example, >ALL (1, 2, 3) means greater than 3. >ANY means greater than at least one value ¾ in other words, greater than the minimum. So >ANY (1, 2, 3) means greater than 1.

In the context of a subquery, >ALL means that for a row to satisfy the condition specified in the outer query, the value in the column that introduces the subquery must be greater than each value in the list of values returned by the subquery.

Similarly, >ANY means that for a row to satisfy the condition specified in the outer query, the value in the column that introduces the subquery must be greater than at least one of the values in the list of values returned by the subquery.

The use of ALL and ANY can be confusing because computers cannot tolerate the ambiguity that these words sometimes have in English. For example, you might ask the question, "Which books commanded an advance greater than any book published by Algodata Infosystems?"

This question can be paraphrased to make its SQL translation clearer: "Which books commanded an advance greater than the largest advance paid by Algodata Infosystems?" The ALL keyword (not the ANY keyword) is required here:

SELECT title
FROM titles
WHERE advance > ALL
    (SELECT advance
    FROM publishers, titles
    WHERE titles.pub_id = publishers.pub_id
        AND pub_name = 'Algodata Infosystems')

For each title, the inner query finds a list of advance amounts paid by Algodata. The outer query looks at the largest value in the list and determines whether the title currently being considered has commanded an even bigger advance.

If a subquery introduced with ALL and a comparison operator does not return any values, all rows in outer query satisfy the condition.

The following query provides an example of a subquery introduced with a comparison operator modified by ANY. It finds the titles that got an advance larger than the minimum advance amount paid by Algodata Infosystems.

SELECT title
FROM titles
WHERE advance > ANY
    (SELECT advance
    FROM publishers, titles
    WHERE titles.pub_id = publishers.pub_id
        AND pub_name = 'Algodata Infosystems')

title
---------------------------------------------------------------
You Can Combat Computer Stress!
The Gourmet Microwave
But Is It User Friendly?
Secrets of Silicon Valley
Computer Phobic and Non-Phobic Individuals: Behavior Variations
Life Without Fear
Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean
Sushi, Anyone?

(8 row(s) affected)

For each title, the inner query finds a list of advance amounts paid by Algodata. The outer query looks at all values in the list and determines whether the title currently being considered has commanded an advance larger than any of those amounts. In other words, it finds titles with advances as large or larger than the lowest value paid by Algodata.

If the subquery does not return any values, the entire query fails to return any values.

The =ANY operator is equivalent to IN. For example, to find authors who live in the same city as a publisher, you can use either IN or =ANY:

SELECT au_lname, au_fname
FROM authors
WHERE city IN
    (SELECT city
    FROM publishers)

SELECT au_lname, au_fname
FROM authors
WHERE city = ANY
    (SELECT city
    FROM publishers)

au_lname            au_fname
--------            ---------
Carson            Cheryl
Bennet            Abraham

(2 row(s) affected)

The < >ANY operator, however, differs from NOT IN: < >ANY means not = a, or not = b, or not = c. NOT IN means not = a, and not = b, and not = c. <>ALL means the same as NOT IN.

For example, say you want to find the authors who live in a city where no publisher is located. You might mistakenly try this query:

SELECT au_lname, au_fname
FROM authors
WHERE city <> any
    (SELECT city
    FROM publishers)

The results include all 23 authors because every author lives in a city where one or more of the publishers is not located. What's happened is that the inner query finds all the cities in which publishers are located, and then, for each city, the outer query finds the authors who don't live there.

However, when you substitute NOT IN in this query, the results include all the authors except Cheryl Carson and Abraham Bennet, who live in Berkeley, where Algodata Infosystems is located.

SELECT au_lname, au_fname
FROM authors
WHERE city NOT IN
    (SELECT city
    FROM publishers)

You can get the same results with the < >ALL operator, which is equivalent to NOT IN:

SELECT au_lname, au_fname
FROM authors
WHERE city <> ALL
    (SELECT city
    FROM publishers)


Correlated Subqueries

Many of the previous queries can be evaluated by executing the subquery once and substituting the resulting value or values into the WHERE clause of the outer query. In queries that include a correlated subquery (also known as a repeating subquery), the subquery depends on the outer query for its values. This means that the subquery is executed repeatedly, once for each row that might be selected by the outer query.

This statement finds the names of all authors who earn 100 percent of the shared royalty (royaltyper) on a book:

SELECT au_lname, au_fname
FROM authors
WHERE 100 IN
    (SELECT royaltyper
    FROM titleauthor
    WHERE titleauthor.au_ID = authors.au_id)

au_lname

au_fname

-------------

--------

White

Johnson

Green

Marjorie

Carson

Cheryl

Straight

Dean

Locksley

Charlene

Blotchet-Halls

Reginald

del Castillo

Innes

Panteley

Sylvia

Ringer

Albert

(9 row(s) affected)

Unlike most of the subqueries previously shown, the subquery in this statement cannot be resolved independently of the main query. It needs a value for authors.au_id, but this value is a variable ¾ it changes as SQL Server examines different rows of the authors table.

That's exactly how this query is evaluated: SQL Server considers each row of the authors table for inclusion in the results by substituting the value in each row into the inner query. Say that SQL Server first examines the row for Cheryl Carson. The variable authors.au_id takes the value 238-95-7766, which SQL Server substitutes into the inner query:

SELECT royaltyper
FROM titleauthor
WHERE au_id = '238-95-7766'

The result is 100, so the outer query evaluates to:

SELECT au_lname, au_fname
FROM authors
WHERE 100 in (100)

Since this is true, the row for Cheryl Carson is included in the results. If you go through the same procedure with the row for Abraham Bennet, you'll see that this row is not included in the results.


Correlated Subqueries with Aliases

You can use a correlated subquery to find the types of books that are published by more than one publisher. Aliases are required to distinguish the two different roles in which the titles table appears:

SELECT DISTINCT t1.type
FROM titles t1
WHERE t1.type in
    (SELECT t2.type
    FROM titles t2
    WHERE t1.pub_id <> t2.pub_id)

type
----------
business
psychology

(2 row(s) affected)

The preceding nested query is equivalent to this self-join:

SELECT DISTINCT t1.type
FROM titles t1, titles t2
WHERE t1.type = t2.type
    AND t1.pub_id <> t2.pub_id


Correlated Subqueries with Comparison Operators

To find sales where the quantity is less than the average quantity for sales of that title:

SELECT s1.ord_num, s1.title_id, s1.qty
FROM sales s1
WHERE s1.qty <
    (SELECT AVG(s2.qty)
    FROM sales s2
    WHERE s2.title_id = s1.title_id)

ord_num

title_id

qty

--------

--------

-----

6871

BU1032

5

722a

PS2091

3

D4482

PS2091

10

N914008

PS2091

20

423LL922

MC3021

15

(5 row(s) affected)

The outer query selects the rows of the sales table (that is, of s1) one by one. The subquery calculates the average quantity for each sale being considered for selection in the outer query. For each possible value of s1, SQL Server evaluates the subquery and puts the record being considered in the results if the quantity is less than the calculated average.

Sometimes a correlated subquery mimics a GROUP BY statement. This example finds all titles that have a price greater than the average for books of its type:

SELECT t1.type, t1.title
FROM titles t1
WHERE t1.price >
    (SELECT AVG(t2.price)
    FROM titles t2
    WHERE t1.type = t2.type)

type

title

----

-----------------------------------------------------

business

The Busy Executive's Database Guide

business

Straight Talk About Computers

mod_cook

Silicon Valley Gastronomic Treats

popular_comp

But Is It User Friendly?

psychology

Computer Phobic and Non-Phobic Individuals:
Behavior Variations

psychology

Prolonged Data Deprivation: Four Case
Studies

trad_cook

Onions, Leeks, and Garlic: Cooking Secrets
of the Mediterranean

(7 row(s) affected)

For each possible value of t1, SQL Server evaluates the subquery and includes the row in the results if the price value of that row is greater than the calculated average. It is not necessary to group by type explicitly, because the rows for which average price is calculated are restricted by the WHERE clause in the subquery.


Correlated Subqueries in a HAVING Clause

A correlated subquery can also be used in the HAVING clause of an outer query. This construction can be used to find the types of books for which the maximum advance is more than twice the average within a given group.

In this case, the subquery is evaluated once for each group defined in the outer query (once for each type of book):

SELECT t1.type
FROM titles t1
GROUP BY t1.type
HAVING MAX(t1.advance) >=ALL
    (SELECT 2 * AVG(t2.advance)
    FROM titles t2
    WHERE t1.type = t2.type)

type
--------
mod_cook

(1 row(s) affected)


Subqueries Introduced with EXISTS

When a subquery is introduced with the keyword EXISTS, it functions as an existence test. The WHERE clause of the outer query tests for the existence of rows returned by the subquery. The subquery does not actually produce any data; it returns a value of TRUE or FALSE.

A subquery introduced with EXISTS has the following syntax:

WHERE [NOT] EXISTS (subquery)

To find the names of all publishers who publish business books, type:

SELECT pub_name
FROM publishers
WHERE EXISTS
    (SELECT *
    FROM titles
    WHERE pub_id = publishers.pub_id
        AND type = 'business')

pub_name
--------------------
New Moon Books
Algodata Infosystems

(2 row(s) affected)

To determine the results of this query, consider each publisher's name in turn. Does this value cause the subquery to return at least one row? In other words, does it cause the existence test to evaluate to TRUE?

In this case, the first publisher name is Algodata Infosystems, with identification number 1389. Are there any rows in the titles table in which pub_id is 1389 and type is business? If so, Algodata Infosystems should be one of the values selected. The same process is repeated for each of the other publisher names.

Notice that subqueries introduced with EXISTS are a bit different from other subqueries in these ways:

  • The keyword EXISTS is not preceded by a column name, constant, or other expression.
  • The select list of a subquery introduced by EXISTS almost always consists of an asterisk (*). There is no reason to list column names since you are simply testing for the existence of rows that meet the conditions specified in the subquery.

The EXISTS keyword is very important because there is often no alternative, non-subquery formulation.

Although some queries formulated with EXISTS cannot be expressed any other way, all queries that use IN or a comparison operator modified by ANY or ALL can be expressed with EXISTS.


Subqueries with EXISTS Examples

Examples of statements using EXISTS and their equivalent alternatives follow. You've seen some of them before.

Here are two ways to find authors who live in the same city as a publisher:

A.    SELECT au_lname, au_fname
    FROM authors
    WHERE city =ANY
        (SELECT city
        FROM publishers)

B.    SELECT au_lname, au_fname
    FROM authors
    WHERE exists
        (SELECT *
        FROM publishers
        WHERE authors.city = publishers.city)

    au_lname            au_fname
    --------            --------
    Carson            Cheryl
    Bennet            Abraham

    (2 row(s) affected)

The two queries find titles of books published by any publisher located in a city that begins with the letter B:

C.    SELECT title
    FROM titles
    WHERE pub_id IN
        (SELECT pub_id
        FROM publishers
        WHERE city LIKE 'B%')

D.    SELECT title
    FROM titles
    WHERE EXISTS
        (SELECT *
        FROM publishers
        WHERE pub_id = titles.pub_id
            AND city LIKE 'B%')

    title
    ----------------------------------------------------
    The Busy Executive's Database Guide
    Cooking with Computers: Surreptitious Balance Sheets
    You Can Combat Computer Stress!
    Straight Talk About Computers
    But Is It User Friendly?
    Secrets of Silicon Valley
    Net Etiquette
    Is Anger the Enemy?
    Life Without Fear
    Prolonged Data Deprivation: Four Case Studies
    Emotional Security: A New Algorithm

    (11 row(s) affected)


Subqueries Introduced with NOT EXISTS

NOT EXISTS works just like EXISTS, except that the WHERE clause in which it is used is satisfied if no rows are returned by the subquery.

For example, to find the names of publishers who do not publish business books:

SELECT pub_name
FROM publishers
WHERE NOT EXISTS
    (SELECT *
    FROM titles
    WHERE pub_id = publishers.pub_id
        AND type = 'business')

This query finds the titles for which there have been no sales:

SELECT title
FROM titles
WHERE NOT EXISTS
    (SELECT title_id
    FROM sales
    WHERE title_id = titles.title_id)

title
----------------------------------
The Psychology of Computer Cooking
Net Etiquette

(2 row(s) affected)


Using EXISTS and NOT EXISTS to Find Intersection and Difference

Subqueries introduced with EXISTS and NOT EXISTS can be used for two set theory operations: intersection and difference. The intersection of two sets contains all elements that belong to both of the original sets. The difference contains elements that belong only to the first of the two sets.

The intersection of authors and publishers over the city column is the set of cities in which both an author and a publisher are located:

SELECT DISTINCT city
FROM authors
WHERE EXISTS
    (SELECT *
    FROM publishers
    WHERE authors.city = publishers.city)

city
--------
Berkeley

(1 row(s) affected)

This query is included for illustrative purposes. Of course, this query could be written as a simple join:

SELECT DISTINCT authors.city
FROM authors, publishers
WHERE authors.city = publishers.city

The difference between authors and publishers over the city column is the set of cities where an author lives but no publisher is located ¾ that is, all the cities except Berkeley:

SELECT DISTINCT city
FROM authors
WHERE not exists
    (SELECT *
    FROM publishers
    WHERE authors.city = publishers.city)

This query could also be written as:

SELECT DISTINCT city
FROM authors
WHERE city NOT IN
SELECT city FROM publishers


Subqueries Used in Place of an Expression

In Transact-SQL, a subquery can be substituted anywhere an expression can be used in SELECT, UPDATE, INSERT, and DELETE statements. A subquery cannot be used in an ORDER BY list.

The following example illustrates how you might use this enhancement. This statement finds the price of a book, the average price of all books, and the difference between the price of a book and the average price of all books:

SELECT title, price,
average=(SELECT AVG(price) FROM titles),
difference=price-(SELECT AVG(price) FROM titles)
FROM titles
WHERE type="popular_comp"

title

price

average

difference

------------------------

---------

----------

------------

But Is It User Friendly?

22.95

23.94

-0.99

Secrets of Silicon Valley

20.00

23.94

-3.94

Net Etiquette

(null)

23.94

(null)

(3 row(s) affected)


Displaying Totals with GROUP BY or COMPUTE

You can display totals by using aggregate functions and the GROUP BY clause, or row aggregate functions and the COMPUTE clause.

Aggregate functions ¾ SUM, AVG, COUNT, COUNT(*), MAX, and MIN ¾ generate summary values that appear as new columns in query results. The GROUP BY clause, part of the SELECT statement, divides a table into groups. GROUP BY and aggregate functions are often used together, and a summary value is calculated for each group.

Row aggregate functions ¾ SUM, AVG, COUNT, MAX, and MIN ¾ and the COMPUTE clause are always used together as part of a SELECT statement. Row aggregate functions generate summary values that appear as additional rows in the query results. A SQL statement that includes a COMPUTE clause and row aggregate functions produces a report with detail rows and summary rows.


Aggregate Functions and the GROUP BY Clause

Aggregate functions can be applied to all rows in a table, to a subset of the table specified by a WHERE clause, or to one or more groups of rows in the table. A single value is generated from each set of rows to which an aggregate function is applied.

This example calculates the sum of year-to-date sales for all books in the titles table:

SELECT SUM(ytd_sales)

FROM titles

-------------

97446

(1 row(s) affected)

The optional keyword DISTINCT can be used with SUM, AVG, and COUNT to eliminate duplicate values before an aggregate function is applied. For SUM, AVG, and COUNT, ALL is the default.

Important  The output for statements involving MIN or MAX on char or varchar columns depends on the sort order chosen during installation. For information about the effects of different sort orders, see Microsoft SQL Server Setup.

For example, with this query you can find the average price of all books if the prices were doubled:

SELECT avg(price * 2)

FROM titles

------------

47.88

(1 row(s) affected)

The syntax of the aggregate functions and their results are as follows:

Aggregate function | Result
SUM([ALL | DISTINCT] expression) | Total of the values in the numeric expression, either all or distinct
AVG([ALL | DISTINCT] expression) | Average of the values in the numeric expression, either all or distinct
COUNT([ALL | DISTINCT] expression) | Number of values in the expression, either all or distinct
COUNT(*) | Number of selected rows
MAX(expression) | Highest value in the expression
MIN(expression) | Lowest value in the expression

SUM, AVG, COUNT, MAX, and MIN ignore null values; COUNT(*) does not.

Aggregate functions can be used in a select list, as in the preceding examples, or in the HAVING clause of a SELECT statement that includes a GROUP BY clause. For more information, see The HAVING Clause.

Aggregate functions cannot be used in a WHERE clause. However, a SELECT statement with aggregate functions in its select list often includes a WHERE clause that restricts the rows to which the aggregate function is applied. In the examples given earlier, each aggregate function produces a single summary value for the whole table. If a SELECT statement includes a WHERE clause (but not a GROUP BY clause), an aggregate function produces a single value for the subset of rows that the WHERE clause specifies.

This query returns the average advance and the sum of year-to-date sales for business books only:

SELECT AVG(advance), SUM(ytd_sales)
FROM titles
WHERE type = 'business'

---------     -------
6,281.25      30788

(1 row(s) affected)

Whenever an aggregate function is used in a SELECT statement that does not include a GROUP BY clause, it produces a single value. This is true whether it is operating on all rows in a table or on a subset of rows defined by a WHERE clause. Such a function is called a scalar aggregate.

Note that you can use more than one aggregate function in the same select list and produce more than one scalar aggregate in a single SELECT statement.


Aggregate Functions and Datatypes

SUM and AVG can be used only with numeric columns ¾ int, smallint, tinyint, decimal, numeric, float, real, money, and smallmoney datatypes. MIN and MAX cannot be used with bit datatypes. Aggregate functions other than COUNT(*) cannot be used with text and image datatypes.

With these exceptions, the other aggregate functions can be used with any type of column. For example, in a character datatype column, you can use MIN (minimum) to find the lowest value, the one closest to the beginning of the alphabet, as shown in the following example:

SELECT MIN(au_lname)
FROM authors

--------------------
Bennet

(1 row(s) affected)

When you sum or average integer data, Transact-SQL treats the result as an int value, even if the datatype of the column is smallint or tinyint.


COUNT(*)

COUNT(*) does not require an expression parameter because, by definition, it does not use information about any particular column. It counts the total number of rows in a table. This statement finds the total number of books in titles:

SELECT COUNT(*)

FROM titles

-----------

18

(1 row(s) affected)

COUNT(*) returns the number of rows in the specified table without eliminating duplicates. It counts each row separately, including rows that contain null values.

Like other aggregate functions, COUNT(*) can be combined with other aggregate functions in the select list, with WHERE clauses, and so on. This statement shows COUNT(*) combined with a WHERE clause:

SELECT COUNT(*), AVG(price)

FROM titles

WHERE advance > $1000

---------------

--------------

15

24.20

(1 row(s) affected)


The DISTINCT Keyword

The DISTINCT keyword is optional with SUM, AVG, and COUNT. It is not allowed with MIN, MAX, or COUNT(*). When DISTINCT is used, duplicate values are eliminated before the sum, average, or count is calculated.

If you use DISTINCT, the expression must consist of a column name only. It cannot include an arithmetic expression.

DISTINCT is used inside parentheses and before the column name. The following statement returns the average of the distinct prices of business books:

SELECT AVG(DISTINCT price)

FROM titles

WHERE type = 'business'

------------

14.63

(1 row(s) affected)

Without DISTINCT, the AVG function finds the average price of all business titles in the titles table:

SELECT AVG(price)

FROM titles

WHERE type = 'business'

------------

15.97

(1 row(s) affected)


Null Values and Aggregate Functions

Any null values in the column on which the aggregate function is operating are ignored for the purposes of the function.

For example, the count of advances in the titles table is not the same as the count of title names, because null values in the advance column are not counted:

SELECT COUNT(advance)

FROM titles

------------

16

(1 row(s) affected)

SELECT COUNT(title)

FROM titles

------------

18

(1 row(s) affected)

If no rows meet the condition(s) specified in the WHERE clause, COUNT returns a value of zero. The other functions all return NULL. Here are examples:

SELECT COUNT(DISTINCT title)

FROM titles

WHERE type = 'poetry'

------------

0

(1 row(s) affected)

SELECT AVG(advance)

FROM titles

WHERE type = 'poetry'

------------

(null)

(1 row(s) affected)

COUNT(*), however, counts each row, even if every column in it is null.


The GROUP BY Clause

The GROUP BY clause is used in SELECT statements to divide a table into groups. You can group by column name or by the results of computed columns when using numeric datatypes. You cannot group by columns of bit, text, or image datatypes. A GROUP BY clause almost always appears in statements that also include aggregate functions, in which case the aggregate function produces a value for each group. These values are called vector aggregates. (As mentioned earlier, a scalar aggregate is a single value produced by an aggregate function without a GROUP BY clause.)

This statement finds the average advance and sum of year-to-date sales for each type of book:

SELECT type, AVG(advance), SUM(ytd_sales)

FROM titles

GROUP BY type

type
------------ -------------------------- -----------
business     6,281.25                   30788
mod_cook     7,500.00                   24278
popular_comp 7,500.00                   12875
psychology   4,255.00                   9939
trad_cook    6,333.33                   19566
UNDECIDED    (null)                     (null)

(6 row(s) affected)

The summary values produced by SELECT statements with GROUP BY and aggregate functions appear as new columns in the results.

Important  The output for statements involving the GROUP BY clause depends on the sort order chosen during installation. The GROUP BY clause does not order the results. For information about the effects of different sort orders, see Microsoft SQL Server Setup.


GROUP BY Syntax

The GROUP BY clause has the following syntax:

GROUP BY [ALL] aggregate_free_expression
[, aggregate_free_expression]...

Remember that the order of the clauses in the SELECT statement is significant. You can omit any of the optional clauses, but when you use them, they must appear in the appropriate order. For the complete syntax of the SELECT statement, see Creating Basic Queries.

You can group by an expression as long as it does not include aggregate functions. For example:

SELECT AVG(ytd_sales), ytd_sales * royalty

FROM titles

GROUP BY ytd_sales * royalty

----------

----------

(null)

(null)

111

1110

375

3750

2032

24384

2045

24540

3336

33360

3876

38760

4072

40720

4095

40950

8780

140480

15096

211344

18722

449328

22246

533904

(13 row(s) affected)

However, you cannot group by an alias.

You can correct this query if you group by type, title_id.

You must also include in the GROUP BY list all non-aggregates in the select list. In the example above, if the GROUP BY contained only 'GROUP BY TYPE', an error would result, stating that title_id is contained in the select list but not in the grouping. Hence, title_id would either need to be removed from the select list or added to the group by list.

This statement produces an error message:

SELECT Category = type, title_id, avg(price), avg(advance)
FROM titles
GROUP BY Category, title_id

You can list more than one column in the GROUP BY clause to nest groups ¾ that is, you can group a table by any combination of columns. For example, this statement finds the average price and the sum of year-to-date sales, grouped by type and publisher ID:

SELECT type, pub_id, 'avg' = AVG(price), 'sum' = sum(ytd_sales)
FROM titles
GROUP BY type, pub_id

type         pub_id avg                        sum
------------ ------ -------------------------- -----------
business     0736   11.96                      18722
business     1389   17.31                      12066
mod_cook     0877   11.49                      24278
popular_comp 1389   21.48                      12875
psychology   0736   45.93                      9564
psychology   0877   21.59                      375
trad_cook    0877   15.96                      19566
UNDECIDED    0877   (null)                     (null)

(8 row(s) affected)


GROUP BY and Null Values

If the grouping column contains a null value, that row becomes a group in the results. If the grouping column contains more than one null value, the null values are put into a single group.

The royalty column in the titles table contains some null values. Here's an example that uses GROUP BY and the royalty column:

SELECT royalty, AVG(price * 2)

FROM titles

GROUP BY royalty

royalty

-------

------

(null)

(null)

10

53.88

12

63.79

14

23.90

16

45.90

24

14.95

(6 row(s) affected)


GROUP BY and the WHERE Clause

You can use a WHERE clause in a query containing a GROUP BY clause. Rows that don't satisfy the conditions in the WHERE clause are eliminated before any grouping is done. Here's an example:

SELECT type, AVG(price)

FROM titles

WHERE advance > $5000

GROUP BY type

type

------------

-------

business

11.96

mod_cook

2.99

popular_comp

21.48

psychology

24.80

trad_cook

17.97

(5 row(s) affected)

Only rows with advances greater than $5000 are included in the groups shown in the query results.


GROUP BY and ALL

Transact-SQL provides the ALL keyword in the GROUP BY clause. ALL is meaningful only when the SELECT statement in which it is used also includes a WHERE clause.

If you use ALL, the query results include all groups produced by the GROUP BY clause, even if some of the groups don't have any rows that meet the search conditions. Without ALL, a SELECT statement that includes GROUP BY does not show groups for which no rows qualify.

Here are two examples:

SELECT type, AVG(price)

FROM titles

WHERE royalty = 10

GROUP BY type

type

------------

-----------

business

17.31

popular_comp

20.00

psychology

40.38

trad_cook

17.97

(4 row(s) affected)

SELECT type, AVG(price)

FROM titles

WHERE royalty = 10

GROUP BY all type

type

---------

-----------

business

17.31

mod_cook

(null)

popular_comp

20.00

psychology

40.38

trad_cook

17.97

UNDECIDED

(null)

(6 row(s) affected)

The first statement produces groups only for those books that commanded royalties of 10 percent. Since no modern cookbooks have a royalty of 10 percent, there is no group in the results for the mod_cook type.

The second statement produces groups for all types, including modern cookbooks and UNDECIDED, even though the modern cookbook group doesn't include any rows that meet the qualification specified in the WHERE clause.

The column that holds the aggregate value (the average price) is NULL for groups that lack qualifying rows.


GROUP BY and ORDER BY

Add an ORDER BY clause to a SELECT statement when you want the results to be ordered in a particular way. Put the ORDER BY clause after the GROUP BY clause.

For example, to find the average price of each type of book and order the results by average price, type:

SELECT type, AVG(price)

FROM titles

GROUP BY type

ORDER BY AVG(price)

type

------------

-------

UNDECIDED

(null)

mod_cook

11.49

psychology

15.96

business

15.97

trad_cook

21.48

popular_comp

41.06

(6 row(s) affected)


The HAVING Clause

HAVING sets conditions for the GROUP BY clause similarly to the way that WHERE sets conditions for the SELECT clause. Because the HAVING clause is used to restrict groups, HAVING without GROUP BY is not meaningful. In queries without GROUP BY, SQL Server returns the same results as it would if a WHERE clause were used.

The HAVING search conditions are identical to WHERE search conditions with one exception: WHERE search conditions cannot include aggregate functions, and HAVING search conditions often do. HAVING clauses can reference any of the items that appear in the select list. Up to 128 conditions can be included in a HAVING clause.

The following statement shows a HAVING clause with an aggregate function. It groups the rows in the titles table by type and eliminates the groups that include only one book:

SELECT type
FROM titles
GROUP BY type
HAVING COUNT(*) > 1

type
------------
business
mod_cook
popular_comp
psychology
trad_cook

(5 row(s) affected)

Here's an example of a HAVING clause without aggregate functions. It groups the rows in the titles table by type and eliminates those types that do not start with the letter "p":

SELECT type
FROM titles
GROUP BY type
HAVING type LIKE 'p%'

type
------------
popular_comp
psychology

(2 row(s) affected)

When multiple conditions are included in the HAVING clause, they are combined with AND, OR, or NOT. The following example shows how to group the titles table by publisher, including only those publishers with identification numbers greater than 0800, who have paid more than $15,000 in total advances, and who sell books for less than an average of $20:

SELECT pub_id, SUM(advance), AVG(price)

FROM titles

GROUP BY pub_id

HAVING SUM(advance) > $15000

    AND AVG(price) < $20

    AND pub_id > '0800'

The following statement illustrates the use of GROUP BY, HAVING, WHERE and ORDER BY clauses in one SELECT statement. It produces the same groups and summary values as the previous example but does so after eliminating the titles with prices under $5. It also organizes the results by pub_id:

SELECT pub_id, SUM(advance), AVG(price)

FROM titles

WHERE price >= $5

GROUP BY pub_id

HAVING SUM(advance) > $15000

    AND AVG(price) < $20

    AND pub_id > '0800'

ORDER BY pub_id


The COMPUTE Clause

The COMPUTE clause is used in SELECT statements with row aggregate functions ¾ SUM, AVG, MIN, MAX, and COUNT ¾ to generate summary values based on the values in groups of rows.

These summary values appear as new rows in the query results, allowing you to see both detail and summary rows in one set of results. (Compare this to results from aggregate functions and the GROUP BY clause, which appear as new columns.)

The results of a query that includes a COMPUTE clause are like a control-break report, which is a report whose summary values are controlled by the groupings, or breaks, that you specify. You can produce summary values for groups, and you can calculate more than one aggregate function for the same group.

Here's how to use the COMPUTE clause to calculate the sum for the prices of the different types of cookbooks:

SELECT type, price

FROM titles

WHERE type like '%cook'

ORDER BY type, price

COMPUTE SUM(price) BY type

type

price

--------

-------------

mod_cook

2.99

mod_cook

19.99

sum

=============

22.98

type

price

---------

-------------

trad_cook

11.95

trad_cook

14.99

trad_cook

20.95

sum

=============

47.89

(7 row(s) affected)

Notice that the summary values appear as new rows in the results, labeled with the word "sum," and that all the detail rows are also included.

With GROUP BY, detail rows are not shown, and the summary values are displayed as new columns. The same summary information can be produced with this statement:

SELECT type, SUM(price)

FROM titles

WHERE type LIKE '%cook'

GROUP BY type

type

---------

------

mod_cook

22.98

trad_cook

47.89

(2 row(s) affected)


COMPUTE Syntax

The COMPUTE clause has the following syntax:

COMPUTE row_aggregate(column_name)
[, row_aggregate(column_name)...]
[BY column_name [, column_name]...]

For the complete syntax of the SELECT statement, see Creating Basic Queries.

Note You cannot include text or image datatypes in a COMPUTE or COMPUTE BY clause.


Row Aggregate Functions and the COMPUTE Clause

These row aggregate functions are used with COMPUTE:

Row aggregate function | Result
SUM | Total of the values in the numeric expression
AVG | Average of the values in the numeric expression
MAX | Highest value in the expression
MIN | Lowest value in the expression
COUNT | Number of selected rows

SUM, AVG, MAX, MIN, and COUNT ignore null values.

These row aggregate functions are the same aggregate functions that can be used with GROUP BY, except that there is no equivalent to COUNT(*). To find the summary information produced by GROUP BY and COUNT(*), use a COMPUTE clause without BY.


Rules for COMPUTE Clauses

These are the rules for COMPUTE clauses:

  • The DISTINCT keyword is not allowed with row aggregate functions.
  • The columns in a COMPUTE clause must appear in the statement's select list.
  • You cannot use SELECT INTO in the same statement as a COMPUTE clause because statements that include COMPUTE do not generate normal rows.
  • If you use COMPUTE BY, you must also use an ORDER BY clause. The columns listed after COMPUTE BY must be identical to or a subset of those listed after ORDER BY. They must be in the same left-to-right order, start with the same expression, and not skip any expressions.

    For example, if the ORDER BY clause is:

    order by a, b, c

    The COMPUTE BY clause can be any of these:

    compute row_aggregate (column_name) by a, b, c
compute row_aggregate (column_name) by a, b
compute row_aggregate (column_name) by a

    The COMPUTE BY clause cannot be any of these:

    compute row_aggregate (column_name) by b, c
compute row_aggregate (column_name) by a, c
compute row_aggregate (column_name) by c
  • You must use a column name or an expression in the ORDER BY clause; you cannot sort by a column heading.
  • The COMPUTE keyword can be used without BY to generate grand totals, grand counts, and so on. ORDER BY is optional if you use the COMPUTE keyword without BY. (COMPUTE without BY is discussed later in this chapter.)


More Than One Column After COMPUTE BY

Listing more than one column after the keyword BY breaks a group into subgroups and applies the specified row aggregate function at each level of grouping. For example, the following query finds the sum of the prices of psychology books from each publisher:

SELECT type, pub_id, price

FROM titles

WHERE type = 'psychology'

ORDER BY type, pub_id, price

COMPUTE SUM(price) BY type, pub_id

type         pub_id price
------------ ------ --------------------------
psychology   0736   28.00
psychology   0736   31.96
psychology   0736   43.80
psychology   0736   79.96

                    sum
                    ==========================
                    183.72

type         pub_id price
------------ ------ --------------------------
psychology   0877   21.59

                    sum
                    ==========================
                    21.59

(7 row(s) affected)


Using More Than One COMPUTE Clause

You can use different aggregate functions in the same statement by including more than one COMPUTE BY clause. Here's a query similar to the preceding one. It finds the sum of the prices of all psychology books, as well as the sum of the prices of psychology books by publisher:

SELECT type, pub_id, price

FROM titles

WHERE type = 'psychology'

ORDER BY type, pub_id, price

COMPUTE SUM(price) BY type, pub_id

COMPUTE SUM(price) BY type

type         pub_id price
------------ ------ --------------------------
psychology   0736   28.00
psychology   0736   31.96
psychology   0736   43.80
psychology   0736   79.96

                    sum
                    ==========================
                    183.72

type         pub_id price
------------ ------ --------------------------
psychology   0877   21.59

                    sum
                    ==========================
                    21.59
                    sum
                    ==========================
                    205.31

(8 row(s) affected)


Applying an Aggregate to More Than One Column

One COMPUTE BY clause can apply the same aggregate function to several columns. Remember that the columns to which the aggregate functions apply must also be in the select list. This query finds the sum of the prices and advances for each type of cookbook:

SELECT type, price, advance

FROM titles

WHERE type LIKE '%cook'

ORDER BY type, price

COMPUTE SUM(price), SUM(advance) BY type

type         price                      advance
------------ -------------------------- --------------------------
mod_cook     2.99                       15,000.00
mod_cook     19.99                      0.00

             sum
             ==========================
             22.98
                                        sum
                                        ==========================
                                        15,000.00

type         price                      advance
------------ -------------------------- --------------------------
trad_cook    11.95                      4,000.00
trad_cook    14.99                      8,000.00
trad_cook    20.95                      7,000.00

             sum
             ==========================
             47.89
                                        sum
                                        ==========================
                                        19,000.00

(7 row(s) affected)


Using Different Aggregate Functions in the Same COMPUTE BY Clause

You can use different aggregate functions in the same COMPUTE BY clause:

SELECT type, pub_id, price

FROM titles

WHERE type LIKE '%cook'

ORDER BY type, pub_id

COMPUTE SUM(price), MAX(pub_id) BY type

type

pub_id

price

--------

------

-----------

mod_cook

0877

2.99

mod_cook

0877

19.99

sum

==========

22.98

max

=====

0877

type

pub_id

price

---------

------

-----------

trad_cook

0877

11.95

trad_cook

0877

14.99

trad_cook

0877

20.95

sum

==========

47.89

max

=====

0877

(7 row(s) affected)


Grand Values: COMPUTE Without BY

The COMPUTE keyword can be used without BY to generate grand totals, grand counts, and so on.

This statement finds the grand total of the prices and advances for all types of books over $20:

SELECT type, price, advance

FROM titles

WHERE price > $20

COMPUTE SUM(price), SUM(advance)

You can use COMPUTE BY and COMPUTE without BY in the same query. The following query finds the sum of prices and advances by type, and then computes the grand total of prices and advances for all types of books:

SELECT type, price, advance

FROM titles

WHERE type LIKE '%cook'

ORDER BY type, price

COMPUTE SUM(price), SUM(advance) BY type

COMPUTE SUM(price), SUM(advance)

type

price

advance

--------

-----------

-----------

mod_cook

2.99

15,000.00

mod_cook

19.99

0.00

sum

sum

==========

==========

22.98

15,000.00

type

price

advance

---------

-----------

-----------

trad_cook

11.95

4,000.00

trad_cook

14.99

8,000.00

trad_cook

20.95

7,000.00

sum

sum

==========

==========

47.89

19,000.00

sum

sum

==========

==========

70.87

34,000.00

(8 row(s) affected)


Using Built-in Functions

SQL Server provides a variety of built-in functions that help you perform certain operations quickly and easily. These functions fall into the following categories:

  • System functions, most of which return information from the system tables
  • String functions, for manipulating char, varchar, binary, and varbinary values
  • Text and image functions, for manipulating text and image values
  • Mathematical functions, for trigonometry, geometry, and other number handling
  • Date functions, for manipulating datetime and smalldatetime values
  • A conversion function (CONVERT), for converting expressions from one datatype to another and for formatting dates in a wide variety of styles


System Functions

A number of built-in system functions help you query the system tables.

System functions have the following syntax:

SELECT function_name(parameters)

System functions can be used in the select list, in the WHERE clause, and anywhere else an expression is allowed.

For example, there are five pairs of system functions that, for databases, hosts, objects, logins, and users, return a name when given an ID and return an ID when given a name:

DB_ID('database_name') DB_NAME(database_id)
HOST_ID( ) HOST_NAME( )
OBJECT_ID('object_name') OBJECT_NAME(object_id)
SUSER_ID('server_username') SUSER_NAME(server_user_id)
USER_ID('username') USER_NAME(user_id)

To use these functions, combine them with the SELECT statement. These functions can also be included in the WHERE clause of a view to make the view dynamically conform to the user or environment at runtime. Similarly, they can be used in CHECK constraints.

These functions eliminate the need to join two tables when you need to convert a name to an ID or an ID to a name.

The following functions are similar, but they do not occur in complementary pairs and they take more than one input parameter:

COL_NAME(object_id, column_id)
COL_LENGTH('object_name', 'column_name')
INDEX_COL('object_name', index_id, key_id)

The COL_NAME system function returns a column name. The COL_LENGTH system function returns a column length. The INDEX_COL system function returns an index column name.

The following example shows how easy it is to write a query against the system tables when you use the system functions. For example, consider the two system tables sysobjects and sysdepends. If you know the object ID of a particular object, you can list the object IDs of all objects that depend on that object:

select id
from sysdepends
where depid = object_id

Here are some examples:

To find the user identification number of your coworker who logs in as harold:

select user_id('harold')

If harold's user ID number is 13, the result looks like this:

------------

13

(1 row(s) affected)

Generally, as in this example, the name of the function tells you what type of information it returns.

The USER_NAME system function takes an ID number as its parameter and returns the user's name:

select user_name(13)

---------
harold

(1 row(s) affected)

To find the name of the current user (that is, your name), omit the parameter:

select user_name()

------
dbo

(1 row(s) affected)

Built-in functions are always used with parentheses, even when there is no parameter. An exception to this is niladic functions used with DEFAULT constraints. They take no parameters. When the parameter to a system function is optional, the current database, host computer, server user, or database user is assumed.

For a complete list of system functions, see Functions in the Microsoft SQL Server Transact-SQL Reference. The following section gives a few system function examples.


String Functions

String functions are used for various operations on binary data, character strings, or expressions, and they return values commonly needed for operations on character data. String function names are not keywords.

String functions have the following syntax:

SELECT function_name(parameters)

You can concatenate binary or character expressions, like this:

(expression expression [ expression]...)

When concatenating non-character, non-binary expressions, you must use the CONVERT datatype conversion function:

SELECT 'The price is ' + CONVERT(varchar(12), price)
FROM titles
WHERE price > 10.00

-------------------------
The price is 19.99
The price is 11.95
The price is 11.96
The price is 19.99
The price is 19.99
The price is 22.95
The price is 20.00
The price is 21.59
The price is 43.80
The price is 28.00
The price is 79.96
The price is 31.96
The price is 20.95
The price is 11.95
The price is 14.99

(15 row(s) affected)

Most string functions can be used only on char and varchar datatypes and on datatypes that implicitly convert to char or varchar. A few string functions can also be used on binary and varbinary data. PATINDEX (described later in this chapter) can be used on text, char, and varchar columns.

Concatenation can be used on binary and varbinary columns as well as on char and varchar columns.

String functions can be nested, and they can be used anywhere an expression is allowed. When you use constants with a string function, enclose them in single quotation marks.

For a complete list of string functions, see the Functions topic in the Microsoft SQL Server Transact-SQL Reference.

The following sections provide examples using string functions.


SUBSTRING

The SUBSTRING function returns a portion of a character or binary string.

The SUBSTRING function has the following syntax:

SUBSTRING(expression, start, length)

SUBSTRING always takes three parameters. The first can be a character or binary string, a column name, or a string-valued expression that includes a column name. The second parameter specifies the position at which the substring should begin. The third specifies the length (in number of characters) of the string to be returned.

This example displays the last name and first initial of each author ¾ for example, Bennet A:

SELECT au_lname, SUBSTRING(au_fname, 1, 1)
FROM authors

Here's how to display the second, third, and fourth characters of the string constant abcdef:

SELECT x = SUBSTRING('abcdef', 2, 3)

x
----------
bcd

(1 row(s) affected)


CHARINDEX and PATINDEX

The CHARINDEX and PATINDEX functions return the starting position of a pattern you specify.

The CHARINDEX function has the following syntax:

CHARINDEX('pattern', expression)

The PATINDEX function has the following syntax:

PATINDEX('pattern', expression)

Both take two parameters, but work slightly differently because PATINDEX can use wildcard characters (CHARINDEX cannot).

The first parameter is the pattern whose position you want. With PATINDEX, the pattern is a literal string that can contain wildcard characters. With CHARINDEX, the pattern is a literal string (no wildcard characters). The second parameter is a string-valued expression, usually a column name, in which SQL Server searches for the specified pattern.

For example, to find the position at which the pattern "wonderful" begins in a certain row of the notes column in the titles table:

SELECT CHARINDEX('wonderful', notes)

FROM titles

WHERE title_id = 'TC3218'

----------------

46

(1 row(s) affected)

If you do not restrict the rows to be searched, the query returns all rows in the table and it reports non-zero values for those rows in which the pattern was found and zero for all others.

To use wildcards to find the position at which the pattern "wonderful" begins in a certain row of the notes column in the titles table:

SELECT PATINDEX('%wonderful%', notes)

FROM titles

WHERE title_id = 'TC3218'

------------

46

(1 row(s) affected)

If you do not restrict the rows to be searched, the query returns all rows in the table and reports non-zero values for those rows in which the pattern was found.

PATINDEX is useful with text datatypes; it can be used in a WHERE clause in addition to IS NULL, IS NOT NULL, and LIKE (the only other comparisons that are valid on text in a WHERE clause).


STR

The STR function converts numbers to characters, with optional parameters for specifying the total length of the result, including the decimal point and the number of places after the decimal point.

Length and decimal parameters to STR (if supplied) should be positive. The default length is 10. The number is rounded to an integer by default or if the decimal parameter is 0. The specified length should be greater than or equal to the part of the number before the decimal point plus the number's sign (if any):

SELECT STR(123.45, 5, 1)

-----
123.5

(1 row(s) affected)

If the expression exceeds the specified length, the string returns ** for the specified length. For example:

SELECT STR(123.45, 2, 2)

--
**

(1 row(s) affected)

A short expression is right-justified in the specified length, and a long expression is truncated to the specified number of decimal places.

The use of STR() instead of CONVERT (char, numeric expressions) is often preferred because it gives explicit control over formatting.


STUFF

The STUFF function inserts a string into another string. It deletes a specified length of characters in the first string at the start position and then inserts the second string into the first string at the start position.

If the start position or the length is negative, a null string is returned. If the starting position is longer than the first string, a null string is returned. If the length to delete is longer than the first string, it is deleted to the first character in the first string. For example:

SELECT STUFF('abc', 2, 3, 'xyz')

----
axyz

(1 row(s) affected)


SOUNDEX and DIFFERENCE

The SOUNDEX function converts a character string to a four-digit code for use in a comparison. Vowels are ignored in the comparison. Nonalphabetic characters are used to terminate the comparison. This function always returns some value. For example, both of the following strings have the same SOUNDEX codes:

SELECT SOUNDEX ('smith'), SOUNDEX ('smythe')

-----

-----

S530

S530

(1 row(s) affected)

The DIFFERENCE function compares the SOUNDEX values of two strings and evaluates the similarity between them, returning a value from 0 to 4, where 4 is the best match. For example:

SELECT DIFFERENCE('smithers', 'smothers')

------------

4

(1 row(s) affected)

SELECT DIFFERENCE('smothers', 'brothers')

------------

2

(1 row(s) affected)


Concatenation

You can concatenate binary or character expressions, combining two or more character or binary strings, character or binary data, or a combination of them.

If you're concatenating a character string, enclose it in single quotation marks.

Concatenation has the following syntax:

(expression expression [ expression]...)

Here's how to combine two character strings:

SELECT ('abc'  'def')

------
abcdef

(1 row(s) affected)

This query displays California author names under the column heading Moniker in last-name, first-name order, with a comma and space after the last name:

SELECT Moniker = (au_lname + ', ' + au_fname)
FROM authors
WHERE state = 'CA'

Moniker
-------------------------
White, Johnson
Green, Marjorie
Carson, Cheryl
O'Leary, Michael
Straight, Dean
Bennet, Abraham
Dull, Ann
Gringlesby, Burt
Locksley, Charlene
Yokomoto, Akiko
Stringer, Dirk
MacFeather, Stearns
Karsen, Livia
Hunter, Sheryl
McBadden, Heather

(15 row(s) affected)

To concatenate numeric or date datatypes, you must use the CONVERT function:

SELECT 'The due date is ' + convert(varchar(30), pubdate)
FROM titles
WHERE title_id = 'BU1032'

---------------------------------------
The due date is Jun 12 1991 12:00AM

(1 row(s) affected)

The empty string (' ') is evaluated as a single space:

SELECT 'abc' + '' + 'def'

-------
abc def

(1 row(s) affected)


Nested String Functions

String functions can be nested. For example, to display the last name and the first initial of each author living in Oakland, with a comma after the last name and a period after the first initial:

SELECT (au_lname  ',' + '' + substring(au_fname, 1, 1) + '.')
FROM authors
WHERE city = 'Oakland'

----------------------
Green, M.
Straight, D.
Stringer, D.
MacFeather, S.
Karsen, L.

(5 row(s) affected)

To display the pub_id and the first two characters of each title_id for books over $20:

SELECT substring(pub_id  title_id, 1, 6)
FROM titles
WHERE price > $20

For details about other string functions, see Functions in the Microsoft SQL Server Transact-SQL Reference.


Text and Image Functions

Text functions are used for operations on text and image data. For a complete list of text and image functions, see Functions in the Microsoft SQL Server Transact-SQL Reference.

This example uses the TEXTPTR function to locate the text column (pr_info) associated with pub_id 0736 in the pub_info table of the pubs database. It first declares the local variable @val. The text pointer (a long binary string) is then put into @val and supplied as a parameter to the READTEXT statement, which returns 10 bytes starting at the fifth byte (offset of 4):

DECLARE @val varbinary(16)
SELECT @val = textptr(pr_info) FROM pub_info
WHERE pub_id = '0736'
READTEXT pub_info.pr_info @val 4 10

(1 row(s) affected)

pr_info
----------------------------------------
  is sample

The TEXTPTR function returns a 16-character binary string. It is a good idea to put this string into a local variable, as in the preceding example, and use it by reference.

Explicit conversion using the CONVERT function is supported from text to varchar and from image to varbinary or binary, but the text or image data is truncated to 255 bytes. Conversion of text or image to another datatype is not supported, implicitly or explicitly.


Mathematical Functions

Mathematical functions return values commonly needed for operations on mathematical data. Mathematical functions have the following syntax:

FUNCTION_NAME(parameters)

For a complete list of mathematical functions, see Functions in the Microsoft SQL Server Transact-SQL Reference.

Mathematical functions operate on decimal, numeric, integer, float, real, money, or smallmoney numeric data. The precision of built-in operations on float datatype data is six decimal places by default.

By default, a number passed to a mathematical function will be interpreted as a numeric datatype. The CONVERT function can be used to "cast" the datatype to something else, such as a float. For example:

SELECT FLOOR (123.45)

---------------------
123

(1 row(s) affected)

is a numeric and by default returns 123.

But this example:

SELECT FLOOR (CONVERT (float, 123.45))

-------------------------------------
123.0

(1 row(s) affected)

is a float and returns 123.0.

And

SELECT STR (FLOOR (123.45), 8, 3)

---------------------------------
123.000

(1 row(s) affected)

is a numeric nested within STR function, so the result as char with explicit "8,3" formatting (123.000).

Error traps are provided to handle domain or range errors of mathematical functions. A user can set the options ARITHABORT or ARITHIGNORE, which respectively terminate the query or return NULL when a mathematical function encounters a domain error condition. No warning message is displayed. If neither of these options is set, the system returns NULL and prints a warning message after the query is executed. (For additional information about the ARITHABORT and ARITHIGNORE options, see the SET statement in the Microsoft SQL Server Transact-SQL Reference.)

The ROUND function always returns a value even if the length is illegal. If the specified length is positive and longer than the digits after the decimal point, 0 is added after the fraction digits.

If the length is negative and larger than or equal to the digits before the decimal point, ROUND returns 0.00.

For details about the mathematical functions, see Functions in the Microsoft SQL Server Transact-SQL Reference.


Date Functions

Date functions are used to display information about dates and times. They manipulate datetime and smalldatetime values, performing arithmetic operations on them. Date functions can be used in the select list, in the WHERE clause, or wherever an expression can be used.

Values with the datetime datatype are stored internally by SQL Server as two 4-byte integers. The first 4 bytes store the number of days before or after the base date, January 1, 1900. The base date is the system's reference date. Values for datetime earlier than January 1, 1753, are not permitted. The other 4 bytes store the time of day represented as the number of milliseconds after midnight.

The smalldatetime datatype stores dates and times of day with less precision than datetime. SQL Server stores smalldatetime values as two 2-byte integers. The first 2 bytes store the number of days after January 1, 1900. The other 2 bytes store the number of minutes since midnight. Dates range from January 1, 1900, to June 6, 2079, with accuracy to the minute.

The default display format for dates looks like this:

Apr 15 1995 10:23PM

For information about changing the date display format, see "Conversion Function," later in this chapter.

SQL Server recognizes a wide variety of datetime data entry formats. You can use the SET DATEFORMAT statement to set the order of the date parts (month/day/year) for entering datetime or smalldatetime data. When you enter datetime or smalldatetime values, enclose them in single quotation marks.

For a complete list of date functions, see Functions in the Microsoft SQL Server Transact-SQL Reference.


GETDATE

The GETDATE function produces the current date and time in SQL Server internal format for datetime values. GETDATE takes the null parameter ( ).

To find the current system date and time:

SELECT GETDATE()

-------------------------
July 29 1995   2:50    PM

(1 row(s) affected)

You might use GETDATE in designing a report so that the current date and time are printed every time the report is produced. GETDATE is also useful for functions such as logging the time a transaction occurred on an account.


DATEPART and DATENAME

The DATEPART and DATENAME functions produce the specified part of a datetime value ¾ the year, quarter, day, hour, and so on ¾ as either an integer or an ASCII string. Because smalldatetime is accurate only to the minute, when a smalldatetime value is used with either of these functions, the seconds and milliseconds returned are always zero.

The following examples assume the date May 29:

SELECT DATEPART(month, GETDATE())

------------

7

(1 row(s) affected)

SELECT DATENAME(month, GETDATE())

-----------

July

(1 row(s) affected)


DATEDIFF

The DATEDIFF function calculates the amount of time in date parts between the second and first of two dates you specify ¾ in other words, it finds an interval between two dates. The result is a signed integer value equal to date2 - date1 in date parts.

This query uses the date November 30, 1995, and finds the number of days that elapsed between pubdate and that date:

SELECT DATEDIFF(day, pubdate, 'Nov 30 1995')
FROM titles

For the rows in titles having a pubdate of October 21, 1995, the result produced by the previous query is 40. (There are 40 days between October 21 and November 30.) To calculate an interval in months, type:

SELECT interval = DATEDIFF(month, pubdate, 'Nov 30 1995')
FROM titles

This query produces a value of 1 for the rows with a pubdate in October and a value of 5 for the rows with a pubdate in June.

When the first date in the DATEDIFF function is later than the second date specified, the resulting value is negative. Since two of the rows in titles have values for pubdate that are assigned using the GETDATE function as a default, these values are set to the date that your pubs database was created and return negative values in the two preceding queries.

If one or both of the date arguments is a smalldatetime value, they are converted to datetime values internally for the calculation. Seconds and milliseconds in smalldatetime values are automatically set to 0 for the purpose of calculation.


DATEADD

DATEADD adds an interval to a date you specify. For example, if the publication dates of all books in the titles table slipped three days, you could get the new publication dates with this statement:

SELECT DATEADD(day, 3, pubdate)
FROM titles

If the date parameter is a smalldatetime datatype, the result is also a smalldatetime. You can use DATEADD to add seconds or milliseconds to a smalldatetime value, but doing this is meaningful only if the result date returned by DATEADD changes by at least 1 minute.


Conversion Function

The conversion function, CONVERT, is used to convert expressions of one datatype to another datatype whenever these conversions are not performed automatically by SQL Server. It is also used to obtain a variety of special date formats. The conversion function can be used in the select list, in the WHERE clause, and anywhere an expression is allowed.

The CONVERT function has the following syntax:

CONVERT(datatype [(length)], expression [, style])

Here's an example that uses CONVERT in the select list to convert the title column to a char(50) column so the results are more readable:

SELECT CONVERT(char(50), title), ytd_sales
FROM titles
WHERE type = 'trad_cook'

title

ytd_sales

--------------------------------------------------

---------

Onions, Leeks, and Garlic: Cooking Secrets of the
375

Fifty Years in Buckingham Palace Kitchens
15096

Sushi, Anyone?
4095

(3 row(s) affected)

In this example, the ytd_sales column, an int column, is converted to a char(20) column so that it can be used with the LIKE clause:

SELECT title, ytd_sales
FROM titles
WHERE convert(char(20), ytd_sales) LIKE '15%'
    AND type = 'trad_cook'

title

ytd_sales

-----------------------------------

---------

Fifty Years in Buckingham Palace
Kitchens

15096

(1 row(s) affected)

SQL Server automatically handles certain datatype conversions. For example, if you compare a char expression and a datetime expression, or a smallint expression and an int expression, or char expressions of different lengths, SQL Server converts them automatically. You need not use the CONVERT function for these conversions. However, it is never wrong to use the CONVERT function, even when you are comparing two expressions of exactly the same datatype.

If you attempt a conversion that is not possible (for example, if you try to convert a char expression that includes letters to int), SQL Server displays an error message.

For a complete list of possibilities for converting datatypes, see Functions in the Microsoft SQL Server Transact-SQL Reference.

If you do not specify a length when converting for the datatype to which the expression is to be converted, SQL Server automatically supplies a length of 30.

When converting to datetime or smalldatetime, SQL Server rejects all values it cannot recognize as dates (including dates earlier than January 1, 1753).

You can convert datetime values to smalldatetime when the date is in the proper range (January 1, 1900, to June 6, 2079). The time value is rounded up to the nearest minute.

Converting to bit changes any non-zero value to 1.

When converting to money or smallmoney, integers are assumed to be monetary units. For example, the integer value of 4 is converted to the money equivalent of 4 dollars (for us_english, the default language). Numbers to the right of the decimal in floating-point values are rounded to four decimal places for money values.

Expressions of datatypes char or varchar that are being converted to an integer datatype must consist only of digits and an optional plus or minus sign ( or -). Leading blanks are ignored. Expressions of datatypes char or varchar that are being converted to money can also include an optional decimal point and dollar sign ($).

Expressions of datatypes char or varchar that are being converted to float or real can also include optional exponential notation (e or E, followed by an optional  or - sign, and then a number).

When expressions are converted to a datatype of a different size, values too long for the new datatype are truncated, and SQL Server displays an asterisk (*). Here's an example:

SELECT title, CONVERT(char(2), ytd_sales)

FROM titles

WHERE type = 'trad_cook'

title

---------------------------------------------------------------

Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean

Fifty Years in Buckingham Palace Kitchens

Sushi, Anyone?

(3 row(s) affected)

When converting between datatypes with a different number of decimal points, the value is truncated. For example, the result of CONVERT(money, 10.3496) is $10.35.

You can explicitly convert text columns to char or varchar columns, and image columns to binary or varbinary columns. Because these datatypes are limited to 255 characters, you are limited to the maximum length of the character and binary datatypes, 255 characters. If you do not specify the length, the converted value has a default length of 30 characters. Implicit conversion is not supported.


The style Parameter

The style parameter of CONVERT provides a wide variety of date display formats when converting datetime data to char or varchar. The number you supply as the style parameter determines how the datetime data is displayed. The year can be displayed in either two or four digits. Add 100 to a style value to get a four-place year, including the century (yyyy).

The following example shows CONVERT with the style parameter:

SELECT CONVERT(char(12), GETDATE(), 3)

This statement converts the current date to style 3, dd/mm/yy. For more information about the values for the style parameter, see Functions in the Microsoft SQL Server Transact-SQL Reference.


Chapter 5 Optimizing Performance

Optimizing Performance

To most effectively optimize SQL Server performance, you should focus on the areas that will yield the largest performance increases over the widest variety of situations. Microsoft SQL Server includes an intelligent, cost-based query optimizer which can quickly determine the best access method for retrieving the data, including the order in which to join tables and whether or not to use indexes that might be on those tables. The greatest benefit in SQL Server performance can usually be gained when you optimize the following areas:

  • Logical database and table design
  • Index design
  • Query design

The biggest performance problems are often caused by deficiencies in these areas.

This chapter focuses on the areas that have been shown to be of practical value in real world situations. You should concentrate on these areas first, because large performance improvements can often be achieved with a relatively small time investment. You can avoid spending significant time and effort on areas that may not yield sizable improvements.


Optimizing Tables

The logical design of the database, including the tables and the relationships between tables, is the core of an optimized relational database. A good logical database design can lay the foundation for optimal database and application performance. A poor logical database design can hinder the performance of the entire system.


Normalizing Logical Database Design

Normalizing a logical database design involves using formal methods to separate the data into multiple, related tables. A greater number of narrow tables (with
fewer columns) is characteristic of a normalized database. A few wide tables
(with more columns) is characteristic of an unnormalized database.

Reasonable normalization will often improve performance. When useful indexes are available, the SQL Server optimizer is very efficient at selecting rapid, efficient joins between a reasonable number of tables.

These are some of the benefits of normalization:

  • Faster sorting and index creation because tables are narrower.
  • More clustered indexes are allowed because there are more tables.
  • Narrower and more compact indexes.
  • Fewer indexes per table, helping INSERT, UPDATE and DELETE performance.
  • Fewer NULLs and less redundant data, increasing database compactness.
  • Improved concurrency when running DBCC diagnostics, because the necessary table locks will affect less data.

As normalization increases, so will the number and complexity of joins required to retrieve data. Too many complex relational joins between too many tables can hinder performance. Reasonable normalization often includes very few regularly executed queries that use more than four-way joins.

Sometimes the logical database design is already fixed and total redesign is not feasible. Even then, however, it might be possible to selectively normalize a large table into several smaller tables. If access to the database is conducted through stored procedures, this schema change could take place without affecting applications. If not, it might be possible to create a view that hides the schema change from the applications.


Defining Keys

Defining primary keys, foreign keys, and "candidate" keys are an important part of normalization.

These are some of the characteristics of a normalized database:

  • The columns of a table depend on the primary key of the table.
  • A foreign key of a table is related to the primary or "candidate" key of another table.
  • The rows in related tables are retrieved using relational joins.

For tables that will be regularly joined, it is recommended that the columns used to specify the join have the same base datatype, not including nullability or length. For example, these datatypes are considered to be the same base datatype:

  • char(10) and char(20) null and varchar(30)
  • int and int null

These datatypes are considered to be different base datatypes:

  • int and smallint and tinyint
  • char(10) and int

Note that when defining a FOREIGN KEY constraint using the REFERENCES clause of a CREATE TABLE or ALTER TABLE statement, SQL Server requires that the number of columns and the datatypes of each column in the table exactly match the columns listed in the REFERENCES clause.

For two columns of the same base datatype used to specify a join, the SQL Server optimizer can use any indexes defined on the columns to speed up the join. For example, given the following query using the pubs database:

SELECT * FROM sales, titles
WHERE sales.title_id = titles.title_id

it would be best to define the title_id column in both the sales and titles tables as the same base datatype, and to have indexes on one or both title_id columns.

SQL Server automatically creates an index for a PRIMARY KEY or UNIQUE constraint. Consider creating an index manually (using the CREATE INDEX statement) for a FOREIGN KEY constraint.

Note that because each referenced table requires some overhead, you should avoid creating redundant or overlapping FOREIGN KEY constraints. If an existing FOREIGN KEY constraint references table1..id_column:

  • Another FOREIGN KEY constraint that includes a reference to table1..id_column is usually overlapping.
  • Another FOREIGN KEY constraint that includes a reference to table2..id_column is usually redundant.


Optimizing Indexes

Effective index design is very important in achieving good SQL Server performance. Because indexes are not considered part of the logical database design, they can be dropped, added, and changed without affecting the database schema. Experimenting with indexes will affect the performance only of a database or application.

The SQL Server query optimizer can use an index to reduce the number of logical page I/Os required to execute an SQL statement. (A logical page I/O will result in a physical page I/O from the hard disk only when the page is not in the cache.) When no indexes are available, SQL Server must perform a table scan, reading every data page in the table. When an index is available, and the optimizer determines that using that index will result in fewer logical and physical page I/Os than a table scan, it will use that index. Indexes that are likely to be used by the optimizer are called useful indexes.

The optimizer will reliably choose the most useful index in the majority of cases. This means that you must anticipate the types of queries required and define useful indexes to minimize table scans. The overall strategy should be to provide a good selection of indexes to the SQL Server optimizer, and trust it to make the right decision. This reduces analysis time and gives good performance over a wide variety of situations.


Creating Useful Indexes

The usefulness of an index depends on the selectivity of the data for a query. Selectivity is an estimate of the percentage of the rows in a table that are returned for a query. The SQL Server optimizer uses the distribution page statistics to evaluate available indexes, estimate the number of page I/Os required, and chooses the method that will result in the fewest number of logical page I/Os.

Examine the WHERE clause of your queries, since that is the primary focus of the optimizer. Each column included in the WHERE clause is a possible candidate for an index. For optimal performance, consider the following useful indexes for a given column1 in the WHERE clause:

  • A single-column index on column1
  • A multicolumn index, where column1 is the first column of the index

Avoid defining a multicolumn index where column1 is the second or later column in the index. This would not be a useful index.

For example, given the following query using the pubs database:

SELECT au_id, au_lname, au_fname FROM authors
WHERE au_lname = 'White'

an index on the following columns could be useful to the optimizer:

  • au_lname
  • au_lname, au_fname

but an index on these columns would not be useful to the optimizer:

  • au_address
  • au_fname, au_lname

Consider using narrow indexes with one or two columns. Narrow indexes are often more effective than multicolumn, compound indexes. Narrow indexes have more rows per page and fewer index levels, boosting performance. The optimizer can rapidly and effectively analyze hundreds, or even thousands, of index and join possibilities. Having a greater number of narrow indexes provides the optimizer with more possibilities to choose from, which usually helps performance. Having a lesser number of wide, multicolumn indexes provides the optimizer with fewer possibilities to choose from, which may hurt performance.

For multicolumn indexes, SQL Server maintains density statistics (used for joins) on all columns of the index and histogram statistics on the first column of the index. Note that if the first column of a compound index has poor selectivity, the optimizer may not use the index for some queries.

Useful indexes can improve the performance of SELECT statements, as well as INSERT, UPDATE, and DELETE statements. However, because changes to a table might affect the indexes on that table, each indexes can slow down INSERT, UPDATE, and DELETE performance to some degree. Experiment with a new index and examine its effect on performance. Avoid a large number of indexes on a single table, and avoid overlapping indexes that contain shared columns.

Examine the number of unique data values in a column and compare it to the number of rows in the table. This is the selectivity of that column, which can help you decide if a column is a candidate for an index and, if so, what type of index.

You can use the following query to return the number of unique values for a column:

SELECT COUNT (DISTINCT column_name) FROM table_name

This table shows some example return values and the type of index you might consider putting on column_name for a 10,000-row table_name:

Unique values | Index
5000 | Nonclustered index
20 | Clustered index
3 | No index


Clustered Indexes

A clustered index is one in which the physical order of rows is the same as the indexed order of rows. The bottom, or leaf, level of a clustered index contains the actual data pages.

You can have only a single clustered index per table, so use this index wisely. UPDATE and DELETE operations are often accelerated by clustered indexes, since these operations require much reading. Typically, for a table that has at least one index, you should make one of those indexes a clustered index.

Consider using a clustered index for:

  • Columns that contain a limited (but not tiny) number of unique values.

    For example, a state column of a customers table that contains 50 unique state abbreviations, such as WA, CA, and MO.

  • Queries that return a range of values, using operators such as BETWEEN, >, >=, <, and <=.

    For example:

    SELECT * FROM sales
WHERE ord_date BETWEEN '5/1/93' AND '6/1/93'
  • Queries that return large results sets.

    For example:

    SELECT * FROM phonebook
WHERE last_name = 'Smith'

When a significant number of rows are being inserted into a table, avoid putting a clustered index on a monotonically increasing column, such as an identity column, of that table. Insert performance can be degraded if you do this, because each inserted row must go at the end of the table, on the last data page of the table. While one row is being inserted into the last data page (thus locking the data page), all other inserted rows must wait in a queue until the current insert is complete.

The leaf-level pages of a clustered index are actual data pages, and the data pages are physically ordered on the hard disk using the logical order of the clustered index.


Nonclustered Indexes

A nonclustered index is one in which the logical ordering of a table is specified. The physical order of the rows is not the same as their indexed order. The leaf level of a nonclustered index contains pointers to rows on data pages.

You can have multiple nonclustered index per table. Consider using a nonclustered index for:

  • Columns that contain a large number of unique values.

    For example, a part_id column of a parts table.

  • Queries that return small or single-row results sets.

    For example:

    SELECT * FROM employee
WHERE emp_id = 'PCM98509F'
  • Queries that use an ORDER BY clause and the FASTFIRSTROW optimizer hint.

The leaf-level pages of a nonclustered index are index pages, which contain indexed column data and pointers to data pages. These data pages are unordered. Unless all columns in the SELECT list and all columns in the WHERE clause are part of the nonclustered index, SQL Server must first read the index (requiring one or more logical page I/Os depending on the depth of the index) and then read the data page pointed to by the index.

When these extra logical data page I/Os are required, the total number of page I/Os required to execute the query can increase dramatically for large results sets. In this case, a table scan is often more efficient than a nonclustered index. When the selectivity of a query reaches around 15 percent of the table size of a smaller table, it is usually less expensive for the optimizer to use a table scan than to use the nonclustered index. The SQL Server optimizer estimates how many physical I/Os would be required under each strategy, and chooses the optimal one.


Distribution Pages

You can optimize tables by periodically updating the statistics of indexes on the tables. To update statistics, use the UPDATE STATISTICS statement.

The UPDATE STATISTICS statement creates or updates information about the distribution of the key values in the indexes. This helps SQL Server determine which indexes to use when processing a query. You should use this statement when a large amount of data in an indexed column has been added, changed, or deleted.

Distribution pages are a sampling of data values that SQL Server uses to decide if the index is useful. Distribution pages provide a ratio of the number of rows for which the selection clause will qualify to the number of rows in a table. They are used to determine whether it is more efficient to use the index or to scan the table. A distribution page occupies one full data page.

Distribution pages are created when you run UPDATE STATISTICS on data containing one or more indexes, or when you create an index on already existing data. The UPDATE STATISTICS statement adds one distribution page per index on which statistics have been created. If you use UPDATE STATISTICS for an entire table, add one page for each index on the table. If you UPDATE STATISTICS for only one index, add one page.

Note You can see all of the statistical information in the distribution page for an index by using the DBCC SHOW_STATISTICS statement. The results returned indicate the selectivity of an index (the lower the density returned, the higher the selectivity) and provide the basis for determining whether or not an index would be useful to the optimizer. For details, see the DBCC statement in the Microsoft SQL Server Transact-SQL Reference.

You can display the date that the distribution page was last updated with current statistics by using the system function STATS_DATE. For details, see the System Functions topic in the Microsoft SQL Server Transact-SQL Reference.

Before the selectivity of a clause can be determined, the distribution page must contain valid data. It is necessary to establish statistics for the tables used by the optimizer. This requires that you issue an UPDATE STATISTICS statement periodically ¾ especially after extensive changes to a table. This is because a distribution page contains static information and the UPDATE STATISTICS statement is required to update the information in the distribution page based on the current data in a table. As an example, to update the distribution pages for the index called aunmind on the authors table of the pubs database, type:

UPDATE STATISTICS authors aunmind

Permission to execute the UPDATE STATISTICS statement defaults to the table owner and cannot be transferred. For details, see the UPDATE STATISTICS statement in the Microsoft SQL Server Transact-SQL Reference.


Using FILLFACTOR

Using the SQL Server FILLFACTOR feature can reduce page splitting overhead for insert and update operations on a table using a clustered index. Using FILLFACTOR reserves a percentage of free space on each data page of the index to accommodate future expansion.

The FILLFACTOR option allows you to specify how full SQL Server should make each index page, and each data page in the case of a clustered index. This is important from a performance standpoint because when an index page fills up (after enough rows are added), the system must take time to split the index page to make room for the new row. When you're going to add a lot of data to the table after the index is created, specify a low FILLFACTOR. That way, the data is spread over more pages, leaving space for the rows you plan to add.

The FILLFACTOR is not maintained after the index is initially built. However, if index pages become too full and page splits become a performance problem, you can drop and rebuild indexes to reestablish the desired FILLFACTOR.

Using an appropriate FILLFACTOR when indexes are defined allows you to reduce index page splitting and, in the case of clustered indexes, data page splitting. Maintaining free space will avoid page splits and improve online transaction processing performance. In off hours, the clustered index can be rebuilt with the FILLFACTOR to reestablish the space.

Sometimes using a unique index on a table so that no duplicate index values can be inserted reduces processing cost. If all the columns in a WHERE clause use the equality (=) relational operator and are contained in the unique index, the optimizer uses the unique index to process the query because it knows that there is a minimal fixed cost involved in the index.


Optimizing Queries

The SQL Server optimizer automatically performs query optimization by analyzing queries and determining the most efficient execution plan. The optimizer analyzes a query to determine which clauses in the query can be optimized and then selects the useful indexes for the clauses that can be optimized. Finally, the optimizer compares all possible execution plans and selects the most efficient one for execution.

Use the WHERE clause to restrict the number of rows that must be processed to execute a query. Unless absolutely necessary, avoid unrestricted queries that must read and process all the rows of a table. For example, the following restricted query:

SELECT qty FROM sales
WHERE stor_id = 7131

is more efficient than the following unrestricted query:

SELECT qty FROM sales

Avoid returning a large results set to the client for final data selection through browsing. It is much more efficient to restrict the size of the results set, allowing SQL Server to perform the function for which it was intended. This also reduces network I/O and improves concurrency-related performance as the application scales upward to more users.

Because the WHERE clause of a query is the primary focus of the optimizer, use queries that can take advantage of a useful index. Each index on the table includes columns that are possible candidates for including in the WHERE clause. For optimal performance with one of the following indexes on a given column1:

  • A single-column index on column1
  • A multicolumn index where column1 is the first column of the index

consider a query with a WHERE clause that includes column1. Avoid using a WHERE clause that includes only the second or later columns of a multicolumn index, and not column1. The multicolumn index would not be useful in this case.

For example, given a multicolumn index on the au_lname, au_fname columns of the authors table in the pubs database, the following queries would be likely to use the index:

SELECT au_id, au_lname, au_fname FROM authors
WHERE au_lname = 'White'
AND au_fname = 'Johnson'
SELECT au_id, au_lname, au_fname FROM authors
WHERE au_lname = 'White'

and the following query would not be able to use the index:

SELECT au_id, au_lname, au_fname FROM authors
WHERE au_fname = 'Johnson'


Resource-intensive Queries

Some types of queries are inherently resource-intensive. This is related to fundamental database and index issues common to most relational databases, including SQL Server. They are not inefficient, as the optimizer will execute the queries in the most efficient fashion possible. However, they are resource-intensive, and the set-oriented nature of SQL Server may make them appear inefficient. No degree of optimizer intelligence can eliminate the inherent resource cost of these constructs. They are intrinsically costly when compared to a more simple query. Although SQL Server will use the most optimum access plan, this is limited by what is fundamentally possible.

For example, the following query characteristics are resource-intensive:

  • Large results sets
  • IN, NOT IN, and OR queries
  • <> (not equal)
  • Row aggregate functions, such as SUM
  • Local variables, expressions, or data conversions in the WHERE clause
  • Highly nonunique WHERE clause
  • Complex views with GROUP BY or ORDER BY

Various factors may require the use of some of these query constructs. The effect of these will be lessened if the optimizer can restrict the results set before applying the resource-intensive portion of the query. For example, the following restricted query is efficient:

SELECT SUM(qty) FROM sales
WHERE stor_id = 7131

If an index exists on the department column, the optimizer will likely use it to restrict the results set before applying the SUM operation, which can improve performance. Compare that with the following unrestricted and inefficient query, in which the sum operation must read every row in the table:

SELECT SUM(qty) FROM sales

For example, the following query is efficient:

SELECT * FROM phonebook
WHERE last_name = @var
AND zip_code = 98052

If an index exists on the zip_code column, the optimizer will likely use it to restrict the results set, which can improve performance. Compare that with the following inefficient query:

SELECT * FROM phonebook
WHERE last_name = @var

The value in the local variable is only known at run time. Because the optimizer builds the access plan and makes index usage decisions at compile time, the optimizer cannot use the value in the local variable to restrict the results set, even with an index on the zip_code column.


Covered Queries

A nonclustered index covers a query when all columns in the SELECT list and all columns in the WHERE clause are part the nonclustered index. In this case, the optimizer uses the index for data retrieval, because all required data can be read from the index pages, and the data pages do not need to be read. However, avoid creating excessively wide indexes and hoping that the optimizer will use this strategy. It is usually best to use more numerous narrow indexes, which often provides better performance over a wider range of queries.


Analyzing Queries

When performance is slow, first isolate the query or queries that are slow. Often it will appear that an entire application is slow, when only a few of the queries are slow. For a development tool that transparently generates SQL, use any available diagnostic or debug mode of this tool to capture the generated SQL. For tools that use embedded SQL, this is much easier. If your development tool does not provide this, you can use the 4032 trace flag to capture SQL statements sent to SQL Server. For more information about trace flags, see the Microsoft SQL Server Administrator's Companion and Trace Flags in the Microsoft SQL Server Transact-SQL Reference.

After the slow query is isolated, run the suspected slow query in isolation, using a query tool such as isql, and verify it is in fact slow. It is often best to run the query on the server computer using isql and local pipes, and to redirect the output to a file. This helps eliminate complicating factors such as network and screen I/O and application result buffering.

Use SET STATISTICS IO ON to examine the I/O consumed by the query. Give attention to the count of logical page I/Os. The optimizer's goal is to minimize I/O count. Make a record of the logical I/O count. This forms a baseline against which to measure improvement. It is often more effective to focus exclusively on the STATISTICS IO output and experiment with different query and index types than to use SET SHOWPLAN ON. Interpreting and effectively applying the output of SHOWPLAN can require some study, and it can consume time that can be more effectively spent on empirical tests. If your performance problem isn't fixed by these simple recommendations, then you can use SHOWPLAN to investigate the optimizer behavior more deeply. For more information about SHOWPLAN, see the Microsoft SQL Server Administrator's Companion.

If the query involves a view or stored procedures, extract the query from the view or stored procedures and run it separately. This allows the access plan to change as you experiment with different indexes. It also helps localize the problem to the query itself, versus how the optimizer handles views or stored procedures. If the problem is not in the query itself but only when it is run as part of a view or stored procedure, running the query by itself will help determine this.

Be aware of possible triggers or FOREIGN KEY constraints (referencing other tables or referenced by other tables) on the involved tables that can transparently generate I/O as the trigger runs or the constraint is checked. It is best to remove any triggers involved in a slow query. This will help determine if the problem is in the query itself or the trigger or view, and it will help direct your focus.

Examine the indexes of the tables used by the slow query. Use the techniques described in this chapter to determine if these are good indexes, and change them if necessary. For testing, consider an index on each column in your WHERE clause. Often performance problems are caused by having no index or no useful index on a column in the WHERE clause.

Run the query again after making the index change and observe any change in I/O count. After noting improvement, run the main application with the improved query to see if overall performance is better.

In a case in which you want to force the optimizer, you can use the SET FORCEPLAN ON statement or use optimizer hints to persuade the optimizer to use a specific index, locking strategy, or whether to optimize for "first row response time" or overall throughput (that is, minimizing physical I/Os).


Analyzing Locks

When two or more users access a database concurrently, Microsoft SQL Server uses locking to ensure that their actions don't interfere with one another. Locking prevents users from reading data that is being changed by other users, and it prevents users from making more than one change to a record at any one time.

Although SQL Server enforces locking automatically, you can design applications more efficiently by understanding locking and customize locking in your applications.


Understanding Locking

The following table describes the three different types of locks that SQL Server uses:

Lock Type | Description
Shared | SQL Server usually uses shared locks for operations that do not change or update data, such as a SELECT statement.
Update | SQL Server uses update locks when it intends to modify a page, and later promotes the update page lock to an exclusive page lock before actually making the changes.
Exclusive | SQL Server uses exclusive locks for the data modification operations UPDATE, INSERT, or DELETE.

These are the different types of items that can be locked by SQL Server:

Item | Description
Page | A 2K data page or index page. This is the most common type of lock.
Extent | A contiguous group of 8 2K data pages or index pages. This lock is only used for allocation.
Table | An entire table, including all data and indexes.
Intent | A special type of table lock to indicate the type of page locks currently placed on the table.

This table describes the compatibility of different types of page locks with each other:

 | Shared | Update | Exclusive
Shared | Yes | Yes | No
Update | Yes | No | No
Exclusive | No | No | No

An entry of "Yes" means that these locks are compatible. An entry of "No" means these locks are incompatible. While a particular type of lock is held on a specific page, only compatible lock types can be placed on that same page.

For example, while an exclusive lock is held, no other transaction can acquire a lock of any kind (shared, update, or exclusive) on that item until the exclusive lock is released at the end of the first transaction.

If a shared lock has been applied to an item, other transactions can also acquire a shared lock or an update lock on that item ¾ even if the first transaction hasn't completed. However, other transactions cannot acquire an exclusive lock until the shared lock has been released.


Displaying Locking Information

To get a report on the locks currently held on SQL Server, use SQL Enterprise Manager.

To get a report on locks
  • From the Server menu in SQL Enterprise Manager, choose Current Activity, and then examine the User Activity, Detail Activity, and Object Locks tabs in the Current Activity dialog box.

Or

  • Execute the sp_lock system procedure:
    sp_lock
spid

locktype

table_id

page

dbname

----

---------

--------

-----

-----------

1

Sh_intent

16003088

0

master

4

Ex_extent

0

440

pubs

4

Ex_extent

0

504

pubs

4

Sh_table

112003430

0

pubs

4

Ex_table

240003886

0

pubs

The locktype column provides the following information:

  •
The type of lock: shared (Sh), exclusive (Ex), or Update.
    •

  •
What the lock is holding: a table, page, or extent
    •

  •
Whether the lock represents an intent to acquire a shared or exclusive lock on a data page.
    •

  •
Whether the lock is blocking (blk) another process
    •

In general, you apply shared locks for read operations and exclusive locks for write operations. However, if you want to read data initially, but possibly change it later, use an update lock.

An intent lock indicates that SQL Server wants to acquire a shared or exclusive lock on a data page. Setting an intent lock prevents another transaction from subsequently acquiring an exclusive lock on the table containing that page.

An extent lock is a lock held on a group of eight contiguous database pages while they are being allocated or freed. Extent locks are set during a CREATE or DROP statement, or during an INSERT operation that requires new data or index pages.

The blk suffix indicates that one process is blocking other processes that need to acquire locks. As soon as the blocking process completes, the other processes move forward.

For more information about locks, you can query the syslocks system table. For details, see the Microsoft SQL Server Administrator's Companion.


Customizing Locking

Although SQL Server implements locking automatically, you can customize locking by using SELECT statement options or by choosing an isolation level with the SET statement. The system administrator can customize locking for all users of SQL Server by setting the lock escalation level.


Customizing Locking with SELECT

In a SELECT statement, you can specify one or more of the following locking options for a table:

Option | Description
NOLOCK | Directs SQL Server not to issue shared locks and not to honor exclusive locks. When this option is in effect, it is possible to read a noncommitted transaction or a set of pages that are rolled back in the middle of a read. This option is also known as "dirty reads."
HOLDLOCK | Instructs SQL Server to hold a shared lock until completion of the transaction in which HOLDLOCK is used, instead of releasing the lock as soon as the required table, view, or data page is no longer needed.
UPDLOCK | Directs SQL Server to use update locks instead of shared locks while reading a table and to hold the locks until the end of the command or transaction. UPDLOCK has the advantage of allowing you to read data (without blocking other readers) and update it later on with the assurance that the data has not changed since you read it.
TABLOCK | Directs SQL Server to use a shared lock on a table. This lock allows others to read a table, but prevents them from updating it. This lock is held until the end of the command; however, if you also specify HOLDLOCK, the lock is held until the end of the transaction.
PAGLOCK | Directs SQL Server to use shared page locks. This is the default.
TABLOCKX | Directs SQL Server to use an exclusive lock on a table. This lock prevents others from reading or updating the table and is held until the end of the command or transaction.

These locking options override corresponding session-level options specified with the SET statement (see Customizing Transaction Isolation Level). For details about these options, see SELECT statement in the Microsoft SQL Server Transact-SQL Reference.


Customizing Transaction Isolation Level

In addition to customizing locking with SELECT, you can also customize locking for an entire SQL Server session by setting the session's isolation level with the SET TRANSACTION ISOLATION LEVEL statement. When you set the isolation level, you specify the default locking behavior for all SELECT statements in your SQL Server session.

The following table describes the available isolation levels:

Option | Description
READ COMMITTED | Directs SQL Server to use shared locks while reading data (the default). At this level, you cannot experience "dirty reads."
READ UNCOMMITTED | Directs SQL Server not to issue shared locks and does not honor exclusive locks. At this level you can experience "dirty reads," and because you can read an uncommitted transaction that might get rolled back later, you can get "phantom values" (after a rollback, the value you read logically never existed.)
REPEATABLE READ Or SERIALIZABLE | Indicates that "dirty reads," nonrepeatable reads, and phantom values cannot occur. REPEATABLE READ and SERIALIZABLE are interchangeable.

If you specify an isolation level, you can override it in individual SELECT statements by specifying the appropriate locking option with each statement (see Customizing Locking with SELECT).

Additionally, you can use DBCC USEROPTIONS to see which isolation level is set. For more information about DBCC, see DBCC statement in the Microsoft SQL Server Transact-SQL Reference.


Setting the Lock Escalation Level

The system administrator can further customize locking by setting SQL Server's lock escalation level. The lock escalation level determines when SQL Server applies table locks instead of page locks (the default), and it affects all users of SQL Server.

When a query requests rows from a table, SQL Server automatically generates page-level locks. However, if the query requests a large percentage of the table's rows, then SQL Server escalates the locking from page level to table level. This process is called lock escalation, and it makes table scans and operations against a large results set more efficient because it reduces locking overhead.

The system administrator configures lock escalation levels by using the sp_configure system stored procedure. For details, see sp_configure system stored procedure in the Microsoft SQL Server Transact-SQL Reference.


Preventing Deadlocks and Lock Starvation

SQL Server automatically detects and resolves deadlocks. A deadlock occurs when two users have locks on separate objects and each user wants a lock on the other's object. Each user waits for the other to release their lock. A deadlock typically occurs when several long-running transactions execute concurrently in the same database.

SQL Server ends a deadlock by automatically choosing the user that can break the deadlock. SQL Server rolls back the breaking user's transaction, notifies the user's application (with message number 1205), cancels the user's current request, and then allows the nonbreaking user's process to continue.

In a multiuser situation, each application should check for message 1205. This indicates that the transaction was rolled back. If so, the user's application must restart the transaction.

Note To reduce the chance of a deadlock, minimize indexing (and the possibility of index locking) on appropriate tables, shorten transactions and transaction times, and use resources in the same order in all transactions.

SQL Server automatically prevents lock starvation. Lock starvation occurs when read transactions can monopolize a table or page, forcing a write transaction to wait indefinitely. SQL Server handles read and write transactions on a first-come first-served basis, which prevents lock starvation.


Chapter 6 Using Stored Procedures and Triggers

Using Stored Procedures and Triggers

You can refine your applications by using stored procedures, compiled collections of SQL statements and control-of-flow language that execute very quickly. For example, you can use stored procedures called triggers to define business processes.

This chapter describes how to create and use stored procedures in general and triggers in particular.


Using Stored Procedures

Stored procedures greatly enhance the power, efficiency, and flexibility of SQL Server, and dramatically improve the performance of SQL statements and batches.

Stored procedures can:

  • Take parameters.
  • Call other procedures.
  • Return a status value to a calling procedure or batch to indicate success or failure (and the reason for failure).
  • Return values of parameters to a calling procedure or batch.

Stored procedures on other SQL Servers to which the client process is not directly connected to can be executed if the remote server has been set up to allow remote logins. You can write triggers on your local SQL Server that execute procedures on a remote server whenever certain events (inserts, updates, or deletes) occur locally. (For details about triggers, see Using Triggers to Define Business Processes.)

Stored procedures differ from ordinary SQL statements and from batches of SQL statements in that they are pre-parsed and pre-normalized. The first time you run a procedure, the SQL Server query processor analyzes it and prepares internal, normalized structure for the procedure that is stored in a system table. The first time the procedure is run when the SQL Server is started, the procedure is then brought into memory and fully compiled (but it does not need to be re-parsed or "sequenced" since this was done when the procedure was created). The fully compiled plan then stays in memory (unless other memory needs force it out so that the next request for execution (whether by the same or a different client) can be processed without any plan compilation overhead.

Stored procedures can serve as security mechanisms, since a user can be granted permission to execute a stored procedure even if he or she does not have permissions on tables or views referenced in it. (For details, see the Microsoft SQL Server Administrator's Companion.)


Creating Stored Procedures

You create stored procedures using the CREATE PROCEDURE statement. Permission to execute CREATE PROCEDURE defaults to the database owner, who can transfer it to other users. Stored procedures are database objects, and their names must follow the rules for identifiers. You can create a stored procedure only in the current database.

With the exception of CREATE statements, any number and type of SQL statements can be included in stored procedures. (For more information about the rules for creating stored procedures, see Stored Procedure Rules.)

You can nest stored procedures (have one stored procedure call another) up to 16 levels. The nesting level increases by one when the called procedure begins execution and decreases by one when the called procedure completes execution. Attempting to exceed the maximum of 16 levels of nesting causes the whole calling procedure chain to fail. The current nesting level is stored in the @@NESTLEVEL global variable.

After procedures are created, they are executed.

To create a stored procedure
  • From the Manage menu in SQL Enterprise Manager, choose Stored Procedures, and then choose New from the Procedures drop-down list.

    (For details, search for "stored procedures" in SQL Enterprise Manager Help.)

Or

  • Use the CREATE PROCEDURE statement.

    For example:

    CREATE PROCEDURE namelist
AS SELECT name FROM sysusers

    lists the names of all the users in a database. You get a message stating that the command did not return any data, and it did not return any rows. This is fine. The procedure has been created.

    (For details, see the CREATE PROCEDURE statement in the Microsoft SQL Server Transact-SQL Reference.)


Examples

Note Most examples refer to the pubs sample database. The pubs sample database is included as a learning tool; it is created when the server is installed. To use the sample database, your system must have access to the pubs database. If you have a localized version of SQL Server and want to try the examples, drop the localized version of pubs and install the U.S. English version of pubs. To install the U.S. English version of pubs, run the INSTPUBS.SQL script with the isql command-line utility. This script can be found in the INSTALL directory of SQL Server. Also, if other users have executed the examples in this chapter, it is likely that the pubs database has been altered. This will change the output you see from some of the examples. You can reinstall the original pubs database at any time by running the INSTPUBS.SQL script.

To run the INSTPUBS.SQL script, from an operating-system prompt, type:

isql /Usa /P password /S server -i\sql60\install\instpubs.sql

For details about isql, see the isql command-line utility in the Microsoft SQL Server Transact-SQL Reference.

Here is a stored procedure that is useful in the pubs database. Given an author's last and first name, it displays the title and publisher of each of that author's books:

CREATE PROC au_info @lastname varchar(40), @firstname varchar(20) AS SELECT au_lname, au_fname, title, pub_name
FROM authors, titles, publishers, titleauthor
WHERE au_fname = @firstname
AND au_lname = @lastname
AND authors.au_id = titleauthor.au_id
AND titles.title_id = titleauthor.title_id
AND titles.pub_id = publishers.pub_id

You get a message stating that the command did not return any data, and it did not return any rows. This is fine. The procedure has been created.

Now execute au_info:

au_info Ringer, Anne
au_lname

au_fname

title

pub_name

---------

---------

---------------------

----------------

Ringer

Anne

The Gourmet Microwave

Binnet & Hardley

Ringer

Anne

Is Anger the Enemy?

New Moon Books

(2 row(s) affected)

Note If you supply parameters in the form @parameter = value, you can supply them in any order. You can also omit parameters for which defaults have been supplied. If you supply one parameter in the form @parameter = value, you must supply all subsequent parameters this way. If you do not supply parameters in the form @parameter = value, you must supply them in the order given in the CREATE PROCEDURE statement.

When executing a stored procedure, the server will reject any parameters that were not included with the parameter list during procedure creation. Any parameter that is passed by reference (explicitly passing the parameter name) will not be accepted if the parameter name does not match. (For details on creating procedures and passing parameters, see the CREATE PROCEDURE and EXECUTE statements in the Microsoft SQL Server Transact-SQL Reference.)

Although you can omit parameters for which defaults have been supplied, you cannot skip any. In other words, if a procedure has five parameters, you can omit both the fourth and the fifth parameters, but you cannot skip the fourth and still include the fifth.

You can assign a default value for the parameter in the CREATE PROCEDURE statement. This value, which can be any constant, is taken as the parameter to the procedure when the user does not supply one.

Here is a procedure that displays the names of all authors who have written a book published by the publisher given as a parameter. If no publisher name is supplied, the procedure shows the authors published by Algodata Infosystems.

CREATE PROC pub_info2 @pubname varchar(40) = 'Algodata Infosystems'
AS SELECT au_lname, au_fname, pub_name
FROM authors a, publishers p, titles t, titleauthor ta
WHERE @pubname = p.pub_name
AND a.au_id = ta.au_id
AND t.title_id = ta.title_id
AND t.pub_id = p.pub_id

Note that if the default value is a character string that contains embedded blanks or punctuation, or if it begins with a number (for example, 6xxx), it must be enclosed in single quotation marks.

Here's the output from executing pub_info2 with no parameter specified:

pub_info

au_lname

au_fname

pub_name

--------------

----------------

--------------------

Green

Marjorie

Algodata Infosystems

Bennet

Abraham

Algodata Infosystems

O'Leary

Michael

Algodata Infosystems

MacFeather

Stearns

Algodata Infosystems

Straight

Dean

Algodata Infosystems

Carson

Cheryl

Algodata Infosystems

Dull

Ann

Algodata Infosystems

Hunter

Sheryl

Algodata Infosystems

Locksley

Charlene

Algodata Infosystems

(9 row(s) affected)

In the following stored procedure, showind2, titles is assigned as the default value for the @table parameter:

CREATE PROC showind2 @table varchar(30) = titles
AS SELECT TABLE_NAME = sysobjects.name,
INDEX_NAME = sysindexes.name, INDEX_ID = indid
FROM sysindexes, sysobjects
WHERE sysobjects.name = @table
AND sysobjects.id = sysindexes.id

The column headings (for example, TABLE_NAME) make the results more readable. Here's what the procedure shows for the authors table:

showind2 authors

TABLE_NAME

INDEX_NAME

INDEX_ID

----------

----------

----------

authors

UPKCL_auidind

1

authors

aunmind

2

(2 row(s) affected)

If the user does not supply a value, SQL Server uses the default table, titles:

showind2

TABLE_NAME

INDEX_NAME

INDEX_ID

----------

----------

----------

titles

UPKCL_titleidind

1

titles

titleind

2

(2 row(s) affected)

If a parameter is expected but none is supplied, and if a default value is not supplied in the CREATE PROCEDURE statement, SQL Server displays an error message that lists the expected parameters.

The default can be the value NULL. In this case, if the user does not supply a parameter, SQL Server executes the stored procedure according to its other statements. No error message is displayed.

The procedure definition can also specify that some other action be taken if the user does not give a parameter. Here's an example:

CREATE PROC showind3 @table varchar(30) = NULL
AS IF @table IS NULL
    PRINT 'Please give a table name'
ELSE
    SELECT TABLE_NAME = sysobjects.name,
    INDEX_NAME = sysindexes.name, INDEX_ID = indid
    FROM sysindexes, sysobjects
    WHERE sysobjects.name = @table
    AND sysobjects.id = sysindexes.id

When the user fails to give a parameter, SQL Server displays the user-supplied message from the procedure.

(For other examples of setting the default to NULL, examine the text of some system procedures using sp_helptext.)

The default can include wildcard characters (%, _, [] and [^]) if the procedure uses the parameter with the LIKE keyword.

For example, showind can be modified to display information about the system tables if the user does not supply a parameter:

CREATE PROC showind4 @table varchar(30) = 'sys%'
AS SELECT TABLE_NAME = sysobjects.name,
    INDEX_NAME = sysindexes.name, INDEX_ID = indid
FROM sysindexes, sysobjects
WHERE sysobjects.name like @table
    AND sysobjects.id = sysindexes.id

The following variation of the stored procedure au_info has defaults with wildcard characters for both parameters:

CREATE PROC au_info2 @lastname varchar(30) = 'D%',
    @firstname varchar(18) = '%'
AS SELECT au_lname, au_fname, title, pub_name
FROM authors, titles, publishers, titleauthor
WHERE au_fname LIKE @firstname
    AND au_lname LIKE @lastname
    AND authors.au_id = titleauthor.au_id
    AND titles.title_id = titleauthor.title_id
    AND titles.pub_id = publishers.pub_id

If au_info2 is executed with no parameters, all the authors with last names beginning with the letter D are displayed:

au_info2

au_lname

au_fname

title

pub_name

--------

--------

---------------------

-------------------

Dull

Ann

Secrets of Silicon Val

Algodata Infosystems

del
Castillo

Innes

Silicon Val Gastrono

Binnet & Hardley

DeFrance

Michel

The Gourmet Microwave

Binnet & Hardley

(3 row(s) affected)

This example omits the second parameter when defaults for two parameters have been defined, so you can find the books and publishers for all authors with the last name Ringer:

au_info2 Ringer

au_lname

au_fname

title

pub_name

---------

---------

-------------------

---------------

Ringer

Anne

The Gourmet
Microwave

Binnet &
Hardley

Ringer

Anne

Is Anger the Enemy?

New Moon Books

Ringer

Albert

Is Anger the Enemy?

New Moon Books

Ringer

Albert

Life Without Fear

New Moon Books

(4 row(s) affected)


Returning Information from Stored Procedures

Stored procedures return a status value that indicates that they completed successfully or states the reasons for failure. This value can be stored in a variable when a procedure is called and used in future Transact-SQL statements. SQL Server - defined return status values for failure range from -1 through -99; users can define their own return status values outside this range.

Stored procedures can also return information to the caller through return parameters. Parameters designated as return parameters in the CREATE PROCEDURE and EXECUTE statements return the parameter values back to the calling procedure. The caller can then use conditional statements to check the returned value.

Return status values and return parameters allow you to "modularize" your stored procedures. A set of SQL statements used by several stored procedures can be created as a single procedure that returns its execution status or the values of its parameters to the calling procedure. For example, many of the SQL Server - supplied system procedures execute a procedure that verifies that certain parameters are valid identifiers.

Remote procedure calls (stored procedures run on a remote SQL Server) also return both types of information. All of the following examples in this section could be executed remotely if the syntax of the execute statement included the server, database, and owner names as well as the procedure name.


Return Status Values

Stored procedures can return an integer value called a return status. This status can indicate that the procedure completed successfully, or it can indicate the reason for failure. SQL Server has a defined set of return values; users can also define their own values. Here's an example of a batch that returns a status:

DECLARE @status int
EXECUTE @status = au_info @lastname = Ringer, @firstname = Anne
SELECT status = @status

The execution status of the au_info procedure is stored in the variable @status.

Later examples use the return value in conditional clauses.

Reserved Return Status Values

SQL Server reserves 0 to indicate a successful completion and negative values in the range from -1 through -99 to indicate various reasons for failure. The failure values -1 through -14 are currently in use:

Value | Meaning
0 | Procedure was executed successfully
-1 | Object missing
-2 | Datatype error occurred
-3 | Process was chosen as deadlock victim
- 4 | Permission error occurred
-5 | Syntax error occurred
- 6 | Miscellaneous user error occurred
-7 | Resource error, such as out of space, occurred
- 8 | Non-fatal internal problem encountered
-9 | System limit was reached
-10 | Fatal internal inconsistency occurred
-11 | Fatal internal inconsistency occurred
-12 | Table or index is corrupt
-13 | Database is corrupt
-14 | Hardware error occurred

The values -1 through -14 correspond to error severity levels 10 through 24. The values -15 through -99 are reserved for future use by SQL Server. For more information about severity levels, see the Microsoft SQL Server Administrator's Companion.

If more than one error occurs during execution, the status with the highest absolute value is returned.

User-generated Return Values

Users can generate their own return values in stored procedures by adding a parameter to the RETURN statement. All integers other than the reserved values from 0 through -99 can be used.

The following example returns 1 when an author has a valid contract and returns 2 in all other cases:

CREATE PROC checkcontract @param varchar(11)
AS
IF (SELECT contract FROM authors WHERE au_id = @param) = 1
    RETURN 1
ELSE
    RETURN 2

The following stored procedure calls checkcontract and uses conditional clauses (IF...ELSE) to check the return status:

CREATE PROC get_au_stat @param varchar(11)
AS
DECLARE @retvalue int
EXECUTE @retvalue = checkcontract @param
IF (@retvalue = 1)
    PRINT 'Contract is valid'
ELSE
    PRINT 'There is not a valid contract'

Here are the results when you execute get_au_stat with the au_id of an author with a valid contract:

get_au_stat '807-91-6654'
Contract is valid


Return Parameters

When a CREATE PROCEDURE statement and an EXECUTE statement both include the OUTPUT option with a parameter name, the procedure can use a variable to return the value of that parameter to the caller. By using the OUTPUT keyword, any changes to the parameter that result from the execution of the procedure are retained even after the procedure finishes executing, and the variable can subsequently be used in additional SQL statements in the batch or calling procedure. This is often referred to as a "pass-by-reference capability." If the OUTPUT keyword is not used, changes to the parameter are not retained after the procedure finishes executing. In addition, a value can be returned directly ("pass by value") using the RETURN statement.

A single stored procedure can use any or all of these capabilities to return:

  • One or more results sets
  • An explicit return value (using the RETURN statement)
  • An output parameter

The values passed in the parameters must be passed in this form:

@parameter = @variable [OUTput]

If you specify output while you're executing a procedure and the parameter is not defined using output in the stored procedure, you'll get an error message. It is not wrong to call a procedure that includes return value specifications without requesting the return values with output ¾ you just won't get the return values. The stored procedure writer controls what information users can access, and users have control over their variables.

A stored procedure can also return values via "output" parameters. Each must be defined as an OUTPUT variable in the stored procedure and in the calling statements, as in the following example. These values can then subsequently be selected.

myproc @a = @myvara out, @b = @myvarb out

You cannot pass constants. There must be a variable name to receive the return value. The parameters can be of any SQL Server datatype except text or image. If the stored procedure requires several parameters, pass the return value parameter last in the EXECUTE statement or pass all subsequent parameters in this form:

@parameter = [value | @variable [OUTput]]

The following procedure performs division of two integer variables. The third integer variable, @quotient, is defined as an output parameter:

CREATE PROC divide
    @dividend smallint,
    @divisor smallint,
    @quotient int output
AS
IF @divisor = 0
BEGIN
    SELECT @quotient = NULL
    RETURN -100
END
SELECT @quotient = @dividend / @divisor
RETURN 0

If you execute this procedure by providing two integer constants and an OUTPUT parameter, the procedure first checks for an attempt to divide by 0. If the divisor is not 0, the procedure performs the division, puts the answer in the OUTPUT parameter, and sets the return value to 0. For example, if you execute this procedure using 64 and 8 as the integer constants and @quot_parm as the OUTPUT parameter, the result of the division, 8, is put in the @quot_parm parameter:

DECLARE @quot_parm int
DECLARE @retstat int
EXEC @retstat = divide 64, 8, @quot_parm OUTPUT
SELECT @retstat, @quot_parm

----------- -----------
          0           8
(1 row(s) affected)

By using the OUTPUT keyword, any changes to @quot_parm that result from the execution of the divide procedure are retained even after the procedure finishes executing. If the OUTPUT keyword is not used, changes to @quot_parm are not retained.

If you execute this procedure with 0 as the divisor, the procedure sets @quotient to NULL and the return value to - 100, as shown in the following example:

DECLARE @quot_parm int
DECLARE @retstat int
EXEC @retstat = divide 64, 0, @quot_parm OUTPUT
SELECT @retstat, @quot_parm

----------- -----------
-100        NULL
(1 row(s) affected)


Stored Procedures and Performance

As a database is changed by such events as adding indexes, the original query plans used to access its tables should be optimized again by recompiling them. This optimization happens automatically the first time a procedure is run after SQL Server is restarted. It also happens if an underlying table used by the procedure changes. But if a new index is added that the procedure might benefit from, optimization does not automatically happen (until, for example, the next time SQL Server is restarted and the procedure is run). The sp_recompile system procedure forces a recompile of a procedure the next time it's run. The following example marks every stored procedure and trigger that accesses the titles table so that they are recompiled the next time they are executed:

sp_recompile titles


Stored Procedure Rules

Here are some additional rules for creating stored procedures:

  • CREATE PROCEDURE statements cannot be combined with other SQL statements in a single batch.
  • The CREATE PROCEDURE definition itself can include any number and type of SQL statements, with the exception of the following CREATE statements:
CREATE VIEW | CREATE TRIGGER
CREATE DEFAULT | CREATE PROCEDURE
CREATE RULE |

  • Other database objects can be created within a stored procedure. You can reference an object created in the same procedure as long as it is created before it is referenced.
  • Within a stored procedure, you cannot create an object, drop it, and then create a new object with the same name.
  • You can reference temporary tables within a procedure.
  • If you execute a procedure that calls another procedure, the called procedure can access all objects except temporary tables created by the first procedure.
  • If you create a private temporary table inside a procedure, the temporary table exists only for the purposes of the procedure; it disappears when you exit the procedure.
  • The maximum number of parameters in a stored procedure is 255.
  • The maximum number of local and global variables in a procedure is limited only by available memory.
  • Private and public temporary stored procedures, analagous to temporary tables, can be created with the # and ## prefixes to the procedure name. # denotes a private temporary stored procedure. ## denotes a public temporary stored procedure.


Qualifying Names Inside Stored Procedures

Inside a stored procedure, object names used with the statements ALTER TABLE, CREATE TABLE, DROP TABLE, TRUNCATE TABLE, CREATE INDEX, DROP INDEX, UPDATE STATISTICS, and DBCC must be qualified with the object owner's name if other users are to make use of the stored procedure. For example, user Mary, who owns table marytab, must qualify the name of her table when it is used with one of these statements if she wants other users to be able to execute the procedure in which the table is used.

This rule is necessary because object names are resolved when the procedure is run. If marytab is not qualified and user John tries to execute the procedure, SQL Server looks for a table called marytab owned by John. This example shows the correct usage; it tells SQL Server to look for a table called marytab owned by Mary:

create proc p1
as
create index marytab_ind
on mary.marytab(col1)

Object names used with other statements (for example, SELECT or INSERT) inside a stored procedure need not be qualified because the names are resolved when the procedure is compiled.


Renaming Stored Procedures

You can rename a stored procedure using the sp_rename system procedure.

The new name must follow the rules for identifiers. You can rename only the stored procedures that you own. The database owner can change the name of any user's stored procedure. The procedure to be renamed must be in the current database.

You must drop and re-create a stored procedure if you change the name of an object referenced by that procedure. A stored procedure that references a renamed table or view might work fine for a while. In fact, it works until it is recompiled. However, recompilation takes place for many reasons and without notification to the user.

Use the sp_depends system procedure to get a report of the objects referenced by a procedure as shown in Displaying Information About Stored Procedures.

To rename a stored procedure
  • Execute the sp_rename system stored procedure.

    For example:

    sp_rename p1, mary_proc

    renames the p1 procedure created in the preceding section to mary_proc.

    (For details, see the sp_rename system stored procedure in the Microsoft SQL Server Transact-SQL Reference.)


Displaying Information About Stored Procedures

Several system procedures provide information from the system tables about stored procedures.

You can use the sp_help system procedure to get a report on a stored procedure. For example, you can get information on the stored procedure byroyalty, which is part of the pubs database, like this:

sp_help byroyalty

Name

Owner

Type

------------

---------

-----------------

byroyalty

dbo

stored procedure

Data_located_on_segment

When_created

-----------------------

---------------------

not applicable

Jul 25 1995 3:56PM

Parameter_name

Type

Length

Prec

Scale

Param_order

--------------

---------

---------

-----

------

-----------

@percentage

int

4

10

0

1

The sp_depends system procedure lists stored procedures and objects referenced by those procedures. If you specify an object, sp_depends lists all the stored procedures that reference that object. If you specify a stored procedure name, sp_depends lists all the objects referenced by that stored procedure. The following statement lists all the objects referenced by the user-created stored procedure byroyalty:

sp_depends byroyalty
In the current database the specified object references the following:

name

type

updated

selected

----------------

------------

--------

--------

dbo.titleauthor

user table

no

no

(1 row(s) affected)


Dropping Stored Procedures

The DROP PROCEDURE statement removes stored procedures from the current database.

If a stored procedure that has been dropped is called by another stored procedure, SQL Server displays an error message. However, if a new procedure of the same name is defined to replace the one that was dropped, other procedures that reference it can call it successfully.

A procedure group (more than one procedure with the same name but different ;number suffixes) can be dropped with a single DROP PROCEDURE statement. Once procedures have been grouped, procedures within the group cannot be dropped individually.

To drop a stored procedure
  • In SQL Enterprise Manager's Server Manager window, select the stored procedure you want to drop, click the right mouse button, and then choose Drop.

    (For details, search for stored procedures in SQL Enterprise Manager Help.)

Or

  • Use the DROP PROCEDURE statement.

    For example:

    DROP PROCEDURE mary_proc

    drops the mary_proc procedure from the preceding section.

    (For details, see the DROP PROCEDURE statement in the Microsoft SQL Server Transact-SQL Reference.)


Expanding Hierarchies

Databases often store hierarchical information. The following data, for example, is a hierarchical representation of regions of the world:

Parent

Child

-------------

-------------

World

Europe

World

North America

Europe

France

France

Paris

North America

United States

North America

Canada

United States

New York

United States

Washington

New York

New York City

Washington

Redmond

This representation does not clearly show the structure implied by the data. The following example is easier to interpret:

World
    North America
        Canada
        United States
            Washington
                Redmond
            New York
                New York City
    Europe
        France
            Paris

The following Transact-SQL procedure expands an encoded hierarchy to any arbitrary depth. Although Transact-SQL supports recursion, it is more efficient to use a temporary table as a stack to keep track of all of the items for which processing has begun but is not complete. When processing is complete for a particular item, it is removed from the stack. New items are added to the stack as they are identified. (Note that this example is for illustration only and it does not come from the pubs database.)

create proc expand (@current char(20)) as
set nocount on
declare @level int, @line char(20)
create table #stack (item char(20), level int)
insert into #stack values (@current, 1)
select @level = 1
while @level > 0
begin
    if exists (select * from #stack where level = @level)
        begin
            select @current = item
            from #stack
            where level = @level
            select @line = space(@level - 1)  @current
            print @line
            delete from #stack
            where level = @level
                and item = @current
            insert #stack
                select child, @level  1
                from hierarchy
                where parent = @current
            if @@rowcount > 0
                select @level = @level  1
        end
    else
        select @level = @level - 1
end

In this example, the input parameter (@current) is used to indicate the place in the hierarchy to start. It also keeps track of the current item in the main loop.

The two local variables used are @level, which keeps track of the current level in the hierarchy, and @line, which is a work area used to construct the indented line.

The SET NOCOUNT ON statement avoids cluttering up the output with ROWCOUNT messages from each SELECT.

The temporary table, #stack, is created and primed with the item identifier of the starting point in the hierarchy, and @level is set to match. The level column in #stack allows the same item to appear at multiple levels in the database. Although this situation does not apply to the geographic data in the example, it can apply in other examples.

In this example, when @level is greater than 0, the procedure follows several steps:

  1. If there are any items in the stack at the current level (@level), choose one and call it @current.
  2. Indent the item @level spaces, and then print the item.
  3. Delete the item from the stack so it won't be processed again, and then add all its child items to the stack at the next level (@level 1).

    Note With a conventional programming language, you would have to find each child item and add it to the stack individually. With Transact-SQL, you can find all child items and add them with a single statement, avoiding another nested loop.

    This is the only place where the hierarchy table (#stack) is used.

  4. If there are child items (IF @@ROWCOUNT > 0), descend one level to process them (@level = @level 1); otherwise, continue processing at the current level.
  5. Finally, if there are no items on the stack awaiting processing at the current level, go back up one level to see if there are any awaiting processing at the previous level (@level = @level - 1). When there is no previous level, the expansion is complete.


Expanding Networks

In the example in the preceding section, each item had only one superior. In a network, an item can have more than one superior. The following data, for example, is a representation of airline flights among a number of cities:

Departure    Destination
---------    -------------
Chicago    New York
Chicago    Milwaukee
Denver    Chicago
Seattle    Chicago
Seattle    Denver
Seattle    San Francisco

A common problem you can have with this data is finding all routes between a given pair of cities:

Itineraries
----------------------------------
Seattle, Chicago, New York
Seattle, Denver, Chicago, New York

A few changes to the example in the preceding section can accomplish this:

  • Two additional input parameters are required: the goal city and the depth-of-search limit.
  • The current itinerary is saved in another temporary table and displayed only when a goal is reached.
  • To avoid expanding around a cycle in the network, don't expand cities that appear in the current itinerary.

These changes are illustrated in the following example (not from pubs):

create proc route
(@current char(20), @dest char(20), @maxlevel int = 5) as
set nocount on
declare @level int
create table #stack (city char(20), level int)
create table #list (city char(20), level int)
insert #stack values (@current, 1)
select @level = 1
while @level > 0
begin
    if exists (select * from #stack where level = @level)
        begin
            select @current = city
            from #stack
            where level = @level
            delete from #stack
            where level = @level
                and city = @current
            delete from #list
            where level >= @level
            if exists(select * from #list where city = @current)
                continue
            insert #list values(@current, @level)
            if(@current = @dest)
            begin
                select itinerary = city
                from #list
                continue
            end
            insert #stack
            select destination, @level  1
            from flights
            where departure = @current
                and @level < @maxlevel
            if @@rowcount > 0
                select @level = @level  1
        end
    else
        select @level = @level - 1
end

In this example, when @level is greater than 0, the process follows several steps:

  1. The current city is added to #list by clearing anything at the current level or below (DELETE FROM #list WHERE level > = @level) and then adding the current city (INSERT #list VALUES(@current, @level)).
  2. Whenever the goal city is reached (@current = @dest), this example displays the path (SELECT itinerary = city FROM #list) and doesn't expand the path any further (CONTINUE).
  3. The depth of search is limited by adding a condition (@level < @maxlevel) to the INSERT statement that adds cities to the stack.

The IF EXISTS statement at the beginning of the WHILE loop skips the current city if it's already in the current itinerary.

If the flights table in the preceding example also contains cost information, the lowest cost route can be found by saving the current itinerary if its total cost is less than the best cost so far:

select @cost = sum(cost)
from #list
if @cost < @lowest_cost
begin
    @lowest_cost = @cost
    truncate table #best_route
    insert #best_route
        select *
        from #list
end

For greater efficiency, you can stop expanding the current route if the current cost far exceeds the cost of the best route:

if (select sum(cost) from #list) > @lowest_cost
    continue

If the flights table also includes a departure and arrival time, you can add an IF statement to expand only the routes that have a departure time at least one hour after the arrival time of the current route:

if ((select sum(cost) from #list) > @lowest_cost)
    and datediff(hh, departuretime, @arrivaltime) > 1)
continue


Using Triggers to Define Business Processes

A trigger is a special kind of stored procedure that goes into effect when you modify data in a specified table. Triggers are often created to enforce business rule consistency among logically related data in different tables.

An advantage of triggers is that they are automatic ¾ they work no matter what caused the data modification ¾ a clerk's entry or an application action. Each trigger is specific to one or more of the data modification operations UPDATE, INSERT, or DELETE. The trigger is executed once per SQL statement; it "fires" immediately after the data modification statements are completed. The trigger and the statement that fires it are treated as a single transaction that can be rolled back from within the trigger. If a severe error is detected, the entire transaction automatically rolls back.

Triggers are useful in these ways:

  • Triggers can cascade changes through related tables in the database.

    For example, a delete trigger on the title_id column of the titles table causes a corresponding deletion of matching rows in other tables, using the title_id column as a unique key to locating rows in titleauthor, sales, and roysched.

  • Triggers can disallow or roll back changes that violate referential integrity, canceling the attempted data modification transaction.

    Such a trigger might go into effect when you try to change a foreign key and the new value does not match its primary key. For example, you can create an insert trigger on titleauthor.title_id that rolls back an insert if the new value does not match some value in titles.title_id. (However, declarative referential integrity (DRI) is usually used for this purpose.)

  • Triggers can enforce restrictions that are more complex than those defined with CHECK constraints.

    Unlike CHECK constraints, triggers can reference columns in other tables. For example, a trigger can roll back updates that attempt to increase a book's price by more than 1 percent of its advance, might be checked with a SELECT to another table.

  • Triggers can also find the difference between the state of a table before and after a data modification and take action(s) based on that difference.

Note Except for the deltitle trigger, the triggers discussed in this chapter are not part of the pubs database included with SQL Server. To work with the examples shown, you must create each trigger by using the CREATE TRIGGER statement. Note that each new trigger for the same operation (INSERT, UPDATE, or DELETE) on a table or column overwrites the previous one without warning. For details about CREATE TRIGGER, see the CREATE TRIGGER statement in the Microsoft SQL Server Transact-SQL Reference.


How Triggers Work

A trigger is defined on a particular table. Only the owner of the table has CREATE TRIGGER and DROP TRIGGER permissions for the table. These permissions cannot be transferred to others.

SQL Server accepts a trigger definition that affects tables you do not own, and attempts actions for which you do not have permissions. You must rectify the permissions or drop the trigger. For example, Joe owns the sales table and creates a trigger on it. The trigger is supposed to update titles.ytd_sales when sales.qty is updated. However, Mary is the owner of titles and has not granted permissions on it to Joe. When Joe tries to update sales, SQL Server detects the trigger and Joe's lack of permission on titles and rolls back the update transaction. Joe must either get update permission on titles.ytd_sales from Mary or drop the trigger on sales.


Nested Triggers

Triggers can have as many as 16 nested levels. Nesting is set on at installation; you can turn trigger nesting on and off with the sp_configure system procedure. To disable nesting, use the following statement:

sp_configure 'nested triggers', 0

If nested triggers are enabled, a trigger that changes a table on which there is another trigger activates the second trigger, which can, in turn, activate a third trigger, and so on. If any trigger in the chain sets off an infinite loop, the nesting level is exceeded and the trigger terminates.

You can use nested triggers to perform useful housekeeping functions such as storing a backup copy of rows affected by a previous trigger. For example, you can create a trigger on titleauthor that saves a backup copy of the titleauthor rows that the delcascadetrig trigger deleted. With the delcascadetrig trigger in effect, deleting title_id PS2091 from titles deletes the corresponding row or rows from titleauthor. To save the data, you create a DELETE trigger on titleauthor that saves the deleted data into another separately created table, del_save.

CREATE TRIGGER savedel
ON titleauthor
FOR DELETE
AS
INSERT del_save
SELECT * FROM deleted

It is not a good idea to use nested triggers in an order-dependent sequence. Use separate triggers to cascade data modifications.

Note Because triggers are put into a transaction, a failure at any level of a set of nested triggers cancels the entire transaction, and all data modifications are rolled back. Include PRINT statements in your triggers so that you can determine where the failure occurred.

A trigger does not call itself recursively. In other words, a trigger does not call itself in response to a second update to the same table within the trigger. For example, if an update trigger on one column of a table results in an update to another column, the update trigger activates only once rather than repeatedly.


Triggers and Performance

In performance terms, trigger overhead is usually low. The time involved in running a trigger is spent mostly in referencing other tables, which can be either in memory or on the database device. The deleted and inserted tables are always in memory. The location of other tables referenced by the trigger determines the amount of time the operation takes.


Creating Triggers

A trigger is a database object. You create a trigger by specifying the current table and the data modification statements that activate the trigger. Then you specify the action or actions the trigger is to take.

A table can have a maximum of three triggers: one update trigger, one insert trigger, and one delete trigger. However, each trigger can perform numerous functions and call up to 16 stored procedures. Each trigger can apply to only one table. However, a single trigger can apply to all three user actions (UPDATE, INSERT, and DELETE).

You cannot create a trigger on a view or on a temporary table, although triggers can reference views or temporary tables.

Although a TRUNCATE TABLE statement is, in effect, like a DELETE statement without a WHERE clause (it removes all rows), it cannot activate a trigger because the TRUNCATE TABLE statement is not logged.

You can use the SET statement inside a trigger. Any SET option you invoke remains in effect during the execution of the trigger and then reverts to its former setting.

To create a trigger
  • From the Manage menu in SQL Enterprise Manager, choose Triggers, select a table from the Tables drop-down list, and then choose New from the Triggers drop-down list.

    (For details, search for "trigger" in SQL Enterprise Manager Help.)

Or

  • Use the CREATE TRIGGER statement.

    For example:

    CREATE TRIGGER reminder
ON titles
FOR INSERT, UPDATE
AS RAISERROR (50009,16,10)

    prints a message to the client when anyone tries to add or change data in the titles table.

    (For details, see the CREATE TRIGGER statement in the Microsoft SQL Server Transact-SQL Reference.)


Multirow Considerations

Multirow considerations are particularly important when the function of a trigger is to automatically recalculate summary values (ongoing tallies).

Note Triggers used to maintain summary values should contain GROUP BY clauses to create summary values when more than one row is being inserted, updated, or deleted. Because a GROUP BY clause imposes extra overhead, the following examples are written to test whether the value of @@ROWCOUNT is equal to one, meaning that only one row in the trigger table was affected. If @@ROWCOUNT is equal to one, the trigger actions take effect without a GROUP BY clause.

This insert trigger updates the ytd_sales column in the titles table every time a new sales row is added. It goes into effect whenever you record a sale by adding a row to the sales table. It updates the ytd_sales column in the titles table so that ytd_sales is equal to its previous value plus the value added to sales.qty. This keeps the totals up to date for inserts into sales.qty.

CREATE TRIGGER intrig
ON sales
FOR INSERT AS
    /* check value of @@rowcount */
IF @@rowcount = 1
    UPDATE titles
    SET ytd_sales = ytd_sales  qty
    FROM inserted
    WHERE titles.title_id = inserted.title_id
ELSE
    /* when rowcount is greater than 1,
    **use a GROUP BY clause */
    UPDATE titles
    SET ytd_sales = ytd_sales  (SELECT SUM(qty)
        FROM inserted
        GROUP BY inserted.title_id
        HAVING titles.title_id = inserted.title_id)

The following example shows a delete trigger that updates the ytd_sales column in the titles table every time one or more sales rows are deleted. It goes into effect whenever a row is deleted from the sales table. It updates the ytd_sales column in the titles table so that ytd_sales is equal to its previous value minus the value subtracted from sales.qty.

CREATE TRIGGER deltrig
ON sales
FOR DELETE
as
    /* check value of @@rowcount */
IF @@rowcount = 1
    UPDATE titles
    SET ytd_sales = ytd_sales - qty
    FROM deleted
    WHERE titles.title_id = deleted.title_id
ELSE
    /* when rowcount is greater than 1,
    **use a GROUP BY clause */
    UPDATE titles
    SET ytd_sales = ytd_sales - (SELECT SUM(qty)
        FROM deleted
        GROUP BY deleted.title_id
        HAVING titles.title_id = deleted.title_id)


Conditional Insert Trigger

The triggers examined so far have looked at each data modification statement as a whole; if one row of a four-row insert was unacceptable, the whole insert was unacceptable and the transaction was rolled back. This is the way triggers work. A trigger rejects or accepts each data modification transaction as a whole.

However, you don't have to roll back all data modifications simply because some of them are unacceptable. Using a correlated subquery in a trigger can force the trigger to examine the modified rows one by one.

The following example assumes the existence of a table called newsale. Here is the CREATE statement for newsale:

CREATE TABLE newsale
(stor_id char(4),
ord_num varchar(20),
date datetime,
qty smallint,
payterms varchar(12),
title_id tid)

What if you want to examine each of the records you are trying to insert? The trigger conditionalinsert analyzes the insert row by row, and then deletes the rows that do not have a title_id in titles. Here's how:

CREATE TRIGGER conditionalinsert
ON sales
FOR INSERT AS
IF
(SELECT COUNT(*) FROM titles, inserted
WHERE titles.title_id = inserted.title_id) <> @@rowcount
BEGIN
    DELETE sales FROM sales, inserted
    WHERE sales.title_id = inserted.title_id AND
        inserted.title_id NOT IN
            (SELECT title_id
            FROM titles)
    PRINT 'Only sales records with matching title_ids added.'
END

The trigger test is the same as the one in the insert trigger (intrig) example shown earlier, but the transaction is not rolled back. Instead, the trigger deletes the unwanted rows. This ability to delete rows that have been inserted relies on the order in which processing occurs when triggers are fired. First rows are inserted into the table and the inserted table, and then the trigger fires.

To test the conditional trigger, insert four rows in the newsale table. Two of the newsale rows have title_ids that do not match any of those already in the titles table. Here is the data to insert:

newsale

stor_id

ord_num

date

qty

payterms

title_id

-------

--------

-------------------

---

--------

--------

7066

QA7442.3

Jul 25 1995 8:35AM

75

Net 30

PS1372

7066

QA7442.3

Jul 24 1995 8:35AM

75

Net 60

BU7832

7067

D4482

Jul 27 1995 12:00AM

10

Net 30

PSxxxx

7131

N914008

Jul 27 1995 12:00AM

20

Net 30

PSyyyy

Next insert data from newsale into sales. The statement looks like this:

INSERT sales
SELECT * FROM newsale

The title_ids PSxxxx and PSyyyy do not match any in the titles table, and the conditionalinsert trigger deletes these two rows from the sales and inserted tables.


Testing Data Modifications Against the Trigger Test Tables

Two special tables are used in trigger statements: the deleted table and the inserted table. These temporary tables are used in trigger tests. Use these tables to test the effects of certain data modifications and to set conditions for trigger actions. You cannot directly alter the data in the trigger test tables, but you can use the tables in SELECT statements to detect the effects of an INSERT, UPDATE, or DELETE statement.

  • The deleted table stores copies of the affected rows during DELETE and UPDATE statements. During the execution of a DELETE or UPDATE statement, rows are removed from the trigger table and transferred to the deleted table. The deleted table and the trigger table ordinarily have no rows in common.
  • The inserted table stores copies of the affected rows during INSERT and UPDATE statements. During an INSERT or an UPDATE transaction, new rows are added to inserted and the trigger table at the same time. The rows in inserted are copies of the new rows in the trigger table.
  • An UPDATE transaction is, conceptually, a delete followed by an insert; the old rows are copied to the deleted table first, and then the new rows are copied to the trigger table and to the inserted table.

When setting trigger conditions, use trigger test tables that are appropriate for modifying data. Although it is not wrong to reference deleted while testing an INSERT, or inserted while testing a DELETE, these trigger test tables won't contain any rows in these cases.

Note A given trigger fires only once per statement. If trigger actions depend on the number of rows a data modification affects, you should use tests (such as an examination of @@ROWCOUNT) for multirow data modifications (an INSERT, DELETE, or UPDATE based on a SELECT statement), and take appropriate actions.

The trigger examples in the following sections accommodate multirow data modifications as necessary. The @@ROWCOUNT variable, which stores the number of rows affected by the most recent data modification operation, tests for a multirow insert, delete, or update. If any other SELECT statement precedes the test on @@ROWCOUNT within the trigger, you should use local variables to store the value for later examination. (All Transact-SQL statements that don't return values reset @@ROWCOUNT to 0).


Triggers and ROLLBACK TRANSACTION

When triggers that include ROLLBACK TRANSACTION statements are executed from a batch, they cancel the entire batch. In the following example, if the INSERT statement fires a trigger that includes a ROLLBACK TRANSACTION, the DELETE statement is not executed because the batch is canceled:

INSERT employee VALUES ('XYZ12345M', 'New', 'M', 'Employee', 1, 1, '9952', '6/1/95')
DELETE employee WHERE emp_id = 'PMA42628M'

If triggers that include ROLLBACK TRANSACTION statements are fired from within a user-defined transaction, the ROLLBACK TRANSACTION rolls back the entire transaction. In this example, if the INSERT statement fires a trigger that includes a ROLLBACK TRANSACTION, the UPDATE statement is also rolled back:

BEGIN TRAN
UPDATE employee SET hire_date = '7/1/94' WHERE emp_id = 'VPA30890F'
INSERT employee VALUES ('XYZ12345M', 'New', 'M', 'Employee', 1, 1, '9952', '6/1/95')

For more information about user-defined transactions, see Transactions in the Microsoft SQL Server Transact-SQL Reference.


Implicit and Explicit Null Values

The IF UPDATE (column_name) clause is true for an INSERT statement whenever the column is assigned a value in the select list or in the VALUES clause. An explicit NULL or a default assigns a value to a column and thus activates the trigger. With an implicit NULL, if the value is not specified by the query or by the assigned default, the trigger on that column is not activated.

CREATE TABLE junk
(a int NULL, b int NOT NULL)
go
CREATE TRIGGER junktrig
ON junk
FOR INSERT
AS
IF UPDATE(a) AND UPDATE(b)
    PRINT 'FIRING'
go
CREATE DEFAULT b_dflt
AS 99
go
sp_bindefault b_dflt, junk.b
go
INSERT junk (a, b)        /*IF UPDATE is true for both columns, */
VALUES (1, 2)            /*the trigger is activated. */
INSERT junk                /*IF UPDATE is true for both columns, */
VALUES (1, 2)            /*the trigger is activated. */
INSERT junk                /*Explicit NULL: */
VALUES (null, 2)            /*IF UPDATE is true for both columns, */
                        /*the trigger is activated. */
INSERT junk (b)            /*No default on column a, */
VALUES (2)                /*IF UPDATE is not true for both columns, */
                        /*the trigger is not activated. */
INSERT junk (a)            /*Default on column b, */
VALUES (2)                /*IF UPDATE is true for both columns, */
                        /*the trigger is activated. */

Exactly the same results are produced by using only this clause:

IF UPDATE(a)

To create a trigger that disallows the insertion of implicit null values, use:

IF UPDATE(a) OR UPDATE(b)

SQL statements in the trigger can then test to see whether a is NULL.


Renaming and Triggers

If you change the name of an object referenced by a trigger, you must drop the trigger and re-create it so that its text reflects the new name of the object that it references. To avoid problems, re-create a trigger that references any tables or views that you rename.

The sp_depends system procedure lists all the triggers that reference the object (for example, table or view) or all the tables or views that the trigger affects. This example shows how to use sp_depends to get a list of all the objects referenced by the trigger deltrig:

sp_depends deltrig
In the current database the specified object references the following:

name

type

updated

selected

---------

----------

-------

--------

dbo.sales

user table

yes

yes

(1 row(s) affected)

This statement lists all the objects that reference the sales table:

sp_depends sales
In the current database the specified object references the following:

name

type

------------

---------------

dbo.conditionalinsert

trigger

(1 row(s) affected)


Displaying Information About Triggers

Because they are database objects, triggers are listed in the sysobjects system table by name. The type column in sysobjects identifies triggers with the abbreviation TR. Execution plans for triggers are stored in sysprocedures.

This query finds the triggers in a database:

SELECT *
FROM sysobjects
WHERE type = 'TR'

name

id

uid

type

userstat

sysstat

indexdel

---------

-------

---

----

--------

-------

--------

employee_
insupd

832005995

1

TR

0

8

0

schema

refdate

crdate

version

deltrig

------

-------------------

-----------

-------

-------

0

May 26 1995 12:44PM

May 26 1995

12:44PM

0

instrig

updtrig

seltrig

category

cache

-----------

-----------

-----------

-----------

-----

688005482

0

0

0

0

(1 row(s) affected)

      To display information about a trigger

  •
Execute the sp_help system stored procedure.
    •

For example, to get information on the deltrig trigger:

sp_help deltrig

Name

Owner

Type

When_created

--------

-----

-------

-----------------

deltrig

dbo

trigger

June 14 1995 6:10AM

Data_located_on_segment
-----------------------
not applicable

The CREATE TRIGGER statement for each trigger is stored in the syscomments system table. You can display the trigger definition by using the sp_helptext system procedure:

sp_helptext deltrig
text
-------------------------------------------
create trigger deltrig
on sales
for delete
as
.
.
.


Dropping a Trigger

You can remove a trigger by dropping it or by dropping the trigger table. When a table is dropped, any triggers associated with it are also dropped. DROP TRIGGER permission defaults to the trigger table owner and is not transferable.

To drop a trigger
  • Use the Microsoft SQL Enterprise Manager.

    (For details, search for "dropping a trigger" in SQL Enterprise Manager Help.)

Or

  • Use the DROP TRIGGER statement.

    For example:

    DROP TRIGGER deltrig

    drops the deltrig trigger from the sales table.

    (For details, see the DROP TRIGGER statement in the Microsoft SQL Server Transact-SQL Reference.)


Before You Begin

Microsoft® SQL Server™ 6.0 extends the performance, reliability, and scalability of earlier releases of Microsoft SQL Server to meet the needs of customers who are deploying large-scale distributed information systems. SQL Server 6.0 provides powerful tools for enterprise-wide administration, data replication, parallel DBMS performance, and scalability to very large databases. SQL Server 6.0 also provides tight integration with OLE object technology.

SQL Server 6.0 continues to adhere to industry standards, with improved ANSI SQL support and language enhancements that include declarative referential integrity (DRI), and powerful server-based cursor support that far exceeds the ANSI standard.


About the Transact-SQL Reference

The Microsoft SQL Server Transact-SQL Reference explains how to use Transact-SQL®, the enhanced version of SQL (structured query language), and provides in-depth reference information and examples.

This book uses many examples to illustrate database fundamentals. Most examples refer to the pubs sample database. The pubs sample database is included as a learning tool; it is created when SQL Server is installed. To use the sample database, your system must have access to the pubs database. If you have a localized version of SQL Server and want to try the examples, drop the localized version of pubs and install the U.S. English version of pubs. To install the U.S. English version of pubs, run the INSTPUBS.SQL script with the isql command-line utility. This script can be found in the INSTALL directory of SQL Server. Also, as you execute the examples in this book, you alter the pubs database, which can change the output you receive from some of the example queries. You can reinstall the original pubs database at any time by running the INSTPUBS.SQL script.

To run the INSTPUBS.SQL script, from an operating-system prompt, type:

isql /Usa /P password /S server -i\sql60\install\instpubs.sql

Note You can create the queries in this book by using isql, ISQL/w, the query analyzer in SQL Enterprise Manager, or any number of other (third-party or custom-built) tools.

For details on isql, see the isql command-line utility. For details on ISQL/w, see the Utilities and Executables topic. For details on SQL Enterprise Manager, see the SQL Enterprise Manager online Help.


Finding Further Information

In addition to the administration information in this book, additional information about using SQL Server 6.0 is available from the following sources, as well as from the Microsoft® Development Library and Microsoft® TechNet.

The Microsoft Developer Network provides in-depth information for developers. With Level 1 of the Developer Network, you get four quarterly releases of the Development Library, packed with inside information on programming for Microsoft Windows and Windows NT, plus other program benefits. With Level 2 of the Developer Network, you'll receive all the Level 1 benefits plus quarterly releases of the Development Platform, containing the latest Windows and Windows NT Workstation operating systems and API-level SDKs and DDKs from Microsoft. For ordering information, call (800) 759-5474.

Microsoft TechNet is the front-line resource for fast complete answers to technical questions on Microsoft desktop and system products. Through two monthly CDs, you get everything from crucial data on client/server and workgroup computing, systems platforms, and database products to the latest applications support for Microsoft Windows and the Apple® Macintosh®. For ordering information, call your reseller or (800) 344-2121.

Online Help

To access online Help while using SQL Enterprise Manager or ISQL/w, choose the Help button or press f1. To access context-sensitive Transact-SQL Help while using SQL Enterprise Manager or ISQL/w, press shift f1. From within isql, execute the sp_helpsql system stored procedure.

SQL Server Books Online

The setup program gives you the option of installing Microsoft SQL Server Books Online. If you choose this option, setup adds the Books Online icon to the Microsoft SQL Server 6.0 program group. By choosing this icon, you can access online versions of the SQL Server documentation.

Microsoft SQL Server System Administrator's Companion
Incorporates configuration, administration, and troubleshooting topics. Describes server and client configuration. Explains system administration tasks, such as managing devices and databases, backing up and recovering data, performing replication, scheduling tasks, managing security, and monitoring performance. Describes error conditions and gives troubleshooting procedures.
Microsoft SQL Server Database Developer's Companion
Provides an overview of Transact-SQL, which is an enhanced version of SQL (structured query language). Discusses managing data and database objects, such as tables, views, indexes, stored procedures, defaults, rules, constraints, and user-defined datatypes.
Microsoft SQL Server Transact-SQL Reference
The online version of this book, explains how to use Transact-SQL statements and other features to access databases, and provides syntax and descriptions for Transact-SQL statements, system procedures, utility programs, and system tables.
Microsoft SQL Server Setup
Provides instructions for installing SQL Server 6.0 servers and clients.
Microsoft SQL Server Programming SQL Distributed Management Objects
Provides syntax and reference information for the SQL Distributed Management Objects, which are 32-bit OLE Automation objects for the Microsoft Windows 95 and Windows NT operating systems. These objects, properties, methods, and collections are used to write scripts and programs that can administer multiple SQL Servers distributed across a network.
Microsoft SQL Server Programming DB-Library for C
Provides syntax and reference information for the DB-Library™ application programming interface (API), which is used to write C/C++ client programs for the Microsoft Windows, Microsoft Windows 95, Windows NT, and MS-DOS operating systems.
Microsoft SQL Server Programming DB-Library for Visual Basic
Provides syntax and reference information for the DB-Library API, which is used to write Microsoft® Visual Basic® programming system-based client programs for the Windows operating system.
Microsoft SQL Server Programming Open Data Services
Provides syntax and reference information for the Microsoft Open Data Services API, which is used to write C/C++ server and gateway programs for the Windows NT operating system.


Obtaining Technical Support

Microsoft offers a variety of support options to help you get the most from Microsoft SQL Server 6.0. For information about these options, see the service and support card included in your SQL Server 6.0 package.


Overview

Microsoft® SQL Server 6.0 provides a variety of graphical and command-line utilities that enable clients to access data in a variety of ways. At the heart of these tools is Transact-SQL® code.

Transact-SQL is an enhanced version of structured query language (SQL). SQL is a high-level language for relational database systems. Originally developed by IBM®, SQL has been adapted for many relational database management systems (DBMSs) and has been approved as the official relational query language standard by the American National Standards Institute (ANSI). Transact-SQL is compliant with many ANSI SQL standards and also provides important additional capabilities and functions.

With SQL, you can retrieve data from a database, create databases and database objects, add data, modify existing data, and perform other complex functions. You can also change the server configuration, modify database or session settings, and control data and access statements. Many of these capabilities are implemented by using one of three SQL categories: Data Definition Language (DDL), Data Manipulation Language (DML), and Data Control Language (DCL).

Microsoft SQL Server continues to adhere to industry standards, and provides improved ANSI SQL support and language enhancements that include declarative referential integrity (DRI) and powerful server-based cursor support, which far exceed the ANSI standard. SQL Server 6.0 enhances several existing Transact-SQL language statements and builds upon its existing tools and system procedures.


How to Use the Transact-SQL Reference

The Microsoft SQL Server Transact-SQL Reference is organized for ease of use. In this reference, information about all Transact-SQL statements, server-supplied stored procedures, utilities, and additional informational topics appears in alphabetical order. Transact-SQL users who need an understanding of the SQL syntax and Transact-SQL extensions should refer to this reference when writing SQL scripts, executing ad hoc queries, or modifying the database environment.

Syntax, limitations and restrictions, examples, and references to topics of similar interest are given.

Most topic examples refer to the pubs sample database. The pubs sample database is included as a learning tool; it is created when the server is installed. To use the sample database, your system must have access to the pubs database. If you have a localized version of SQL Server and want to try the examples, drop the localized version of pubs and install the U.S. English version of pubs. To install the U.S. English version of pubs, run the INSTPUBS.SQL script with the isql command-line utility. This script can be found in the INSTALL directory of SQL Server. Use this syntax:

isql /Usa /P password /S server -i\sql60\install\instpubs.sql

For information about using the isql command-line utility, see the Utilities and Executables topic. For an overview of the pubs database, see Appendix B, "The pubs Sample Database."

Users who need an understanding of system administration strategies and server configuration should refer to the Microsoft SQL Server Administrator's Companion. Users who need an understanding of database development ¾ designing and optimizing databases, writing queries, and manipulating data ¾ should refer to the Microsoft SQL Server Database Developer's Companion.


Where Transact-SQL Commands Are Executed

Transact-SQL commands are executed within the utilities provided by Microsoft, as well as in third party applications that support embedded SQL. For information about writing client applications, refer to Microsoft SQL Server Programming DB-Library for C and Microsoft SQL Server Programming DB-Library for Visual Basic.

These are the utilities in which Transact-SQL statements and procedures can be executed:

Utility | Description
isql | Provides a query interface and allows you to perform system administration tasks from a server or a workstation. Also allows scripts to be created for automating tasks.
ISQL/w | Allows you to enter Transact-SQL statements and system stored procedures in a graphical query interface. ISQL/w also provides a graphical way to analyze queries.
SQL Enterprise Manager | Provides easy, enterprise-wide management from a server or a workstation and includes the query window capabilities of the ISQL/w utility.


What's New in SQL Server 6.0

SQL Server 6.0 includes many feature enhancements. In addition, capabilities have been added and/or features changed to allow ANSI-standard compliance in a variety of areas.


Data Definition Language Enhancements

The Data Definition Language (DDL) refers to Transact-SQL statements used to define databases and database objects and to manage their properties. In SQL Server 6.0, DDL includes a significant number of statements. The feature areas with significant enhancements can be categorized as shown in the following table. The DDL enhancements are then described in detail.

Feature area | Related DDL statements and Transact-SQL Reference topics
Table definition | ALTER TABLE CREATE TABLE Constraints IDENTITY Property Data Integrity
View definition | CREATE VIEW
Dropping objects | All drop statements DROP DEFAULT DROP PROCEDURE DROP TABLE
Encrypted definition: procedures, triggers, and views | CREATE PROCEDURE CREATE TRIGGER CREATE VIEW syscomments
Parameters | CREATE PROCEDURE
Local and global temporary objects: procedures and tables | CREATE PROCEDURE CREATE TABLE

Table Definition

The syntax for the CREATE TABLE and ALTER TABLE statements has been updated to include ANSI-standard constraints and the IDENTITY property. Constraints can enforce primary and foreign key references through declarative referential integrity (DRI) as well as other various aspects of data integrity: entity, domain, and user-defined. The IDENTITY property refers to a column attribute which defines a series of values to be used for inserts.

Earlier releases of SQL Server supported only user-defined datatypes, defaults, rules, triggers, and stored procedures. SQL Server now supports all of these objects, and the table-definition syntax now includes a variety of extensions that achieve similar results without requiring separate object-creation and "binding" steps to enforce them. Constraint information is maintained in new system tables (sysconstraints and sysreferences). All of these options can be used together to provide efficient and effective data integrity.

Integrity type | Earlier options | Comparable, new options
Entity | Unique indexes | PRIMARY KEY and UNIQUE constraints, IDENTITY Property
Domain | Datatypes, defaults, rules | CHECK, DEFAULT and FOREIGN KEY constraints
Referential | Triggers | FOREIGN KEY constraints
User-defined | Rules, triggers, stored procedures | All column- and table-level constraints in CREATE TABLE

Entity Integrity
Defines a row as a unique entity for a particular table. Entity integrity usually enforces the primary key of a table (through UNIQUE or PRIMARY KEY constraints or indexes).
Domain Integrity
Refers to the valid entries for a given column. Domain integrity is enforced by restricting the datatype (through system or user-defined datatypes), format (through CHECK constraints and rules), or range of possible values (through FOREIGN KEY and CHECK constraints, and rules and NULL/NOT NULL declarations).
Referential Integrity
Enforces the validity of data entered to ensure that it exists within a range of values within another table. With SQL Server 6.0, referential integrity is declarative with FOREIGN KEY constraints. (In earlier releases, the requirement to check the existence of a foreign key was programmatically defined through triggers.)
User-defined Integrity
Allows specific business rules that don't fall into one of the above categories to also be defined. All options listed above support user-defined integrity.

The syntax for constraints includes support for specifying clustered or nonclustered indexes to support PRIMARY KEY and UNIQUE constraints. For more information about defining and manipulating constraints, and for information about the IDENTITY property, see the ALTER TABLE and CREATE TABLE statements.

View Definition

Views provide an alternate method for looking at the data within a table or group of related tables. The CREATE VIEW statement in SQL Server 6.0 checks the validity of data updated through a view, and permits the use of the DISTINCT keyword in the definition of the view. For details, see the CREATE VIEW statement.

Encrypted Definition and Passwords

Procedures, triggers, and views can be created with an optional (one way) encryption parameter that encrypts the definition text stored in syscomments. For details, see the CREATE PROCEDURE, CREATE TRIGGER, and CREATE VIEW statements. In addition, if passwords are stored (that is, not using integrated security), they are now always encrypted.

Dropping Objects

The DROP object_name statements (DROP DEFAULT, DROP PROCEDURE, DROP TABLE, DROP TRIGGER, etc.) can now be executed by the database owner (DBO) or the system administrator (SA). The DBO and SA no longer need to use the SETUSER statement to drop objects. All other object owner functionality is maintained by the database object owner. The DBO and SA must continue to use SETUSER to perform tasks such as granting permissions.

Parameters

When executing a stored procedure, the server will reject any parameters that were not included with the parameter list during procedure creation. Any parameter that is passed by reference (explicitly passing the parameter name) will not be accepted if the parameter name does not match. For details on creating procedures and passing parameters, see the CREATE PROCEDURE and EXECUTE statements.

Local and Global Temporary Objects

Tables and stored procedures can be created for permanent access by any user who has appropriate permissions, or they can be created as temporary objects. You can create local and global temporary procedures or tables for use only in the current session or for use in all sessions. Local temporary objects are visible in the current session only; global temporary objects are visible to all sessions. Local temporary objects are automatically dropped at the end of the current session; global temporary objects are dropped at the end of the last session using the table (normally, this is when the session that created the object ends). For details, see the sections about the CREATE PROCEDURE and CREATE TABLE statements.


Data Manipulation Language Enhancements

Data Manipulation Language (DML) encompasses Transact-SQL statements used to manipulate database objects. SQL Server 6.0 has significantly enhanced DML in the areas shown in the following table. The DML enhancements are then described in detail.

Feature area | Related DML statements and Transact-SQL Reference topics
Default and identity values | INSERT, UPDATE, DELETE statements
Dynamically-built string execution | EXECUTE statement
Server cursors | DELETE and UPDATE statements
Setting variables with UPDATE | UPDATE statement, Variables

Default and Identity Values

With the addition of DEFAULT constraints and the IDENTITY property, the INSERT, UPDATE, and DELETE statements have been enhanced to allow the IDENTITYCOL, DEFAULT, and DEFAULT VALUES keywords. These keywords allow columns to be updated by referring to their "property" (DEFAULT or IDENTITY) rather than their column name. For details, see the CREATE TABLE, ALTER TABLE, DELETE, INSERT, and UPDATE statements.

Server Cursors

With the addition of server cursors in SQL Server 6.0, the DELETE and UPDATE statements have been modified for use with cursors. If modifications to the results set of a cursor are necessary, use the WHERE CURRENT OF clause with DELETE and UPDATE. For details, see the Cursors topic and the DELETE and UPDATE statements.

Setting Variables

The UPDATE statement has been enhanced to allow the SET clause to set local variables as well as columns. This enhances performance and lowers possible concurrency issues (because locks are held for a shorter period of time) when data verification is needed for an update. For details, see the UPDATE statement.


Data Control Language Enhancements

Data Control Language (DCL) refers to Transact-SQL statements that permit access to database objects. SQL Server 6.0 has enhanced object permissions.

Feature area | Related DCL statements and Transact-SQL Reference topics
Object permissions | GRANT and REVOKE statements

When FOREIGN KEY constraints are defined, REFERENCES or SELECT permission must be granted on the referenced table. For details, see the GRANT and REVOKE statements.


General Server Enhancements

SQL Server 6.0 has significantly enhanced the features listed in the following table. The enhancements are then described in detail.

Feature Area | Related statements and Transact-SQL Reference topics
CASE expression | CASE Expression
Comments | Comments
Configuration | sp_configure system stored procedure
Database consistency checker | DBCC statement
Datatypes | Any statement that uses datatypes: CREATE TABLE, CREATE PROCEDURE, DECLARE, etc.
Double quote (") delimited identifiers | Identifiers (includes quoted identifiers) and SET statement
Dynamically-built string execution | EXECUTE statement
Functions | Datatypes and Functions
Keywords | Keywords (includes reserved words)
Error handling | RAISERROR statement
Server cursors | Cursors, DELETE and UPDATE statements
Session settings | SET statement
Stored procedures | Stored Procedures
System tables | System Tables
Utilities and command-line executables | Utilities and Executables
Variables | Variables

CASE Expression

The ANSI-compliant CASE expression allows SQL expressions to be simplified for conditional values (such as to classify certain values in a results set). The CASE expression provides extremely powerful capabilities in SQL Server 6.0. The CASE expression is ANSI SQL-92-compliant and allowed anywhere an expression is used. For details, see the CASE Expression topic.

Comments

In SQL Server 6.0, ANSI-compliant comments can be defined using the double hyphen (--) identifier. ANSI-style comments should be used for all comments that are nested. The earlier comment style (/* text_of_comments */) is still available for multiline comments, but it should not be used for nested comments. For details, see the Comments topic.

Configuration

SQL Server 6.0 includes many new standard and advanced configuration options. Some configuration options that used to be set up by using the SQL Setup utility are now available as advanced options.

For details of the new options, whether standard or advanced, see the sp_configure system stored procedure.

Database Consistency Checker

DBCC, the database consistency checker, includes many new options and enhancements to previously existing options. For details, see the DBCC statement.

Datatypes

Datatypes specify the data characteristics of columns, stored-procedure parameters, and local variables.

SQL Server 6.0 includes these datatype changes:

  • Exact precision datatypes, decimal and numeric, have been added. For details, see the Datatypes topic.

    ·For ANSI compatibility, configurable session- or database-level default column nullability is used to determine the nullability of a column or a user-defined datatype when the nullability is not explicitly defined. The ANSI NULL default (default allows null values) is configurable for the client session (with the SET statement) or for the entire database (with the sp_dboption system stored procedure). Additionally, a system function (GETANSINULL) has been added that allows the current nullability setting to be queried. For information about precedence and rules of nullability, see the CREATE TABLE statement. For information about session- or database-level default nullability, see the SET statement and the sp_dboption system stored procedure. For details on system functions, see the Functions topic.

  • Datatype synonyms including the VARYING keyword can be used anywhere a datatype is specified. Support has been added for binary varying, character, character varying, char varying, double precision, and integer. For details, see the Datatypes topic.
  • The special system datatype timestamp has been changed to binary(8). For details, see the Datatypes topic.
  • For ANSI compliance, datatypes are case-insensitive regardless of the case-sensitivity of the server. Datatype names can be entered in any case. For details, see the Datatypes topic.
  • Text support has been improved. You can now send a text parameter to a stored procedure, and you can update text with the new UPDATETEXT statement. For details, see the CREATE PROCEDURE statement, and the Datatypes and Text and Image Manipulation topics.

Double Quote Delimited Identifiers

Double quote delimited identifiers allow the server to skip evaluation of the text that appears within double quotation marks ("). The text within double quotation marks can include any kind of character in the installed code page except for double quotation marks. This feature provides ANSI compatibility for delimited identifiers. And although not recommended, keywords specified within double quotation marks can now be used as object names. For details, see the Identifiers topic and the SET statement.

Dynamically-built String Execution

The EXECUTE statement has been enhanced to support the execution of a character string constructed at execution time as a Transact-SQL batch. This allows for object names and Transact-SQL syntax to be resolved at execution time rather than compile time. For details, see the EXECUTE statement.

Functions

Built-in functions allow access to database or server information from within an expression such as a WHERE clause or the SELECT statement. Many of these functions have been updated for use with new features. The mathematical functions have been updated to allow numeric and decimal datatypes.

These system functions have been added:

  • COALESCE
  • GETANSINULL
  • IDENT_INCR
  • IDENT_SEED
  • NULLIF
  • STATS_DATE

For details, see the Functions topic.

Keywords

Numerous keywords and reserved words have been added in SQL Server 6.0. Keywords include words that cannot be used for object or column names. Reserved words include words that, for future compatibility reasons, should be avoided for object or column names. For details and a complete list of keywords and reserved words, see the Keywords topic.

Error Handling

The RAISERROR statement has been enhanced to allow argument substitution to an error message (similar to the C printf capabilities). The severity of RAISERROR messages can now be configured. When creating a RAISERROR message, a user-defined message can now be created or a message can be referenced from the sysmessages system table. To create user-defined messages, three new system procedures have been added. For details, see the RAISERROR statement.

Server Cursors

SQL Server 6.0 supports forward, backward, absolute, and relative-position server cursors. The advantages of server cursors, which follow and extend standard ANSI conventions, can be seen explicitly through Transact-SQL cursors and transparently through built-in server functions accessed by client programs using DB-Library™ or ODBC. In addition to the statements used for cursor declaration and manipulation (DECLARE, OPEN, FETCH, and so on), the DELETE and UPDATE statements have been modified for use within a cursor with the WHERE CURRENT OF clause.

For information about creating, removing, and using cursors by using Transact-SQL statements, see the Cursors topic. For information about manipulating cursor data (a single "fetched" row), see the DELETE and UPDATE statements.

Session Settings

The SET command now includes several options that control default datatype nullability, whether double quotation mark-delimited identifiers are evaluated by the server, how identity values are handled, and the transaction isolation level. For details, see the SET statement.

Stored Procedures

System stored procedures provide a consistent method for updating the system catalog (the tables in the master database used to maintain and track overall system configuration). Some stored procedures have been added, and many existing system procedures have been enhanced.

These are the categories of system-supplied stored procedures:

Catalog Stored Procedures
Catalog stored procedures provide a consistent mechanism for access to database information in SQL Server as well as database gateways. Several catalog stored procedures have been added. For details, see the Stored Procedures¾Catalog Stored Procedures topic.
Extended Stored Procedures
Extended stored procedures provide a way to dynamically load and execute a function with a dynamic-link library (DLL) in a manner similar to a stored procedure. Many new extended stored procedures have been added. For details on using general features, such as setting up and administering mail, see the Microsoft SQL Server Administrator's Companion. For details about the individual procedures and the information returned, see the Stored Procedures¾Extended Stored Procedures topic.
Replication Stored Procedures
Replication stored procedures have been added for use by SQL Enterprise Manager; however, replication can be set up manually through these new stored procedures. For details on setting up subscriber and publisher databases to be used in replication, see the Microsoft SQL Server Administrator's Companion. For details and syntax about the procedures used for replication, see the Stored Procedures¾Replication Stored Procedures topic.
SQL Executive Stored Procedures
Alert management and scheduling stored procedures have been added for use by SQL Enterprise Manager. Scheduling events and alerts can also be set up manually. For details on managing alerts and scheduling events, see the Microsoft SQL Server Administrator's Companion. For details about the procedures used with SQL Executive, see the Stored Procedures¾SQL Executive Stored Procedures topic.
System Stored Procedures
In addition to adding functionality to existing system stored procedures, some system stored procedures have been included for backward compatibility only. These stored procedures should not be expected to be upgraded or maintained in future releases of SQL Server. For details, see the Stored Procedures¾System Stored Procedures topic.

Additionally, some undocumented procedures may exist. These procedures are for internal use or have been replaced by new features. For example, some stored procedures used only to record primary key and foreign key relationships still exist but are no longer included in Microsoft SQL Server documentation because constraints should now be used to enforce referential integrity. Use these procedures only if you have used them with earlier releases or as examples for your own procedures. The undocumented procedures are for internal use and backward compatibility only; they will not be maintained and may not be included in future releases.

System Tables

System tables store information about the database (database catalog¾tables found in all databases) or about the system (system catalog¾tables found only in the master database). Because new features such as replication and constraints require information to be maintained in one or all of these databases, certain tables (replication tables and SQL Executive tables) have been added. For details on replication, the distribution database, and managing alerts with the SQL Executive, see the Microsoft SQL Server Administrator's Companion. For details on these tables, see the System Tables ¾ Database Catalog topic.

Utilities and Executables

The bldmastr command-line utility has been replaced by the SQL Setup graphical user interface. All options previously available only through bldmastr have been moved or have been enhanced in SQL Setup.

The isql command-line utility has been enhanced for integrated login security and includes enhanced error handling on exit.

For details, see the Utilities and Executables topic.

Variables

Global variables are maintained by the system and give specific information about the server or the current user's activity. Because of new features in SQL Server 6.0, many new global variables have been added. For details, see the Variables topic.


ALTER DATABASE Statement

Increases the amount of disk space allocated to a database.

Syntax

ALTER DATABASE database_name
[ON {DEFAULT | database_device} [= size]
[, database_device [= size]]...]
[FOR LOAD]

where

database_name
Is the database whose storage size is to be changed.
ON
Indicates a size and/or location for the database extension. The default extension size is 1 megabyte (MB).

If extending the amount of space allocated to the transaction log, give the name of the log's database device. This will automatically allocate new space only for the transaction log if the database was originally created using the LOG ON clause.

If the database was not created with the LOG ON clause and you want to move the log to a newly added device, then, after altering the database, use the sp_logdevice system stored procedure to make the newly allocated space available only for the log.

Note You must use the sp_logdevice system stored procedure or the LOG ON extension of CREATE DATABASE to put your transaction log on a separate device before you can use the DUMP TRANSACTION statement. Placing the log on the same device as the database minimizes the number of recoverability features available for your database.

DEFAULT
Indicates that ALTER DATABASE can put the database extension on any default database device(s). To see a listing of all available database devices, use the sp_helpdevice system stored procedure. To specify a size for the database extension without specifying the location, use ON DEFAULT = size. To change the status of a database device to default, use the sp_diskdefault system stored procedure.
database_device
Is the logical name of the database device on which you want to place the database extension. A database can reside on more than one database device with different amounts of space on each. To create a device, use the DISK INIT statement.
size
Specifies the amount of space, in megabytes, allocated to the database extension. The minimum, and default, extension is 1 MB (512 2K pages). Legal values range from 1 through 2^24 MB. If SQL Server can't allocate the requested size, it allocates as much space as possible, in 0.5-MB units (allocation units).

When an explicit value is not supplied, SQL Server will use the larger value between the size of the model database or the configured database size (configured with sp_configure). For example, if database size is configured to 2 (the default) and the model database has been altered to 3MB, the database will be 3MB.

FOR LOAD
Prevents use of the database until after a successful database load. This can be used only if the database was created with the FOR LOAD option. For details, see the CREATE DATABASE statement.

Remarks

ALTER DATABASE increases the size of a database. To rename a database, use the sp_renamedb system stored procedure. To decrease the size of a database, see the DBCC statement's SHRINKDB option.

It is important to back up the master database using the DUMP DATABASE statement after each use of ALTER DATABASE. This makes recovery easier and safer if the master database becomes damaged. (If you use ALTER DATABASE and fail to back up the master database, you might still be able to recover the changes with the DISK REFIT statement. For details, see the DISK REFIT statement.)

The SYSTEM and DEFAULT segments are mapped to each new database device included in an ALTER DATABASE statement. When ALTER DATABASE extends a database on a device already in use by that database, the segments mapped to that device are also extended. The maximum number of segments for any database is 32.

Permission

ALTER DATABASE permission defaults to the database owner if he or she has CREATE DATABASE permission. Permission cannot be transferred. The system administrator can also alter databases.

Examples

A. Alter a Single Database on a Single Device

This example alters the testing database on the DEVICE1 device by adding an 8-MB fragment.

ALTER DATABASE testing
    ON DEVICE1 = 8
B. Alter a Database's Log Space

This example increases the size of the sales_info database by 5 MB. After the database has been altered, that fragment is made log-only by executing the sp_logdevice system stored procedure.

ALTER DATABASE sales_info
    ON DEVICE9 = 5
go
sp_logdevice sales_info, DEVICE9

See Also

CREATE DATABASE | sp_helpdb
DROP DATABASE | sp_helpsegment
DBCC | sp_logdevice
sp_addsegment | sp_spaceused
sp_diskdefault |


ALTER TABLE Statement

For SQL Server 6.5 information, see ALTER TABLE Statement in What's New for SQL Server 6.5.

Adds new columns or constraints to an existing table.

Syntax

ALTER TABLE [database.[owner].]table_name
[WITH NOCHECK]
[ADD
{col_name column_properties [column_constraints]
| [[,] table_constraint]}
[, {next_col_name | next_table_constraint}]...]
|
[DROP [CONSTRAINT]
constraint_name [, constraint_name2]...]

where

table_name
Specifies which table to alter. You can include local or global temporary tables, but FOREIGN KEY constraints are not enforced on temporary tables.
WITH NOCHECK
Allows CHECK or FOREIGN KEY constraints to be added to a table without verifying existing data for constraint violations. PRIMARY KEY and UNIQUE constraints are always checked. When this option is not specified (the default), any added constraints will be validated against existing data. If there are any constraint violations, the ALTER TABLE statement fails and a message is returned, stating the type of constraint and name that caused the violation. Use this option with extreme caution. This option is useful when you know your data already meets the new constraints or when a business rule requires the constraint to be enforced only from this point forward.

Note The WITH NOCHECK option will bypass checking FOREIGN KEY and CHECK constraints only at the time the table is altered. Future data modifications made against any column will demand that all columns satisfy all CHECK constraints, even those columns not included in the UPDATE column list.

ADD
Allows a column or table-level constraint to be added to an existing table.
col_name
Is a new column for the table. Column names must conform to the rules for identifiers and must be unique in the table.
column_properties =
datatype [NULL | IDENTITY[(seed, increment)]]
datatype
Specifies the datatype of the column. System or user-defined datatypes are acceptable. Columns added to a table must be defined as NULL. When a column is added, the initial value for the column will be set to NULL. This restriction forces the ALTER TABLE statement to fail if the bit or timestamp datatypes are used.
IDENTITY[(seed, increment)]
Generates values for existing rows based on the seed and increment parameters. If used, the seed value will be assigned to the first row in the table and each subsequent row will receive the next identity value, equal to the last identity plus the increment value. If neither argument is given, both default to 1.

Note If the maximum value, based on the datatype for the identity column, is exceeded during the generation of identity values, the ALTER TABLE statement fails and an error is returned.

The IDENTITY property cannot be added to an existing column; it can be added only to a new column. The IDENTITY property can be assigned a tinyint, smallint, int, decimal(p,0) or numeric(p,0) column that does not allow null values. Defaults and DEFAULT constraints cannot be bound to an identity column, and an identity value cannot be changed. Only one column per table can be defined as an identity column.

column_constraints =
Can include up to one UNIQUE or FOREIGN KEY constraint, one DEFAULT constraint, and any number of CHECK constraints for each new or existing column. All can be entered within the same ALTER TABLE statement.
For a column-level UNIQUE constraint:
[CONSTRAINT constraint_name]
UNIQUE [CLUSTERED | NONCLUSTERED] [(col_name)]
[WITH FILLFACTOR = fillfactor]
[ON segment_name]
For a column-level FOREIGN KEY constraint:
[CONSTRAINT constraint_name]
[FOREIGN KEY [(col_name)]]
REFERENCES [owner.]ref_table [(ref_col)]
For a column-level DEFAULT constraint:
[CONSTRAINT constraint_name]
DEFAULT {constant_expression | niladic-function | NULL}
For a column-level CHECK constraint:
[CONSTRAINT constraint_name]
CHECK [NOT FOR REPLICATION] (expression)
table_constraint =
Can include up to one PRIMARY KEY constraint per table, one DEFAULT constraint per column, and any number of FOREIGN KEY, UNIQUE, or CHECK constraints on any column or columns. All can be entered within the same ALTER TABLE statement.
For a table-level PRIMARY KEY constraint:
[CONSTRAINT constraint_name]
PRIMARY KEY [CLUSTERED | NONCLUSTERED]
(col_name [, col_name2 [..., col_name16]])
[WITH FILLFACTOR = fillfactor]
[ON segment_name]
For a table-level UNIQUE constraint:
[CONSTRAINT constraint_name]
UNIQUE [CLUSTERED | NONCLUSTERED]
(col_name [, col_name2 [..., col_name16]])
[WITH FILLFACTOR = fillfactor]
[ON segment_name]
For a table-level FOREIGN KEY constraint:
[CONSTRAINT constraint_name]
FOREIGN KEY (col_name [, col_name2 [..., col_name16]])
REFERENCES [owner.]ref_table [(ref_col [, ref_col2
[..., ref_col16]])]
For a table-level DEFAULT constraint:
[CONSTRAINT constraint_name]
DEFAULT {constant_expression | niladic-function | NULL}
FOR col_name
For a table-level CHECK constraint:
[CONSTRAINT constraint_name]
CHECK [NOT FOR REPLICATION] (expression)

Important When a PRIMARY KEY or UNIQUE constraint is added, an index is automatically created to enforce the constraint. If the constraint creates a clustered index, other indexes (previously created with CREATE INDEX or with other constraints) will need to be rebuilt by the system. Rebuilding indexes can be a potentially time-intensive operation with numerous concurrency ramifications. Whenever possible, make data definition changes when database activity is minimal.

CONSTRAINT constraint_name
Names the given constraint within the database. Constraint names must follow the rules for identifiers, except that the name cannot begin with a pound sign (#). If constraint_name is not supplied, a system-generated name is assigned to the constraint.
UNIQUE [CLUSTERED | NONCLUSTERED]
Provides entity integrity for a given column or columns. Although columns participating in UNIQUE constraints can allow null values, it is not recommended that you use null values. If null values are necessary, the complete key (a single column or multiple columns for a composite index) cannot be NULL for more than one row. Multiple UNIQUE constraints can be defined on a specific table. SQL Server automatically creates a UNIQUE index on this column or columns. UNIQUE key constraints can be dropped only by dropping the associated table or constraint. If no index type is specified, a NONCLUSTERED index is created by default.
WITH FILLFACTOR = fillfactor
Specifies how full SQL Server makes each index page when creating an index with existing data.
ON segment_name
Creates the index on the specified segment. If the index specified is a clustered index, the entire table will be moved to the specified segment. It is important that the segment have at least 1.2 times the space required for the entire table. For more information, see the CREATE INDEX statement.
[FOREIGN KEY [(col_name)]] REFERENCES [owner.]ref_table [(ref_col)]
or
FOREIGN KEY (col_name [, col_name2 [..., col_name16]])
REFERENCES [owner.]ref_table [(ref_col [, ref_col2 [..., ref_col16]])]
Provides single- or multicolumn referential integrity. When defined, the number of columns and datatypes of each column specified in the FOREIGN KEY clause must identically match the columns in the REFERENCES clause. Values entered in this column or columns must exist in the table, and column(s) defined in the REFERENCES clause and the referenced table's columns should have a PRIMARY KEY or UNIQUE constraint defined on them. For column-level constraints, using the FOREIGN KEY and col_name identifiers are optional.

When a FOREIGN KEY constraint is added to a table, all non-null values in the foreign key column(s) must reference an existing key within the referenced table. If any rows are invalid, the ALTER TABLE statement will fail.

Important REFERENCE constraints can reference only tables within the same database; this can include the same table on which the reference is defined (self-referenced tables). If you want cross-database referential integrity or custom messaging, implement these through triggers.

A table can have a maximum of 31 FOREIGN KEY constraints. This limit is an absolute upper limit; the maximum may be lower depending on the number of work tables the server has to create to enforce the constraint and varies by the type of query being executed. FOREIGN KEY constraints are not enforced for temporary tables.

FOREIGN KEY constraints, unlike PRIMARY KEY constraints, do not create an index. To improve performance of data retrieval operations, use the CREATE INDEX statement to create an index on a column with a FOREIGN KEY constraint. This will allow for quicker execution times when a referenced key is modified.

For a FOREIGN KEY to be successfully created, the user must have SELECT or REFERENCES permission on the referenced column or columns. For details, see the GRANT statement. When a specific reference column(s) is not provided, the primary key for the referenced table is used.

Note If REFERENCE constraints are added or altered, any stored procedures that reference the table will be recompiled. This allows changes made to a table definition (through the ALTER TABLE statement) to be visible to procedures created prior to the schema change.

DEFAULT constant_expression | niladic-function | NULL
Specifies the value that will be provided for the column when one is not explicitly supplied during an insert. A DEFAULT constraint can contain constant values, functions, built-in functions that do not take arguments (niladic-function), or NULL. A constant_expression must follow the same rules as defaults.

DEFAULT constraints can be added to columns that are not the timestamp datatype or have the IDENTITY property. If the column was defined with a user-defined datatype that has a default bound to it or if the column has a default bound to it, the DEFAULT constraint will not be allowed and the ALTER TABLE statement will fail. If a default or a DEFAULT constraint already exists for that column, it must be dropped before a DEFAULT constraint can be added. If the default exists on a user-defined datatype, the default must be unbound before that datatype can be used in a table definition with a DEFAULT constraint.

Niladic-functions allow a system-supplied value to be inserted when no value is specified. ANSI-standard niladic-functions include:

  • USER
  • CURRENT_USER
  • SESSION_USER
  • SYSTEM_USER
  • CURRENT_TIMESTAMP

USER, CURRENT_USER, and SESSION_USER all default to the database username of the user performing the insert or update. SYSTEM_USER will provide the login ID, and CURRENT_TIMESTAMP will provide the same information as the GETDATE() function.

A benefit to using a DEFAULT constraint instead of a default (created with the CREATE DEFAULT statement) is that no explicit binding/unbinding is required and DEFAULT constraints are removed when the table is dropped.

When a DEFAULT is added for an existing column (as a table-level constraint), the column to which it applies is specified with FOR col_name.

CHECK (expression)
Enforces domain integrity by limiting the possible values that can be entered into a column or columns. The search condition must evaluate to a Boolean expression and cannot contain subqueries. CHECK constraints adhere to the same policies as rules, but they are automatically bound to the column(s) on which they are defined. A column-level CHECK constraint can only reference the constrained column, and a table-level CHECK constraint can only reference columns of the constrained table. Multiple CHECK constraints can be defined for a table; however, only one can be defined per column per ALTER TABLE statement (although each column constraint can have multiple conditions). When a rule and one or more CHECK constraints exist for a column or columns, all restrictions are evaluated. If defined on multiple columns, they must be defined as table-level constraints.
NOT FOR REPLICATION
Prevents the specified CHECK constraint from being enforced for the distribution process used by replication; however, CHECK constraints will be enforced for all other users (including the system administrator). NOT FOR REPLICATION is used to protect horizontally partitioned tables that receive "source" data from a publishing server from data modifications made to the replicated data. When replication is in effect, any modifications to the data that is replicated should be made on the publishing server (the main source of the data) and not on any of the subscribing servers (each of which receives exact copies of the publishing server's data).

The NOT FOR REPLICATION CHECK constraint will be applied to both the "before" and "after" image of an updated record to prevent records from being added to or deleted from the replicated range. All deletes and inserts will be checked; if they fall within the replicated range, they will be rejected.

When NOT FOR REPLICATION is used with ALTER TABLE, existing data is not checked to see if it meets the requirements of the constraint. The NOT FOR REPLICATION clause behaves as though the NOCHECK option were used on the column(s). All future data modifications, except those occurring through replication, will be checked.

PRIMARY KEY [CLUSTERED | NONCLUSTERED]
Enforces entity integrity only for an existing column or columns. New columns can only be added as a PRIMARY KEY if they have the identity property, because a new non-identity column cannot be defined NOT NULL and a PRIMARY KEY constraint must be NOT NULL. All columns changed to PRIMARY KEY constraint columns must have been defined as NOT NULL.

To enforce uniqueness of a primary key, SQL Server automatically creates a unique index on this column or columns. This unique index can be dropped only by dropping the associated table or PRIMARY KEY constraint.

If no index type is specified, a clustered index is created by default. If NONCLUSTERED is specified or if CLUSTERED is specified for a different UNIQUE constraint in the same statement block, a nonclustered index is created.

Only one PRIMARY KEY constraint can be specified for a given table. However, "alternate" or "candidate" keys can be effectively created with a UNIQUE constraint.

DROP CONSTRAINT constraint_name
Allows an existing column- or table-level constraint to be removed from the table definition.

Remarks

ALTER TABLE adds columns or constraints to a table, or drops constraints from a table, but it does not allow columns to be removed. When constraints are added, all existing data will be verified for constraint violations. If you do not want to verify new CHECK or FOREIGN KEY constraints against existing data, use the WITH NOCHECK option; but this is not recommended.

The number of columns in a table cannot exceed 250. The maximum number of bytes per row is 1962, not including text or image columns, which are stored with their own separate chain of data pages.

Important If a stored procedure using SELECT * references a table that has been altered with new columns, the procedure (even if you use the WITH RECOMPILE option) does not recognize the columns you added to the table. In order for the new columns to be visible to the procedure, you must drop the stored procedure and then re-create it.

To rename a table, execute the sp_rename system stored procedure. To get information on a table and its columns, use the sp_help system stored procedure or the sp_helpconstraint system stored procedure.

Permission

ALTER TABLE permission defaults to the table owner. Permission cannot be transferred; however, the database owner can impersonate the table owner by using the SETUSER statement. The system administrator can also alter users' tables.

Examples

A. Add a PRIMARY KEY Constraint

The authors table in SQL Server 6.0 includes a PRIMARY KEY constraint on the au_id column. This example shows how to add only this constraint (with an explicit name).

ALTER TABLE authors
ADD
CONSTRAINT UPKCL_auidind PRIMARY KEY CLUSTERED (au_id)
B. Add a FOREIGN KEY Constraint

The titles table in SQL Server 6.0 includes a foreign key reference to the authors table. This example adds only this constraint (allowing the system to supply a name).

ALTER TABLE titles
ADD
CONSTRAINT FK_pub_id FOREIGN KEY (pub_id) REFERENCES publishers(pub_id)
C. Add a UNIQUE Constraint

The stores table has columns of stor_id, stor_name, and city, where stor_id is the primary key; however, no two stores in the same city should have the same name. This example adds only this constraint.

ALTER TABLE stores
ADD
CONSTRAINT UNC_name_city UNIQUE NONCLUSTERED (stor_name, city)
D. Add a DEFAULT Constraint

The authors table has a phone column where a value is required. This example adds a default value of UNKNOWN for future inserts that do not explicitly enter a phone number.

ALTER TABLE authors
ADD
DEFAULT 'UNKNOWN' FOR phone
E. Add a CHECK Constraint

The authors table has a zip column where a 5-digit character string is required. This example adds a CHECK constraint to guarantee that only numbers are entered.

ALTER TABLE authors
ADD
CONSTRAINT CK_zip CHECK (zip LIKE '[0-9][0-9][0-9][0-9][0-9]')
F. Add a New Column with Constraints

In SQL Server 6.0, the publishers table has a new column called country with a default value of USA. This example adds the country column.

ALTER TABLE publishers
ADD
country varchar(30)        NULL
        DEFAULT('USA')
G. Complex ALTER TABLE Statement with Multiple Changes

In SQL Server 6.0, the publishers table has a CHECK and PRIMARY KEY constraint on the pub_id column and a new column called country with a default value of USA. This example alters the table with all of these changes.

ALTER TABLE publishers
ADD
country varchar(30)        NULL
        DEFAULT('USA'),
CONSTRAINT UPKCL_pubind PRIMARY KEY CLUSTERED (pub_id) ,
CHECK (pub_id IN ('1389', '0736', '0877', '1622', '1756')
    OR pub_id LIKE '99[0-9][0-9]')
H. Drop a Constraint

To drop a constraint, you must first know the constraint name. If the constraint names were not explicitly entered, use either the sp_help or the sp_helpconstraint system stored procedure to retrieve the system-supplied constraint names.

This example drops the UPKCL_auidind created in example A.

ALTER TABLE authors
    DROP CONSTRAINT UPKCL_auidind

See Also

CREATE TABLE | sp_help
DROP TABLE | sp_rename


Batches

A batch is a set of SQL statements submitted together and executed as a group. A script is often a series of batches submitted one after the other. A batch is compiled only once as a whole and is terminated by an end-of-batch signal. Because of this, certain restrictions on batch size exist.

These rules apply to batches:

  • CREATE DEFAULT, CREATE PROCEDURE, CREATE RULE, CREATE TRIGGER, and CREATE VIEW statements cannot be combined with other statements in a batch. They must be submitted one at a time.
  • Rules and defaults cannot be bound to columns and used within the same batch. That is, the sp_bindrule and sp_bindefault system stored procedures cannot be used in the same batch as INSERT statements that invoke the rule or default.
  • CHECK constraints follow the same rule as rules and defaults. A table created with CHECK constraints cannot enforce those constraints in the same batch as the definition.
  • You cannot drop an object and then reference or re-create it in the same batch.
  • You cannot alter a table and then reference the new columns in the same batch.
  • Options changed with a SET statement take effect only at the end of the batch. For details, see the SET statement.
  • You can submit batches through a graphical tool such as the ISQL/w utility, through a command-line utility such as isql, or through files (scripts) passed to isql. A file submitted to isql can include more than one batch of SQL statements if each batch is terminated by the GO command batch separator.
  • The SQL Server batch size of 128K limits the maximum amount of explicit data values that can be inserted or updated in a single batch. Since some memory is required for a query's execution plan, the actual size of the data you can insert or update is somewhat less than 128K. For example, you might be able to insert or update one column of 125K or two columns of 60K each. This limit does not apply to text or image data inserted or updated with WRITETEXT or UPDATETEXT, data inserted with the bcp command-line utility, data inserted from another table, or data passed by remote procedure calls.

Examples

A. Multiple SELECTs

This example shows multiple selects in one batch. Two results sets will be returned.

SELECT COUNT(*) FROM titles
SELECT COUNT(*) FROM authors
B. Create and Use an Object

This example shows a table creation, an insert, and then a select.

CREATE TABLE test
(
    column1         char(10)            NOT NULL,
    column2         int                NULL
)
INSERT test
    VALUES ('hello', 598)
SELECT * FROM test
C. INSERT with Constraints in Separate Batches

This example shows how batches that include table definition and inserts into the table should be written. First, create the table in a separate batch from the INSERT statements(s), and then place the INSERT(s) in a separate batch.

This INSERT fails because 1234 is not a valid publisher ID.

CREATE TABLE publishers
(
pub_id        char(4)            NOT NULL
    CONSTRAINT UPKCL_pubind PRIMARY KEY CLUSTERED
    CHECK (pub_id in ('1389', '0736', '0877', '1622', '1756')
        OR pub_id like '99[0-9][0-9]'),
pub_name        varchar(40)        NULL,
city            varchar(20)        NULL,
state        char(2)            NULL,
country        varchar(30)        NULL
    DEFAULT    ('USA')
)
go

INSERT publishers (pub_id, pub_name) VALUES('1234', 'Publishers test')

See Also

CREATE DEFAULT | CREATE TABLE
CREATE INDEX | CREATE TRIGGER
CREATE PROCEDURE | CREATE VIEW
CREATE RULE | SET


CASE Expression

The CASE expression allows SQL expressions to be simplified for conditional values. The CASE expression in SQL Server 6.0 is ANSI SQL-92-compliant and allowed anywhere an expression is used.

Syntax

Simple CASE expression:

CASE expression
WHEN expression1 THEN expression1
[[WHEN expression2 THEN expression2] [...]]
[ELSE expressionN]
END

Searched CASE expression:

CASE
WHEN Boolean_expression1 THEN expression1
[[WHEN Boolean_expression2 THEN expression2] [...]]
[ELSE expressionN]
END

CASE-related functions:

COALESCE (expression1, expression2)
COALESCE (expression1, expression2, ...expressionN)
NULLIF (expression1, expression2)

where

expression
Is a constant, column name, function, subquery, and any combination of arithmetic, bitwise, and string operators.

In a simple CASE expression, the first expression is compared to the expression in each WHEN clause for equivalency. If these expressions are equivalent, the expression in the THEN clause will be returned.

Boolean_expression
Determines whether to use the THEN clause. The searched CASE expression allows comparison operators, and the use of AND and/or OR between each Boolean_expression. A simple CASE expression does not. The simple CASE expression checks only for equivalent values.
ELSE expressionN
Specifies the result to be returned when all other WHEN clauses fail. ELSE expressionN is optional. When not included, if all other WHEN clauses fail, CASE returns NULL.
COALESCE (expression1, expression2)
Is equivalent to a searched CASE expression where a NOT NULL expression1 returns expression1 and a NULL expression1 returns expression2. In searched CASE expression form, it would look like this:
CASE
    WHEN expression1 IS NOT NULL THEN expression1
    ELSE expression2
END
COALESCE (expression1, expression2, ... expressionN)
Is equivalent to the COALESCE function where each of the expressions return that expression when the value is NOT NULL. A NULL expressionN will return the first non-null expressionN in the list. If no non-null values are found, CASE returns NULL. In searched CASE statement form, it would look like this:
CASE
    WHEN value_expression1 IS NOT NULL THEN value_expression1
    ELSE COALESCE(value_expression2, ... value_expressionN)
END
NULLIF (expression1, expression2)
Is equivalent to a searched CASE expression where expression1 = expression2 and the resulting expression is NULL. In searched CASE expression form, it would look like this:
CASE
    WHEN expression1=expression2 THEN NULL
    ELSE expression1
END

Remarks

All datatypes used for the replacement expression in the THEN clause must include compatible datatypes. This table shows compatible and resulting datatypes.

Datatypes in THEN expressions | Resulting datatype
Mixed. | If the datatype used is not compatible (implicit conversion not supported by SQL Server), an error will occur.
Combination of fixed-length char with lengths cl1, cl2, and cl3. | Fixed-length char with length equal to the greater of cl1, cl2, and cl3.
Combination of fixed-length binary with lengths bl1, bl2, and bl3. | Fixed-length binary with length equal to the greater of bl1, bl2, and bl3.
Combination of fixed and variable-length char. | Variable-length char with length equal to the maximum-length expression.
Combination of fixed and variable-length binary. | Variable-length binary with length equal to the maximum-length expression.
Combination of numeric datatypes (for example, smallint, int, float, money, numeric, and decimal). | Datatype equal to the maximum precision expression. For example, if one expression resulted in an int and another in a float, the resulting datatype would be float, because float is more precise than int.

Examples

A. SELECT Statement with a Simple CASE Expression

Within a SELECT statement, a simple CASE expression allows only an equality check; no other comparisons are made. In this example, the CASE expression is used to alter the display of book categories to make them more understandable.

SELECT     Category =
        CASE type
            WHEN 'popular_comp' THEN 'Popular Computing'
            WHEN 'mod_cook' THEN 'Modern Cooking'
            WHEN 'business' THEN 'Business'
            WHEN 'psychology' THEN 'Psychology'
            WHEN 'trad_cook' THEN 'Traditional Cooking'
            ELSE 'Not yet categorized'
        END,
    "Shortened Title" = CONVERT(varchar(30), title),
    Price = price
FROM titles
WHERE price IS NOT NULL
ORDER BY type
COMPUTE AVG(price) BY type
go

Category            Shortened Title                Price
------------------- ------------------------------ -----------
Business            Cooking with Computers: Surrep 11.95
Business            Straight Talk About Computers  19.99
Business            The Busy Executive's Database  19.99
Business            You Can Combat Computer Stress 2.99

                                                   avg
                                                   ===========
                                                   13.73

Category            Shortened Title                Price
------------------- ------------------------------ -----------
Modern Cooking      Silicon Valley Gastronomic Tre 19.99
Modern Cooking      The Gourmet Microwave          2.99

                                                   avg
                                                   ===========
                                                   11.49

Category            Shortened Title                Price
------------------- ------------------------------ -----------
Popular Computing   But Is It User Friendly?       22.95
Popular Computing   Secrets of Silicon Valley      20.00

                                                   avg
                                                   ===========
                                                   21.48

Category            Shortened Title                Price
------------------- ------------------------------ -----------
Psychology          Computer Phobic And Non-Phobic 21.59
Psychology          Emotional Security: A New Algo 7.99
Psychology          Is Anger the Enemy?            10.95
Psychology          Life Without Fear              7.00
Psychology          Prolonged Data Deprivation: Fo 19.99

                                                   avg
                                                   ===========
                                                   13.50

Category            Shortened Title                Price
------------------- ------------------------------ -----------
Traditional Cooking Fifty Years in Buckingham Pala 11.95
Traditional Cooking Onions, Leeks, and Garlic: Coo 20.95
Traditional Cooking Sushi, Anyone?                 14.99

                                                   avg
                                                   ===========
                                                   15.96

(21 row(s) affected)
B. SELECT Statement with Simple and Searched CASE Expressions

Within a SELECT statement, the searched CASE expression allows values to be replaced in the results set based on comparison values. In this example, the price (a money column) is displayed as a text comment based on ranges of cost for the books. It is important that all possibilities are checked.

SELECT     "Price Category" =
        CASE
            WHEN price IS NULL THEN 'Not yet priced'
            WHEN price < 10 THEN 'Very Reasonable Title'
            WHEN price >= 10 and price < 20 THEN 'Coffee Table Title'
            ELSE 'Expensive book!'
        END,
    "Shortened Title" = CONVERT(varchar(20), title),
    Category =
        CASE type
            WHEN 'popular_comp' THEN 'Popular Computing'
            WHEN 'mod_cook' THEN 'Modern Cooking'
            WHEN 'business' THEN 'Business'
            WHEN 'psychology' THEN 'Psychology'
            WHEN 'trad_cook' THEN 'Traditional Cooking'
            ELSE 'Not yet categorized'
        END
FROM titles
ORDER BY price
go

Price Category        Shortened Title      Category
--------------------- -------------------- -------------------
Not yet priced        Net Etiquette        Popular Computing
Not yet priced        The Psychology of Co Not yet categorized
Very Reasonable Title The Gourmet Microwav Modern Cooking
Very Reasonable Title You Can Combat Compu Business
Very Reasonable Title Life Without Fear    Psychology
Very Reasonable Title Emotional Security:  Psychology
Coffee Table Title    Is Anger the Enemy?  Psychology
Coffee Table Title    Cooking with Compute Business
Coffee Table Title    Fifty Years in Bucki Traditional Cooking
Coffee Table Title    Sushi, Anyone?       Traditional Cooking
Coffee Table Title    Prolonged Data Depri Psychology
Coffee Table Title    Silicon Valley Gastr Modern Cooking
Coffee Table Title    Straight Talk About  Business
Coffee Table Title    The Busy Executive's Business
Expensive book!       Secrets of Silicon V Popular Computing
Expensive book!       Onions, Leeks, and G Traditional Cooking
Expensive book!       Computer Phobic And  Psychology
Expensive book!       But Is It User Frien Popular Computing

(18 row(s) affected)
C. SELECT Statement with Searched CASE Expressions and Nested Subquery

Within a SELECT statement, the searched CASE expression allows values to be replaced in the results set based on comparison values. In this example, the royalty percentage is checked in a separate table to determine a royalty category for each author.

SELECT "Author's Full Name" = CONVERT(varchar(25), (RTRIM(au_fname)
                             ' '  RTRIM(au_lname))),
    "Shortened Title" = CONVERT(varchar(25), title),
    "Royalty Category" =
        CASE
            WHEN (SELECT AVG(royaltyper) FROM titleauthor ta
                    WHERE t.title_id = ta.title_id) > 60
                THEN 'High Royalty'
            WHEN (SELECT AVG(royaltyper) FROM titleauthor ta
                    WHERE t.title_id = ta.title_id)
                        BETWEEN 41 and 59
                THEN 'Medium Royalty'
            ELSE 'Low Royalty'
        END
FROM authors a, titles t, titleauthor ta
WHERE a.au_id = ta.au_id AND ta.title_id = t.title_id
ORDER BY "Royalty Category", "Author's Full Name"
go
Author's Full Name        Shortened Title           Royalty Category
------------------------- ------------------------- ----------------
Akiko Yokomoto            Sushi, Anyone?            Low Royalty
Burt Gringlesby           Sushi, Anyone?            Low Royalty
Michael O'Leary           Sushi, Anyone?            Low Royalty
Albert Ringer             Life Without Fear         High Royalty
Charlene Locksley         Emotional Security: A New High Royalty
Charlene Locksley         Net Etiquette             High Royalty
Cheryl Carson             But Is It User Friendly?  High Royalty
Innes del Castillo        Silicon Valley Gastronomi High Royalty
Johnson White             Prolonged Data Deprivatio High Royalty
Marjorie Green            You Can Combat Computer S High Royalty
Reginald Blotchet-Halls   Fifty Years in Buckingham High Royalty
Sylvia Panteley           Onions, Leeks, and Garlic High Royalty
Abraham Bennet            The Busy Executive's Data Medium Royalty
Albert Ringer             Is Anger the Enemy?       Medium Royalty
Ann Dull                  Secrets of Silicon Valley Medium Royalty
Anne Ringer               Is Anger the Enemy?       Medium Royalty
Anne Ringer               The Gourmet Microwave     Medium Royalty
Livia Karsen              Computer Phobic And Non-P Medium Royalty
Marjorie Green            The Busy Executive's Data Medium Royalty
Michael O'Leary           Cooking with Computers: S Medium Royalty
Michel DeFrance           The Gourmet Microwave     Medium Royalty
Sheryl Hunter             Secrets of Silicon Valley Medium Royalty
Stearns MacFeather        Computer Phobic And Non-P Medium Royalty
Stearns MacFeather        Cooking with Computers: S Medium Royalty

(25 row(s) affected)
D. UPDATE Statement with CASE Expressions

With an UPDATE statement and CASE expressions, it's easy to modify a significant number of rows based on multiple columns of conditional information. In this example, reviews have been turned in and salary increases are due. A review rating of 4 will double the worker's salary, 3 will increase it by 60 percent, 2 will increase it by 20 percent, and a rating lower than 2 results in no raise. Also, a raise will not be given if the employee has been at the company for less than 18 months.

UPDATE employee_salaries
    SET salary =
        CASE
            WHEN (review = 4 AND
                (DATEDIFF(month, hire_date, GETDATE()) > 18))
                THEN salary * 2
            WHEN (review = 3 AND
                (DATEDIFF(month, hire_date, GETDATE()) > 18))
                THEN salary * 1.6
            WHEN (review = 2 AND
                (DATEDIFF(month, hire_date, GETDATE()) > 18))
                THEN salary * 1.2
            ELSE salary
        END
E. CASE-related Function (COALESCE)

In this example, a wages table is shown to include three columns with information about an employee's yearly wage: hourly_wage, salary, and commission. However, an employee receives only one type of pay. To determine the total amount paid to all employees, use the COALESCE function to receive only the non-null value found in hourly_wage, salary, and commission.

CREATE TABLE wages
(
    emp_id        tinyint     identity,
    hourly_wage    decimal    NULL,
    salary        decimal     NULL,
    commission    decimal    NULL,
    num_sales    tinyint    NULL
)
INSERT wages VALUES(10.00, NULL, NULL, NULL)
INSERT wages VALUES(20.00, NULL, NULL, NULL)
INSERT wages VALUES(30.00, NULL, NULL, NULL)
INSERT wages VALUES(40.00, NULL, NULL, NULL)
INSERT wages VALUES(NULL, 10000.00, NULL, NULL)
INSERT wages VALUES(NULL, 20000.00, NULL, NULL)
INSERT wages VALUES(NULL, 30000.00, NULL, NULL)
INSERT wages VALUES(NULL, 40000.00, NULL, NULL)
INSERT wages VALUES(NULL, NULL, 15000, 3)
INSERT wages VALUES(NULL, NULL, 25000, 2)
INSERT wages VALUES(NULL, NULL, 20000, 6)
INSERT wages VALUES(NULL, NULL, 14000, 4)
go

SELECT "Total Salary" = CONVERT(money,
        (COALESCE(hourly_wage * 40 * 52,
            salary,
            commission * num_sales)))
    FROM wages
go

Total Salary
--------------------------
20,800.00
41,600.00
62,400.00
83,200.00
10,000.00
20,000.00
30,000.00
40,000.00
45,000.00
50,000.00
120,000.00
56,000.00

(12 row(s) affected)
F. CASE-related Functions (NULLIF and COALESCE)

In this example, the budgets table is created to show a department (dept), its current budget (current_year) and its previous budget (previous_year). For the current year, NULL is used for departments whose budget will not change from the prior year, and 0 is used for budgets that have not yet been determined. To find out the average of only those departments that have received a budget as well as include the budget value from the prior year (use the previous_year value, where the current_year is 0), combine the NULLIF and COALESCE functions.

CREATE TABLE budgets
(
    dept                tinyint    IDENTITY,
    current_year        decimal    NULL,
    previous_year    decimal    NULL
)
INSERT budgets VALUES(100000, 150000)
INSERT budgets VALUES(NULL, 300000)
INSERT budgets VALUES(0, 100000)
INSERT budgets VALUES(NULL, 150000)
INSERT budgets VALUES(300000, 250000)

SELECT "Average Budget" = AVG(NULLIF(COALESCE(current_year,
                             previous_year), 0.00))
    FROM budgets
go

Average Budget
----------------------------------------
212500.000000

(1 row(s) affected)

See Also

Expressions | SELECT
Search Conditions | UPDATE


CHECKPOINT Statement

Forces all dirty pages (those that have been updated since the last checkpoint) in the current database to be written to disk. Checkpoints caused by the CHECKPOINT statement supplement automatic checkpoints, which occur at intervals calculated by SQL Server on the basis of the configurable value for maximum acceptable recovery time.

Syntax

CHECKPOINT

Remarks

The CHECKPOINT statement saves time in recovery by identifying a point at which all completed transactions are guaranteed to have been written to disk.

A typical checkpoint takes 1 second to complete, although this figure varies depending on the amount of activity on SQL Server and the size of the data cache.

The automatic checkpoint interval is calculated by SQL Server on the basis of system activity and the recovery interval value in the syscurconfigs system table. The recovery interval determines checkpoint frequency by specifying the amount of time it should take the system to recover. Reset this value by executing the sp_configure system stored procedure and the RECONFIGURE statement. For details, see the Microsoft SQL Server Administrator's Companion.

Although automatic recovery will always recover rows after a power failure, use CHECKPOINT as a precautionary measure and to speed up recovery after power failures. For example, if the automatic checkpoint is infrequent because the recovery interval is set high, use the CHECKPOINT statement to force the dirty pages out of the data cache and onto the actual disk pages.

Note In addition to occurring automatically at the recovery interval, a checkpoint will also occur at two other times: After you change a database option with the sp_dboption system stored procedure, a checkpoint will automatically occur within the database where the option was changed. Using the SHUTDOWN statement or stopping the server with the SQL Service Manager also forces a checkpoint in every database.

Permission

Permission to use the CHECKPOINT statement defaults to the database owner. It cannot be transferred.

See Also

RECONFIGURE | sp_dboption
SHUTDOWN |


Comments

Comments provide user-documented information about SQL statements, statement blocks, and stored procedures.

Syntax

/* text_of_comment */

Or

-- text_of_comment

where

text_of_comment
Represents a statement or section that should not be evaluated by the server. Comments can be inserted on a separate line, nested (-- only) at the end of a Transact-SQL command line, or within a Transact-SQL statement.

Remarks

Multiple-line comments are allowed as long as they are surrounded by /* and */. A stylistic convention often used for multiple-line comments is to begin the first line with /*, subsequent lines with **, and end with */.

Single-line or nested comments are supported with the ANSI-standard comments of the double hyphens (--). Comments inserted with -- are delimited by the end-of-line (NEWLINE) character.

There is no maximum length for comments.

Note To avoid generating an error message, do not include a GO command within a comment.

Example

Combining Comments

In this example, comments are used to document and test the behavior during different phases of development for a trigger. In this "in progress" example, parts of the trigger are commented out to narrow down problems and test only one of the conditions. Both styles of comments are used; ANSI-style comments are shown both alone and nested.

CREATE TRIGGER employee_insupd
/*
    Because CHECK constraints can only reference the column(s)
    on which the column- or table-level constraint has
    been defined, any cross-table constraints (in this case,
    business rules) need to be defined as triggers.

    Employee job_lvls (on which salaries are based) should be within
    the range defined for their job. To get the appropriate range,
    the jobs table needs to be referenced. This trigger will be
    invoked for INSERT and UPDATES only. For information about
    triggers, see the Microsoft SQL Server Transact-SQL Reference.
*/
ON employee
FOR INSERT, UPDATE
AS
/* Get the range of level for this job type from the jobs table. */
DECLARE @min_lvl tinyint,        -- Minimum level var. declaration
    @max_lvl tinyint,            -- Maximum level var. declaration
    @emp_lvl tinyint,            -- Employee level var. declaration
    @job_id smallint                -- Job ID var. declaration
SELECT @min_lvl = min_lvl,        -- Set the minimum level
    @max_lvl = max_lvl,             -- Set the maximum level
    @emp_lvl = i.job_lvl,        -- Set the proposed employee level
    @job_id = i.job_id            -- Set the Job ID for comparison
FROM employee e, jobs j, inserted i
WHERE e.emp_id = i.emp_id AND i.job_id = j.job_id
IF (@job_id = 1) and (@emp_lvl <> 10)
BEGIN
    RAISERROR ('Job id 1 expects the default level of 10.',16,-1)
    ROLLBACK TRANSACTION
END
/* Only want to test first condition. Remaining ELSE is commented out.
-- Comments within this section are unaffected by this commenting style.
ELSE
IF NOT (@emp_lvl BETWEEN @min_lvl AND @max_lvl) -- Check valid range
BEGIN
    RAISERROR ('The level for job_id:%d should be between %d and %d.',
        16, -1, @job_id, @min_lvl, @max_lvl)
    ROLLBACK TRANSACTION
END
*/
go


Control-of-Flow Language

Control-of-flow language controls the flow of execution of SQL statements, statement blocks, and stored procedures. These keywords can be used in ad hoc SQL statements, in batches, and in stored procedures.

These are the control-of-flow keywords:

Keyword | Description
BEGIN...END | Defines a statement block.
GOTO label | Continues processing at the statement following the label as defined by label.
IF...ELSE | Defines conditional, and optionally, alternate execution when a condition is false.
RETURN | Exits unconditionally.
WAITFOR | Sets a delay for statement execution.
WHILE | Repeats statements while a specific condition is true.
...BREAK | Exits the innermost WHILE loop.
...CONTINUE | Restarts a WHILE loop.

In addition to the keywords used for conditional processing and control-of-flow for SQL statements, a variety of helpful Transact-SQL extensions and ANSI-standard additions are available:

Feature | Description
CASE Expression | Allows an expression to have conditional return values. This is the ANSI SQL-92-standard CASE expression.
Comments | Inserts a comment anywhere in an SQL statement. Two commenting styles are supported: Transact-SQL style (/* and */) and as ANSI-standard comment style (--).
DECLARE Statement | Declares local variables as well as cursors.
PRINT Statement | Prints a user-defined message on the user's screen.
RAISERROR Statement | Returns a sysmessages entry or a dynamically built message with user-specified severity and state. RAISERROR also sets a system flag (in the global variable @@ERROR) to record that an error condition has occurred.

The control-of-flow keywords and their syntax are shown in the following sections.


BEGIN...END Block

Encloses a series of SQL statements so that control-of-flow language, such as IF...ELSE, affects the performance of a group of statements instead of only the statement that immediately follows IF...ELSE. BEGIN...END blocks can be nested.

Syntax

BEGIN
{sql_statement | statement_block}
END

where

sql_statement | statement_block
Is any valid grouping of Transact-SQL statements. Although all SQL statements are valid within a BEGIN...END block, certain SQL statements should not be grouped together within the same block (or batch). For details, see the Batches topic and the individual statements you're using.


GOTO label

Alters the flow of execution to a label. The SQL statement(s) following GOTO are skipped and processing continues at the label. GOTO statements and labels can be used anywhere within a procedure, batch, or statement block, and they can be nested.

Syntax

Define the label:

label:

Alter the execution:

GOTO label

where

label
Defines the point after which processing will begin if a GOTO is targeted to that label. Labels must follow the rules for identifiers. A label can be used as a commenting method regardless of whether or not GOTO is used.

Remarks

GOTO can exist within conditional control-of-flow statements, statement blocks, or procedures, but it cannot go to a label outside of the batch. GOTO branching can go to a label defined before or after GOTO.


IF...ELSE Block

Imposes conditions on the execution of an SQL statement. The SQL statement following an IF keyword and its condition is executed if the condition is satisfied (when the Boolean expression returns true). The optional ELSE keyword introduces an alternate SQL statement that is executed when the IF condition is not satisfied (when the Boolean expression returns false).

Syntax

IF Boolean_expression
{sql_statement | statement_block}
[ELSE [Boolean_expression]
{sql_statement | statement_block}]

where

Boolean_expression
Is an expression that returns true or false. If the Boolean expression contains a SELECT statement, the SELECT statement must be enclosed in parentheses.
sql_statement | statement_block
Is any SQL statement or statement grouping as defined with a statement block. The IF or ELSE condition can affect the performance of only a single SQL statement unless a statement block is used. To define a statement block, use the control-of-flow keywords BEGIN and END.

Remarks

IF...ELSE constructs can be used in batches, in stored procedures (where these constructs are often used to test for the existence of some parameter), and in ad hoc queries.

IF tests can be nested, either after another IF or following an ELSE. There is no limit to the number of levels of nesting.


RETURN Statement

Exits unconditionally from a query or procedure. RETURN is immediate and complete; statements following RETURN are not executed.

Syntax

RETURN ([integer_expression])

where

integer_expression
Is the integer value returned. Stored procedures can return an integer value to a calling procedure or an application.

Remarks

The RETURN keyword can be used at any point where you want to exit from a procedure, batch, or statement block.

When used with a stored procedure, RETURN cannot return a null value. If a procedure attempts to return a null value (for example, using RETURN @@status where @@status is NULL), a warning message is generated and a value in the range of 0 through - 14 is returned.

SQL Server reserves 0 to indicate a successful return and reserves negative values from - 1 through - 99 to indicate different reasons for failure. If no user-defined return value is provided, the SQL Server value is used. User-defined return status values should not conflict with those reserved by SQL Server. The values 0 through -14 are currently in use.

Value | Meaning
0 | Procedure was executed successfully.
-1 | Object is missing.
-2 | Datatype error occurred.
-3 | Process was chosen as deadlock victim.
-4 | Permission error occurred.
-5 | Syntax error occurred.
-6 | Miscellaneous user error occurred.
-7 | Resource error, such as out of space, occurred.
-8 | Nonfatal internal problem was encountered.
-9 | System limit was reached.
-10 | Fatal internal inconsistency occurred.
-11 | Fatal internal inconsistency occurred.
-12 | Table or index is corrupt.
-13 | Database is corrupt.
-14 | Hardware error occurred.

If more than one error occurs during execution, the status with the highest absolute value is returned. User-defined return values always take precedence over those supplied by SQL Server.

You can include the return status value in subsequent Transact-SQL statements in the batch or procedure that executed the current procedure, but you must enter it in the following form:

EXECute @return_status = procedure_name

For more information, see the EXECUTE statement.


WAITFOR Statement

Specifies a time, time interval, or event that triggers execution of a statement block, stored procedure, or transaction.

Syntax

WAITFOR {DELAY 'time' | TIME 'time'}

where

DELAY
Instructs SQL Server to wait until the specified amount of time has passed, up to a maximum of 24 hours.
TIME
Instructs SQL Server to wait until the specified time.
time
Specifies a time in one of the acceptable formats for datetime data. The time you specify can include hours, minutes, and seconds. Use the format 'hh:mm:ss'. You cannot specify dates ¾ the date portion of the datetime value is not allowed. You can also specify a local variable in place of the 'time' string. For details, see the Datatypes topic.

Remarks

After executing the WAITFOR statement, you cannot use your connection to SQL Server until the time or event that you specified occurs.

To see the active and waiting processes, use the sp_who system stored procedure.


WHILE Construct

Sets a condition for the repeated execution of an sql_statement or statement block. The statements are executed repeatedly as long as the specified condition is true. The execution of statements in the WHILE loop can be controlled from inside the loop with the BREAK and CONTINUE keywords.

Syntax

WHILE Boolean_expression
{sql_statement | statement_block}
[BREAK]
{sql_statement | statement_block}
[CONTINUE]

where

Boolean_expression
Is an expression that returns true or false. If the Boolean expression contains a SELECT statement, the SELECT statement must be enclosed in parentheses.
sql_statement | statement_block
Is any SQL statement or statement grouping as defined with a statement block. To define a statement block, use the control-of-flow keywords BEGIN and END.
BREAK
Causes an exit from the WHILE loop. BREAK is often (but not always) activated by an IF test. Any statements that appear after the END keyword that marks the end of the loop are executed.
CONTINUE
Causes the WHILE loop to restart, skipping any statements after CONTINUE. CONTINUE is often (but not always) activated by an IF test.

Remarks

If two or more WHILE loops are nested, the inner BREAK exits to the next outermost loop. First, all the statements after the end of the inner loop run, and then the next outermost loop restarts.


CREATE DATABASE Statement

Creates a new database. You must be in the master database to create a new database.

Syntax

CREATE DATABASE database_name
[ON {DEFAULT | database_device} [= size]
[, database_device [= size]]...]
[LOG ON database_device [= size]
[, database_device [= size]]...]
[FOR LOAD]

where

database_name
Is the name of the new database. Database names must conform to the rules for identifiers.
ON
Indicates that you will specify a location and (optionally) a size for the database.
DEFAULT
Indicates that CREATE DATABASE can put the new database on any default database device(s) shown in the sysdevices table. To specify a size for the database without specifying a location, use ON DEFAULT = size. To change the status of a database device to default, use the sp_diskdefault system stored procedure.
database_device
Is the logical name of the database device on which you want to put a database. A database can occupy different amounts of space on each of several database devices. To create a device, use the DISK INIT statement.
size
Specifies the amount of space, in megabytes, allocated to the database. A database can range from 1 to 2^24 MB.

When an explicit value is not supplied, SQL Server will use the larger value between the size of the model database or the configured database size (configured with sp_configure). For example, if database size is configured to 2 (the default) and the model database has been altered to 3MB, the database will be 3MB.

LOG ON
Is the name of the device that stores the database log. You can specify more than one device in the LOG ON clause.
FOR LOAD
Prevents anyone from using the database between the CREATE DATABASE, ALTER DATABASE, and LOAD statements. FOR LOAD can also be specified with the ALTER DATABASE statement, but only if the database was created with FOR LOAD.

When a database is created with FOR LOAD, SQL Server ensures that only the database owner, by setting the database to dbo use only, can use the database. After the database has been loaded, you can change the database option by using the sp_dboption system stored procedure.

Note This capability is similar to that provided in SQL Server 4.21a via trace flag 1802, but FOR LOAD guarantees that only the database owner can use the database between the CREATE and LOAD statements.

Remarks

When the CREATE DATABASE statement is executed, SQL Server makes a copy of the model database (the database catalog). You can update the model database just like any other database and add your own tables, stored procedures, user-defined datatypes, and so on.

In SQL Server 6.0, CREATE DATABASE is intelligent during the initialization of the device(s) on which the database will reside. When executing a CREATE DATABASE statement, SQL Server determines whether the devices are newly created. If the devices have not previously contained data, the devices will not be reinitialized.

SQL Server can manage up to 32,767 databases, each of which can be up to 1 TB in size. Each database can have a maximum of 32 device fragments. Each time you use CREATE DATABASE or ALTER DATABASE to allocate space on a database device, that allocation represents a device fragment and is entered as a row in the sysusages system table.

The total number of physical devices that can be used or the total size of each logical device is not limited (this is limited by the physical device(s) used, with an absolute maximum of 32 GB for each logical device). Instead, only the total number of logical device fragments is limited. Each device fragment can actually exist on one or more physical devices if some form of hardware or software striping is used. Whenever possible, it is recommended that striping is used. Striping can provide performance improvements and, in some cases, fault tolerance. For more information, see the Microsoft SQL Server Administrator's Companion.

If you don't specify a location and size for a database, the default location is any default database device, and the default size is the size of the model database or the configuration setting for database size. To display available devices, use the sp_helpdevice system stored procedure. To see configuration settings, use the sp_configure system stored procedure.

If SQL Server can't give as much space as you've requested, SQL Server creates the database, allocating as much space as possible (in 0.5-MB increments) on each database device, and then prints a message showing how much space was allocated and where.

Each new database inherits its database option settings from the model database. For example, the database option select into/bulkcopy is originally set to "off." You can change that setting for each newly created database by using the sp_dboption system stored procedure in the model database.

It is important to back up the master database with the DUMP DATABASE statement after each use of CREATE DATABASE. This makes recovery easier and safer in case the master database is damaged. (If you create a database and fail to back up master, you may be able to recover the changes with the DISK REFIT statement.)

To display a report on a database or on all the databases on a SQL Server, execute the sp_helpdb system stored procedure. For a report on the space used in a database, use the sp_spaceused system stored procedure.

Using the LOG ON Clause

For full recoverability, place the transaction log on a different physical device or devices from the device that stores the data. If a disk crashes, you can recover the database from database dumps and from the transaction log dumps. Although you can create a database on a single device and store the transaction log together with the rest of the database, this is not recommended because you would have to rely solely on the DUMP DATABASE statement for recovery.

Note If you do not create the database with the LOG ON option, you can still move the transaction log later by using the sp_logdevice system stored procedure.

The size of the database device required for the transaction log varies according to the amount of update activity and the frequency of transaction log dumps. As a rule, allocate to the transaction log 10 to 25 percent of the space you allocate to the database. It is best to start small, since space allocated to a transaction log database device cannot be reclaimed and cannot be used for storage of data.

Permission

CREATE DATABASE permission defaults to the system administrator, who can transfer it. However, CREATE DATABASE permission is often centralized to maintain control over disk allocation. CREATE DATABASE permission is not included when you use the GRANT statement. For more information, see the Microsoft SQL Server Administrator's Companion.

Examples

A. Create a Single Database on a Single Device

This example creates a 12-MB database called testing on DEVICE1.

CREATE DATABASE testing
ON DEVICE1 = 12
B. Create a Single Database on Two Devices ¾ Separate Data and Log

This example creates a single database (sales) with the data portion on DEVICE3 and the log portion on DEVICE4.

CREATE DATABASE sales
ON DEVICE3 = 125
LOG ON DEVICE4 = 60
C. Create a Database FOR LOAD

This example creates a single database (personnel) with the data portion spanning three devices (DEVICE5, DEVICE6, and DEVICE7) and the log portion on DEVICE8. The total database size is 200 MB composed of 150 MB for data and 50 MB for log.

CREATE DATABASE personnel
ON DEVICE5 = 50, DEVICE6 = 50, DEVICE7 = 50
LOG ON DEVICE8 = 50
FOR LOAD
go

See Also

ALTER DATABASE | sp_helpdb
DISK INIT | sp_logdevice
DROP DATABASE | sp_renamedb
sp_changedbowner | sp_spaceused
sp_diskdefault |


CREATE DEFAULT Statement

Creates an object that, when bound to a column or a user-defined datatype, specifies a value to be inserted into the column to which the object is bound (or into all columns, in the case of a user-defined datatype) when no value is explicitly supplied during an insert. An alternate and preferred method to creating defaults is to create DEFAULT constraints as described with the CREATE TABLE statement. Using constraints is the preferred method of restricting column data because the constraint definition is stored with the table and automatically dropped when the table is dropped. A default is beneficial, however, when the default will be used again and again for multiple columns.

Syntax

CREATE DEFAULT [owner.]default_name
AS constant_expression

where

default_name
Is the name of the default. Default names must conform to the rules for identifiers.
constant_expression
Specifies an expression that contains only constant values (it cannot include the names of any columns or other database objects). You can use any constant, built-in function, mathematical expression, or global variable. Enclose character and date constants in single quotation marks ('); money, integer, and floating-point constants do not require quotation marks. Binary data must be preceded by 0x, and money data must be preceded by a dollar sign ($). The default value must be compatible with the datatype of the column.

Remarks

You can create a default only in the current database. Within a database, default names must be unique by owner.

After you've created a default, use the sp_bindefault system stored procedure to bind it to a column or to a user-defined datatype.

You cannot use "N/A," for example, as a default for a numeric column. If the default is not compatible with the column to which you've bound it, SQL Server generates an error message when trying to insert the default value, but not when you bind it.

If the default value is too long for the column to which you've bound it, the value will be truncated.

CREATE DEFAULT statements cannot be combined with other SQL statements in a single batch.

To display definitions and binding information, execute the sp_helptext system stored procedure. You can find the value of a default by using the sp_helptext system stored procedure with the default name as the parameter.

You must drop a default before you create a new one of the same name, and you must unbind a default (with the sp_unbindefault system stored procedure) before you drop it.

If a column has both a default and a rule associated with it, the default value must not violate the rule. A default that conflicts with a rule is never inserted, and SQL Server generates an error message each time it attempts to insert the default.

Once bound to a column, a default value is inserted when:

  • You do not explicitly insert a value.
  • You use the DEFAULT VALUES or DEFAULT keyword with INSERT. For details and examples, see the INSERT statement.

If you specify NOT NULL when you create a column and do not create a default for it, an error message is generated whenever a user fails to make an entry in that column. The following table illustrates the relationship between the existence of a default and the definition of a column as NULL or NOT NULL. The entries in the table show the result.

Column definition | No entry, no default | No entry, default | Enter NULL, no default | Enter NULL, default
NULL NOT NULL | NULL error | default default | NULL error | NULL error

To rename a default, use the sp_rename system stored procedure. For a report on a default, use the sp_help system stored procedure.

Permission

CREATE DEFAULT permission defaults to the database owner, who can transfer it to other users.

Examples

A. Simple Character Default

This example creates a character default of 'unknown'.

CREATE DEFAULT phonedflt AS 'unknown'
B. Bind a Default

This example binds the default created in example A. The default takes effect only if there is no entry in the phone column of the authors table. Note that no entry is not the same as an explicit null value.

sp_bindefault phonedflt, 'authors.phone'

See Also

Batches | sp_bindefault
CREATE RULE | sp_help
CREATE TABLE | sp_helptext
DROP DEFAULT | sp_rename
DROP RULE | sp_unbindefault


CREATE INDEX Statement

For SQL Server 6.5 information, see CREATE INDEX Statement in What's New for SQL Server 6.5.

Creates an index on a given table that either changes the physical ordering of the table or provides the optimizer with a logical ordering of the table to increase efficiency for queries. When creating an index for the primary key, use the table- and column-level PRIMARY KEY constraint provided with the CREATE TABLE statement.

Syntax

CREATE [UNIQUE] [CLUSTERED | NONCLUSTERED] INDEX index_name
ON [[database.]owner.]table_name (column_name [, column_name]...)
[WITH
[FILLFACTOR = x]
[[,] IGNORE_DUP_KEY]
[[,] {SORTED_DATA | SORTED_DATA_REORG}]
[[,] {IGNORE_DUP_ROW | ALLOW_DUP_ROW}]]
[ON segment_name]

where

UNIQUE
Specifies to create a unique index (one in which no two rows are permitted to have the same index value). The system checks for duplicate values when the index is created (if data already exists) and checks each time data is added with an INSERT or UPDATE statement. If there are duplicate key values, the statement is canceled and an error message giving the first duplicate is returned. You cannot create a unique index on a single column or multiple columns (composite index) where the complete key (all columns of that key) is NULL in more than one row; these are treated as duplicate values for indexing purposes.

Specifying a unique index makes sense only when uniqueness is a characteristic of the data itself. If uniqueness is required, create a UNIQUE or PRIMARY KEY constraint on the column. Specify a unique index only when manually enforcing a primary key (not recommended).

When a unique index exists, UPDATE or INSERT statements that would generate duplicate key values are rolled back, and SQL Server displays an error message. This is true even if the UPDATE or INSERT statement would have changed many rows but caused only one duplicate. If you try to change data on which there is a unique index and you have used the IGNORE_DUP_KEY option, only the rows that violate the UNIQUE index will fail. (For details, see the IGNORE_DUP_KEY option, later in this section.)

You cannot create a unique index on columns that already include duplicate values, whether or not IGNORE_DUP_KEY is set. If you attempt to do so, SQL Server displays an error message and lists the duplicate values. You must eliminate duplicates before you can create a unique index on the column.

CLUSTERED
Creates an object where the physical order of rows is the same as the indexed order of the rows, and the bottom, or leaf, level of the clustered index contains the actual data pages. Because a clustered index changes the physical order of the rows, create the clustered index before creating any nonclustered indexes so that the nonclustered indexes will not have to be rebuilt. By definition, only one clustered index is permitted per table (regardless of how it is created: implicitly, with constraints, or explicitly, with CREATE INDEX). Often it is created on the column(s) that is frequently accessed in groupings. Before you create indexes, it is important to know how your data will be accessed.

Using a clustered index to find data is almost always faster than using a nonclustered index. In addition, using a clustered index is advantageous when many rows with contiguous key values are being retrieved ¾ that is, on columns that are often searched for ranges of values. Once the row with the first key value is found, rows with subsequent indexed values are guaranteed to be physically adjacent.

For example, it would be helpful on an employee table to include a nonclustered index on the primary key of emp_id; however, the clustered index could be created on lname, fname (last name, first name) as that is often how employees are grouped.

If you do not specify CLUSTERED, a nonclustered index will be created.

Note Because the leaf level of a clustered index and its data pages are the same by definition, creating a clustered index and using the ON segment_name clause effectively moves a table from the device on which the table was created to the new segment. Before creating tables or indexes on specific segments, verify which segments are available and that they have enough empty space for the index. It is important that the segment have at least 1.2 times the space required for the entire table.

NONCLUSTERED
Creates an object that specifies the logical ordering of a table. With a nonclustered index, the physical order of the rows is not the same as their indexed order. The leaf level of a nonclustered index contains pointers to rows on data pages. That is, each leaf page contains an indexed value and a pointer to the row with that value. A nonclustered index, in comparison with a clustered index, has an extra level between the index structure and the data itself.

You can have as many as 249 nonclustered indexes per table (regardless of how they are created: implicitly, with constraints, or explicitly, with CREATE INDEX). Each can provide access to the data in a different sorted order.

index_name
Is the name of the index. Index names must be unique within a table but need not be unique within a database. Index names must follow the rules of identifiers. You must be the owner of a table to create an index on it. The owner of a table can create an index at any time, whether or not there is data in the table. Indexes can be created on tables in another database by qualifying the database name.
table_name
Specifies the table that contains the column or columns to be indexed.
column_name
Specifies the column or columns to which the index applies. Specify two or more column names if you want to create a composite index on the combined values in the specified columns. List the columns to be included in the composite index (in sort-priority order) inside the parentheses after table_name.

Composite indexes are used when two or more columns are best searched as a unit. You can combine as many as 16 columns into a single composite index. All the columns in a composite index must be in the same table. The maximum allowable size of the combined index values is 256 bytes. (That is, the sum of the lengths of the columns that make up the composite index cannot exceed 256.)

FILLFACTOR
Specifies how full SQL Server should make each index page. It is seldom necessary to include the FILLFACTOR option in a CREATE INDEX statement. It is provided for fine-tuning performance and is useful only when you are creating a new index on a table with existing data, and then it is useful only when you can accurately predict future changes in that data.

The amount of empty space on an index page is important because when an index page fills up, the system must take time to split it to make room for new rows. The value of the original FILLFACTOR is stored with the index in the sysindexes table.

Note Using an explicit FILLFACTOR setting applies only when the index is first created. SQL Server does not dynamically keep the specified percentage of empty space in the pages.

User-specified FILLFACTOR values can be from 1 through 100. If you don't specify a value, the default is 0. When FILLFACTOR is set to 0, only the leaf pages are filled. Space is left in nonleaf pages for at least one entry (two for nonunique clustered indexes). You can change the default with the sp_configure system stored procedure.

Use a FILLFACTOR of 100 only when there will be no inserts or updates. If FILLFACTOR is 100, SQL Server creates indexes with each page 100 percent full. A FILLFACTOR of 100 makes sense only for read-only tables. An INSERT or UPDATE made after the creation of an index with a 100 percent FILLFACTOR would cause page splits for each INSERT and possibly each UPDATE. The default FILLFACTOR algorithm assumes that there will be at least enough space for one more entry in an internal page.

Smaller FILLFACTOR values (except 0) cause SQL Server to create new indexes with pages that are not completely full. For example, a FILLFACTOR of 10 can be a reasonable choice if you are creating an index on a table that you know contains a small portion of the data it will eventually hold. Smaller FILLFACTOR values also cause each index to take more storage space.

When FILLFACTOR is set to any value other than 0 or 100, space is left in nonleaf pages for one entry (two for nonunique clustered indexes), and the space is left in leaf pages such that no leaf page is more full than the percentage specified by FILLFACTOR, as shown in the following table.
FILLFACTOR | Internal page | Leaf page
0% | One free slot* | 100% full
1 - 99% | One free slot* | <= FILLFACTOR % full
100% | 100% full | 100% full
*Two free slots for nonunique clustered indexes

Important Creating a clustered index with a FILLFACTOR affects the amount of storage space your data occupies, since SQL Server redistributes the data when it creates the clustered index.

IGNORE_DUP_KEY
Controls what happens when you attempt to enter a duplicate key in a unique clustered index. It is meaningful only when the UPDATE or INSERT statement affects multiple rows. SQL Server issues a warning and does not insert the row containing the duplicate. If IGNORE_DUP_KEY is set and you issue an UPDATE or INSERT statement that creates duplicate keys, the row that causes the duplicates is ignored. In the case of UPDATE, the row is discarded.

Other changes to the database caused by the UPDATE or INSERT attempt (for example, changes to index pages) are also backed out. However, if the UPDATE or INSERT attempt affects multiple rows, the other rows are added or changed as usual. If IGNORE_DUP_KEY is not specified, no rows will be inserted by the UPDATE or INSERT statement. For more information on duplicate rows, see the IGNORE_DUP_ROW | ALLOW_DUP_ROW option, later in this section.

You cannot create a unique index on a column that already includes duplicate values, whether or not IGNORE_DUP_KEY is set. If you attempt to do so, SQL Server displays an error message and lists the duplicate values. You must eliminate duplicates before you can create a unique index on the column.

Caution With IGNORE_DUP_KEY set, if you try to update a row in a way that creates a duplicate key, that row is discarded. Neither the new value nor the original value of the row that would produce the duplicate exists in the updated table. For example, if you try to update "Smith" to "Jones" and "Jones" already exists, you have one "Jones" and no "Smith." Essentially, the original row is lost because an UPDATE statement is actually a DELETE followed by an INSERT. SQL Server has no way to know about the disallowed duplicate when it deletes the row, and the whole transaction can't be rolled back because the purpose of IGNORE_DUP_KEY (and of the IGNORE_DUP_ROW option) is to allow a transaction to proceed in spite of the presence of duplicates.

SORTED_DATA | SORTED_DATA_REORG
Are options that eliminate the sort performed when a clustered index is created. Both options verify that the data has been sorted by checking each index value to determine whether it is higher than the previous one. If any row fails this check, the CREATE INDEX statement terminates. You can either fix the data or rerun the CREATE INDEX statement without the SORTED_DATA option (in which case the data will be sorted). The SORTED_DATA option, when the data satisfies the checks, will always be faster than the SORTED_DATA_REORG because the data is not copied and nonclustered indexes will not be rebuilt.

SORTED_DATA_REORG differs from SORTED_DATA because it physically reorganizes the data. This option is useful when a FILLFACTOR is specified to compact or expand the pages on which a table is stored. The effects of these options change slightly if used with the ON segment_name option. For details, see the ON segment_name section, later in this section.

Reorganizing the data is a good idea when a table becomes fragmented. To determine whether or not a table is contiguous, use the DBCC statement's SHOW_CONTIG. For details about what causes table fragmentation and recommended solutions, see the DBCC statement.

IGNORE_DUP_ROW | ALLOW_DUP_ROW
Are options for creating a nonunique clustered index; they are mutually exclusive. When creating a nonunique nonclustered index, these options are irrelevant because SQL Server attaches a unique row identification number internally; it never checks for duplicate rows or for identical data values.

The IGNORE_DUP_KEY, IGNORE_DUP_ROW, and ALLOW_DUP_ROW index options control what happens when a duplicate key or duplicate row is created with the INSERT or UPDATE statement. This table shows when these options can be used.
Index type | Options
Clustered | IGNORE_DUP_ROW or ALLOW_DUP_ROW
Unique clustered | IGNORE_DUP_KEY
Nonclustered | None
Unique nonclustered | IGNORE_DUP_KEY

This table illustrates how ALLOW_DUP_ROW and IGNORE_DUP_ROW affect attempts to create a nonunique clustered index on a table that includes duplicate rows and attempts to enter duplicate rows into a table.

Option set 		Table has duplicate
rows
Insert duplicate rows
Neither option | CREATE INDEX statement fails. | INSERT statement fails.
ALLOW_DUP_ROW | Statement is completed. | Statement is completed.
IGNORE_DUP_ROW | Index created but duplicate rows deleted; error message returned. | All rows accepted except duplicates; error message returned (see earlier caution).

ON segment_name
Specifies the database segment on which the index is to be created. A nonclustered index can be created on a different segment from the data pages. Before creating an index on a segment, verify which segments you can use. Certain segments can be allocated to specific tables or indexes for performance reasons or for other considerations.

The ON segment_name clause can affect the placement of the data portion and the index portions of a table:

  • Creating a nonclustered index on a specified segment_name ensures that index pages (current and future) will be placed on that segment. All data pages will continue to be allocated from the original segment on which the table was created.
  • Creating a clustered index with SORTED_DATA_REORG on a specified segment_name causes the entire table to be moved to that segment.
  • Creating a clustered index with SORTED_DATA on specified segment_name causes all future data pages to be allocated from the new segment_name only. The index pages (the B-tree) is created on the new seqment_name only. Current page allocations will not be affected.

Caution If you create a table on a segment and then create a clustered index on that table without specifying a segment name, the entire table migrates to the default segment (unless the SORTED_DATA option is used).

Remarks

Space is allocated to tables and indexes in increments of one extent (8 2K pages) at a time. Each time an extent is filled, another is allocated. For a report on the amount of space allocated and used by an index, use the sp_spaceused system stored procedure.

Creating a clustered index requires space available in your database equal to approximately 1.2 times the size of the data. This is space in addition to the space used by the existing table; the data is duplicated (unless SORTED_DATA is specified) in order to create the clustered index, and the old, nonindexed data is deleted when the index is complete.

You can neither create an index on a view nor create indexes on columns of bit, text, and image types. As the syntax signifies, you can create an index on a table in another database as long as you are the owner of that table.

You can create an index on a temporary table. When the table is dropped or the session ends, all indexes and triggers are dropped.

If there is no data in the table when an index is created, run the UPDATE STATISTICS statement after data is added. To check when the statistics were last updated, use DBCC SHOW_STATISTICS.

A composite index, like any other index, is represented by one row in the sysindexes table.

To display a report on an object's indexes, execute the sp_helpindex system stored procedure.

Permission

CREATE INDEX permission defaults to the table owner and is not transferable.

Examples

A. Simple Index

This example creates an index on the au_id column of the authors table.

CREATE INDEX au_id_ind
    ON authors (au_id)
B. Unique Clustered Index

This example creates an index on the au_id column of the authors table that enforces uniqueness. This index will physically order the data on disk because the CLUSTERED option is specified.

CREATE UNIQUE CLUSTERED INDEX au_id_ind
    ON authors (au_id)
C. Simple Composite Index

This example creates an index on the au_id and title_id columns of the authors table.

CREATE INDEX ind1
    ON titleauthor (au_id, title_id)
D. FILLFACTOR

This example uses the FILLFACTOR option set to 100. A FILLFACTOR of 100 fills every page completely and is useful only when you know that no index values in the table will ever change.

CREATE NONCLUSTERED INDEX zip_ind
    ON authors (zip)
    WITH FILLFACTOR = 100
E. IGNORE_DUP_KEY

This example creates a unique clustered index on the stores table. If a duplicate key is entered, the INSERT or UPDATE statement will be ignored.

CREATE UNIQUE CLUSTERED INDEX stor_id_ind
    ON stores(stor_id)
    WITH IGNORE_DUP_KEY

See Also

CREATE TABLE | sp_helpindex
DROP INDEX | sp_spaceused
INSERT | UPDATE
RECONFIGURE | UPDATE STATISTICS
SET |


CREATE PROCEDURE Statement

Creates a stored procedure (a precompiled collection of SQL statements) that can take and/or return user-supplied parameters. Stored procedures help to increase performance and consistency when performing repetitive tasks because stored procedures are compiled the first time they are executed. When executed again, subsequent run time is much shorter than for the equivalent set of stand-alone statements. Procedures can be created for permanent use or for temporary use within a user's session (local temporary procedure) or for temporary use within all user's sessions (global temporary procedure).

Syntax

CREATE PROCedure [owner.]procedure_name[;number]
[(parameter1 [, parameter2]...[parameter255])]
[{FOR REPLICATION} | {WITH RECOMPILE}
[{[WITH] | [,]} ENCRYPTION]]
AS sql_statements

where

procedure_name
Is the name of the new stored procedure. Procedure names must conform to the rules for identifiers and must be unique within the database and its owner.

You can create local or global temporary procedures by preceding the procedure_name with a single pound sign (#table_name) for local temporary procedures and a double pound sign (##table_name) for global temporary procedures. The complete name, including # or ##, cannot exceed 20 characters. For more information, see "Temporary Stored Procedures," later in this topic.

Stored procedures can also be created for auto execution. Auto execution stored procedures are run automatically when SQL Server starts. For more information, see "Auto Execution Stored Procedures," later in this topic.

;number
Is an optional integer used to group procedures of the same name so that they can be dropped together with a single DROP PROCEDURE statement. When grouping is used with a procedure whose name was created using quoted identifiers, the number should not be included as part of the identifier; use double quotation marks only around the procedure_name. Procedures used in the same application are often grouped this way. For example, the procedures used with the application orders might be named orderproc;1, orderproc;2, and so on. The statement DROP PROCEDURE orderproc drops the entire group. Once procedures have been grouped, individual procedures within the group cannot be dropped.
parameter =
@parameter_name datatype [= default] [OUTPUT]
parameter_name
Specifies a parameter in the procedure. One or more parameters can optionally be declared in a CREATE PROCEDURE statement. The value of each declared parameter must be supplied by the user when the procedure is executed (unless a default for the parameter has been defined). A stored procedure can have a maximum of 255 parameters.

The first character of a parameter name must be the "at" symbol (@) and conform to the rules for identifiers. Parameters are local to the procedure; the same parameter names can be used in other procedures. By default, parameters can take the place only of constants; they cannot be used in place of table names, column names, or the names of other database objects. For more information, see the EXECUTE statement.

datatype
Specifies the datatype of the parameter. All datatypes except image are supported. For a list of SQL Server - supplied datatypes and their syntax, see the Datatypes topic.
default
Specifies a default value for the parameter. If a default is defined, a user can execute the procedure without specifying a value for that parameter. The default must be a constant. It can include wildcard characters (%, _, [], and [^]) if the procedure uses the parameter with the LIKE keyword. The default can be NULL. The procedure definition can specify that some action be taken if the parameter value is NULL.
OUTPUT
Indicates that the parameter is a return parameter. The value of this option can be returned to the EXECUTE statement that called the procedure. Use return parameters to return information to the calling procedure. Text parameters cannot be used as OUTPUT parameters.
FOR REPLICATION
Is mutually exclusive of the WITH RECOMPILE option. Stored procedures created for replication cannot be executed on the subscribing server. FOR REPLICATION is used when creating a filter stored procedure that will be executed only by replication.
RECOMPILE
Indicates that SQL Server does not cache a plan for this procedure and the procedure is recompiled each time it is executed. Use this optional clause when you expect that the parameters you supply to the procedure won't be typical (that is, they won't result in the same optimal plan each time the procedure is executed). This can be beneficial when using wildcards in passing parameters because the distribution may be drastically different depending on the number of matches with the wildcard pattern.

Note If any constraints are added or altered, any stored procedures that reference the table will be automatically recompiled.

ENCRYPTION
Encrypts the syscomments table entry that contains the text of the CREATE PROCEDURE statement.

Important When a database is upgraded, syscomments entries are required in order to re-create procedures. Use encryption only when absolutely necessary; never delete entries from syscomments.

AS sql_statements
Specifies the actions the procedure is to take. Any number and type of SQL statements can be included in the procedure; however, there are some general limitations. For more information, see "sql_statement Limitations," later in this topic.

Remarks

When defining a stored procedure, you can create a stored procedure only in the current database (except for temporary procedures, which are always created in tempdb), and the CREATE PROCEDURE statement cannot be combined with other SQL statements in a single batch.

Stored procedures can use nesting, when one stored procedure calls another. The nesting level is incremented when the called procedure starts execution, and it is decremented when the called procedure finishes execution. Exceeding the maximum of 16 levels of nesting causes the whole calling procedure chain to fail. The current nesting level is stored in the @@NESTLEVEL global variable.

The maximum amount of text in a stored procedure is 65,025 characters. This limit is imposed because the text is stored in the syscomments system tables, where each procedure can occupy 255 rows of 255 bytes each (255 * 255 = 65,025).

To estimate the size of a compiled stored procedure, use DBCC MEMUSAGE. For details, see the DBCC statement.


Executing Stored Procedures

When a CREATE PROCEDURE statement is successfully executed, the procedure's name is stored in the sysobjects system table, its normalized plan in sysprocedures, and the text of the CREATE PROCEDURE statement in syscomments. When executed for the first time, the procedure is compiled to determine an optimal access plan to retrieve the data.

A stored procedure can be run by issuing the EXECUTE statement along with the procedure's name and any parameters. Parameters supplied in the format of @parameter = value can be supplied in any order; however, if you supply one parameter in the form @parameter = value, you must supply all subsequent parameters this way. If you do not supply parameters in the form @parameter = value, you must supply them in the order given in the CREATE PROCEDURE statement. Although you can omit parameters for which defaults have been supplied, you cannot skip any ¾ that is, if a procedure has five parameters, you can omit both the fourth and the fifth parameters, but you cannot skip the fourth and still include the fifth.

If a procedure is the first statement in a batch, you can give its name without using the EXECUTE keyword. When a procedure is executed successfully, the global variable @@ERROR is set to 0.


Referencing Objects

Objects referenced within a stored procedure must already exist. If objects are created within the stored procedure, you can reference them only after they've been created. The same holds true for temporary objects. A stored procedure can reference a temporary object only if the temporary object exists at the time the procedure is created or if the procedure itself creates the temporary object. A temporary object created in a procedure is dropped when the procedure exits.

If tables are created within a stored procedure, the column nullability decision is determined when the procedure is created. If column nullability is not explicitly defined, the nullability for each column will be defined based on the rules discussed in the CREATE TABLE topic and set based on the default nullability of the session and the database. To avoid any potential nullability problems, make sure to always explicitly define the nullability for each column.

Within a stored procedure, you cannot create an object (including a temporary one), drop the object, and then create a new object with the same name.

If you execute a procedure that calls another procedure, the called procedure can access objects created by the calling procedure.


sql_statement Limitations

You can use a SET statement inside a stored procedure. The SET option you choose remains in effect during the execution of the stored procedure and then reverts to its former setting.

Inside a stored procedure, object names used with certain statements (the utility statements) must be qualified with the object owner's name if other users are to use the stored procedure. The utility statements are:

  • ALTER TABLE/CREATE TABLE
  • DROP TABLE/TRUNCATE TABLE
  • CREATE INDEX/DROP INDEX
  • UPDATE STATISTICS
  • DBCC

If you use SELECT * in a CREATE PROCEDURE statement, the procedure (even with the WITH RECOMPILE option to EXECUTE) does not recognize any new columns you might have added to the table after the procedure was created. To include new columns, you must drop the procedure and then re-create it.


Temporary Stored Procedures

SQL Server supports two types of temporary procedures: local and global. A local temporary procedure is visible only to the connection that created it. A global temporary procedure is available to all connections. Local temporary procedures are automatically dropped at the end of the current session. Global temporary procedures are dropped at the end of the last session using the table. Normally, this is when the session that created the procedure ends.

Temporary procedures named with # and ## can be created by any user. Once the procedure is created, the owner of the local procedure is the only one who can use it. Permission to execute a local temporary procedure cannot be granted to other users. If a global temporary procedure is created, all users can access it; permissions cannot be explicitly revoked. Explicitly creating a temporary procedure in tempdb (naming without a pound sign) can be performed only by those with explicit CREATE PROCEDURE permission in the tempdb database. Permission can be granted to and revoked from these tables.


Auto Execution Stored Procedures

It is now possible to have one or more stored procedures execute automatically when SQL Server starts. The stored procedures must be created by the system administrator (SA) and will execute under the SA account as a background process. The procedure(s) cannot have any input parameters.

There is no limit to the number of startup procedures you can have, but be aware that each consumes one connection while executing. If you need to execute multiple procedures at startup, but don't need to execute them in parallel, you can make one procedure the startup procedure and have that procedure call the other procedures. This will use only one connection.

Execution of the stored procedures starts when the last database has been recovered at startup. To skip launching these stored procedures, you can specify trace flag 4022 as a startup parameter. If you start SQL Server with minimal configuration (using the -f flag), the startup stored procedures are not executed. For more information, see the Trace Flags topic or the Utilities and Executables topic.

To create a startup stored procedure, you must be logged in as system administrator and create the stored procedure in the master database.

  • To make an existing stored procedure a startup procedure, type:

sp_makestartup procedure_name

  • To stop a procedure from executing at startup, type:

sp_unmakestartup procedure_name

  • To view a list of all procedures that will execute at startup, type:

sp_helpstartup

For more information, see the specific stored procedures within the System Stored Procedures topic.


User-defined System Stored Procedures

During installation, numerous system stored procedures are provided for convenience as shortcuts to retrieve or manipulate information stored in the system tables. Most SQL Server database administration tasks are accomplished with these predefined system procedures; however, you can also create user-defined system stored procedures. By default, each frequently used system stored procedure name begins with the sp_ prefix. To create a user-defined system stored procedure, use sp_ for the beginning of the procedure_name. Once created, this procedure will have the following characteristics:

  • It can be executed in any database.
  • When executed, a stored procedure is typically found within the current database. If the procedure name begins with sp_ and is not found in the current database, SQL Server will look in the master database. Tables referenced within a stored procedure named with sp_ that are not resolved within the current database will be looked up in the master database.
  • Objects referenced within a stored procedure are resolved when the procedure is executed, not when it is created.


Getting Information About Stored Procedures

To display the text used to create the procedure, execute the sp_helptext system stored procedure (in the database where the procedure exists) with the procedure name as the parameter.

Note Procedures created with the ENCRYPTION option cannot be viewed with the sp_helptext system stored procedure.

For a report on the objects referenced by a procedure, use the sp_depends system stored procedure.

To rename a procedure, use the sp_rename system stored procedure.

Permission

CREATE PROCEDURE permission defaults to the database owner, who can transfer it to other users. Permission to execute a stored procedure is given to the procedure owner, who can grant execution permission on it to other database users.


CREATE RULE Statement

Creates an object called a rule, which, when bound to a column or a user-defined datatype, specifies the acceptable values that can be inserted into that column. An alternative method to creating rules is to create table- and column-level CHECK constraints as described with the CREATE TABLE. Using constraints is the preferred method of restricting column data because multiple constraints can be defined on a column or multiple columns. A column or user-defined datatype can have only one rule bound to it. However, a column can have a rule and one or more CHECK constraints associated with it. When this is true, all restrictions are evaluated.

Syntax

CREATE RULE [owner.]rule_name
AS condition_expression

where

rule_name
Is the name of the new rule. Rule names must conform to the rules for identifiers.
AS condition_expression
Specifies the conditions that define the rule. A rule can be any expression that is valid in a WHERE clause, and it can include such elements as arithmetic operators, relational operators, IN, LIKE, BETWEEN, and so on. It cannot reference columns or other database objects. Built-in functions that do not reference database objects can be included.

A condition_expression includes one variable. The at symbol (@) precedes each local variable. The expression refers to the value that is entered with the UPDATE or INSERT statement. You can use any name or symbol to represent the value when you write the rule, but the first character must be @.

Remarks

CREATE RULE statements cannot be combined with other SQL statements in a single batch. Rules do not apply to data already existing in the database at the time the rules are created, and rules cannot be bound to system datatypes. You can create a rule only in the current database. After creating a rule, execute the sp_bindrule System Stored Procedure to bind the rule to a column or to a user-defined datatype.

The rule must be compatible with the datatype of the column. You cannot bind a rule to a text, image, or timestamp column. Be sure to enclose character and date constants with single quotation marks (') and to precede binary constants with 0x. For example, you cannot use "@value like A%" as a rule for a numeric column. If the rule is not compatible with the column to which you've bound it, SQL Server returns an error message when you try to insert a value (not when you bind the rule).

A rule bound to a user-defined datatype is activated only when you attempt to insert a value into or to update a database column of the user-defined datatype. Because rules do not test variables, do not assign a value to a user-defined datatype variable that would be rejected by a rule bound to a column of the same datatype.

To get a report on a rule, use the sp_help System Stored Procedure. To display the text of a rule, execute the sp_helptext System Stored Procedure with the rule name as the parameter. To rename a rule, use the sp_rename System Stored Procedure.

You must drop a rule (using the DROP RULE) before you can create a new one with the same name, and you must unbind a rule (using the sp_unbindrule System Stored Procedure) before you drop it. Use the sp_unbindrule System Stored Procedure to unbind a rule from a column.

You can bind a new rule to a column or datatype without unbinding the previous one; the new rule overrides the previous one. Rules bound to columns always take precedence over rules bound to user-defined datatypes. Binding a rule to a column replaces a rule already bound to the user-defined datatype of that column. But binding a rule to a datatype does not replace a rule bound to a column of that user-defined datatype. The following table shows the precedence in effect when binding rules to columns and to user-defined datatypes where rules already exist:

 | Old rule bound to
New rule bound to | User-defined datatype | Column
User-defined datatype | Old rule replaced | No change
Column | Old rule replaced | Old rule replaced

If a column has both a default and a rule associated with it, the default must fall within the domain defined by the rule. A default that conflicts with a rule is never inserted. SQL Server generates an error message each time it attempts to insert such a default.

Permission

CREATE RULE permission defaults to the database owner, who can transfer it to other users.

Examples

A. Rule with a Range

This example creates a rule that restricts the range of integers inserted into the column(s) to which this rule is bound.

CREATE RULE range_rule
AS
@range >= $1000 AND @range < $20000
B. Rule with a List

This example creates a rule that restricts the actual values entered into the column(s) to which this rule is bound to only those listed in the rule.

CREATE RULE list_rule
AS
@list IN ('1389', '0736', '0877')
C. Rule with a Pattern

This example creates a rule to follow a pattern of any two characters followed by a hyphen, any number of characters (or no characters), and ending with an integer between 0 and 9.

CREATE RULE pattern_rule
@value LIKE '_ _-%[0-9]'

See Also

Batch Queries | sp_help System Stored Procedure
CREATE DEFAULT | sp_helptext System Stored Procedure
DROP DEFAULT | sp_rename System Stored Procedure
DROP RULE | sp_unbindrule System Stored Procedure
sp_bindrule System Stored Procedure | Wildcard characters


CREATE TABLE Statement

For SQL Server 6.5 information, see CREATE TABLE Statement in the What's New for SQL Server 6.5.

Creates a new table.

Syntax

CREATE TABLE [database.[owner].]table_name
(
{col_name column_properties [constraint [constraint [...constraint]]]
| [[,] constraint]}
[[,] {next_col_name | next_constraint}...]
)
[ON segment_name]

where

table_name
Is the name of the new table. Table names must conform to the rules for identifiers and must be unique within the database and for its owner.

You can create local and global temporary tables. Local temporary tables are visible in the current session only; global temporary tables are visible to all sessions. Temporary tables names are stored in the tempdb..sysobjects table by their names and a system-supplied numeric suffix. Local temporary tables are automatically dropped at the end of the current session or, for global temporary tables, at the end of the last session using the table. Normally, this is when the session that created the table ends.

Signify temporary tables by preceding the table_name with a single pound sign (#table_name) for local temporary tables and a double pound sign (##table_name) for global temporary tables. For local temporary tables, the complete name, including #, cannot exceed 20 characters.

When creating local or global temporary tables, the CREATE TABLE syntax supports constraint definitions; however, FOREIGN KEY constraints are not enforced on temporary tables.

If you are listed in that database's sysusers table and have CREATE TABLE permission in that database, you can create a table in a database different from the current one by fully qualifying the table_name.

col_name
Is the name of a column in the table. Column names must conform to the rules for identifiers and must be unique in the table.
column_properties =
datatype [NULL | NOT NULL | IDENTITY[(seed, increment)]]
datatype
Specifies the datatype of the column. System or user-defined datatypes are acceptable.
IDENTITY[(seed, increment)]
Generates incremental values for new rows based on the seed and increment parameters. If used, the seed value will be assigned to the first row in the table and each subsequent row will receive the next identity value, equal to the last identity plus the increment value. If neither argument is given, both will default to 1.

The IDENTITY property can be assigned to a tinyint, smallint, int, decimal(p,0), or numeric(p,0) column that does not allow null values. Only one column per table can be defined as an identity column. Defaults and DEFAULT constraints cannot be bound to an identity column, and an identity value cannot be changed. For more information, see "IDENTITY Property," later in this topic.

constraint =
Can include a table- or column-level constraint(s) where there are at most, one PRIMARY KEY per table, no more than 249 UNIQUE constraints, no more than 31 FOREIGN KEY constraints per table (each of which can reference at most 16 columns), one DEFAULT constraint per column, and any number of CHECK constraints. All can be entered within the same CREATE TABLE statement.
For a PRIMARY KEY constraint:
[CONSTRAINT constraint_name]
PRIMARY KEY [CLUSTERED | NONCLUSTERED]
(col_name [, col_name2 [..., col_name16]])
[ON segment_name]
For a UNIQUE constraint:
[CONSTRAINT constraint_name]
UNIQUE [CLUSTERED | NONCLUSTERED]
(col_name [, col_name2 [..., col_name16]])
[ON segment_name]
For a FOREIGN KEY constraint:
[CONSTRAINT constraint_name]
[FOREIGN KEY (col_name [, col_name2 [..., col_name16]])]
REFERENCES [owner.]ref_table [(ref_col [, ref_col2
[..., ref_col16]])]
For a DEFAULT constraint:
[CONSTRAINT constraint_name]
DEFAULT {constant_expression | niladic-function | NULL}
[FOR col_name]
For a CHECK constraint(s):
[CONSTRAINT constraint_name]
CHECK [NOT FOR REPLICATION] (expression)
CONSTRAINT constraint_name
Names the given constraint within the database. Constraint names must follow the rules for identifiers, except that the name cannot begin with a pound sign (#). If constraint_name is not supplied, a system-generated name is assigned to the constraint. The constraint_name will appear in any error message about constraint violations. If constraint requirements change, the constraint must be dropped and re-created using the ALTER TABLE statement.
PRIMARY KEY [CLUSTERED | NONCLUSTERED]
Enforces entity integrity for a given column or columns. All columns defined within a PRIMARY KEY constraint must be defined as NOT NULL. If nullability is not specified, all columns participating in a PRIMARY KEY constraint will have their nullability set to NOT NULL.

To enforce uniqueness of a primary key, SQL Server automatically creates a unique index on that column or columns. This unique index can be dropped only by dropping the associated table or the PRIMARY KEY constraint.

If no index type is specified, a CLUSTERED index is created by default. If NONCLUSTERED is specified or if CLUSTERED is specified for a different constraint in the same statement block, a NONCLUSTERED index is created.

Only one PRIMARY KEY constraint can be specified for a given table. However, "alternate" or "candidate" keys can be effectively created with a UNIQUE constraint.

UNIQUE [CLUSTERED | NONCLUSTERED]
Provides entity integrity for a given column or columns. Although columns participating in UNIQUE constraints can allow null values, it is not recommended that you use null values. If null values are necessary, the complete key (a single column or multiple columns for a composite index) cannot be NULL for more than one row. Multiple UNIQUE constraints can be defined on any given table. SQL Server automatically creates a unique index on this column or columns. Indexes created for use in UNIQUE constraint enforcement can be dropped only by dropping the associated table or constraint. If no index type is specified, a NONCLUSTERED index is created by default.
[FOREIGN KEY (col_name [, col_name2 [..., col_name16]])]
REFERENCES [owner.]ref_table [(ref_col [, ref_col2 [..., ref_col16]])]
Provide single- or multicolumn referential integrity. When defined, the number of columns and datatypes of each column specified in the FOREIGN KEY clause must identically match the REFERENCES clause. A non-null value entered in this column(s) must exist in the table and column(s) defined in the REFERENCES clause, and the referenced table's columns should have a PRIMARY KEY or UNIQUE constraint defined on them. For column-level constraints, using the FOREIGN KEY and col_name identifiers are optional.

Important REFERENCE constraints can reference only tables within the same database; this can include the same table on which the reference is defined (self-referenced tables). If you want cross-database referential integrity or custom messaging, implement these through triggers.

A table can have a maximum of 31 FOREIGN KEY references. This limit is an absolute upper limit, but the maximum may be lower depending on the number of work tables the server has to create to enforce the constraint, and the limit varies by the type of query being executed. FOREIGN KEY constraints are not enforced for temporary tables.

FOREIGN KEY constraints, unlike PRIMARY KEY constraints, do not create an index. To improve performance for data retrieval operations, use the CREATE INDEX statement to create an index on a foreign key column. This will allow for quicker execution times when a referenced key is modified.

For a FOREIGN KEY to be successfully created, the user must have SELECT or REFERENCES permission on the column or columns to which the FOREIGN KEY refers. For details, see the GRANT statement. When a specific reference column(s) is not provided, the primary key for the referenced table is used.

DEFAULT constant_expression | niladic-function | NULL
Specifies the value that will be provided for the column when a value is not explicitly supplied during an insert. A DEFAULT constraint can contain constant values, functions, built-in functions that do not take arguments (niladic-functions), or NULL. If used, a constant_expression must follow the same rules as defaults.

DEFAULT constraints can be created on columns of any datatype except columns that are the timestamp datatype or have the IDENTITY property. If a DEFAULT constraint is bound to a column defined with a user-defined datatype that has a default bound to it, the DEFAULT constraint is not allowed and the CREATE TABLE statement will fail. The default must be unbound from the user-defined datatype before that datatype can be used in a table definition with a DEFAULT constraint.

Niladic-functions allow a system-supplied value to be inserted when no value is specified. ANSI-standard niladic-functions include:

  • USER
  • CURRENT_USER
  • SESSION_USER
  • SYSTEM_USER
  • CURRENT_TIMESTAMP

In SQL Server 6.0, USER, CURRENT_USER, and SESSION_USER all default to the database username of the user performing the insert or update. SYSTEM_USER will provide the login ID, and CURRENT_TIMESTAMP will provide the same information as the GETDATE() function.

Benefits to using a DEFAULT constraint instead of a default (created with the CREATE DEFAULT statement) are that no explicit binding/unbinding is required and DEFAULT constraints are removed when the table is dropped.

When a DEFAULT is created as a table-level constraint, the column to which it applies is specified with FOR col_name.

CHECK (expression)
Enforces domain integrity by limiting the possible values that can be entered into a column or columns. The search condition must evaluate to a Boolean expression and cannot contain subqueries. CHECK constraints adhere to the same policies as rules; however, they are automatically bound to the columns on which they are defined. A column-level CHECK constraint can only reference the constrained column, and a table-level CHECK constraint can only reference columns of the constrained table. Multiple CHECK constraints can be defined for a table; however, only one can be defined per column per CREATE TABLE statement (although each column constraint can have multiple conditions). When a rule and one or more CHECK constraints exist for a column or columns, all restrictions are evaluated. If defined on multiple columns, CHECK constraints must be defined as table-level constraints.
NOT FOR REPLICATION
Prevents the specified CHECK constraint from being enforced for the distribution process used by replication; however, CHECK constraints will be enforced for all other users (including the system administrator). NOT FOR REPLICATION is used to protect horizontally partitioned tables that receive "source" data from a publishing server of data modifications to the replicated data. When replication is in effect, any modifications to the data that is replicated should be made on the publishing server (the main source of the data) and not on any of the subscribing servers (each of which receives exact copies of the publishing server's data).

The NOT FOR REPLICATION CHECK constraint will be applied to both the "before" and "after" image of an updated record to prevent records from being added to or deleted from the replicated range. All deletes and inserts will be checked; if they fall within the replicated range, they will be rejected.

ON segment_name
If specified with a PRIMARY KEY or UNIQUE constraint, creates only the index on the named segment. If that key is defined with a clustered index, the entire table will be placed on the named segment. For more information, see the CREATE INDEX statement.

If not specified with a constraint, ON segment_name creates the table on the named segment.

Caution If you create a table on a segment and then create a clustered index on that table without specifying a segment name, the entire table migrates to the default segment (unless the SORTED_DATA option is used).

When using ON segment_name, the logical device must already be assigned to the database by the CREATE DATABASE statement or the ALTER DATABASE statement, and the segment must have been previously created in the database with the sp_addsegment system stored procedure. To see a list of segment names available in your database, use the sp_helpsegment system stored procedure.

Important Constraints are not enforced in the same batch as CREATE TABLE. If you want constraints to take effect for all new rows, do not insert, delete, or update data in the batch in which CREATE TABLE is executed.

When a constraint is violated, the command is terminated. However, the transaction (if the statement is part of an explicit transaction) will continue to be processed. If desired, use the ROLLBACK TRANSACTION statement with the transaction definition by checking the @@error global variable.

FOREIGN KEY constraints are not enforced on temporary tables.

Remarks

SQL Server can have as many as 2 billion tables per database and 250 columns per table. The number of rows and total size of the table are limited only by the available storage. The maximum size of a database is 1 terabyte (TB). A table can be as large as 1 TB minus the size of the database catalog and any other objects. The maximum number of bytes per row is 1962. If you create tables with varchar or varbinary columns whose total defined width exceeds 1962 bytes, the table is created but a warning message appears. Trying to insert more than 1962 bytes into such a row or to update a row so that its total row size exceeds 1962, produces an error message and the statement fails. For details on calculating row size, see the Microsoft SQL Server Administrator's Companion.

The table is created in the currently open database unless a different database is explicitly specified in the CREATE TABLE statement with the optional database name. (Cross-database creation of tables and indexes is allowed as long as the creator is listed in the sysusers table of the other database and has CREATE TABLE permission in that database. However, cross-database creation of views, rules, defaults, stored procedures, and triggers is not allowed.)

User-defined datatypes are defined in terms of system datatypes. User-defined datatypes permit frequently used type information to be accessed by a name you choose with a specified rule, default, and display format attached to it. User-defined datatypes are created with the sp_addtype system stored procedure before they can be used in a table definition.

The NULL/NOT NULL assignment for a user-defined datatype can be overridden during the CREATE TABLE statement. However, the length specification cannot be changed; you cannot specify a length for a user-defined datatype in a CREATE TABLE statement.

For a report on a table and its columns, use the sp_help or sp_helpconstraint system stored procedure. To rename a table, use the sp_rename system stored procedure. For a report on the views and stored procedures that depend on a table, use the sp_depends system stored procedure.

Space is allocated to tables and indexes in increments of one extent, (eight pages) at a time. An extent is allocated when the table or index is created, and another extent is allocated each time the previous extent becomes full. For a report on the amount of space allocated and used by a table, execute the sp_spaceused system stored procedure.


Nullability Rules Within a Table Definition

The nullability of a column determines whether or not that column can allow a null value (NULL) as the data in that column. NULL is not 0 or blank. It means no entry has been made or an explicit NULL was supplied, and it usually implies that the value is either unknown or not applicable.

When creating or altering a table with the CREATE TABLE or ALTER TABLE statements, database and session settings will influence and possibly override the nullability of the datatype used in a column definition. It is recommended that you always explicitly define a column as NULL or NOT NULL or, if using a user-defined datatype, allow the column to use the datatype's default nullability.

When not explicitly specified, column nullability follows these rules:

  1. If the column is defined with a user-defined datatype:
    • SQL Server will use the nullability specified when the datatype was created. Use the sp_help system stored procedure to get the datatype's default nullability.
  2. If the column is defined with a system-supplied datatype:
    • If the system-supplied datatype has only one option, it will take precedence. Currently, the bit and timestamp datatypes can be defined only as NOT NULL.
    • If any session settings are ON (turned on with the SET), then:

      ·If ANSI_NULL_DFLT_ON is ON, NULL will be assigned.

      ·If ANSI_NULL_DFLT_OFF is ON, NOT NULL will be assigned.

    • If any database settings are configured (changed with the sp_dboption System Stored Procedure), then:

      ·If 'ANSI null default' is TRUE, NULL will be assigned.

      ·If 'ANSI null default' is FALSE, NOT NULL will be assigned.

  3. When not explicitly defined (neither of the ANSI_NULL_DFLT options are set), the session has not been changed and the database is set to the default ('ANSI null default' is FALSE), then the SQL Server default of NOT NULL will be assigned.


Temporary Tables

SQL Server supports two types of temporary tables: local and global. A local temporary table is visible only to the connection that created it. A global temporary table is available to all connections. Local temporary tables are automatically dropped at the end of the current session. Global temporary tables are dropped at the end of the last session using the table (normally, this is when the session that created the table ends).

Temporary tables named with # and ## can be created by any user. Once the temporary table is created, the owner of the local table is the only one who can access that table. Permissions cannot be granted on local temporary tables. Once a global temporary table is created, all users can access it; permissions cannot be explicitly revoked. Explicitly creating a temporary table in tempdb (named without a pound sign) can be performed only by those with explicit CREATE TABLE permission in the tempdb database. Permission can be granted to and revoked from these tables.

Because temporary tables are not generally maintained for long (they are automatically dropped by the system), because referenced objects could be dropped (drop dependencies), and because FOREIGN KEY constraints are not enforced, a simplified CREATE TABLE syntax can be used:

CREATE TABLE #[#]table_name
(column_definition
[, next_column_definition]...)

Note In addition to naming a temporary table with # or ##, temporary tables can be created without the pound sign by qualifying the table name with tempdb as the database. If created in tempdb, the table will exist until SQL Server is restarted.

Stored procedures can reference temporary tables that are created during the current session. If a temporary table is created by a stored procedure or created within an EXECUTE statement, it is deleted when the procedure or EXECUTE is completed. Within a stored procedure, you cannot create a temporary table, drop it, and then create a new temporary table that has the same name.

If user-defined datatypes are used within a temporary table's definition, the user-defined datatypes must first be added to tempdb. There are two ways to add a user-defined datatype (or any other object) to the tempdb database:

  • To add an object for the current session only, execute the sp_addtype system stored procedure while using tempdb.
  • To permanently add a user-defined datatype, execute the sp_addtype system stored procedure in the model database and then restart SQL Server so that model is copied to tempdb.

If you execute system stored procedures from within the tempdb database, system stored procedures such as the sp_help system stored procedure will work only on temporary tables.


IDENTITY Property

Columns that have the IDENTITY property contain system-generated values that uniquely identify each row within a table. You can use this feature to generate sequential numbers (for example, employee identification numbers). When inserting values into a table with an identity column, SQL Server automatically generates the next identifier based on the last used identity value (incremented by adding rows) and the increment value specified during column creation.

There is no need to remember which column has the IDENTITY property ¾ simply use the IDENTITYCOL keyword instead. When referencing data in a table, use the keyword IDENTITYCOL in place of the identity column name. It can be qualified with a table name if necessary. The IDENTITYCOL keyword can be used in SELECT, INSERT, UPDATE, and DELETE statements to reference an identity column.

Two system functions return identity information for an object containing an identity column. IDENT_SEED returns the seed value specified during creation of an identity column. IDENT_INCR returns the increment value specified during creation of an identity column.

Manipulating Data in Identity Columns

Data inserted into the table should not include a value for an identity column in the INSERT statement; instead, use the DEFAULT VALUES option (available with the INSERT statement).

By default, data cannot be inserted directly into an identity column; however, if a row was accidentally deleted, an identity value can be re-created and reconstructed. To get the last identity value, use the @@IDENTITY global variable. This variable is accurate after an insert into a table with an identity column; however, this value is reset after an insert into a table without an identity column occurs. To allow an insert with a specific identity value, see the SET statement for the IDENTITY_INSERT option.

Important When explicitly inserting values into the identity column, SQL Server does not validate uniqueness or the possibility of a gap based on the explicitly entered value. To ensure that this value is unique, use a UNIQUE or PRIMARY KEY constraint, or create a unique index on the identity column.

If an IDENTITY column exists for a table with frequent deletions, gaps can occur between IDENTITY values. If this is a concern, do not use the IDENTITY property. However, to ensure that no gaps have been created or to fill an existing gap, evaluate the existing identity values before explicitly entering one with the IDENTITY_INSERT option ON. If reusing a removed identity value, use the following sample code to check for the next available identity value. Replace tablename, column_type, and max(column_type) - 1 with your table name, identity column datatype, and numeric value of the maximum allowable value (for that datatype) -1.

SET IDENTITY_INSERT tablename ON
go
DECLARE @nextidentval column_type
SELECT @nextidentval = MIN(IDENTITYCOL) IDENT_INCR(tablename)
FROM tablename t1
WHERE IDENTITYCOL BETWEEN IDENT_SEED(tablename) AND max(column_type) - 1
AND NOT EXISTS (SELECT * FROM tablename t2
        WHERE t2.IDENTITYCOL = t1.IDENTITYCOL  IDENT_INCR(tablename))
go
SET IDENTITY_INSERT tablename OFF

To check that no gaps exist, this example uses a smallint identity column on a table named images, where the identity column was defined with a seed of 6 and an increment value of 8:

SET IDENTITY_INSERT images ON
go
DECLARE @@nextidentval smallint
SELECT @@nextidentval = MIN(IDENTITYCOL) IDENT_INCR(images)
FROM images t1
WHERE IDENTITYCOL BETWEEN IDENT_SEED(images) AND 32766
AND NOT EXISTS (SELECT * FROM images t2
        WHERE t2.IDENTITYCOL = t1.IDENTITYCOL  IDENT_INCR(images))
go

Using the IDENTITY Property with SELECT [INTO] or a View

Ordinarily, selecting an existing identity column into a new table or view, the new column inherits the identity property. If one of the following conditions is true, the new column does not inherit the identity property:

  • The SELECT statement contains a union, join, group by, or aggregate function
  • The identity column is selected more than once
  • The identity column is part of an expression

If one of these conditions is true, the column is created NOT NULL instead of inheriting the identity property. Because this column does not have the identity property, a column value must be explicitly specified when inserting a row into the new table.

If none of these conditions is true, the new table will inherit the identity column. All rules and restrictions, for the identity columns apply to the new table.

Permission

CREATE TABLE permission defaults to the database owner, who can transfer it to other users. Any user can create temporary tables.


CREATE TRIGGER Statement

Creates a trigger, a special kind of stored procedure that is executed automatically when a user attempts the specified data-modification statement on the specified table. Triggers are often used for enforcing business rules and data integrity. Referential integrity can be defined by using FOREIGN KEY constraints with the CREATE TABLE statement. If constraints exist on the "trigger table," they are checked prior to the trigger execution. If constraints are violated, the trigger is not run.

Triggers have been commonly used in earlier versions of SQL Server to enforce complex business rules and referential integrity (integrity rules about relationships between the primary and foreign keys of tables or views). SQL Server 6.0 provides declarative referential integrity through the CREATE TABLE statement. Triggers are useful to ensure appropriate actions when cascading deletions or updates need to occur.

In performance terms, trigger overhead is usually very low. The time involved in running a trigger is spent mostly in referencing other tables, which may be either in memory or on disk.

Syntax

CREATE TRIGGER [owner.]trigger_name
ON [owner.]table_name
FOR {INSERT, UPDATE, DELETE}
[WITH ENCRYPTION]
AS sql_statements

Or, using the IF UPDATE clause:

CREATE TRIGGER [owner.]trigger_name
ON [owner.]table_name
FOR {INSERT, UPDATE}
[WITH ENCRYPTION]
AS
IF UPDATE (column_name)
[{AND | OR} UPDATE (column_name)...] sql_statements

where

trigger_name
Is the name of the trigger. A trigger name must conform to the rules for identifiers and must be unique within the database.
table_name
Specifies the table on which the trigger will be executed; sometimes called the trigger table.
INSERT, UPDATE, DELETE
Are keywords that specify which data modification statements, when attempted against this table, will activate the trigger. Any combination (in any order) of these are allowed in the trigger definition.
ENCRYPTION
Encrypts the syscomments entries that contain the text of the CREATE TRIGGER statement.

Important When a database is upgraded, syscomments entries are required in order to re-create triggers. Use encryption only when absolutely necessary; never delete entries from syscomments.

AS sql_statements
Specify trigger conditions and actions. Trigger conditions specify additional criteria that determine whether the attempted INSERT, DELETE, or UPDATE statements will cause the trigger action(s) to be carried out.

The trigger actions specified in the SQL statements go into effect when the user action (UPDATE, INSERT, or DELETE) is attempted. If multiple trigger actions are specified, they are grouped within a BEGIN...END block.

Triggers can include any number and kind of SQL statements but should not include the SELECT statement. A trigger is meant to check or change data based on a data modification statement; it should not return data to the user. The SQL statements in a trigger often include control-of-flow language. A few special tables are used in CREATE TRIGGER statements:

  • Deleted and inserted are logical (conceptual) tables. They are structurally like the table on which the trigger is defined ¾ that is, the table on which the user action is attempted ¾ and hold the old values or new values of the rows that would be changed by the user action. For details, see "Inserted and Deleted Tables," later in this topic.

The following SQL statements are not allowed in a trigger:

  • All CREATE statements (DATABASE, TABLE, INDEX, PROCEDURE, DEFAULT, RULE, TRIGGER, and VIEW)
  • All DROP statements
  • ALTER TABLE and ALTER DATABASE
  • TRUNCATE TABLE
  • GRANT and REVOKE
  • UPDATE STATISTICS
  • RECONFIGURE
  • LOAD DATABASE and LOAD TRANSACTION
  • All DISK statements
  • SELECT INTO (because it creates a table)
IF UPDATE
Tests for an INSERT or UPDATE action to a specified column. It is not used with DELETE. More than one column can be specified. Because you specify the table name in the ON clause, do not use the table name in front of the column name with IF UPDATE.

Remarks

In earlier releases of SQL Server, triggers were commonly used to enforce referential integrity (rules about the relationships between the primary and foreign keys of tables). SQL Server 6.0 provides declarative referential integrity (DRI) through the table creation statements (ALTER TABLE and CREATE TABLE); however, DRI does not provide cross-database referential integrity in this release.

When creating a trigger, it must be the first statement in the batch and can apply to only one table. You can create a trigger only in the current database; however, a trigger can reference objects outside the current database. If you use an owner name to qualify a trigger, qualify the table name the same way. A table can have a maximum of three different triggers ¾ one each for INSERT, UPDATE, and DELETE. However, the same trigger action can be defined for more than one user action (for example, INSERT and UPDATE) in the same CREATE TRIGGER statement.

If a trigger is defined for an operation (INSERT, UPDATE, or DELETE) that already has a trigger association, the existing trigger is replaced. No warning message is given before the replacement occurs. When you drop a table, all triggers associated with it are also dropped.

Triggers can be nested 16 levels deep. If a trigger changes a table on which there is another trigger, the second trigger is activated and can then call a third trigger, and so on. If any trigger in the chain sets off an infinite loop, the nesting level will be exceeded and the trigger will be canceled. If nested triggers are not desired, use the sp_configure System Stored Procedure to set the nested triggers option to 0 (off). The default configuration allows nested triggers.

A trigger does not call itself in response to a second update to the same table within the trigger. For example, if an update trigger on one column of a table results in an update to another column, the update trigger is activated only once.


Inserted and Deleted Tables

When an INSERT, UPDATE or DELETE statement is executed, rows are added to the trigger table and to the inserted or deleted table(s) at the same time. Deleted and inserted tables can be examined by the trigger to determine whether or how the trigger action(s) should be carried out. Deleted tables are used with DELETE and UPDATE; inserted tables are used with INSERT and UPDATE. Thus, the rows in the inserted table are always duplicates of one or more rows in the trigger table.

Triggers are often used to roll back that transaction if an error is detected.

A trigger is activated only once per command or once per single data modification statement (even if it affects multiple rows). A complex query containing a WHILE loop can repeat an UPDATE or INSERT many times, and the trigger is activated each time.

If a desired result (such as a summary value) depends on the number of rows affected by data modification, use the global variable @@ROWCOUNT to test for modification to multiple rows (an INSERT, DELETE, or UPDATE based on a SELECT statement) and take appropriate action. Any Transact-SQL statement that does not return rows (such as an IF statement) sets @@ROWCOUNT to 0, so be sure to test with @@ROWCOUNT at the beginning of a trigger.

An UPDATE or INSERT trigger can use the IF UPDATE statement. It tests whether the UPDATE or INSERT action changed a particular column. IF UPDATE (column_name) is true for an INSERT statement whenever the column is assigned a value in the select list or in the VALUES clause. IF UPDATE (column_name) is true for an UPDATE statement if the column is assigned a value in the SET clause. An explicit NULL or a default assigns a value to a column and thus activates the trigger. An implicit NULL, however, does not assign a value to a column and does not activate the trigger.


Trigger Limitations

It is recommended that a trigger not include SELECT statements that return results to the user, since special handling for these returned results would have to be written into every application in which modifications to the trigger table are allowed.

You cannot create a trigger on a view.

You can use the SET statement inside a trigger. With SET, the option you invoke remains in effect during the execution of the trigger and then reverts to its former setting when the trigger is completed.

A TRUNCATE TABLE statement is not caught by a DELETE trigger. Although a TRUNCATE TABLE statement is, in effect, like a DELETE without a WHERE clause (it removes all rows), it is not logged and thus cannot execute a trigger. Since permission for the TRUNCATE TABLE statement defaults to the table owner and is not transferable, only the table owner should be concerned about inadvertently circumventing a DELETE trigger with a TRUNCATE TABLE statement.

The WRITETEXT statement, whether logged or unlogged, does not activate a trigger.


Getting Information About Triggers

The text of the CREATE TRIGGER statement is stored in the syscomments table. To see this text, execute the sp_helptext System Stored Procedure.

Note Triggers created with the ENCRYPTION option cannot be viewed with the sp_helptext system stored procedure.

The normalized tree for the trigger is stored in the sysprocedures table.

For a report on a trigger, execute the sp_help System Stored Procedure. For a report on the tables and views that are referenced by a trigger, use the sp_depends System Stored Procedure. To rename a trigger, use the sp_rename System Stored Procedure.

Permission

CREATE TRIGGER permission defaults to the table owner and is not transferable.


CREATE VIEW Statement

Creates a virtual table that represents an alternative way of looking at the data in one or more tables. You can use views as security mechanisms by granting permission on a view but not on underlying tables.

Syntax

CREATE VIEW [owner.]view_name
[(column_name [, column_name]...)]
[WITH ENCRYPTION]
AS select_statement [WITH CHECK OPTION]

where

view_name
Is the name of the view. View names must follow the rules for identifiers.
column_name
Is the name to be used for a column in a view. Naming a column in CREATE VIEW is always legal but only necessary when a column is derived from an arithmetic expression, a function, or a constant, when two or more columns could otherwise have the same name (usually because of a join), or when you want to give a column in a view a name different from the column from which it is derived. Column names can also be assigned in the SELECT statement.

If column_name is not specified, the view columns acquire the same names as the columns in the SELECT statement.

ENCRYPTION
Encrypts the syscomments entries that contain the text of the CREATE VIEW statement.

Important When a database is upgraded, syscomments entries are required in order to re-create views. Use encryption only when absolutely necessary; never delete entries from syscomments.

AS select_statement
Is the SELECT statement that defines the view. It can use more than one table and other views. You must have permission to select from the objects referenced in the SELECT clause of a view you are creating.

A view need not be a simple subset of the rows and columns of one particular table. You can create a view using more than one table and/or other views with a SELECT clause of any complexity.

There are, however, a few restrictions on the SELECT clauses in a view definition:

  • You cannot include ORDER BY, COMPUTE, or COMPUTE BY clauses.
  • You cannot include the INTO keyword.
  • You cannot reference a temporary table.
WITH CHECK OPTION
Forces all data modification statements executed against the view to adhere to the criteria set within the select_statement defining the view. When a row is modified through a view, the WITH CHECK OPTION guarantees that the data will remain visible through the view after the modification has been committed.

Remarks

You can create a view only in the current database. A view can reference a maximum of 250 columns.

In a view defined with a SELECT * clause, if you alter the structure of its underlying table(s) by adding columns, the new columns do not appear in the view unless the view is first deleted and redefined. The asterisk shorthand is interpreted and expanded when the view is first created.

When you query through a view, SQL Server checks to make sure that all the database objects referenced anywhere in the statement exist, that they are valid in the context of the statement, and that data modification statements do not violate any data integrity rules. A check that fails returns an error message. A successful check translates the action into an action against the underlying table(s).

If a view depends on a table (or view) that has been dropped, SQL Server produces an error message if anyone tries to use the view. If a new table (or view) is created to replace the one dropped, the view again becomes usable.

When you create a view, the name of the view is stored in the sysobjects table and the view's normalized query tree is stored in the sysprocedures table. Information about the columns defined in a view is added to the syscolumns table, and information about the view dependencies is added to the sysdepends table. In addition, the text of the view creation statement is added to the syscomments table. This is similar to a stored procedure; but when a view is executed for the first time, only its query tree is stored in procedure cache. Each time a view is accessed, its execution plan is recompiled.


View Restrictions

When creating and using a view, these rules apply:

  • CREATE VIEW statements cannot be combined with other SQL statements in a single batch.
  • You cannot create a trigger on a view.
  • The UNION operator cannot be used within a CREATE VIEW statement.
  • Data modification statements (INSERT or UPDATE) are allowed on multitable views if the data modification statement affects only one base table. You cannot use data modification statements on more than one table in a single statement.
  • INSERT statements are not allowed if a computed column exists within the view.
  • INSERT statements are not accepted unless all the NOT NULL columns without defaults in the underlying table or view are included in the view through which you are inserting new rows. (SQL Server has no way to supply values for NOT NULL columns in the underlying table or view.)
  • All column(s) being modified must adhere to all restrictions for the data modification statement as if it were executed directly against the base table. This applies to column nullability, constraints, identity columns, and columns with rules and/or defaults and base table triggers.
  • UPDATE statements cannot change any column in a view that is a computation, nor can they change a view that includes aggregate functions, built-in functions, a GROUP BY clause, or DISTINCT.
  • You cannot use READTEXT or WRITETEXT on text or image columns in views.
  • By default, data modification statements on views are not checked to determine whether the rows affected will be within the scope of the view. You can issue an INSERT statement on a view to add a row to the underlying base table, but not to add it to the view. Similarly, you can issue an UPDATE statement that changes a row so that the row no longer meets the criteria for the view. If all modifications should be checked, use the WITH CHECK option.

Important If you define a view with an outer join and then query the view with a qualification on a column from the inner table of the outer join, the results can differ from what you expect. All rows from the inner table are returned. Rows that do not meet the qualification show a null value in the appropriate columns for those rows.


Getting Information About Views

To display the text used to create a view, execute the sp_helptext system stored procedure with the view name as the parameter.

Note Views created with the ENCRYPTION option cannot be viewed with the sp_helptext system stored procedure.

To get a report of the tables or views on which a view depends, and of objects that depend on a view, execute the sp_depends system stored procedure.

You can rename a view with the sp_rename system stored procedure.

Permission

CREATE VIEW permission defaults to the database owner, who can transfer it to other users. The creator of a view must have SELECT permission for any object referenced in the view definition to SELECT from the view.


Cursors

For more information about how SQL Server 6.5 affects existing database systems, see Cursors in the What's New for SQL Server 6.5.

Server cursors allow individual row operations to be performed on a given results set or on the entire set. In SQL Server 6.0, ANSI SQL cursors are server based. In earlier releases, cursors were provided only through the DB-Library and Open Database Connectivity (ODBC) cursor APIs.

The addition of cursors to the server provides an efficient way for single-row operations to occur within a given results set. ANSI SQL cursors support only single-row cursors. Each fetch will return only one row from the results set. Server cursors enhance the general use of relational databases by allowing row-level operations when set-oriented operations are impractical. In relational systems, set operations are preferred; cursors provide a powerful complement to set operations. Using cursors, multiple operations can be performed row by row against a results set with or without returning to the original table. In other words, cursors conceptually return a results set based on tables within the database(s). For example, a cursor can be generated to include a list of all user-defined table names within a database. After the cursor has been opened, movement (fetching) through the results set can include multiple operations against each table by passing each table name as a variable. Cursors are extremely powerful when combined with stored procedures and the EXECUTE statement (to dynamically build strings).

SQL Server provides two interfaces for cursor functions. When using cursors in Transact-SQL batches or stored procedures, ANSI-standard SQL syntax has been added for declaring, opening, and fetching from cursors as well as positioned updates and deletes. When using cursors from a DB-Library or ODBC program, the SQL Server 6.0 client libraries transparently call built-in server functions to handle cursors more efficiently.

This overview shows the statements, in order, used to implement a cursor.

Statement | Description
DECLARE CURSOR Statement | Defines a cursor.
OPEN Statement | Opens a declared cursor.
FETCH Statement | Retrieves a specific row from the cursor.
CLOSE Statement | Closes an open cursor.
DEALLOCATE Statement | Removes the cursor data structures.

In addition to browsing through the cursor results with FETCH, the current row of an open cursor can be modified. The UPDATE statement and the DELETE statement, when used against a cursor, affect only the row on which the cursor is currently positioned.

Syntax

To update the current row:

UPDATE table_name
SET column_name1 =
{expression1 | NULL | (select_statement)}
[, column_name2 =
{expression2 | NULL | (select_statement)}...]
WHERE CURRENT OF cursor_name

To delete the current row:

DELETE FROM table_name
WHERE CURRENT OF cursor_name

Modifications made with WHERE CURRENT OF cursor_name affect only the single row on which the cursor is positioned. In the case of a cursor based on a join, only the table_name specified in the DELETE or UPDATE statement is modified. Other tables participating in the cursor are not affected. For complete syntax and more information, see the DELETE and UPDATE statements.

The following sections discuss each of the statements used to define, access, and close a cursor.


DECLARE Statement

Defines a cursor. Once declared, row sets for cursors are assigned by using the OPEN statement. (The DECLARE statement can also be used to define the name and type of local variables for a batch or procedure. For more information on variable declaration and assignment, see the DECLARE Statement.)

Syntax

DECLARE cursor_name [INSENSITIVE] [SCROLL] CURSOR
FOR select_statement
[FOR {READ ONLY | UPDATE [OF column_list]}]

where

cursor_name
Is the name of the cursor being defined. The cursor_name must conform to the rules for identifiers.
INSENSITIVE
Defines a cursor that makes a temporary copy of the data to be used by the cursor. All requests to the cursor are answered from this temporary table; therefore, modifications made to base tables will not be reflected in the data returned by fetches made to this cursor, and this cursor does not allow modifications.
SCROLL
Specifies that all methods of fetching data are available. Committed deletes and updates made to the underlying tables (by any users) are reflected in subsequent fetches (provided that the cursor is not declared with the INSENSITIVE option).
select_statement
Is a standard SELECT statement used to identify a set of rows from a given table or tables within a database. If each of the underlying tables does not have a unique index, the cursor will automatically be an INSENSITIVE cursor.

The keywords COMPUTE, COMPUTE BY, FOR BROWSE, and INTO are not allowed within the select_statement of a cursor declaration.

If DISTINCT, UNION, GROUP BY, and/or HAVING are used, one or more of the underlying tables does not have a unique index, an outer join is used, or a constant expression is included in the select_list, the cursor will be created as INSENSITIVE.

READ ONLY
Prevents updates from occurring against any row within this cursor. This option overrides the default capability of a cursor to be updated.
UPDATE [OF column_list]
Defines updatable columns within the cursor. If OF column_list is supplied, only the columns listed will allow modifications. If no list is supplied, all columns can be updated unless the cursor has been defined as READ ONLY.


OPEN Statement

Opens a cursor.

Syntax

OPEN cursor_name

where

cursor_name
Specifies the name of an already-declared cursor. In the case of an INSENSITIVE cursor, this will generate the required temporary table. At the time the cursor is opened, results set membership and ordering are fixed.

Note Membership and ordering are fixed when the cursor is opened; updates and deletes that have been committed against the base tables of the cursor by other users will be reflected in fetches made against all cursors defined without the INSENSITIVE option. This behavior is commonly called keyset-driven. Rows that have been deleted from a results set will appear with NULLs in all variable columns, spaces in all char columns, and default or zero values in all other non-null columns. To differentiate between a deleted row and a row that has been inserted with NULL data values, use the global variable @@FETCH_STATUS after each FETCH is made against the cursor.

Remarks

Once a cursor has been opened, use the global variable @@CURSOR_ROWS to receive the number of qualifying rows in the last opened cursor. Depending on the number of rows expected in the results set, SQL Server may choose to populate the keyset asynchronously on a separate thread. This allows fetches to proceed immediately, even if the keyset is not fully populated. @@CURSOR_ROWS returns:

-m | If the cursor is being populated asynchronously. The value returned (-m) refers to the number of rows currently in the keyset.
n | If the cursor is fully populated. The value returned (n) refers to the number of rows.
0 | If no cursors have been opened or the last opened cursor has been closed or deallocated.

To set the threshold at which SQL Server will generate keysets asynchronously, use the cursor threshold configuration option. For details, see the sp_configure system stored procedure.


FETCH Statement

For more information about how SQL Server 6.5 affects existing database systems and for updated SQL Server 6.5 syntax, see FETCH Statement in the "What's New for SQL Server 6.5".

Retrieves a specific row from the cursor.

FETCH [[NEXT | PRIOR | FIRST | LAST | ABSOLUTE n | RELATIVE n] FROM] cursor_name
[INTO @variable_name1, @variable_name2, ...]

where

NEXT
Returns the first row of the results set if this is the first fetch against the cursor; otherwise, it moves the cursor one row within the results set. NEXT is the primary method used to move through a results set. NEXT is the default cursor fetch.

Note PRIOR, FIRST, LAST, ABSOLUTE n, and RELATIVE n are available only with cursors defined with the SCROLL option.

PRIOR
Returns the previous row within the results set.
FIRST
Moves the cursor to the first row within the results set and returns the first row.
LAST
Moves the cursor to the last row within the results set and returns the last row.
ABSOLUTE n
Returns the nth row within the results set. If n is a negative value, the returned row will be the nth row counting backward from the last row of the results set.
RELATIVE n
Returns the nth row after the currently fetched row. If n is a negative value, the returned row will be the nth row counting backward from the relative position of the cursor.
FROM cursor_name
Defines the cursor from which the fetch should be made. Multiple cursors are allowed within any session provided that each has a unique name.
INTO @variable_name1, @variable_name2, ...
Allows data returned within a fetch to be placed into local variables. Each of the variables must match the datatype. Errors will occur when the datatypes are incompatible. Implicit datatype conversions are not provided here.

A global variable, @@FETCH_STATUS, will be updated at every execution of FETCH. At a successful fetch, @@FETCH_STATUS will be set to 0. If no data was fetched because the requested cursor position exceeded the results set, -1 will be returned. If the row returned is no longer a member of the results set (for example, the row was deleted from the base table after the cursor was opened), @@FETCH_STATUS will return -2. Always use this to determine the validity of the data returned from a cursor fetch prior to attempting any operation against that data.


CLOSE Statement

Closes an open cursor. CLOSE leaves the data structures accessible for reopening; however, modifications or fetches are not allowed until the cursor is reopened.

Syntax

CLOSE cursor_name

where

cursor_name
Specifies the name of an already-declared cursor.


DEALLOCATE Statement

Removes the cursor data structures. DEALLOCATE is different from CLOSE in that a closed cursor can be re-opened. DEALLOCATE releases all data structures associated with the cursor and removes the definition of the cursor.

Syntax

DEALLOCATE cursor_name

where

cursor_name
Specifies the name of an already-declared cursor.


Datatypes

Datatypes specify the data characteristics of columns, stored-procedure parameters, and local variables.

SQL Server supplies various system datatypes, which can be categorized by the type of data stored within the datatype. In addition to system-supplied datatypes, SQL Server allows user-defined datatypes, which are based on the system datatypes. For details about user-defined datatypes, see the sp_addtype system stored procedure.

In SQL Server 6.0, all system datatype names are case-insensitive. This change allows table definitions, variable declarations, and procedure parameters to include uppercase or lowercase datatype definitions. Because datatypes are case-insensitive, identical user-defined datatype names with only differing capitalization are not allowed for user-defined datatypes.

Important An existing user-defined datatype whose name conflicts with that of another user-defined datatype or system-supplied datatype will no longer be referenced. If an existing user-defined datatype is found within a table, view, or procedure definition and has a conflict, the user-defined datatype will be mapped to the system datatype and no longer reference the user-defined datatype.

These are the system datatypes:

Type of data | System-supplied datatype
Binary | binary[(n)] varbinary[(n)]
Character | char[(n)] varchar[(n)]
Date and time | datetime smalldatetime
Exact numeric | decimal[(p[, s])] numeric[(p[, s])]
Approximate numeric | float[(n)] real
Integer | int smallint tinyint
Monetary | money smallmoney
Special | bit timestamp user-defined datatypes
Text and image | text image
Synonyms | binary varying for varbinary character for char character for char (1) character (n) for char (n) character varying (n) for varchar (n) dec for decimal integer for int double precision for float float [(n)] for n = 1–7 for real float [(n)] for n = 8–15 for float


Using Datatypes in Transact-SQL Statements

To declare the datatype for a column in a table:

CREATE TABLE [[database.]owner.]table_name
(column_name datatype [NOT NULL | NULL]
[, column_name datatype [NOT NULL | NULL]]...)

ALTER TABLE [[database.]owner.]table_name
ADD column_name datatype NULL
[, column_name datatype NULL...]

For complete syntax, see the CREATE TABLE and ALTER TABLE statements.

To declare the datatype for a local variable:

DECLARE @variable_name datatype
[, @variable_name datatype...]

For complete syntax, see the DECLARE statement.

To declare the datatype for a parameter in a stored procedure:

CREATE PROCedure [owner.]procedure_name[;number]
[(parameter1 [, parameter2]...[parameter255])]
[{FOR REPLICATION} | {WITH RECOMPILE}
[{[WITH] | [,]} ENCRYPTION]]
AS sql_statements

where

parameter =
@parameter_name datatype [= default] [OUTPUT]

For complete syntax, see the CREATE PROCEDURE statement.

To change a value from one datatype to another:

CONVERT (datatype[(length)], expression [, style])

For the complete CONVERT function syntax, see the Functions topic.


Binary Data

Binary data consists of the characters 0 through 9 and A through F (or a through f), in groups of two characters each. Binary strings must be preceded by 0x. For example, to input "FF", type 0xFF. The maximum binary data value is 255 bytes, each of which is "FF". The binary datatypes are not for hexadecimal data, but rather for bit patterns. Conversions and calculations of hexadecimal numbers stored as binary data can be unreliable. For more information, see the CONVERT function in the Functions topic.

When specifying the length of a binary datatype, every two characters count as one. A length of 10 signifies that 10 two-character groupings will be entered.

These are the binary datatypes:

binary[(n)]
Is a datatype that holds as many as 255 bytes of fixed-length binary data. Specify the maximum byte length with n. The binary datatype can contain 0 bytes, but when specified, n must be a value from 1 through 255. Storage size is n regardless of the actual length of the entry.

Choose binary when you think the data entries in the column will be consistently close to the same size. Columns of type binary are accessed somewhat faster than varbinary columns because they use a fixed storage length (n).

Note When the binary datatype is used with the ALTER TABLE or CREATE TABLE statement, a column defined as NULL will be handled as a varbinary column.

varbinary[(n)]
Is a variable-length binary datatype that holds a maximum of 255 bytes of variable-length binary data. Specify the maximum byte length with n. A varbinary datatype can contain 0 bytes, but when specified, n must be a value from 1 through 255. Storage size is the actual length of the data entered, not n.

Choose varbinary when you expect null values or a variation in data size.

Important When n is not specified in a data definition statement (such as CREATE TABLE) or in a variable declaration, the length supplied is 1 (the ANSI-standard). When n is not specified with the CONVERT function, SQL Server defaults to a length of 30.

If the data entered is too long for the specified datatype, binary and varbinary entries are truncated.


Character Data

Character data consists of any combination of letters, symbols, and numbers. When entered, character data must be enclosed with single quotation marks ('). If numbers are stored as character data, they must be converted to a numeric datatype (decimal, float, int, money, numeric, real, smallint, smallmoney, or tinyint) before you can use them in calculations. If the value of the string is the null value, do not enclose NULL in single quotation marks ('). To supply the null value, use the keyword NULL during INSERT or UPDATE.

Note An empty string is not considered the same as NULL. An empty string with no characters, supplied as ' ', will insert a single blank space.

These are the character datatypes:

char[(n)]
Is a datatype that holds a maximum of 255 characters. Specify the maximum length with n. The char datatype can contain 0 characters, but when specified, n must be a value from 1 through 255. Storage size is n regardless of the actual length of the entry.

Choose char when you think the data entries in the column will be consistently close to the same size. Columns of type char are accessed somewhat faster than varchar columns because they use a fixed storage length (n).

Note When the char datatype is used with the ALTER TABLE or CREATE TABLE statement, a column defined as NULL will be handled as a varchar column.

varchar[(n)]
Is a datatype that holds a maximum of 255 characters. Specify the maximum length with n. The varchar datatype can contain 0 characters, but n must be a value from 1 through 255. Storage size is not fixed with a varchar column. Instead, storage is defined by the actual size of the data entered (ignoring all trailing blanks).

Choose varchar when you expect null values or a wide variation in data size.

Important When n is not specified in a data definition statement (such as CREATE TABLE) or in a variable declaration, the length supplied is 1 (the ANSI-standard). When n is not specified with the CONVERT function, SQL Server determines the appropriate value of n based on the length of the data being converted.

If the data entered is too long for the specified datatype, char and varchar entries are truncated. Similarly, if you enter strings that are shorter than the maximum length, char columns that do not allow null values and char variables will be padded with trailing blanks; char columns that allow null values and varchar columns or variables will not store trailing blanks. This is important when using the LIKE comparison operator with varchar and char strings. Other comparison operators, such as the equal sign (=), always right-pad the shorter string with blanks before comparing. For more information, see the Search Conditions and Wildcard Characters topics.


Date and Time Data

Date and time data consist of alphanumeric data representing a date and time of day. The default display format for dates is "Mon dd yyyy hh:mmAM" (or PM), such as "Apr 15 1996 10:23AM". When time data is entered, the order of time components is significant: hours; minutes; seconds; milliseconds; AM, am, PM, or pm (12AM is midnight, 12PM is noon). To be recognized as time, a value must contain either a colon (:) or an AM/PM signifier.

Always enclose datetime values with single quotation marks ('). Capitalization (case) is ignored, and spaces can occur anywhere between date parts. SQL Server recognizes the date portion and the time portion of the data separately, so the time can precede or follow the date.

Use date functions with the CONVERT function to display seconds and milliseconds and to get other date styles and date part orderings by converting datetime data to char.

These are the date and time datatypes:

datetime
Is a datatype stored in 8 bytes of two 4-byte integers: 4 bytes for the number of days before or after the base date of January 1, 1900, and 4 bytes for the number of milliseconds after midnight. The date segments of datetime values representing dates prior to the base date are stored as negative values.

Data values for datetime range from January 1, 1753, to December 31, 9999, to an accuracy of one three-hundredth second, or 3.33 milliseconds. SQL Server rejects all values it cannot recognize as dates between 1753 and 9999. You can omit either portion, but if you omit both, datetime defaults to January 1, 1900, 12:00:00:000AM. If you omit the time portion of a datetime value, the default (12:00:00:000AM) is supplied. If you omit the date portion, the default (Jan 1 1900) is supplied. For example, an empty string or missing date is interpreted as the base date, January 1, 1900. A time value without a date, for example 4:33, is interpreted as January 1, 1900, 4:33AM.

smalldatetime
Is a date and time datatype less precise than datetime. This parameter's storage size is 4 bytes, consisting of one small integer for the number of days after January 1, 1900, and one small integer for the number of minutes past midnight. Data values for smalldatetime range from January 1, 1900, through June 6, 2079, with accuracy to the minute.

Date Formats

SQL Server recognizes the following formats (alphabetic, numeric, and unseparated string) for date data. Enclose each format with single quotation marks (').

Alphabetic format

The month can be the full name or the abbreviation given in the current language; commas are optional and capitalization (case) is ignored.

These alphabetic formats are acceptable:

Apr[il] [15][,] 1996
Apr[il] 15[,] [19]96
Apr[il] 1996 [15]
Apr[il] [19]96 15
[15] Apr[il][,] 1996
15 Apr[il][,][19]96
15 [19]96 apr[il]
[15] 1996 apr[il]
1996 APR[IL] [15]
[19]96 APR[IL] 15
1996 [15] APR[IL]

If you specify only the last two digits of the year, values less than 50 are interpreted as 20yy, and values greater than or equal to 50 are interpreted as 19yy. For example, if you specify 3, the result is 2003. If you specify 82, the result is 1982. You must type the century when the day is omitted or when you need a century other than the default.

If the day is missing, the first day of the month is supplied.

The DATEFORMAT session setting is not applied when you specify the month in alphabetic form. For more information, see the SET statement.

Numeric format

You must specify the month, day, and year in a string with slashes (/), hyphens (-), or periods (.) as separators.

This string must appear in the following form:

<num> <sep> <num> <sep> <num> [<time_spec>] [<time_spec>]

These numeric formats are acceptable:

[0]4/15/[19]96 (mdy)
[0]4-15-[19]96 (mdy)
[0]4.15.[19]96 (mdy)
[04]/[19]96/15 (myd)

15/[0]4/[19]96 (dmy)
15/[19]96/[0]4 (dym)
[19]96/15/[0]4 (ydm)
[19]96/[04]/15 (ymd)

When the language is set to us_english, the default order for the date is mdy. You can change the date order with the SET DATEFORMAT statement, which can also affect the date order, depending on the language.

The setting for DATEFORMAT determines how date values are interpreted. If the order doesn't match the setting, the values are not interpreted as dates (because they are out of range), or the values are misinterpreted. For example, 12/10/08 can be interpreted as one of six dates, depending on the DATEFORMAT setting. For more information, see the SET statement.

Unseparated string format

An unseparated string can specify four, six, or eight digits, an empty string, or a time value without a date value.

The DATEFORMAT session setting does not apply to all-numeric date entries (numeric entries without separators). Six- or eight-digit strings are always interpreted as ymd. The month and day must always be two digits.

This is the acceptable unseparated string format:

[19]960415

A string of only four digits is interpreted as the year. The month and date are set to January 1. When specifying only four digits, you must include the century.

Time Formats

SQL Server recognizes the following formats for time data. Enclose each format with single quotation marks ('). The hour can refer to 12-hour or 24-hour time. Capitalization (case) (for AM or PM) is ignored.

14:30
14:30[:20:999]
14:30[:20.9]
4am
4 PM
[0]4[:30:20:500]AM

Milliseconds can be preceded by either a colon (:) or a period (.). If preceded by a colon, the number means thousandths-of-a-second. If preceded by a period, a single digit means tenths-of-a-second, two digits mean hundredths-of-a-second, and three digits mean thousandths-of-a-second. For example, "12:30:20:1" means twenty and one-thousandth seconds past 12:30; "12:30:20.1" means twenty and one-tenth seconds past 12:30.

Using Data and Time Datatypes

You can perform some arithmetic calculations on datetime data with the built-in date functions. For more information, see the Functions topic.

Searching for datetime values with an equal sign (=) and the month, day, and year returns only those time values that are precisely 12:00:00:000 AM (the default).

If you use the keyword LIKE with datetime values, SQL Server first converts the dates to datetime format and then to varchar. Since the standard display formats don't include seconds or milliseconds, you cannot search for them with LIKE and a matching pattern, unless you use the CONVERT function with the style parameter set to 9 or 109. However, LIKE works well when searching for datetime values that contain a variety of date parts. For example, if you insert the value 9:20 into a column named arrival_time, the clause WHERE arrival_time = '9:20', does not find the value because SQL Server converts the entry into Jan 1 1900 9:20AM. However, the clause WHERE arrival_time LIKE '%9:20%' does find the value.

When using LIKE with a single-digit day of the month (1 to 9), you must insert one space between the month and the day to match the varchar conversion of the datetime value. Similarly, if the hour is less than 10, the conversion places two spaces between the year and the hour. The clause 'LIKE May 2%' (with one space between May and 2) finds all dates from May 20 through May 29, but not May 2. You don't need to insert the extra space with other date comparisons, because LIKE is the comparison for which the datetime values are converted to varchar.


Exact Numeric Data

Exact numeric data consists of numeric data with accuracy preserved to the least-significant digit. SQL Server 6.0 supports two exact numeric datatypes: decimal and numeric. Both decimal and numeric data can contain an integer component to the left of the decimal point and a fractional component to the right of the decimal point. Exact numeric datatypes are different from the approximate numeric datatypes float and real, which cannot store all decimal numbers with complete accuracy. The decimal and numeric datatypes are identical in the SQL Server 6.0 implementation. Both are provided for ANSI compatibility.

These are the exact numeric datatypes:

decimal[(p[, s])] and numeric[(p[, s])]
Are exact numeric datatypes that hold values from 1038 - 1 through - 1038 - 1. Storage size varies based on the specified precision, and it ranges from a minimum of 2 bytes to a maximum of 17 bytes, as follows:
Precision | Storage bytes
1 - 2 | 2
3 -4 | 3
5-7 | 4
8-9 | 5
10-12 | 6
13-14 | 7
15-16 | 8
17-19 | 9
20-21 | 10
22-24 | 11
25-26 | 12
27-28 | 13
29-31 | 14
32-33 | 15
34-36 | 16
37-38 | 17

Precision (p) specifies the maximum total number of decimal digits that can be stored, both to the left and to the right of the decimal point. Scale (s) specifies the maximum number of decimal digits that can be stored to the right of the decimal point, and it must be less than or equal to the precision.

Specify the precision with p, which must be a value from 1 through the maximum precision, and the scale with s, which must be a value from 0 through p. SQL Server normally supports a maximum precision of 28 digits for compatibility with limits of various front ends, such as Microsoft Visual Basic. However, if a precision greater than 28 is needed, use the /p parameter with SQLSERVR.EXE. For more information on running SQLSERVR.EXE, see the Utilities and Executables topic. If you do not specify the precision, SQL Server uses a default precision of 18. If you do not specify the scale, SQL Server uses a default scale of 0.


Approximate Numeric Data

Approximate numeric data consists of numeric data preserved as accurately as the binary numbering system allows. Many floating-point values cannot be accurately represented in binary notation. For these numbers, it is necessary to store an approximation of the decimal number. Examples of these numbers are floating-point values ending in .3, .6, and .7. The IEEE 754 specification provides four rounding modes: round to nearest, round up, round down, and round toward zero. SQL Server uses round up. All are accurate to guaranteed precision but can result in slightly different floating-point values. Because the binary representation of a floating-point number may use one of many legal rounding schemes, it is impossible to reliably quantify a floating-point value. It is best to avoid referencing to floating-point columns in WHERE clauses.

These are the approximate numeric datatypes:

float[(n)]
Is a datatype that holds positive or negative floating-point numbers. Specify the binary precision with b, which must be from 1 through 15. If the binary precision is from 1 through 7, it is another name for the real datatype. If the binary precision is from 8 through 15, it is considered a synonym for the float datatype. By default, this column has a 15-digit precision. The range of positive values is approximately from 2.23E - 308 through 1.79E 308, zero can be stored, and the range of negative values is approximately from -2.23E - 308 through -1.79E 308. Storage size is 8 bytes. All arithmetic operations except modulo are available with float.

Data of type float can include an optional exponent. For float data with an exponential component, enter a number (with or without a decimal point and a positive or negative sign), followed by e or E, followed by an optionally signed integer. The value represented by a float is the product of the first number and 10 to the power of the second number.

real
Is a floating-point column similar to float. This column has 7-digit precision. The range of positive values is approximately from 1.18E - 38 through 3.40E 38, zero can be stored, and the range of negative values is approximately from -1.18E - 38 through -3.40E 38. Storage size is 4 bytes.


Integer Data

Integer data consists of numeric data with precision to a whole number.

These are the integer datatypes:

int
Is a datatype that holds whole numbers from -2 (31) (-2,147,483,648) through 2 (31) - 1 (2,147,483,647). Storage size is 4 bytes.
smallint
Is a datatype that holds whole numbers from -2 (15) (-32,768) through 2 (15) - 1 (32,767). Storage size is 2 bytes.
tinyint
Is a datatype that holds whole numbers from 0 through 255. Storage size is 1 byte.


Monetary Data

Monetary datatypes consist of numeric data for decimal currency. Precede monetary data with a dollar sign ($). If there is no dollar sign, SQL Server treats the value as a numeric with a scale of 4. Money values, even when input with a dollar sign, do not return dollar signs in the results.

To represent negative monetary data values, place a minus sign (-) after the dollar sign. You cannot enter monetary data values with commas, although the default print format for monetary data places a comma after every three digits.

When monetary data is displayed, they are rounded up to the nearest cent. All arithmetic operations except modulo are available with monetary datatypes.

Note With both money and smallmoney, you can store monetary values other than U.S. dollars, but SQL Server does not provide any form of conversion.

These are the monetary datatypes:

money
Is a datatype that stores monetary values from -922,337,203,685,477.5808 through +922,337,203,685,477.5807, with accuracy to a ten-thousandth-of-a-monetary-unit. Money values are represented as double-precision integers. Storage size is 8 bytes.
smallmoney
Is a column that stores monetary values from - 214,748.3648 through +214,748.3647, with accuracy to a ten-thousandth-of-a-monetary-unit. Storage size is 4 bytes. When smallmoney values are displayed, they are rounded up to two places.


Special Datatypes

Special datatypes consist of datatypes with a distinct, or special use.

These are the special datatypes:

bit
Is a datatype that holds either 1 or 0. Integer values other than 1 or 0 are accepted but are always interpreted as 1. Storage size is 1 byte. Multiple bit types in a table can be collected into bytes. For example, 7-bit columns fit into 1 byte; 9-bit columns take 2 bytes. The status column in the syscolumns system table indicates the unique offset position for bit columns.

Columns of type bit cannot be NULL and cannot have indexes on them. Use bit for true/false or yes/no types of data.

timestamp
Is a datatype that is automatically updated every time a row containing a timestamp column is inserted or updated. Browse mode requires timestamp columns in tables that are to be browsed in DB-Library applications. Values in timestamp columns are not datetime data, but binary(8) varbinary(8) data, indicating the sequence of SQL Server activity on the row. A table can have only one timestamp column.

The timestamp datatype has no relation to the system time ¾ it is simply a monotonically increasing counter whose values will always be unique within a database.

If you do not supply a datatype, a column named timestamp is automatically defined as a timestamp datatype. You can create a column named timestamp and assign it another datatype (although assigning another datatype can confuse other users and does not allow browsing with the DB-Library BROWSE functions).

By default, the timestamp datatype is defined as binary(8). If timestamp is used with NOT NULL, the column will be stored as varbinary(8). In client applications, the metadata declares the timestamp as varbinary, regardless of the nullability. The current timestamp value for a database can be selected with the global variable @@DBTS.

user_defined_datatype_name
Is the name of a user-defined datatype created with the sp_addtype system stored procedure. For details, see the sp_addtype system stored procedure.


Text and Image Data

Text and image data consists of character or binary data stored and managed as a linked list of 2K data pages that appear as if they were stored in a table row. A text or image column contains NULL or a pointer (assigned at initialization) to the first text page for that entry, and thus to the entire text or image value. Although text and image datatype definitions do not include length, they do allow null values.

At least one 2K data page is allocated for each non-null text or image data value. To save storage space, you can insert null values until you use the text or image column. Note that any update (even an update that sets the value to NULL) to a text or image column initializes the column; that is, it assigns a valid text pointer and causes the first 2K data page to be allocated.

These are the text and image datatypes:

text
Is a variable-length datatype that can hold as many as 2 (31) - 1 (2,147,483,647) characters. The text definitions do not include a length, and text values must be surrounded by single quotation marks in an INSERT statement. You can use the LIKE keyword and wildcard characters with text data.

You can explicitly convert text data to char or varchar with the CONVERT function, but the limit is the maximum length of these datatypes, 255 bytes.

image
Is a variable-length datatype that can hold as many as 2 (31) - 1 (2,147,483,647) bytes of binary data. The image definitions do not include a length, and image values must be preceded by 0x in an INSERT statement. The image datatype cannot be used for variables or parameters in stored procedures.

You can explicitly convert image data to binary or varbinary with the CONVERT function, but the limit is the maximum length of these datatypes (255 bytes).

When image is data entered with an odd number of bytes (but less than 255), it is padded with a leading zero. For example, an insert of "0xaaabb" becomes "0x0aaabb". You cannot insert image values with an odd number of characters greater than 255 bytes.

Using text and image Datatypes

To enter text or image data, the column must first be initialized. Initialization causes a 2K data page to be allocated. Initialize the text or image column by providing non-null data with an INSERT statement or any value (including a NULL) with an UPDATE statement. Then use the READTEXT statement to read text or image data, the WRITETEXT statement to replace text or image data, and the UPDATETEXT statement to modify text or image data.

Using UPDATE to replace existing text and image data with NULL reclaims all allocated data pages except the first page, which remains available for WRITETEXT in the future. To release all storage for the row, first delete the row, and then re-insert the non-text or non-image data.

SELECT statements return text and image data up to the limit specified in the global variable @@TEXTSIZE. The SET statement (TEXTSIZE option) changes this limit on a session basis. The initial value of @@TEXTSIZE is 4K; the maximum value for @@TEXTSIZE is 2 (31) - 1 (2,147,483,647).

Text and image columns cannot be used:

  • As local variables
  • In ORDER BY, COMPUTE, and GROUP BY clauses
  • In an index
  • In a WHERE clause (with the exception of text data¾text data can be specified with the keyword LIKE in a WHERE clause)

Each table that contains text or image columns has a row in the sysindexes system table. The name column in sysindexes uses the form t<tablename>. The indid is always 255. These columns provide information about text storage:

Column | Description
Reserved | Number of pages allocated
Used | Number of pages used
First | Pointer to the first page
Segment | Number of the segment where the object resides


Synonyms

Datatype synonyms are included for ANSI compatibility.

The keyword VARYING complies with ANSI-standards to allow variable-length character or binary strings. The VARYING keyword is valid with the character, char, and binary datatypes. Using the VARYING keyword with any other datatype generates syntax errors.

These are the datatype mappings:

User-defined datatype | Mapped to system datatype
binary varying | varbinary
char varying | varchar
character | char
character | char(1)
character(n) | char(n)
character varying(n) | varchar(n)
dec | decimal
double precision | float
float[(n)] for n = 1–7 | real
float[(n)] for n = 8–15 | float
integer | int

See Also

CREATE PROCEDURE | sp_bindrule
CREATE TABLE | sp_help
DECLARE | sp_rename
EXECUTE statement | sp_unbindefault
Functions | sp_unbindrule
SET | Text and Image Manipulation
sp_addtype | Variables
sp_bindefault | Wildcard Characters
sp_droptype |


DBCC Statement

Used to check the logical and physical consistency of a database, check memory usage, decrease the size of a database, check performance statistics, and so on. DBCC is the SQL Server "database consistency checker." DBCC helps ensure the physical and logical consistency of a database; however, DBCC is not corrective. It is recommended that you make periodic checks to ensure the logical and physical consistency of your data.

Syntax

DBCC {
CHECKALLOC [(database_name [, NOINDEX])] |
CHECKCATALOG [(database_name)] |
CHECKTABLE (table_name [, NOINDEX | index_id]) |
CHECKDB [(database_name [, NOINDEX])] |
CHECKIDENT [(table_name)] |
DBREPAIR (database_name, DROPDB [, NOINIT]) |
dllname (FREE) |
INPUTBUFFER (spid) |
MEMUSAGE |
NEWALLOC [(database_name [, NOINDEX])] |
OPENTRAN ({database_name} | {database_id})
[WITH TABLERESULTS] |
OUTPUTBUFFER (spid) |
PERFMON |
PINTABLE (database_id, table_id) |
SHOW_STATISTICS (table_name, index_name) |
SHOWCONTIG (table_id, [index_id]) |
SHRINKDB (database_name [, new_size [, 'MASTEROVERRIDE']]) |
SQLPERF ({IOSTATS | LRUSTATS | NETSTATS | RASTATS [, CLEAR]} |
{THREADS} | {LOGSPACE}) |
TEXTALL [({database_name | database_id}[, FULL | FAST])] |
TEXTALLOC [({table_name | table_id}[, FULL | FAST])] |
TRACEOFF (trace#) |
TRACEON (trace#) |
TRACESTATUS (trace# [, trace#...]) |
UNPINTABLE (database_id, table_id) |
UPDATEUSAGE ({0 | database_name} [, table_name [, index_id]]) |
USEROPTIONS}
[WITH NO_INFOMSGS]

where

database_id
Specifies the ID of the database in which the command is to be run. If database_id is not supplied, the current database is assumed.
database_name
Specifies the database in which the command is to be run. If database_name is not supplied, the current database is assumed.
index_id
Specifies the ID of the index to be used. When optional and not specified, the statement is used against all indexes for the specified table.
index_name
Specifies the index to be used.
table_id
Specifies the ID of the table to be used. When optional and not specified, the statement is used against all tables in the current or specified database.
table_name
Specifies the table to be used.
CHECKALLOC [(database_name [, NOINDEX])]
Checks the specified database to make sure that all pages are correctly allocated and used. If no database name is given, CHECKALLOC checks the current database. CHECKALLOC reports on the amount of space allocated and used.

DBCC CHECKALLOC is provided for backward compatibility. The preferred DBCC statement is NEWALLOC. NEWALLOC provides more detailed information and will continue to execute even after errors are encountered. For information on the output provided by NEWALLOC, see the NEWALLOC option.

Note Before running DBCC CHECKALLOC or DBCC NEWALLOC on a database installed on read-only removable media, set the database status to 'read only' using sp_dboption. This will prevent the SHUTDOWN command from doing a checkpoint in the database. (Otherwise, checkpoint would attempt to write the allocation pages used by DBCC CHECKALLOC or DBCC NEWALLOC for scratch space and encounter I/O errors on the read-only media.

As an additional precaution, shut down and restart the server after DBCC has completed to prevent the possibility of a manual checkpoint attempting to write the allocation pages.

Also note that DBCC CHECKALLOC or DBCC NEWALLOC may print warning message 2558 for user objects residing on a removable device. You can ignore these messages. They arise because the segmap in sysusages for fragments corresponding to these devices is intentionally set to zero.

Important DBCC CHECKALLOC should be executed while minimal database activity is occurring. If DBCC CHECKALLOC is executed while transactions are in progress, the output may return spurious errors. To ensure that no other users have transactions in progress, set the database to readonly or single user with the sp_dboption system stored procedure.

CHECKCATALOG [(database_name)]
Checks for consistency in and between system tables. For example, CHECKCATALOG makes sure that every type in syscolumns has a matching entry in systypes, that every table and view in sysobjects has at least one column in syscolumns, and that the last checkpoint in syslogs is valid. CHECKCATALOG also reports on any segments that have been defined. If no database name is given, CHECKCATALOG checks the current database.
CHECKTABLE (table_name [, NOINDEX | index_id])
Checks the specified table to see that index and data pages are correctly linked, that indexes are in proper sorted order, that all pointers are consistent, that the data information on each page is reasonable, and that page offsets are reasonable. If the log segment is on its own device, running DBCC CHECKTABLE on the syslogs table reports the log's used and free space.

In SQL Server 6.0, the performance of DBCC CHECKTABLE has been significantly improved by spawning multiple threads to automatically check nonclustered indexes in parallel. Because the table will be loaded in the data cache, each of the simultaneous threads will see an improvement because of an increase in the cache hit ratio.

If an index_id is specified, CHECKTABLE will check only that index.

CHECKDB [(database_name [, NOINDEX])]
Runs the same checks as CHECKTABLE, but on every table in the specified database. If database_name is not supplied, CHECKDB checks the current database.
CHECKIDENT [(table_name)]
Checks the current identity value and compares it with the maximum value in the identity column. If the current identity value is invalid, it will be reset using the maximum value in the identity column. Invalid identity information can cause SQL Server message 2627 when a PRIMARY KEY or UNIQUE KEY constraint exists on an identity column.
NOINDEX
Specifies that only the clustered index (the B-Tree and the data itself) is to be checked for user-defined tables. If no clustered index exists, only the data is checked. The NOINDEX option decreases the overall execution time of CHECKALLOC, CHECKDB, CHECKTABLE, and NEWALLOC because it does not check nonclustered indexes for user-defined tables. The NOINDEX option does not affect a check made against the system tables. When used against a system table(s), all clustered and nonclustered indexes are checked.
DBREPAIR (database_name, DROPDB [, NOINIT])
Drops the specified, and usually damaged, database. No user, including the person executing the statement, can be using the specified database when this DBCC statement is executed. When the NOINIT option is specified, the allocation pages of the dropped database are not modified. DBCC DBREPAIR is used for backward compatibility only. To drop a damaged database, use the DROP DATABASE statement. If the DROP DATABASE statement fails, use the sp_dbremove system stored procedure.
dllname (FREE)
Unloads the specified dynamic-link library (DLL) from SQL Server memory. After you execute an extended stored procedure, the DLL is loaded by SQL Server until the server is shut down. This statement also allows a DLL to be unloaded without shutting down SQL Server.
INPUTBUFFER (spid)
Returns one row containing the first 255 bytes of the "current input" buffer for the specified spid (system process ID taken from the sp_who system stored procedure output). This can be used to see the last query sent from the client. For processes that do not contain input streams, an error message is returned. DBCC INPUTBUFFER can be executed only by the system administrator.
MEMUSAGE
Provides detailed reports on memory use. DBCC MEMUSAGE reports three different types of information:
  • How the server's memory was allocated at start-up time.
  • How much memory is used by the 20 largest objects in the buffer cache (including "pinned" tables).
  • How much memory is used by the 12 largest objects in the procedure cache ¾ stored procedures, triggers, views, rules, and defaults. If multiple copies of an object are in the procedure cache, DBCC MEMUSAGE sums the total memory used by them. Of the multiple copies, some are precompiled versions of the object (trees) and some are compiled versions (plans). DBCC MEMUSAGE shows the sizes of both the trees and plans, and it shows the total trees and plans used to evaluate the largest objects.
NEWALLOC [(database_name [, NOINDEX])]
Checks data and index pages against corresponding extent structures. DBCC NEWALLOC details all table information as well as provides the same summary information provided by DBCC CHECKALLOC, which is retained for compatibility. Unlike DBCC CHECKALLOC, DBCC NEWALLOC will not stop processing if it encounters an error.

DBCC NEWALLOC returns a listing for each allocation unit of the number of extents currently reserved for use by objects, the number of pages marked as being used by objects, and the actual number of pages being used by objects. An allocation unit can hold, at most, 32 database objects. An allocation unit is 512K (0.5 MB) made up of 32 extents (8 2K pages). From this, 512K/16K results in 32 objects. The used pages value and the ref pages value should be equivalent for most, if not all, allocation units. A difference of 7 is possible due to the transaction log. A slightly larger difference is acceptable when text or image data exists within the database.

The number of extents tells whether or not you can create new objects on that allocation unit. To estimate the total amount of space reserved by database objects (tables and indexes), multiply the total number of extents by 16K. To estimate the amount of that space being used by data or index information, multiply the total number of used pages by 2K.

Note Before running DBCC CHECKALLOC or DBCC NEWALLOC on a database installed on read-only removable media, set the database status to 'read only' using sp_dboption. This will prevent the SHUTDOWN command from doing a checkpoint in the database. (Otherwise, checkpoint would attempt to write the allocation pages used by DBCC CHECKALLOC or DBCC NEWALLOC for scratch space and encounter I/O errors on the read-only media.

As an additional precaution, shut down and restart the server after DBCC has completed to prevent the possibility of a manual checkpoint attempting to write the allocation pages.

Also note that DBCC CHECKALLOC or DBCC NEWALLOC may print warning message 2558 for user objects residing on a removable device. You can ignore these messages. They arise because the segmap in sysusages for fragments corresponding to these devices is intentionally set to zero.

Important DBCC NEWALLOC should be executed while minimal database activity is occurring. If DBCC NEWALLOC is executed while transactions are in progress, the output may return errors. To ensure that no other users have transactions in progress, set the database to read only or single user with the sp_dboption system stored procedure.

OPENTRAN ({database_name} | {database_id}) [WITH TABLERESULTS]
Displays information on the oldest active transaction and the oldest distributed and nondistributed replicated transactions, if any, within the specified database. When the WITH TABLERESULTS option is not used, the results returned are formatted for easy readability. Use the WITH TABLERESULTS option for a table of results that can be inserted into a table for comparisons.

Note Results are displayed only if there is an active transaction or if the database contains replication information.

DBCC OPENTRAN is extremely useful in determining whether or not an open transaction exists within the log. When using the DUMP TRANSACTION statement, only the inactive portion of the log can be truncated, so an open transaction could cause the log not to be truncated completely. In earlier versions of SQL Server, all users needed to log off or the server needed to be shut down and restarted in order to clear the uncommitted transactions from the log. With DBCC OPENTRAN, an open transaction can be identified (the spid, the system process ID taken from the sp_who system stored procedure output, is returned) and terminated, if necessary.

OUTPUTBUFFER (spid)
Returns the "current output" buffer in hexadecimal and ASCII format for the specified spid. This can be used to see the results that were sent to the specified client (spid). For processes that do not contain output streams, an error message is returned. DBCC OUTPUTBUFFER can be executed only by the system administrator.
PERFMON
Provides a way to view all three types of SQLPERF statistics in order (IOSTATS, LRUSTATS, and NETSTATS). It takes no parameters.
PINTABLE (database_id, table_id)
Marks a table (data pages, text pages, and index pages) to remain in data cache (once used) until "unpinned." DBCC PINTABLE does not automatically read the table into cache; instead, as pages of the table are accessed and put into cache, they are marked so that they do not get flushed later. Once "pinned," data modifications are fully logged and the table can be recovered. Although this can provide performance improvements for some tables, it should be used with caution. As the table is read into cache, the size of the table is limited only by the available cache. If you are not careful, a large table could consume all the data cache, the server need to be restarted, and then the table unpinned. For more information, see DBCC UNPINTABLE, later in this section.
SHOW_STATISTICS (table_name, index_name)
Displays all the statistical information in the distribution page for an index (index_name) on a specified table (table_name). The results returned indicate the selectivity of an index (the lower the density returned, the higher the selectivity) and provide the basis for determining whether or not an index would be useful to the optimizer. The results returned are based on distribution steps of the index. To understand the output of SHOW_STATISTICS, see the examples, later in this section.

To see the last date the statistics were updated, use the system function STATS_DATE. For details, see the Functions topic.

SHOWCONTIG (table_id, [index_id])
Traverses the page chain at the leaf level of the specified index (index_id) or data level (if only table_id is specified) and determines whether the table is heavily fragmented. Table fragmentation occurs through the process of data modifications (INSERT, UPDATE, and DELETE statements) made against the table. Because the normal distribution of these modifications are not usually equally distributed among the records of the table, the "fullness" of each page will begin to vary over time. For queries that scan part of or all of a table, this can cause additional page reads. When the table is heavily fragmented, you can reduce fragmentation and improve read-ahead (parallel data scan) performance by dropping and re-creating a clustered index (without using the SORTED_DATA option). Re-creating a clustered index will "compact" the data such that data pages are essentially full again; however, the level of "fullness" can also be configured with the FILLFACTOR option.

To find the index_id of a nonclustered index, specify the nonclustered index name (nc_index_name) in the following query:

SELECT indid FROM sysindexes
    WHERE name = 'nc_index_name'

DBCC SHOWCONTIG returns these statistics:

Statistic | Description
Pages Scanned | Number of pages in the table or index.
Extent Switches | The number of times the DBCC statement left an extent while it was traversing the pages of the extent.
Avg. Pages per Extent | The number of pages per extent in the page chain.
Scan Density [Best Count: Actual Count] | Best Count is the ideal number of extent changes if everything is contiguously linked. Actual Count is the actual number of extent changes. The number in Scan Density is 100 if everything is contiguous; if it is below 100, some fragmentation exists. The Scan Density is a percentage.
Avg. Bytes free per page | The average number of free bytes on the pages scanned. The higher the number, the less full the pages are; lower numbers are better. Be aware, however, that this number is also affected by row size, so a large row size may result in a higher number.
Avg. Page density (full) | The average page density shows how full a page is (as a percentage). This value takes into account row size, so it is a more accurate indication of how full your pages are. The higher the percentage, the better.
Overflow Pages | This value is for internal use.
Disconnected Overflow Pages | This value is for internal use.

SHRINKDB (database_name [, new_size [, 'MASTEROVERRIDE']])
When specified with only the database_name parameter, DBCC SHRINKDB returns the minimum size to which this database can shrink, and it lists all objects and indexes that are preventing you from shrinking it further. You cannot shrink the database to a size smaller than the one returned; use caution and drop or move the database objects until the returned size is acceptable.

When new_size is specified, DBCC SHRINKDB shrinks the size of the specified database to the value, as specified in 2K pages by the new_size parameter. DBCC SHRINKDB may shrink both the data and log portions of the database. To change the size of only the data or the log, shrink the entire database first and then use the ALTER DATABASE statement to increase the size of the data or log portion of the database.

To shrink a user database, the database must be set to single user mode. Use the sp_dboption system stored procedure to set this database option. After setting the database to single-user mode, it is recommended that you dump both the master database and the database you are shrinking, prior to using DBCC SHRINKDB.

To shrink the master or tempdb databases you must start the server in single-user mode (use the sqlservr command-line executable with the -m parameter).

Important The database cannot be shrunk beyond either the size of the model database or to a size that is not a valid increment of allocation units. That is, new_size must be equal to or greater than the minimum size as returned by DBCC SHRINKDB plus any number of 512-byte increments (each of which is 256 2K pages). For example, if DBCC SHRINKDB returned a message that the 'Database can be shrunk to 5376 pages', the database can be shrunk to 5376 (10.5 MB), 5632 (11 MB), 5888 (11.5 MB), and so on. For more information, see the "Shrink a Database" example, later in this section.

After successfully shrinking a database to the desired size, back up both the master database and the database that has been shrunk.

DBCC SHRINKDB is fully logged and recoverable except when used on the master database. The MASTEROVERRIDE clause is required when decreasing the size of the master database. However, use caution if you need to shrink the size of the master database, because recovery could fail if the system fails while shrinking the master database. Back up the master database prior to shrinking it. You must be the system administrator or database owner to execute this statement.

SQLPERF ({IOSTATS | LRUSTATS | NETSTATS | RASTATS [, CLEAR]}
{THREADS} {LOGSPACE})
Can provide information about performance statistics. Four performance options are available for this statement: IOSTATS, LRUSTATS, NETSTATS, and RASTATS. You can view replication statistics by using the sp_distcounters (subscription server statistics) and sp_replcounters (publication server statistics) system stored procedures.

IOSTATS generates the I/O statistics since the server was last started or since the statistics were last cleared.

LRUSTATS generates statistics about cache use since the server was last started or since the statistics were last cleared. (LRU stands for "least recently used" and is the algorithm used by the SQL Server cache manager.)

NETSTATS provides statistics about network use.

RASTATS provides statistics about Read Ahead.

The CLEAR option clears the statistics and does not display them.

The following list describes the statistics generated for each option:

IOSTATS
Statistic | Definition
Batch Average Size | The average number of pages written in a batch.
Batch Max. Size | The maximum number of simultaneous outstanding physical I/Os.
Batch Writes | The number of times multiple pages were written to disk in a batch.
Log Flush Average | Log flush requests per physical write.
Log Flush Requests | Number of requests to flush the log to disk.
Log Logical IO Average | Logical pages written per physical write.
Log Logical Page IO | Logical page I/O for transaction log.
Log Physical IO | Physical I/O for transaction log.
Log Writes | Total writes for the log.
Page Reads | The number of 2K pages read from disk (physical reads).
Reads Outstanding | The number of read requests issued to the operating system that have not been completed.
Single Page Writes | The number of 2K pages written individually to disk (physical writes, including log writes).
Transactions | The number of Transact-SQL batches executed. This value is useful in computing ratios involving log write numbers.
Transactions/Log Write | The number of transaction records written to disk during each physical log write.
Writes Outstanding | The number of write requests issued to the operating system that have not completed.

LRUSTATS
Statistic | Definition
Cache Flushes | The number of times a page needed to be flushed from cache to make room for another page.
Cache Hit Ratio | The percentage of times a data page was found in the cache.
Cache Size | The total number of pages in the cache.
Free Page Scan (Avg.) | The average number of buffer pages that had to be scanned in order to find a free page.
Free Page Scan (Max.) | The maximum number of buffer pages that had to be scanned in order to find a free page.
Free Buffers | The number of buffers currently on the free list.
Min. Free Buffers | The lazy writer will attempt to maintain at least this number of buffers on the free list.

DBCC SQLPERF (LRUSTATS) statistics are useful in determining whether you have a large enough cache in your system. After running SQL Server for a day or two, check the Cache Flushes and Average Free Page Scan. For optimal performance, Average Free Page Scan should be less than 10 and Cache Flushes should be less than 100. If you get higher numbers, it means that the SQL Server cache is not big enough to hold your working set. You can improve your server performance by increasing its cache size (adding more memory). If these numbers are below the recommended limits, it means that adding more memory to your system will not make a large difference in performance and that you have a cache big enough to cover the server's working set.

NETSTATS
Statistic | Definition
Max. Worker Threads | The highest number of worker threads that serviced the command queue since the network application was started or since the statistics were cleared.
Network Reads | The total number of reads from the network.
Network Writes | The total number of writes to the network.
Worker Threads | The current number of worker threads servicing the command queue.

RASTATS
Statistic | Definition
RA Pages Found in Cache | How many pages the RA Manager found already in the cache when trying to perform scans.
RA Pages Placed in Cache | How many pages were brought into the cache by the RA Manager.
RA Physical IO | How many 16K reads were done by the RA Manager.
Used Slots | How many RA slots are being used by active queries. Note that a single query may use multiple RA slots.

SQLPERF (THREADS)
Provides a mechanism to map the Windows NT system thread ID to a SQL Server spid. Because of thread pooling, many different Windows NT threads will service a single SQL Server spid over time, so this Windows NT system thread ID is usually not useful. This statement also returns the login name, the number of I/Os, and CPU and MEMUSAGE totals.
SQLPERF (LOGSPACE)
Returns the percentage of log space used at the time the statement is executed. This statement can be used only on a log that is on a separate device from its database.
TEXTALL [({database_name | database_id}[, FULL | FAST])]
Selects tables in the database that have text or image columns and runs TEXTALLOC on them. To select the speed at which the report is generated, choose FULL (all allocation pages in the database will be checked by the report) or FAST (does not generate an allocation report, but checks the linkage of the text chains and verifies that the pages in the chain are allocated). The default is FULL.
TEXTALLOC [({table_name | table_id}[, FULL | FAST])]
Checks the allocation of text or image columns for one table. To select the speed at which the report is generated, choose FULL (all allocation pages in the database will be looked at by the report) or FAST (does not generate an allocation report, but checks the linkage of the text chains and verifies that the pages in the chain are allocated). The default is FULL.
TRACEOFF (trace#)
Turns off the specified trace flag trace#. For a list of trace flags, see the Trace Flags topic.
TRACEON (trace#)
Turns on the specified trace flag trace#.
TRACESTATUS (trace# [, trace#...])
Displays the status for the specified trace flag(s). Can be 1 (on) or 0 (off). You can specify more than one trace flag by separating the numbers with a comma. If you specify - 1 for trace#, status information about all trace flags currently turned on will be returned.
UNPINTABLE (database_id, table_id)
Marks the table as no longer being RAM resident; however, the table will remain in cache until it is aged out of cache (and flushed to disk). "Pinning" a table is not recommended for widespread use; see DBCC PINTABLE, earlier in this section.
UPDATEUSAGE ({0 | database_name} [, table_name [, index_id]])
Reports and corrects inaccuracies in the sysindexes table that may result in incorrect space usage reports by the sp_spaceused system stored procedure. This command corrects the rows, used, reserved, and dpages columns of the sysindexes table for any clustered indexes on objects of the type U (user-defined table) or S (system table). Size information is not maintained for nonclustered indexes. It can be used to synchronize space usage counters in sysindexes, which will result in accurate usage information being returned. When 0 is used instead of the database_name, the update is performed in the current database.

When processing, UPDATEUSAGE acquires a shared table lock on the table being processed, so updates to the sysindexes row for syslogs can be performed only if the database is in single user mode and when the syslogs table is specified. This prevents any logging during the update and ensures accurate changes. All other changes to sysindexes are fully logged.

If there are no inaccuracies in sysindexes, DBCC UPDATEUSAGE will return no data. Otherwise, data will be returned that shows you what rows and columns are being updated in sysindexes.

Note This command may take some time to run if you run it on large tables or databases, so it should typically be used only when you suspect incorrect values returned by the sp_spaceused system stored procedure or via a timed operation to run during off hours.

USEROPTIONS
Returns the list of SET options that are active (or set) for the current connection. It takes no parameters. For details and a listing of the session options available, see the SET statement.
WITH NO_INFOMSGS
Prevent the printing of informational messages (severity 1 through 10). This helps to determine real problems when using verbose commands such as DBCC CHECKDB.

Permission

Permission to execute the DBCC statement varies for each of the DBCC options. Permission is not transferable. DBCC permissions are:

DBCC option | Permission defaults to
CHECKALLOC | SA or DBO
CHECKCATALOG | SA or DBO
CHECKDB | SA or DBO
CHECKTABLE | SA, DBO, or the table owner
DBREPAIR | SA only
dllname | SA only
INPUTBUFFER | SA only
MEMUSAGE | Any user
NEWALLOC | SA or DBO
OPENTRAN | SA or DBO
OUTPUTBUFFER | SA only
PERFMON | SA only
PINTABLE | SA only
SHOW_STATISTICS | SA, DBO, or the table owner
SHOWCONTIG | SA or DBO
SHRINKDB | SA or DBO
SQLPERF | Any user
TEXTALL | SA or DBO
TEXTALLOC | SA or DBO
TRACEOFF | SA only
TRACEON | SA only
TRACESTATUS | SA only
UNPINTABLE | SA only
UPDATEUSAGE | SA or DBO
USEROPTIONS | Any user

Examples

A. Check the Allocation Units (CHECKALLOC)

This example runs the DBCC CHECKALLOC command against the pubs database.

DBCC CHECKALLOC(pubs)
go
Checking pubs
Alloc page 0 (# of extent=32 used pages=58 ref pages=58)
Alloc page 256 (# of extent=26 used pages=37 ref pages=37)
Alloc page 512 (# of extent=14 used pages=40 ref pages=40)
Alloc page 768 (# of extent=1 used pages=8 ref pages=2)
Alloc page 1024 (# of extent=1 used pages=0 ref pages=0)
Alloc page 1280 (# of extent=1 used pages=0 ref pages=0)
Total (# of extent=75 used pages=143 ref pages=137) in this database
DBCC execution completed. If DBCC printed error messages, see your System Administrator.

This database contains six allocation units of 256 2K pages (0.5 MB) each, giving 1536 2K pages in all (3 MB). Of that 3 MB, 88 extents (88 * 16K = 1408K), is reserved and 215 pages (or 215 * 2K = 430K) are used by data and indexes. The reserved 88 extents include objects that have been created but not yet completely populated with data. Used pages refer to those pages that do contain actual data or index pages.

B. Check a Single Table (CHECKTABLE)

This example runs the DBCC CHECKTABLE command against all indexes and data on the employee table in the pubs database.

USE pubs
go
DBCC CHECKTABLE(employee)
go
Checking employee
The total number of data pages in this table is 2.
Table has 43 data rows.
DBCC execution completed. If DBCC printed error messages, see your System Administrator.
C. Check a Table with NOINDEX (CHECKTABLE)

This example skips all of the nonclustered indexes.

USE pubs
go
DBCC CHECKTABLE(employee, NOINDEX)
go
Checking employee
WARNING: NOINDEX option of 'CHECKTABLE' being used, checks on non-system indexes will be skipped
The total number of data pages in this table is 2.
Table has 43 data rows.
DBCC execution completed. If DBCC printed error messages, see your System Administrator.
D. Check the Transaction Log (CHECKTABLE)

This example runs the DBCC CHECKTABLE command against the syslogs table within the sales database.

USE sales
go
DBCC CHECKTABLE(syslogs)
go
Checking syslogs
The total number of data pages in this table is 145.
*** NOTICE:  Space used on the log segment is 0.29 Mbytes, 4.72.
*** NOTICE:  Space free on the log segment is 5.85 Mbytes, 95.28.
Table has 3194 data rows.
DBCC execution completed. If DBCC printed error messages, see your System Administrator.
E. Report Memory Usage (MEMUSAGE)

The report given by DBCC MEMUSAGE is broken down into three parts. Only 3 of the 20 procedures are shown here.

DBCC MEMUSAGE
go
Memory Usage:

                    Meg.         2K Blks           Bytes

      Configured Memory:  8.0000        4096     8388608
              Code size:  1.7166         879     1800000
      Static Structures:  0.2385         123      250064
                  Locks:  0.2480         127      260000
           Open Objects:  0.1068          55      112000
         Open Databases:  0.0031           2        3220
     User Context Areas:  0.8246         423      864688
             Page Cache:  3.3040        1692     3464544
           Proc Headers:  0.0796          41       83448
        Proc Cache Bufs:  1.3379         685     1402880

Buffer Cache, Top 20:

       DB Id     Object Id    Index Id    2K Buffers

           4             5           0          26
           1            56           0          20
           1                 1       0          16
           1     576005083           0          11
           4             3           0          10
           4            99           0           6
           1             2           0           5
           1             1           2          17
           1             5           2           4
           1           399           0           4
           4             1           0           4
           4             2           0           4
           1             3           0           3
           4             1           0           3
           4             6           0           3
           4     192003715           0           3
           1             5           0           2
           1            45           1           2
           2             2         255           2
           2            99           0           2

Procedure Cache, Top 5:

Procedure Name: sp_helpconstraint sp_server_info
Database Id: 1
Object Id: 1516532436
Version: 1
Uid: 1
Type: stored procedure
Number of trees: 0
Size of trees: 0.000000 Mb, 0.000000 bytes, 0 pages
Number of plans: 1
Size of plans: 0.002974 Mb, 3118.000000 bytes, 42 pages

Procedure Name: CA only
Database Id: 4
Object Id: 1104006964
Version: 0
Uid: 1
Type: stored view
Number of trees: 1
Size of trees: 0.001659 Mb, 1740.000 bytes, 1 pages
Number of plans: 0
Size of plans: 0.000000 Mb, 00000.000000 bytes, 0 pages

Procedure Name: categories
Database Id: 4
Object Id: 1168007192
Version: 0
Uid: 1
Type: stored view
Number of trees: 1
Size of trees: 0.001883 Mb, 1974.00000 bytes, 1 pages
Number of plans: 0
Size of plans: 0.000000 Mb, 0.000000 bytes, 0 pages
.
.
.
F. View Index Statistics (SHOW_STATISTICS)

This table is a copy of the authors table created in the pubs database. The authors table includes a clustered index on the primary key (au_id) column and a nonclustered index on the composite key (au_lname, au_fname). This example shows the DBCC output for each index after 1500 rows are inserted and the statistics have been updated.

The first example shows statistics for the clustered primary key index on the au_id column. Because a PRIMARY KEY constraint enforces uniqueness, the selectivity of this index is highly selective (only 1 row will match). In this case, the Density * Rows is 1.0, showing that there is only 1 match. If a query were executed against the authors table using a WHERE clause specifying equality with an au_id, this index would be used.

DBCC SHOW_STATISTICS (authors, UPKCL_auidind)
go

 Updated                  Rows    Steps       Density
 -------------------- -------- -------- -------------
 Apr 17 1995  1:22PM      1520      109      0.000658

(1 row affected)

 All density          Columns
 -------------------- ------------------------------
             0.000658 au_id

(1 row affected)

 Steps
 -----------
 100-10-1000
.
.
.
 724-08-9931

(109 rows affected)

DBCC execution completed. If DBCC printed error messages, see your
System Administrator.

The second example shows statistics for the nonclustered index on the au_lname and au_fname columns. Because this index is not unique, the selectivity is based on the distribution of the data and the likelihood of duplicates. In this case, the Density * Rows is 20.8, showing that there are roughly 21 duplicates based on the au_lname, column alone, not counting any values in more than one step (values with an extremely high number of duplicates and low selectivity).

The All Density is more accurate and shows the selectivity of each column, including those that are more than two steps (lowering the selectivity further and emphasizing how a large number of duplicates can affect the effectiveness of an index). Looking at the au_lname column only, the selectivity is not very high (48 potential duplicates) and an index might be used; however, the selectivity of au_lname, au_fname is much higher (only 3 potential duplicates). If both the au_lname and au_fname are specified with a WHERE clause, it is likely that this index will be used.

DBCC SHOW_STATISTICS (authors, aunmind)
go

 Updated                  Rows    Steps       Density
 -------------------- -------- -------- -------------
 Apr 17 1995  1:22PM      1520       39      0.013674

(1 row affected)

 All density          Columns
 -------------------- ------------------------------
             0.031665 au_lname
             0.002028 au_lname, au_fname

(2 rows affected)

 Steps
 ----------------------------------------
 Abbott
.
.
.
 Xenon

(39 rows affected)

DBCC execution completed. If DBCC printed error messages, see your
System Administrator.
The inserts are performed and DBCC is executed again.
G. Shrink a Database (SHRINKDB)

This example defines the steps to ensure a proper decrease in size of a database:

  1. Set the database to single-user mode using the sp_dboption system stored procedure.
  2. Change your current database to the database you want to shrink.
  3. Verify how small you can make the database. (Run DBCC SHRINKDB without specifying a new_size.)
  4. Shrink the database.
USE master
go
sp_dboption 'sales', 'single user', true
go
USE sales
go
DBCC SHRINKDB(sales)
go
Current size of database Size database can be shrunk to
------------------------ ------------------------------
1536                     1024

(1 row(s) affected)

DBCC execution completed. If DBCC printed error messages, see your System Administrator.

DBCC SHRINKDB reported a minimum size of 5376 pages. Because the absolute minimum is not always necessary, shrink the sales database down to a new size of 12 MB.

DBCC SHRINKDB(sales, 6144)
go
DBCC SHRINKDB running on database "sales"...
DBCC execution completed. If DBCC printed error messages, see your System Administrator.

See Also

DROP DATABASE | sp_configure
RECONFIGURE | sp_helpdb


DECLARE Statement

Defines the name and type of local variables for a batch or procedure and defines cursors.

Syntax

DECLARE @variable_name datatype
[, @variable_name datatype...]

where

@variable_name
Is the name of the variable. Variable names must conform to the rules for identifiers, except variable names use the "at" symbol (@) to signify a variable name.
datatype
Is a system or user-defined datatype. For information on available system datatypes, see the Datatypes topic. For information on creating user-defined datatypes, see the sp_addtype system stored procedure.

Example

This example is a stored procedure (reptq3) from the pubs database. This stored procedure uses three variables declared as input parameters.

CREATE PROCEDURE reptq3 @lolimit money, @hilimit money,
@type char(12)
AS
SELECT pub_id, type, title_id, price
    FROM titles
        WHERE price > @lolimit
        AND price < @hilimit
        AND type = @type OR type LIKE '%cook%'
            ORDER BY pub_id, type
            COMPUTE count(title_id) BY pub_id, type

See Also

Batches | PRINT
Control-of-Flow Language | RAISERROR
CREATE PROCEDURE | SELECT
Cursors | UPDATE
Datatypes | Variables
EXECUTE |


DELETE Statement

Removes rows from a table.

Syntax

DELETE [FROM] {table_name | view_name}
[WHERE clause]

where

table_name | view_name =
[[database_name.]owner.]{table_name | view_name}

Specifies the table or view used in the DELETE statement. If the table or view exists in another database, use a fully qualified table_name or view_name (database_name.owner.object_name).

Because DELETE can affect only one base table at a time, you cannot use DELETE with a view that has a FROM clause naming more than one table.

WHERE clause =
WHERE {search_conditions | CURRENT OF cursor_name}

Is used to perform a searched delete (using search_conditions) or a positioned delete (using CURRENT OF cursor_name). When no WHERE clause is given in the DELETE statement, all rows in the table are removed. The table itself, along with its indexes, constraints, and so on, remains in the database.

search_conditions
Specifies the criteria for a searched delete. For details, see the Search Conditions topic.

The IDENTITYCOL keyword can be used in the place of a column_name that has the IDENTITY property. For more information, see the CREATE TABLE statement.

CURRENT OF cursor_name
Specifies the criteria for a positioned delete against the current row within the specified cursor. Cursor operations affect only the single row on which the cursor is positioned. For details, see the Cursors topic.

Remarks

The TRUNCATE TABLE statement and the DELETE statement without a WHERE clause are functionally equivalent, but TRUNCATE TABLE is faster. The DELETE statement removes rows one at a time and logs each row deletion; the TRUNCATE TABLE statement deletes all rows by logging only the page deallocations. Both DELETE and TRUNCATE TABLE reclaim the space occupied by the data and its associated indexes.

Transact-SQL Extension for the DELETE Statement

In addition to the syntax shown earlier, Transact-SQL includes a feature that allows you to select data from a table or tables and delete corresponding data from the first-named table. The functionality provided is similar to that of using a correlated subquery as a search_condition in the WHERE clause as a standard update.

Transact-SQL extension syntax:

DELETE [FROM] {table_name | view_name}
[FROM {table_name | view_name}
[, {table_name | view_name}]...]
[..., {table_name16 | view_name16}]]
[WHERE clause]

where

FROM
Lets you name more than one table or view to use with a WHERE clause to specify which rows to delete. The additional FROM clause allows you to delete rows from one table based on data stored in other tables, giving you similar functionality to a correlated subquery (SELECT statement in the WHERE clause).

For an example of the differences between correlated subqueries and this Transact-SQL extension, see the examples later in this section.

Permission

DELETE permission defaults to the table owner, who can transfer it to other users.

Examples

A. DELETE with No Parameters

This example deletes all rows from the authors table.

DELETE authors
B. DELETE a Set of Rows

Because au_lname may not be unique, this example deletes all rows where au_lname is McBadden.

DELETE FROM authors
    WHERE au_lname = 'McBadden'
C. DELETE the Current Row of a Cursor

This example shows a delete made against a cursor named complex_join_cursor. It affects only the single row that is currently fetched from the cursor.

DELETE FROM authors
    WHERE CURRENT OF complex_join_cursor
D. DELETE Based on a Subquery or Using the Transact-SQL Extension

This example shows the Transact-SQL extension used to delete records from a base table based on a join or correlated subquery. The first DELETE shows the ANSI-compatible subquery solution, and the second DELETE shows the Transact-SQL extension.

/* ANSI-Standard subquery */
DELETE FROM titleauthor
    WHERE au_id IN
        (SELECT a.au_id
            FROM authors a, titles t, titleauthor ta
                WHERE a.au_id = ta.au_id
                AND ta.title_id = t.title_id
                AND t.title LIKE '%computers%')

/* Transact-SQL extension */
DELETE FROM titleauthor
    FROM authors a, titles t
        WHERE a.au_id = titleauthor.au_id
        AND titleauthor.title_id = t.title_id
        AND t.title LIKE '%computers%'

See Also

CREATE TABLE | INSERT
CREATE TRIGGER | SELECT
Cursors | TRUNCATE TABLE
DROP TABLE | UPDATE
DROP TRIGGER |


DISK INIT Statement

Creates a device on which a database or multiple databases can be placed. A device is an operating-system file that SQL Server pre-allocates for database use.

Syntax

DISK INIT
NAME = 'logical_name',
PHYSNAME = 'physical_name',
VDEVNO = virtual_device_number,
SIZE = number_of_2K_blocks
[, VSTART = virtual_address]

where

NAME
Is the logical name of the database device. Logical names must correspond to the rules for identifiers and must be enclosed with single quotation marks ('). Identifiers exceeding 30 characters are accepted but truncated to 30 characters. This name is recorded in the name column of the master..sysdevices table, and is used in the CREATE DATABASE, ALTER DATABASE, DISK RESIZE, and many other SQL statements.
PHYSNAME
Is the drive letter, full path, and filename of the database device. Paths for database devices must follow the rules for the operating-system paths and filenames. They must be enclosed with single quotation marks (').
VDEVNO
Is the virtual device number. This number must be unique among the database devices associated with SQL Server. Values can be from 1 through 255; 0 is reserved for the MASTER database device.
SIZE
Specifies the size, in 2K blocks, of the database device.

If you are planning to use the new database device to create a new database, the minimum size is 1 MB.

VSTART
Is the starting virtual address or the starting offset in 2K blocks. The value for VSTART should be 0 (the default). Reset VSTART only if instructed to do so.

Remarks

The DISK INIT statement takes advantage of the fact that Windows NT creates a file either by zeroing out all bytes (FAT) or by presenting the application immediately with a zeroed image of the file (NTFS).

Execute DISK INIT once for each new database device. Each time DISK INIT is executed, a row is added to the master..sysdevices table. A new database device does not automatically become part of the pool of default database storage. Assign default status to a database device with the sp_diskdefault system stored procedure.

Because entries are made in the master..sysdevices table, it is important to back up the master database with the DUMP DATABASE statement after each use of DISK INIT.

User databases are assigned to specific database devices with the optional ON database_device clause of the CREATE DATABASE or ALTER DATABASE statement, or they are placed on a default device(s).

The LOG ON extension to CREATE DATABASE is the preferred method for putting a database's transaction log (that is, the sylogs system table) on a device different from the one on which the data is stored. Alternatively, you can name at least two database devices when you create the database and then execute the sp_logdevice system stored procedure. ALTER DATABASE can also be used at any point to add another database device and migrate the log to it with the sp_logdevice system stored procedure.

Note The LOG ON extension in CREATE DATABASE immediately moves the entire log to a separate device. The sp_logdevice method retains part of the system log on the original database device until a transaction completes the transfer. Using the LOG ON extension is preferable to using the sp_logdevice system stored procedure.

For a report on all database devices and dump devices on your system, execute the sp_helpdevice system stored procedure.

Before removing a database device with the sp_dropdevice system stored procedure, you must first drop all existing databases on that database device.

Note The sp_dropdevice system stored procedure does not remove the operating-system file. The physical file can be deleted by using the standard operating-system del command.

After dropping a database device, you can create a new one with the same information (using DISK INIT) as long as you delete the physical file first.

To successfully complete disk initialization, the SQL Server process must have the appropriate operating-system permissions to create the file as named by the PHYSNAME parameter. To see the account under which SQL Server is running, use the Control Panel Services icon for the MSSQLServer service.

Permission

DISK INIT permission defaults to the system administrator and is not transferable.

Example

Define Database Devices

This example creates a 12 MB (6144 2K pages) device called DEVICE1. This device is created in the same directory as the default SQL Server 6.0 MASTER device.

DISK INIT
    NAME = 'DEVICE1',
    PHYSNAME = 'c:\sql60\data\device1.dat',
    VDEVNO = 1,
    SIZE = 6144

This example creates a 16 MB (8192 2K pages) device called DEVICE2. This device is created on a different logical drive from DEVICE1. The SQLDATA directory must exist prior to the execution of this statement.

DISK INIT
    NAME = 'DEVICE2',
    PHYSNAME = 'd:\sqldata\device2.dat',
    VDEVNO = 2,
    SIZE = 8192

This example creates a 125 MB (64,000 2K pages) device called DEVICE3. This device is created on a third logical drive. The SQLDATA directory must exist prior to the execution of this statement.

DISK INIT
    NAME = 'DEVICE3',
    PHYSNAME = 'e:\sqldata\device3.dat',
    VDEVNO = 3,
    SIZE = 64000

See Also

ALTER DATABASE | LOAD
CREATE DATABASE | sp_diskdefault
DISK REFIT | sp_dropdevice
DISK REINIT | sp_helpdevice
DISK RESIZE | sp_logdevice
DUMP |


Disk Mirroring

Note In the future, support for SQL Server device mirroring may be discontinued. It is recommended that you use either the mirroring functionality of the Microsoft Windows NT operating system, or hardware-based mirroring if your hardware supports it. For more information about Windows NT mirroring, see the Microsoft Windows NT operating system documentation in What's New for SQL Server 6.5.

Disk mirroring allows a software mirror of a user database device or the MASTER database device to add to the recoverability options available for the database or databases that reside on that device. When a database resides on multiple devices, mirror all the devices to ensure that the whole database is mirrored. If a database device fails, its mirror immediately takes over; database users are unaffected and can continue to access data without interruption.

You can mirror or unmirror database devices without shutting down SQL Server. Disk mirroring does not interfere with ongoing activities in the database.

For even greater protection, always put the log portion of the database on a separate device from the data portion (see the LOG ON clause of the CREATE DATABASE statement). Whenever possible, this device should also be on a separate physical device.

For a report on all the SQL Server devices on your system (user database devices and their mirrors, as well as dump devices), execute the sp_helpdevice system stored procedure.

SQL Server device mirroring for all user-defined devices consists of three statements (discussed in the following sections).

  • DISK MIRROR
  • DISK UNMIRROR
  • DISK REMIRROR

Software device mirroring can be set up by the system administrator.

Note To mirror the MASTER device, use the -r option (with the sqlservr command-line executable) and the name of the mirror when you restart SQL Server. To add the -r option as a parameter, choose the Parameters button in the Set Server Options dialog box provided with the SQL Setup Utility. For more information, see Microsoft SQL Server Setup.

Other SQL Server fault-tolerance options include hardware fault tolerance and operating-system software fault tolerance. For more information, see the Microsoft SQL Server Administrator's Companion.


DISK MIRROR Statement

Note In the future, support for SQL Server device mirroring may be discontinued. It is recommended that you use either the mirroring functionality of the Microsoft Windows NT operating system, or hardware-based mirroring if your hardware supports it. For more information about Windows NT mirroring, see the Microsoft Windows NT operating system documentation in the What's New for SQL Server 6.5.

Creates a software image of the SQL Server device.

Syntax

DISK MIRROR
NAME = 'logical_name',
MIRROR = 'physical_name'
[, WRITES = {SERIAL | NOSERIAL}]

where

NAME
Is the logical name of the database device that you want to mirror.
MIRROR
Is the drive letter and full path of the database mirror image (file) that is to be your secondary device. The path must be enclosed with single quotation marks ('). The physical name of this device goes in the mirrorname column of the sysdevices table. A device and its mirror together constitute one logical device. It cannot be an existing file.
WRITES
Enforces serial writes to the devices. In the default case (SERIAL), the write to the primary database device is guaranteed to finish before the write to the secondary device begins. Assuming that the primary and secondary devices are on different physical devices, serial writes can ensure that at least one of the disks may be unaffected by a power failure. SQL Server always performs serial writes. The NOSERIAL parameter is retained for compatibility with SQL Server on other platforms.

Remarks

The system administrator must be using the master database to use the DISK MIRROR statement.

Permission

DISK MIRROR permission defaults to the system administrator and is not transferable.


DISK UNMIRROR Statement

Note In the future, support for SQL Server device mirroring may be discontinued. It is recommended that you use either the mirroring functionality of the Microsoft Windows NT operating system, or hardware-based mirroring if your hardware supports it. For more information about Windows NT mirroring, see the Microsoft Windows NT operating system documentation in the What's New for SQL Server 6.5.

Temporarily pauses software mirroring for the SQL Server device. Often this is useful when large nonlogged operations are occurring against the database and when a database backup (using the DUMP statement) will be performed after the nonlogged operations are completed.

Syntax

DISK UNMIRROR
NAME = 'logical_name'
[, SIDE = {PRIMARY | SECONDARY}]
[, MODE = {RETAIN | REMOVE}]

where

NAME
Is the logical name of the database device that you want to unmirror.
SIDE
Indicates which device of the mirrored pair you want to disable with DISK UNMIRROR. PRIMARY refers to the original device created by DISK INIT. SECONDARY refers to the mirror device created with DISK MIRROR. The default is SECONDARY. Use the sp_helpdevice system stored procedure to display a list of all devices.
MODE
Determines whether the unmirroring is temporary or permanent. If set to RETAIN, the following conditions are true:
  • I/O is directed only at the device not being unmirrored by this statement.
  • The status column of sysdevices is altered to indicate that mirroring has been deactivated.
  • The entries for primary and secondary disks in the phyname and mirrorname columns are not altered.

RETAIN is the default. RETAIN mimics what happens when failover is activated automatically. Failover occurs when the other device of the mirrored pair takes over. Set RETAIN when you plan to remirror the database device later in the same configuration.

If set to REMOVE, the following conditions are true:

  • The status column is altered to indicate that mirroring is to be ignored.
  • The name of the secondary device in the mirrorname column replaces the phyname column if the primary device is the one being deactivated.
  • The mirrorname column is set to NULL.

Note REMOVE does not remove an operating-system file that had been used as a mirror device.

Permission

DISK UNMIRROR permission defaults to the system administrator and is not transferable.


DISK REMIRROR Statement

Note In the future, support for SQL Server device mirroring may be discontinued. It is recommended that you use either the mirroring functionality of the Microsoft Windows NT operating system, or hardware-based mirroring if your hardware supports it. For more information about Windows NT mirroring, see the Microsoft Windows NT operating system documentation in the What's New for SQL Server 6.5.

Resumes software mirroring for the SQL Server device.

DISK REMIRROR
NAME = 'logical_name'

where

NAME
Is the logical name of the database device that you want to discontinue.

Remarks

When a mirrored device is remirrored, it begins by copying all pages from the source device to the mirror device. For large devices, this may take quite some time to complete.

Permission

DISK REMIRROR permission defaults to the system administrator and is not transferable.

Disk Mirroring
Examples

A. Mirror a Device

This example creates a software mirror for the database device DEVICE8.

In this example, the mirror is written to a file on different logical drive (for better data recoverability, this should also be a separate physical drive).

DISK MIRROR
    NAME = 'DEVICE8',
    MIRROR = 'g:\sqlimage\device8.mir'
B. Unmirror a Device

This example suspends software mirroring for DEVICE8.

DISK UNMIRROR
    NAME = 'DEVICE8'
C. Remirror a Device

This example resumes software mirroring for DEVICE8.

DISK REMIRROR
    NAME = 'DEVICE8'

See Also

CREATE DATABASE | sp_helpdevice
DISK INIT | sqlservr command-line Executable


DISK REFIT Statement

Restores usage information from the system tables when a device exists (the file is present) but the entries in the sysusages table no longer exist. This occurs after a damaged master database is restored and the master database is incomplete (databases and devices were added or altered since the last backup of the master database).

Syntax

DISK REFIT

Remarks

DISK REFIT is executed after DISK REINIT. DISK REFIT uses information in the sysdevices table to rebuild the sysusages and sysdatabases tables. To run DISK REFIT, SQL Server must be started in single-user mode and the system administrator must be using the master database. For information on starting the server in single-user mode, see the Utilities and Executables topic.

After using DISK REFIT, stop and restart SQL Server.

Note If this statement is not immediately run after the DISK INIT statement, DISK INIT will fail. To see the complete recovery steps (DISK REINIT and then DISK REFIT), see the DISK REINIT statement examples.

Permission

Execute permission defaults to the system administrator and is not transferable.

See Also

DISK INIT | sp_helpdevice
DISK REINIT |


DISK REINIT Statement

Restores the device entries to the system tables when a device exists (the file is present) and the entry in the sysdevices table no longer exists. This occurs after a damaged master database is restored and the master database is incomplete (databases and devices were added or altered since the last backup of the master database). This is the first step for restoring access to user databases. The DISK REFIT statement completes the recovery.

Syntax

DISK REINIT
NAME = 'logical_name',
PHYSNAME = 'physical_name',
VDEVNO = virtual_device_number,
SIZE = number_of_2K_blocks
[, VSTART = virtual_address]

where

NAME
Specifies the logical name of the database device. Logical names must correspond to the rules for identifiers and must be enclosed with single quotation marks ('). This name is used in the CREATE DATABASE and ALTER DATABASE statements.
PHYSNAME
Specifies the drive letter, full path, and filename of the database device file that already exists. Physical name must follow the rules for your operating system's paths and filenames. It must be enclosed with quotation marks (').
VDEVNO
Specifies the virtual device number. It must be unique among database devices used by SQL Server. Values can be from 1 through 255; 0 is reserved for the MASTER database device.

Note NAME, PHYSNAME, and VDEVNO do not have to be identical to the device as it was originally created; however, the SIZE parameter must match.

SIZE
Specifies the size, in 2K blocks, of the database device. The minimum usable size is 512 2K blocks (1 MB).
VSTART
Specifies the starting virtual address or the starting offset in 2K blocks. The value for VSTART should be 0 (the default). Reset it only if instructed to do so.

Remarks

DISK REINIT is very similar to DISK INIT but does not initialize the disk space.

Caution If you give DISK REINIT incorrect information about sizes and attempt to run update operations, you can permanently corrupt your data. SQL Server warns you of potential problems if it can, but be sure to run the suggested checks after issuing DISK REINIT and DISK REFIT.

If problems occur, you probably did not run DISK REINIT or ran it with inaccurate information. If you recognize discrepancies in the sysusages table, correct them. Correct the sysdevices table by rerunning DISK REINIT and then reissuing DISK REFIT. The system administrator must be in the master database to use DISK REINIT.

For more information about using DISK REINIT, see the Microsoft SQL Server Administrator's Companion.

Permission

DISK REINIT permission defaults to the system administrator and is not transferable.

Example

DISK REINIT must be run for each device of the database prior to running DISK REFIT.

DISK REINIT
    NAME = 'DEVICE5',
    PHYSNAME = 'c:\sqldata\device5.dat',
    VDEVNO = 5,
    SIZE = 25600

DISK REINIT
    NAME = 'DEVICE6',
    PHYSNAME = 'd:\sqldata\device6.dat',
    VDEVNO = 6,
    SIZE = 25600

Once all devices have been created, run DISK REFIT.

DISK REFIT

See Also

ALTER DATABASE | DISK INIT
CREATE DATABASE | DISK REFIT
DBCC | sp_helpdevice


DISK RESIZE Statement

Allows you to expand a device. You can use DISK RESIZE on any database device, including the MASTER device.

Syntax

DISK RESIZE
NAME = logical_device_name,
SIZE = final_size

where

logical_device_name
Specifies the database device to resize.
final_size
Is the final size to which the device should be expanded, specified in 2K pages.

Remarks

The DISK RESIZE statement expands a device; it does not shrink devices or alter any databases that reside on that device. DISK RESIZE cannot be used for dump devices or the TEMPDB device when tempdb is in RAM.

Permission

DISK RESIZE permission defaults to the system administrator and is not transferable.

Examples

A. Increase the Size of a Device

This example increases the size of DEVICE1 from it's initial size of 12 MB to 20 MB.

DISK RESIZE
    NAME = 'DEVICE1',
    SIZE = 10240
B. Increase the Size of the MASTER Device

This example increases the MASTER device from its initial size of 25 MB to 32 MB.

DISK RESIZE
    NAME = 'MASTER',
    SIZE = 16384

See Also

ALTER DATABASE | DISK INIT
CREATE DATABASE | sp_addumpdevice
DBCC | sp_helpdevice


DROP DATABASE Statement

Removes one or more databases from SQL Server.

Syntax

DROP DATABASE database_name [, database_name...]

where

database_name
Specifies the database to be removed. Execute the sp_helpdb system stored procedure from the master database to see a list of databases.

Remarks

Removing a database deletes the database and all its objects, frees its storage allocation, and erases references to it in the master database. A database that has been dropped can only be re-created from database backups. You cannot drop a database that is in use (open for reading or writing by any user).

In earlier releases, the DROP DATABASE statement would not work on damaged databases. In SQL Server 6.0, the DROP DATABASE statement works on databases marked suspect, offline, or not recovered. To drop a database in recovery (sysdatabases..status = 128), use the sp_dbremove system stored procedure.

After any changes are made to the master database, use the DUMP DATABASE statement to back up the master database.

Permission

DROP DATABASE permission defaults to the database owner and cannot be transferred. The database owner must be in the master database to use DROP DATABASE.

Examples

A. Drop a Single Database

This example removes all references for the publishing database from the system tables.

DROP DATABASE publishing
B. Drop Multiple Databases

This example removes all references for each of the listed databases from the system tables.

DROP DATABASE pubs, newpubs

See Also

ALTER DATABASE | sp_helpdb
CREATE DATABASE | sp_renamedb
sp_dbremove | USE


DROP DEFAULT Statement

Removes a user-defined default from a database.

The DROP DEFAULT statement does not apply to DEFAULT constraints. For details about dropping DEFAULT constraints, see the ALTER TABLE statement.

Syntax

DROP DEFAULT [owner.]default_name [, [owner.]default_name...]

where

default_name
Specifies the name of an existing default. You can find out what defaults exist by executing the sp_help system stored procedure.

Remarks

To drop a default, you must first unbind it by using the sp_unbindefault system stored procedure if it is currently bound to a column or to a user-defined datatype.

When you drop a default from a column that allows null values, NULL is inserted in that position when rows are added and no value is explicitly supplied. When you drop a default from a NOT NULL column, you get an error message when rows are added and no value is explicitly supplied.

Permission

DROP DEFAULT permission defaults to the owner of the default and is not transferable. However, the database owner and system administrator can drop any object by specifying the owner in the DROP DEFAULT statement. The database owner can also use the SETUSER statement to impersonate another user.

Examples

A. Drop a Default

If a default has not been bound to a column or to a user-defined datatype, it can simply be dropped using the DROP DEFAULT statement. This example removes the user-created default datedflt.

DROP DEFAULT datedflt
B. Drop a Default That Has Been Bound to a Column

This example unbinds the default associated with the phone column of the authors table and then drops the phonedflt default.

sp_unbindefault 'authors.phone'
go
DROP DEFAULT phonedflt

See Also

CREATE DEFAULT | sp_helptext
sp_help | sp_unbindefault


DROP INDEX Statement

Removes an index from a database.

The DROP INDEX statement does not apply to indexes created by PRIMARY KEY or UNIQUE constraints. For details about dropping constraints, see the ALTER TABLE statement.

Syntax

DROP INDEX [owner.]table_name.index_name
[, [owner.]table_name.index_name...]

where

table_name
Specifies the table where the indexed column is located. If DROP INDEX is used by the DBO or SA, then the owner name can be included to drop an index not owned by the DBO.
index_name
Specifies the index to be dropped.

Remarks

Once the DROP INDEX statement is executed, you regain all the space occupied by the index. This space can then be used for any database object.

You can't use DROP INDEX on an index on a system table.

To get information about what indexes exist on a table, use the sp_helpindex system procedure with the table name as a parameter.

Permission

DROP INDEX permission defaults to the table owner and is not transferable. However, the database owner and system administrator can drop any object by specifying the owner in the DROP INDEX statement. The system administrator and database owner can also use the SETUSER statement to impersonate another user.

Example

This example removes the index au_id_ind in the authors table.

DROP INDEX authors.au_id_ind

See Also

CREATE INDEX | sp_spaceused
sp_helpindex |


DROP PROCEDURE Statement

Removes user-created stored procedures from the current database.

Syntax

DROP PROCedure [owner.]procedure_name [, [owner.]procedure_name...]

where

procedure_name
Specifies the stored procedure(s) to be removed.

Remarks

DROP PROCEDURE removes user-created procedures from the user's current database. User-defined system procedures (prefixed with sp_) are dropped from the master database whether or not it is the current database. If the procedure is not found in the current database, SQL Server tries to drop it from the master database. When you drop a stored procedure, information about the procedure is removed from the sysobjects, sysprocedures, and syscomments system tables.

To see a list of procedure names, use the sp_help system stored procedure. To display the procedure definition (which is stored in the syscomments system table), use the sp_helptext system stored procedure.

A procedure group (more than one procedure with the same name but with different ;number suffixes) can be dropped using a single DROP PROCEDURE statement. For example, if the procedures used with the application orders are named orderproc;1, orderproc;2, and so on, the "DROP PROC orderproc" statement drops the entire group. Once procedures have been grouped, individual procedures within the group cannot be dropped. For example, "DROP PROCEDURE orderproc;2" is not allowed.

Permission

DROP PROCEDURE permission defaults to the procedure owner and is not transferable. However, the database owner and system administrator can drop any object by specifying the owner in the DROP PROCEDURE statement.

Example

This example removes the stored procedure byroyalty.

DROP PROCEDURE byroyalty

See Also

CREATE PROCEDURE | sp_helptext
sp_depends | sp_rename


DROP RULE Statement

Removes a user-specified rule from a database.

The DROP RULE statement does not apply to CHECK constraints. For details about dropping CHECK constraints, see the ALTER TABLE statement.

Syntax

DROP RULE [owner.]rule_name [, [owner.]rule_name...]

where

rule_name
Specifies the rule to be removed.

Remarks

To drop a rule, you must first unbind it if it is currently bound to a column or to a user-defined datatype. Use the sp_unbindrule system stored procedure to unbind the rule. If the rule is bound when you try to drop it, an error message is displayed and the DROP RULE statement is canceled.

After you drop a rule, new data entered into the columns previously governed by the rule is entered without these constraints. Existing data is not affected in any way.

Permission

DROP RULE permission defaults to the rule owner and is not transferable. However, the database owner and system administrator can drop any object by specifying the owner in the DROP RULE statement. The system administrator and database owner can also use the SETUSER statement to impersonate another user.

Example

This example unbinds and then drops the pub_id rule.

sp_unbindrule 'publishers.pub_id'
go
DROP RULE pub_id_rule

See Also

CREATE RULE | sp_helptext
sp_bindrule | sp_unbindrule
sp_help |


DROP TABLE Statement

Removes a table definition and all data, indexes, triggers, constraints, and permission specifications for that table from the database.

Syntax

DROP TABLE [[database.]owner.]table_name
[, [[database.]owner.]table_name...]

where

table_name
Specifies the table to be removed.

Remarks

The DROP TABLE statement cannot be used to drop a table that is being referenced by a FOREIGN KEY constraint. You must first drop the referencing FOREIGN KEY constraint or the referencing table.

If you are the table owner, you can drop a table in any database. When you drop a table, rules or defaults on it lose their binding, and any constraints or triggers associated with it are automatically dropped. If you re-create a table, you must rebind the appropriate rules and defaults, re-create any triggers, and add all necessary constraints.

The sysobjects, syscolumns, sysindexes, sysprotects, and syscomments system tables are affected when a table is dropped.

You cannot use the DROP TABLE statement on system tables.

If you delete all rows in a table (DELETE tablename) or use the TRUNCATE TABLE statement, the table still exists until you drop it.

Permission

DROP TABLE permission defaults to the table owner and is not transferable. However, the database owner and system administrator can drop any object by specifying the owner in the DROP TABLE statement. The system administrator and database owner can also use the SETUSER statement to impersonate another user.

Examples

A. Drop a Table in the Current Database

This example removes the titles1 table and its data and indexes from the current database.

DROP TABLE titles1
B. Drop a Table in Another Database

The following example drops the authors2 table in the pubs database. This can be executed from any database.

DROP TABLE pubs.dbo.authors2

See Also

ALTER TABLE | sp_help
CREATE TABLE | sp_spaceused
DELETE | TRUNCATE TABLE
sp_depends |


DROP TRIGGER Statement

Removes a trigger from a database.

Syntax

DROP TRIGGER [owner.]trigger_name [, [owner.]trigger_name...]

where

trigger_name
Specifies the trigger(s) to remove.

Remark

You can remove a trigger by dropping it or by dropping the trigger table. When a table is dropped, all triggers associated with it are also dropped.

If a new trigger will replace the previous trigger, use the CREATE TRIGGER statement instead. For details, see the CREATE TRIGGER statement.

When you drop a trigger, information about the trigger is removed from the sysprocedures, sysobjects, and syscomments system tables.

Permission

DROP TRIGGER permission defaults to the trigger table owner and is not transferable. However, the system administrator and database owner can drop any object by explicitly specifying the owner in the DROP TRIGGER statement.

Example

This example drops the employee_insupd trigger.

DROP TRIGGER employee_insupd

See Also

CREATE TRIGGER | sp_help
sp_depends | sp_helptext


DROP VIEW Statement

Removes a view from a database.

Syntax

DROP VIEW [owner.]view_name [, [owner.]view_name...]

where

view_name
Specifies the view(s) to be removed.

Remarks

When you use DROP VIEW, the definition of the view and other information about it are deleted from the sysobjects, syscolumns, syscomments, sysdepends, sysprocedures, and sysprotects system tables. All privileges for the view are also deleted.

To see a list of view names, use the sp_help system stored procedure.

Permission

DROP VIEW permission defaults to the view owner and is not transferable. However, the system administrator and database owner can drop any object by explicitly specifying the owner in the DROP VIEW statement.

Example

This example removes the titles_view view.

DROP VIEW titles_view

See Also

CREATE VIEW | sp_help
sp_depends | sp_helptext


DUMP Statement

For SQL Server 6.5 information, see DUMP Statement in What's New for SQL Server 6.5.

Makes a backup copy of a database and its transaction log (DUMP DATABASE) or makes a copy of only the transaction log (DUMP TRANSACTION) in a form that can be read into SQL Server using the LOAD statement.

Syntax

Dumping a database:

DUMP DATABASE {dbname | @dbname_var}
TO dump_device [, dump_device2 [..., dump_device32]]
[WITH options
[[,] STATS [ = percentage]]]

Dumping a transaction log:

DUMP TRANSACTION {dbname | @dbname_var}
[TO dump_device [, dump_device2 [..., dump_device32]]]
[WITH {TRUNCATE_ONLY | NO_LOG | NO_TRUNCATE}
{options}]

where

dump_device =
{dump_device_name | @dump_device_namevar}
| {DISK | TAPE | FLOPPY | PIPE} =
{'temp_dump_device' | @temp_dump_device_var}}
[VOLUME = {volid | @volid_var}]
options =
[[,] {UNLOAD | NOUNLOAD}]
[[,] {INIT | NOINIT}]
[[,] {SKIP | NOSKIP}]
[[,] {{EXPIREDATE = {date | @date_var}}
| {RETAINDAYS = {days | @days_var}}]

Note The UNLOAD and NOUNLOAD options are supported only by TAPE dump devices.

When you specify a PIPE dump device, multivolume dumps and dump device options (UNLOAD, NOUNLOAD, INIT, NOINIT, SKIP, NOSKIP, EXPIREDATE, and RETAINDAYS) are not supported.

DATABASE
Specifies that the complete database and transaction log are to be backed up.

If the transaction log is on the same device as the database, using DUMP DATABASE is the only way you can create a backup copy of both the database and its transaction log. However, because DUMP DATABASE does not remove the inactive portion of the log, you must use DUMP TRANSACTION WITH TRUNCATE_ONLY to purge the log of completed transactions. Generally, databases and transaction logs should be stored on different devices; this improves performance and enables unrestricted use of both the DUMP DATABASE and DUMP TRANSACTION statements.

TRANSACTION
Specifies that only the transaction log is to be backed up. DUMP TRANSACTION removes the inactive part of the transaction log and makes a backup copy of it in a form that can be read in with the LOAD statement. To retain a backup of only the transaction log (using DUMP TRANSACTION without the TRUNCATE_ONLY or NO_LOG options), the transaction log must be stored on a separate database device from the data portion of the database.

Note If dumping the transaction log doesn't appear to truncate the majority of your transaction log, you may have an open transaction in the log. To determine whether a transaction has been left open, use DBCC OPENTRAN.

For databases that store the data portion of the database on a separate device from the log portion, log space can be monitored with various DBCC commands and the Performance Monitor. For details, see the DBCC statement.

TRUNCATE_ONLY
Removes the inactive part of the log without making a backup copy of it. This optional clause frees disk space used by the transaction log. Specifying a dump_device is unnecessary because the transaction log dump will not be saved.

Prior to backing up a database, it is useful to dump a transaction log using the TRUNCATE_ONLY option to clear out the log and decrease the total time required to back up the database.

Note After dumping a transaction log using the TRUNCATE_ONLY option, you should immediately make a backup of the database using DUMP DATABASE. Dumping of the transaction log (using DUMP TRANSACTION) will not be allowed until a full database dump (using DUMP DATABASE) has been performed.

NO_LOG
Is used only when you have run out of space in the database and cannot use DUMP TRANSACTION WITH TRUNCATE_ONLY to purge the log. The NO_LOG option removes the inactive part of the log without making a backup copy of it, and it saves space by not logging the operation.

If the transaction log of a published (replicated) database becomes full and absolutely must be truncated, unsubscribe all subscriptions to the publications of that database. This allows you to truncate past the oldest distributed transaction.

After the transaction log has been dumped using NO_LOG, the changes recorded in the log are not recoverable. For recovery purposes, immediately execute the DUMP DATABASE statement.

Because both options clear the log without making a backup of it, it is unnecessary to use both the TRUNCATE_ONLY and NO_LOG option in the same statement.

NO_TRUNCATE
Makes it possible to dump a transaction log even if the database is inaccessible by using a pointer to the transaction log in the master database.

The NO_TRUNCATE option provides up-to-the-minute media recovery when the master database and the log portion of the user database reside on undamaged database devices and when only the data portion of the user database is damaged.

dbname | @dbname_var
Specifies the database from which the transaction log or complete database is being dumped. If supplied as a variable (@dbname_var), this name can be specified as a string, or as a char or varchar variable.
dump_device_name | @dump_device_namevar
Specifies the logical name of the dump device or devices (as created by the sp_addumpdevice system stored procedure) to which the database will be backed up. If supplied as a variable (@dump_device_namevar), the dump device name can be specified as a string or as a char or varchar variable.
DISK | TAPE | FLOPPY | PIPE =
'temp_dump_device' | @temp_dump_device_var

Allows backups directly to temporary dump devices. These devices are created (or accessed, if they already exist) when the dump occurs; they do not have entries in the sysdevices system table. With DISK, TAPE, and FLOPPY specify the complete path and filename of the device. With PIPE, specify the name of the named pipe that will be used by the client application. If supplied as a variable (@temp_dump_device_var), the temporary dump device name can be specified as a string or as a char or varchar variable. If you are using a network server with a UNC name or using a redirected drive letter, specify a device type of DISK.

Important When specifying a striped dump, logical device names (or variables) and temporary device names (or variables) can be mixed. PIPE devices have been added to allow third-party vendors a flexible and powerful way to connect their own software. For typical Transact-SQL use, the PIPE device will not be used.

VOLUME = volid | @volid_var
Specifies the volume ID, volid, a 6-byte character string. If dumping to a new tape, this value is the name of the ANSI VOL1 label. For SQL Server, the default is SQ0001. For subsequent dumps, this value is used to validate the volume name of the dump device. If supplied as a variable (@volid_var), the volume name can be specified as a string or as a char or varchar variable. It is not necessary, or recommended, to explicitly specify the volume ID.
UNLOAD
Specifies that the tape is automatically rewound and unloaded when the dump is finished. UNLOAD is set by default when a new user session is started. It remains set until that user specifies NOUNLOAD. This option is used only for tape devices.
NOUNLOAD
Specifies that the tape will not be unloaded automatically from the tape drive after a dump. NOUNLOAD remains set until UNLOAD is specified. This option is used only for tape devices.
INIT
Specifies that the dump should be the first file on the DISK or TAPE device. If INIT is specified, any existing data on that device will be overwritten. If the first file on the device has an ANSI-standard label, the label will be evaluated to determine whether the previous dump(s) can be overwritten. For details, see the EXPIREDATE and RETAINDAYS options, later in this section.
NOINIT
Specifies that the dump should be appended to the current DISK or TAPE device. This is the default for both single dump devices and striped dumps. Dump devices used in a stripe set must always be used in a stripe set (unless reinitialized at some point with INIT). Once a device is defined as part of a stripe set, it cannot be used for a single device dump unless INIT is specified. Similarly, a device that contains nonstriped dumps cannot be used in a stripe set unless INIT is specified.
SKIP
Instructs the server not to read the ANSI TAPE device headers.
NOSKIP
Specifies that the server will read ANSI TAPE device headers. This is the default.

Note When specified, SKIP and NOSKIP override the setting as defined with the dump device (when the sp_addumpdevice system stored procedure was executed).

EXPIREDATE = date | @date_var
Specifies the date when the dump media expires and can be overwritten. If supplied as a variable (@date_var), this date can be specified as a string or as a char or varchar variable, and it must follow the configured datetime format for the system. This option is used for DISK and TAPE devices only and is effective only when specified with INIT.
RETAINDAYS = days | @days_var
Specifies the number of days that must elapse between the existing dump and when the dump media can be overwritten. If supplied as a variable (@days_var), it must be specified as an integer. This option is used for DISK and TAPE devices only and is effective only when specified with INIT.

Important EXPIREDATE and RETAINDAYS override the configuration value for media retention when specified with the DUMP DATABASE or DUMP TRANSACTION statements. These options are used with DISK and TAPE devices only. If an expiration date is needed for diskette devices, configure media retention with the sp_configure system stored procedure.

If EXPIREDATE or RETAINDAYS is specified, subsequent dumps can be appended to that device; however, EXPIREDATE and RETAINDAYS are valid only for dumps specified with INIT.

These options only prevent SQL Server from overwriting a device. Tapes can still be erased using other methods, and disk-device files can still be deleted through the operating system.

STATS = percentage
Returns the percentage of pages dumped in increments optionally set at the time of the dump. If the percentage is not specified, statistics will be shown for each 10 percent of the dump. This option is available only with DUMP DATABASE.

Remarks

In earlier releases of SQL Server, dumping a database or a transaction log to a single device always overwrote the previous dump unless (for tape devices only) NOINIT was specified. With SQL Server 6.0, database or transaction log dumps can be appended to any DISK or TAPE device, allowing you to keep a database and its transaction logs all within one physical location.

The SQL Server dump is a dynamic dump ¾ it can take place while the database is active. The dump captures the state of the data as it is at the moment the statement is executed; no partial transactions are reflected. Any data changes made after the dump begins are not reflected in the dumped database. Performing a dump can slow the system down somewhat, so you may want to run it when the database or table is not being heavily updated.

Ownership and permissions problems on the physical file can interfere with a DUMP statement. The sp_addumpdevice system stored procedure adds the device to the system tables, but it does not check file access permission.

You cannot execute the DUMP TRANSACTION statement while the trunc. log on chkpt. database option is enabled. Nor can you execute it after enabling select into/bulkcopy and making unlogged changes to the database with SELECT INTO or a bulk-copy operation. Use DUMP DATABASE instead.


Database Design and Backup Strategy

With small databases, the transaction log is usually stored on the same database device as the rest of the database. DUMP DATABASE backs up both the database and the transaction log, after which you can use DUMP TRANSACTION WITH TRUNCATE_ONLY to remove committed transactions from the log.

With large databases, the transaction log (the log portion of the database) and the data portion of the database are usually stored on a separate devices. In these cases, you can use DUMP TRANSACTION to maintain a backup of only the transaction log. Dumping only the transaction log uses less storage and takes less time than DUMP DATABASE, which backs up both the transaction log and the database. Dumps of the transaction log are usually coordinated with DUMP DATABASE as part of an overall backup procedure. Typically, transaction log dumps are done more frequently than database dumps. To recover a database, load the most recent database dump and load all the transaction log dumps (in order) made since the database dump. The database is restored to its state at the time of the last transaction log dump.

Regardless of database setup, it is highly recommended that you always run DBCC CHECKDB, DBCC CHECKALLOC or DBCC NEWALLOC, and DBCC CHECKCATALOG on a database just prior to dumping it. DBCC will check the logical and physical consistency of the database. If a database or transaction log that contains errors is dumped, the errors will still exist when the data is reloaded. Under some conditions, this can even prevent successful reloading. If any of the DBCC commands report errors in the database, contact your system administrator or your primary technical support provider.


Dumping the master Database

The master database is backed up in the same way as a user database, and it should be dumped regularly and frequently. Make sure that you back up master after changes that update system tables have been made. (For example, back up the master database after these statements are used: ALTER DATABASE, CREATE DATABASE, DISK INIT, DISK RESIZE, various DBCC options such as SHRINKDB, the sp_configure system stored procedure).

The backups of the master database help in recovery if master fails; however, the recovery method for a damaged master database differs from that for user databases. For information about restoring the master database, see the Microsoft SQL Server Administrator's Companion.

Note The master database contains the system catalog, which is the most important information about your SQL Server configuration. Because the master database cannot be separated from its transaction log, you can back up the master database only with the DATABASE option.


Dumping to a Tape Device

To dump to a tape, the tape dump device must be located on the computer where SQL Server is running. Information about a tape dump is recorded on the tape label. This information includes up to 17 characters of the database name, the time and date of the dump, and the type of dump (database, table, or log).

To add multiple dumps to a single tape, specify NOUNLOAD and INIT when issuing the first dump. Specify UNLOAD while issuing the last dump so that the tape will be unloaded when the dump ends. To add a single dump to the end of an existing multifile tape, specify NOINIT and UNLOAD.

If you are writing over a tape, be sure that you use the INIT option when you dump the first file to that tape. This allows the data on the tape to be overwritten, rather than adding the dump to the end of the tape.

If the tape contains data in a foreign format (not SQL Server backup files), you must specify INIT; otherwise, the tape will be rejected. The tape can be used for a SQL Server backup by issuing a DUMP WITH INIT statement, which treats the tape as blank.


Dumping to a Diskette Device

When a DUMP is executed for dumping to a floppy disk, the console command-line utility must be used to prompt the user and then waits for responses. If console is not running or if the user does not answer its questions, the dump cannot proceed. Dumping to a diskette device is not recommended. Dump to a disk device and copy (or use backup command) to a diskette instead.


Dumping to a Disk Device

Disk devices can be defined on shared network resources. If the dump is to be performed over the network, you must supply the UNC (universal naming convention) name in the form \\servername\sharename\path\filename or use a locally redirected drive letter. Make sure that you have appropriate permissions on the destination device. To ensure proper permissions, SQL Server may need to be started under a domain account (not the local system). To define the domain account under which SQL Server should be started, use the Services application in the Windows NT Control Panel.

To add multiple dumps to a single disk (file), specify INIT while issuing the first dump and NOINIT for subsequent dumps. If you are writing over a disk dump device, make sure that you use the INIT option when you perform the first dump. This allows the data on the disk dump device to be overwritten, rather than appending the dump to the end of the file.


Databases Dumping to Novell File Servers

A redirected drive can also include dump devices located on Novell file servers. The capability to define dump devices located on Novell file servers takes advantage of the Windows NT Workstation Client and Gateway Services for NetWare available from Microsoft.

Defining database dump devices with Microsoft SQL Server without setting up a Gateway Share is simple and does not require special mapping on the Novell file server, nor does it require that there be a shared device defined in File Manager.

It is important that the Client and Gateway Services for NetWare be appropriately set up so that files can be copied from the Novell file server to Windows NT without error. Routing and frame type issues must be resolved prior to implementing this procedure.

To set up the Client and Gateway Services, an NTGATEWAY group must already exist on the Novell file server. There are two ways to do this.

The first method depends on GUEST validation by the Novell file server. Begin the Windows NT setup by assigning the LocalSystem account to the SQL Server service. Use the Services application in the Control Panel to do this. For instructions, see your documentation for Windows NT.

When SQL Server starts, it will log in as a LocalSystem account on Windows NT, which means that the Novell file server will have no knowledge of this Windows NT user ID.

On the Novell file server, add the GUEST account to the NTGATEWAY Group and make sure that account has complete trustee rights to the directory where the SQL Server database dump will be written. When SQL Server attempts to dump the database to this directory, the Novell file server will validate the login and use the GUEST account with NTGATEWAY as the user group.

The second method to set up the Client and Gateway Services is to start the SQL Server service with a user account that is valid on the Novell file server and on Windows NT. This user must have appropriate access to stop and start Windows NT services. The user ID and password on Windows NT must exactly match the user ID and password on the Novell file server. In addition, the user account must also be a member of the NTGATEWAY Group and have complete Trustee rights to the directory where the SQL Server database dump will be written.

Unlike setting up a local disk dump device, a UNC path to a Novell file server consists of the file server name, volume, directory, and file.

For example, to define a database dump device on the Novell file server WHISTLE/SYS:USERS/TEST, the following would be entered as the physical filename:

Logical Name: pubsdump
Physical Name: \\WHISTLE\SYS\USERS\TEST\PUBS.DMP

Once the dump device has been defined, verify that the process works by dumping a database with a valid SQL Server login ID.

Permission

DUMP DATABASE and DUMP TRANSACTION permission default to the database owner, who can transfer it to other users.


EXECUTE Statement

For SQL Server 6.5 information, see EXECUTE Statement in What's New for SQL Server 6.5.

Executes a system procedure, a user-defined stored procedure, or an extended stored procedure. Also supports the execution of a character string within a Transact-SQL batch. In earlier releases, Transact-SQL statements needed to include the actual name of an object at parse and compile time. With the EXECUTE statement, a string can be created with variables that are resolved at execution time.

Syntax

To execute a stored procedure:

EXEC[ute]
{[@return_status =]
{[[[server.]database.]owner.]procedure_name[;number] |
@procedure_name_var}
[[@parameter_name =] {value | @variable [OUTPUT]]
[, [@parameter_name =] {value | @variable [OUTPUT]}]...]
[WITH RECOMPILE]]

To execute a character string:

EXEC[ute] ({@str_var | 'tsql_string'} [{@str_var | 'tsql_string'}...)}

where

@return_status
Is an optional integer variable that stores the return status of a stored procedure. This variable must be declared in the batch or stored procedure before it is used in an EXECUTE statement.
procedure_name
Specifies a stored procedure. You can execute a procedure that has been created in another database if you are its owner or have permission to execute it in that database. You can execute a procedure on another SQL Server if you have permission to use that server (remote access) and to execute the procedure in that database. If you specify a server name but do not specify a database name, SQL Server looks for the procedure in your default database.
@procedure_name_var
Is the name of a locally defined variable that represents a stored procedure name.
;number
Is an optional integer used to group procedures of the same name so that they can be dropped together with a single DROP PROCEDURE statement. Procedures used in the same application are often grouped this way. For example, the procedures used with the application orders might be named orderproc;1, orderproc;2, and so on. The statement DROP PROCEDURE orderproc drops the entire group. Once procedures have been grouped, individual procedures within the group cannot be dropped. For example, the statement DROP PROCEDURE orderproc;2 is not allowed. This parameter is not used for extended stored procedures.
@parameter_name
Specifies the parameter for a procedure, as defined in the CREATE PROCEDURE statement. Parameter names must be preceded by the "at" symbol (@). When used with the @parameter_name = value form, parameter names and constants need not be supplied in the order defined in the CREATE PROCEDURE statement. However, if the @parameter_name = value form is used for any parameter, it must be used for all subsequent parameters.
value
Is the value of the parameter to the procedure. If you do not use parameter names, parameter values must be supplied in the order defined in the CREATE PROCEDURE statement.

If the value of a parameter is an object name, character string, or qualified by a database name or owner name, the entire name must be enclosed in single quotation marks. If the value of a parameter is a keyword, the keyword must be enclosed in double quotation marks.

If a default is defined in the CREATE PROCEDURE statement, a user can execute the procedure without specifying a parameter. The default must be a constant and can include the wildcard characters %, _, [ ], and [^] if the procedure uses the parameter name with the LIKE keyword. For details, see the CREATE PROCEDURE statement.

The default can also be NULL. Usually, the procedure definition specifies what action should be taken if a parameter value is NULL.

@variable
Specifies the variable that stores a return parameter.
OUTPUT
Indicates that the stored procedure returns a parameter. The matching parameter in the stored procedure must also have been created with the keyword OUTPUT.
WITH RECOMPILE
Forces a new plan to be compiled. Use this option if the parameter you're supplying is atypical or if the data has significantly changed. The changed plan is used in subsequent executions. This parameter is not used for extended stored procedures.

Note If you use SELECT * in your CREATE PROCEDURE statement, the procedure (even with the WITH RECOMPILE option to EXECUTE) does not select any new columns added to the table. So that the procedure can select new columns, you must drop the procedure and re-create it.

@str_var
Is the name of a local string variable. In most cases, this variable will be composed of multiple strings that in total will represent a Transact-SQL statement. The @str_var variable can be a char, character, varchar, or text parameter.
tsql_string
Represents a portion or complete string of Transact-SQL statement(s). The total concatenated string passed to the EXECUTE statement must include the complete Transact-SQL command with appropriate spaces and syntax. The string must be enclosed with single quotation marks (').

Remarks

You don't need to use the EXECUTE keyword while executing stored procedures if the statement is the first one in a batch.

You can supply parameters by using value or by using @parameter_name = value. A parameter is not part of a transaction, so if a parameter is changed in a transaction that is later rolled back, the parameter's value does not revert to its previous value. The value returned to the caller is always the value at the time the procedure returns.

If you are using OUTPUT parameters and intend to use the return values in other statements within the calling batch or procedure, the value of the parameter must be passed as a variable ¾ that is, @parameter_name = @variable. It is an error to execute a procedure specifying OUTPUT for a parameter not defined as an OUTPUT parameter in the CREATE PROCEDURE statement. You cannot pass constants to stored procedures using OUTPUT; the return parameter requires a variable name. You must declare the variable's datatype and assign it a value before executing the procedure. Return parameters can be of any datatype except text or image.

Nesting occurs when one stored procedure calls another. The nesting level is incremented when the called procedure begins execution, and it is decremented when the called procedure has finished. Exceeding the maximum of 16 nesting levels causes the whole calling procedure chain to fail. The current nesting level is stored in the @@NESTLEVEL global variable.

SQL Server currently uses return values 0 through -14 to indicate the execution status of stored procedures. Values from -15 through -99 are reserved for future use. For a list of values, see the RETURN statement in the Control-of-flow Language topic.

Remote stored procedures and extended stored procedures are not within the scope of a transaction, so commands executed through calls to them cannot be rolled back. For more information, see the Stored Procedures¾Extended Stored Procedures topic.

Permission

EXECUTE permission for a stored procedure defaults to the owner of the stored procedure, who can transfer it to other users. Permission to use the statement(s) within the EXECUTE string is checked at the time EXECUTE is encountered, even if the EXECUTE statement is included within a stored procedure. When a stored procedure is run that executes a string, the user running the procedure is checked for permissions. In other words, the procedure is checked in the context of the user executing the procedure, not in the context of the user who created the procedure.


Using EXECUTE with a Character String

All items within the EXECUTE string must consist of character data; all numeric data must be converted prior to using EXECUTE. Functions cannot be used to build the string to be executed; however, any valid Transact-SQL statements, including functions, are available to be passed within the tsql_string, and nested EXECUTE statements are permitted.

Statement(s) inside the EXECUTE statement are not parsed, normalized, or compiled until the EXECUTE statement is executed. All table names (referenced within the same batch) are resolved when the batch is compiled. Combining statements that change database context (for example, USE dbname) and table references within the same batch will cause object resolution errors (the objects will not be found).

Incorrect:

EXEC ("USE pubs")
SELECT * FROM authors

Correct:

USE pubs
SELECT * FROM authors
OR
EXEC("USE pubs")
EXEC("SELECT * FROM authors")


Expressions

Used with variables, constants, and column names in many SQL statements, functions, and expressions. An expression returns values and can be nested.

Syntax

{constant | column_name | function | (subquery)}
[{operator | AND | OR | NOT}
{constant | column_name | function | (subquery)}...]

where

constant
Is a literal value, such as numeric or character data, or a variable identifier (in the form @variable_name). Character data must be enclosed with single quotation marks (').
column_name
Specifies a column.
function
Is a built-in function. For details, see the Functions topic.
subquery
Is a nested SELECT statement with some restrictions. A subquery can be used in an expression if the subquery returns a single value. For details, see the Subqueries topic.
operator
Is an arithmetic, bitwise, comparison, or string operator. For details, see the Operators topic.
AND
Used in Boolean expressions to connect two expressions. Returns results when both expressions are true.

When more than one logical operator is used in a statement, AND is processed first. You can change the order of execution by using parentheses.

OR
Use in Boolean expressions to connect two or more conditions. Returns results when either condition is true.

When more than one logical operator is used in a statement, OR is evaluated after AND. You can change the order of execution by using parentheses.

NOT
Negates any Boolean expression (which can include keywords, such as LIKE, NULL, BETWEEN, IN, and EXISTS).

Remarks

Character-constant expressions are treated as varchar. If they are compared with non-varchar variables or column data, the datatype precedence rules are used in the comparison (that is, the lower datatype is converted to the higher). If implicit conversion of the lower to the higher is not allowed, use CONVERT. For details, see the Functions topic.

Comparing a char expression to a varchar expression follows the datatype precedence rule (the lower datatype is converted to the higher). All varchar expressions are converted to char (that is, trailing blanks are added) for the comparison.

See Also

Functions | SELECT
Operators | Subqueries
Search Conditions | Wildcard Characters


Functions

Functions return special information from the system about users, expressions, a database or database objects, and so on. Aggregate functions return summary values. Other built-in functions perform various operations and are often used on their own or as part of a stored procedure or program. When used in SQL statements, functions can be used in the select list, in the WHERE clause, and anywhere an expression is allowed.

The built-in functions detailed below are Transact-SQL extensions to SQL. They can be divided into the following specific categories. For more information, see the Expressions topic and the Text and Image Manipulation topic.

Aggregate Functions

Aggregate functions return summary values. These are the aggregate functions:

AVG | COUNT(*) | MIN
COUNT | MAX | SUM

Date Functions

Date functions compute datetime values and their components, dataparts. These are the date functions:

DATEADD | DATENAME | GETDATE
DATEDIFF | DATEPART |

Mathematical Functions

Mathematical functions perform operations on numeric data. These are the mathematical functions:

ABS | DEGREES | RAND
ACOS | EXP | ROUND
ASIN | FLOOR | SIGN
ATAN | LOG | SIN
ATN2 | LOG10 | SQRT
CEILING | PI | TAN
COS | POWER |
COT | RADIANS |

Niladic Functions

Niladic functions allow a system-supplied value to be inserted into a table when no value is specified. ANSI-standard niladic functions are used in DEFAULT constraints. These niladic functions are supported:

CURRENT_TIMESTAMP | SYSTEM_USER
CURRENT_USER | USER
SESSION_USER |

For details about these functions, see the CREATE TABLE and ALTER TABLE statements.

String Functions

String functions perform operations on binary data, character strings, or expressions. These are the string functions:

 | LTRIM | SOUNDEX
ASCII | PATINDEX | SPACE
CHAR | REPLICATE | STR
CHARINDEX | REVERSE | STUFF
DIFFERENCE | RIGHT | SUBSTRING
LOWER | RTRIM | UPPER

System Functions

System functions return special information from the database. These are the system functions:

COALESCE | HOST_NAME | OBJECT_NAME
COL_LENGTH | IDENT_INCR | STATS_DATE
COL_NAME | IDENT_SEED | SUSER_ID
DATALENGTH | INDEX_COL | SUSER_NAME
DB_ID | ISNULL | USER_ID
DB_NAME | NULLIF | USER_NAME
GETANSINULL | HOST_ID | OBJECT_ID

For details about the COALESCE and NULLIF functions, see the CASE statement.

Text and Image Functions

Text and image functions perform operations on text and image data. These are the text and image functions:

PATINDEX | TEXTPTR
SET TEXTSIZE | TEXTVALID

For details about these functions, see the text and image Manipulation topic.

Type-conversion Function

The type-conversion function transforms expressions from one datatype into another. This is the type-conversion function:

CONVERT


Aggregate Functions

Return summary values. Aggregate functions calculate summary values, such as averages and sums, from the values in a particular column, and they return a single value for each set of rows to which the function applies.

Aggregate functions often appear with GROUP BY, which partitions a table into groups. These functions calculate a single value for each group. Without GROUP BY, an aggregate function in the select list produces a single value as a result, whether it is operating on all the rows in a table or on a subset of rows defined by a WHERE clause.

Syntax

aggregate_ function ([ALL | DISTINCT] expression)

where

aggregate_ function
Specifies an aggregate function.

The aggregate functions are:
Aggregate function | Description
AVG | Returns the average of all the values, or only the DISTINCT values, in the expression. AVG can be used with numeric columns only. Null values are ignored.
COUNT | Returns the number of non-null values in the expression. When DISTINCT is specified, COUNT finds the number of unique non-null values. COUNT can be used with both numeric and character columns. Null values are ignored.
COUNT(*) | Returns the number of rows. COUNT(*) takes no parameters and cannot be used with DISTINCT. All rows are counted, even those with null values.
MAX | Returns the maximum value in the expression. MAX can be used with numeric, character, and datetime columns, but not with bit columns. With character columns, MAX finds the highest value in the collating sequence. MAX ignores any null values. DISTINCT is available for ANSI compatibility; but, it is not meaningful with MAX.
MIN | Returns the minimum value in the expression. MIN can be used with numeric, character, and datetime columns, but not with bit columns. With character columns, MIN finds the value that is lowest in the sort sequence. MIN ignores any null values. DISTINCT is available for ANSI compatibility; but, it is not meaningful with MIN.
SUM | Returns the sum of all the values, or only the DISTINCT values, in the expression. SUM can be used with numeric columns only. Null values are ignored.
Numeric columns refer to decimal, float, int, money, numeric, real, smallint, smallmoney, and tinyint datatypes.

ALL
Applies the aggregate function to all values. ALL is the default.
DISTINCT
Eliminates duplicate values before an aggregate function is applied. DISTINCT is optional with SUM, AVG, COUNT, MIN, MAX and cannot be used with COUNT(*). Although available for ANSI compatibility, DISTINCT is meaningless with MIN and MAX.
expression
Is a column name, constant, function, any combination of column names, constants, and functions connected by arithmetic or bitwise operators. For more information, see the Expressions topic.

Remarks

Aggregate functions, which calculate summary values from the non-null values in a particular column, can be applied to all rows in a table. In this case, they produce a single value called a scalar aggregate function. Or they can be applied to all rows that have the same value in a column or columns or expression (with the GROUP BY and, optionally, the HAVING clause). In this case, they produce a value for each group, called a vector aggregate function. The results of the aggregate functions are shown as new columns.

When you sum or average numeric data, Transact-SQL promotes the resulting datatype to the minimum precision and scale necessary to hold the result. To avoid overflow errors, declare all variables that will hold the result of a sum or average with the most precise datatype of the values supplied. For example, when summing tinyint and int values, use a resulting variable of type int. When working with datatypes of varying precision and scale, use the maximum precision and the maximum scale.

Examples

A. SUM and AVG Functions

This example calculates the average advance and the sum of year-to-date sales for all business books. Each of these aggregate functions produces a single summary value for all of the retrieved rows.

SELECT AVG(advance), SUM(ytd_sales)
    FROM titles
        WHERE type = 'business'
B. SUM and AVG Function with a GROUP BY Clause

When used with a GROUP BY clause, aggregate functions produce single values for each group, rather than for the whole table. This example produces summary values for each type of book.

SELECT type, AVG(advance), SUM(ytd_sales)
    FROM titles
        GROUP BY type
C. COUNT of DISTINCT

This example finds the number of different cities in which authors live.

SELECT COUNT(DISTINCT city)
    FROM authors
D. GROUP BY HAVING COUNT(*)

This example lists the types in the titles table but eliminates the types that include more than one book.

SELECT type
    FROM titles
        GROUP BY type
            HAVING COUNT(*) > 1
E. HAVING SUM and AVG

This example groups the titles table by publisher and includes only those groups of publishers who have paid more than $25,000 in total advances and whose books average more than $15 in price.

SELECT pub_id, SUM(advance), AVG(price)
    FROM titles
        GROUP BY pub_id
            HAVING SUM(advance) > $25000
                AND AVG(price) > $15


CONVERT Function

The CONVERT function converts an expression of one datatype to another datatype. Also obtains a variety of special date formats.

Syntax

CONVERT (datatype[(length)], expression [, style])

where

datatype
Is any system datatype (for example, char(10), varbinary, int) into which the expression is to be converted. User-defined datatypes cannot be used.
length
Is an optional parameter with char, varchar, binary, and varbinary datatypes.

Note For datatypes where specifying length (n) is optional ¾ (binary[(n)], char[(n)], varbinary[(n)], and varchar[(n)]) ¾ SQL Server uses 30 for the length.

The maximum allowable length is 255.

expression
Follows the rules for expressions. For more information, see the Expressions topic.
style
Is the style of date representation you want when converting datetime or smalldatetime data to character data. In the following table, the two columns on the left represent the style values. Add 100 to a style value to get a four-place year that includes the century (yyyy).
Without
century
(yy) 		With
century
(yyyy)

Standard

Output
- 0 or 100 (*) Default mon dd yyyy hh:miAM (or PM)
1 | 101 | USA | mm/dd/yy
2 | 102 | ANSI | yy.mm.dd
3 | 103 | British/French | dd/mm/yy
4 | 104 | German | dd.mm.yy
5 | 105 | Italian | dd-mm-yy
6 106 - dd mon yy
7 107 - mon dd, yy
8 108 - hh:mm:ss
- 9 or 109 (*) Default milliseconds mon dd yyyy hh:mi:ss:mmmAM (or PM)
10 | 110 | USA | mm-dd-yy
11 | 111 | JAPAN | yy/mm/dd
12 | 112 | ISO | yymmdd
- 13 or 113 (*) Europe default milliseconds dd mon yyyy hh:mm:ss:mmm(24h)
14 114 - hh:mi:ss:mmm(24h)
* The default values (style 0 or 100, 9 or 109, and 13 or 113) always return the
century (yyyy).

When converting to character data from smalldatetime, the styles that include seconds or milliseconds show zeros in these positions. You can truncate unwanted date parts when converting from datetime or smalldatetime values by using an appropriate char or varchar datatype length.

Remarks

SQL Server automatically handles certain datatype conversions. For example, if you compare a character expression and a datetime expression, or a smallint expression and an int expression, or character expressions of different lengths, SQL Server makes the conversion automatically for the comparison. You are not required to use CONVERT; however, it is never wrong to use the CONVERT function even when you are comparing two expressions of exactly the same datatype. CONVERT can be used in a select list or in a WHERE clause.

When concatenating noncharacter, nonbinary expressions, always use the CONVERT function. For example:

SELECT 'The date is ' + CONVERT(varchar(12), getdate())

Automatic conversion is not supported for the text and image datatypes. You can explicitly convert text data to character data, and image data to binary or varbinary, but the maximum length you can specify is 255. If you attempt a conversion that is not possible (for example, if you try to convert a character expression that includes letters to an int), SQL Server generates an error message.

When converting between types with a different number of decimal places, the value is rounded to the most precise digit. The result of the following is 10:

SELECT CONVERT(int, 10.6496)

This table shows the possible datatype conversions.

Key: | I Implicit conversion
 | E Explicit conversion, CONVERT function must be used
 | N Conversion not allowed
 | * Converting from decimal or numeric to decimal or numeric requires CONVERT when a loss of precision or scale will occur.
 | - Conversion of a datatype to itself; allowed but meaningless

binary and varbinary

Convert to binary to display the internal representation of a value. If lengths differ, the binary value is padded with zeros on the left.

You can convert int, smallint, and tinyint to binary or varbinary, but if you convert the binary value back to an integer value, it may be different from the original integer value. In addition, if the integer is longer than the specified binary length, it is truncated. For example, a conversion from a long binary to an int value uses only the 4 rightmost bytes of the binary value. The following example shows why binary and varbinary datatypes should be used only for hexadecimal numbers that are interpreted as type streams, and should not be used in calculations.

SELECT CONVERT(int,0x0001000008ae36f0)
SELECT CONVERT(int,0x00010000)

------

145635056

(1 row affected)

------

65536

(1 row affected)

bit

Converting to bit promotes any nonzero value to 1.

Character data

When character expressions are converted to a character datatype of a different size, values too long for the new datatype are truncated.

Character expressions being converted to an approximate numeric datatype can include optional exponential notation (a lowercase e or uppercase E followed by an optional plus () or minus (-) sign and then a number).

Character expressions being converted to an exact numeric datatype must consist of digits, a decimal point, and an optional plus () or minus (-) sign. Leading blanks are ignored.

Character expressions being converted to money datatypes can also include an optional decimal point and dollar sign ($).

datetime and smalldatetime

When converting to datetime, SQL Server rejects all values it cannot recognize as dates (including dates earlier than January 1, 1753). You can convert datetime values to smalldatetime when the date is in the proper range (January 1, 1900 to June 6, 2079). The time value is rounded up to the nearest minute.

float

Values of float are truncated when converted to any integer type.

When you are converting from float or real to character data, the string function STR( ) is usually a better choice than CONVERT( ), because STR( ) gives you more control over formatting. For more information, see the String Functions topic.

money

When converting to money from integer datatypes, units are assumed to be dollars. For example, the integer value of 4 is converted to the money equivalent of 4 dollars.

decimal and numeric

For the decimal and numeric datatypes, SQL Server considers each specific combination of precision and scale as a different datatype. For example, decimal(5,5) and decimal(5,0) are considered different datatypes.

In Transact-SQL statements, a constant with a decimal point is automatically converted into a numeric data value, using the minimum precision and scale necessary. For example, the constant 12.345 is converted into a numeric value with a precision of 5 and a scale of 3. This behavior is different from earlier versions of SQL Server, which converted constants with a decimal point to float. Therefore, calculations can return slightly different (but more precise) results.

Converting from decimal or numeric to float or real can result in some loss of precision. Converting from int, smallint, tinyint, float, real, money, or smallmoney to either decimal or numeric can result in overflow.

If you perform arithmetic on two exact numeric values, v1 and v2, where v1 has a precision of p1 and a scale of s1, and where v2 has a precision of p2 and s2, the precision and scale of the result depends on the operator (with an absolute maximum of @@MAX_PRECISION) and is determined as follows:

Operation | Precision | Scale
v1 v2 | max(s1,s2) max(p1-s1,p2-s2) | max(s1,s2)
v1 - v2 | max(s1,s2) max(p1-s1,p2-s2) | max(s2,s2)
v1 * v2 | s1 s2 (p1-s1) (p2-s2) 1 | s1 s2
v1 / v2 | max(s1+p2-s2+1,6) p1 p2 1 | max(s1+p2-s2+1,6)

By default, SQL Server uses rounding when converting a number to a decimal or numeric value with a lower precision and scale. However, if the ARITHABORT option is enabled (using the SET statement), SQL Server cancels a query and raises a precision error when an exact numeric operation would result in a loss of precision and scale.

Examples

A. Convert to Character Data with SELECT

This example shows how to convert data for display.

SELECT title, CONVERT(char(12), ytd_sales)
    FROM titles
B. Convert to Character Data in WHERE Clause

This example converts sales data to character data prior to performing a string comparison.

SELECT title, ytd_sales
    FROM titles
        WHERE CONVERT(char(20), ytd_sales) LIKE '1%'
C. Convert to Character Data from the Date Function GETDATE( )

This example converts the current date to style 3, dd/mm/yy.

SELECT CONVERT(char(12), GETDATE(), 3)


Date Functions

Date functions manipulate datetime values. Date functions can be summarized as follows:

Syntax

date_ function (parameters)

where

date_ function
Specifies a date function.

The date functions are:
Date function | Description
DATEADD
(datepart, number, date) 		Produces a date by adding an interval to a specified date. The result is a datetime value equal to the date plus the number of date parts.

If the date parameter is a smalldatetime value, the result is also a smalldatetime. You can use DATEADD to add seconds or milliseconds to a smalldatetime value, but the addition is meaningful only where the resulting date changes by at least 1 minute.
DATEDIFF
(datepart, date1, date2) 		Returns the number of datepart "boundaries" crossed between two specified dates. The method of counting crossed boundaries makes the result given by DATEDIFF consistent across all datatypes such as minutes, seconds, and milliseconds.

DATEDIFF takes three parameters. The first is a datepart; the second and third are dates, either datetime or smalldatetime values. The result is a signed integer value equal to the number of datepart boundaries crossed between date2 minus date1. For example, the number of weeks between Sunday, January 4 and Sunday, January 11, is 1.

DATEDIFF produces an error if the result is out range for integer values. For milliseconds, the maximum number that can be represented is 24 days, 20 hours, 31 minutes and 23.647 seconds. For seconds, the maximum number that can be represented is approximately 68 years.

If smalldatetime values are used, they are converted to datetime values internally for the calculation. Seconds and milliseconds in smalldatetime values are set to 0 for calculating the difference.
DATENAME
(datepart, date) 		Returns a character string representing the specified date part (datepart) of the specified date (date).
DATEPART
(datepart, date) 		Returns an integer representing the specified date part (datepart) of the specified date (date).
GETDATE() | Returns the current system date and time in the SQL Server standard internal format for datetime values. GETDATE does not take any parameters.

date
Can be either the GETDATE function, a character string in date format, or the name of a datetime column.
datepart
Is a parameter used with DATEADD, DATEDIFF, DATENAME, and DATEPART. The following table lists the date parts, the abbreviations recognized by SQL Server, and the acceptable values:
Date part | Abbreviation | Values
year | yy | 1753-9999
quarter | qq | 1-4
month | mm | 1-12
day of year | dy | 1-366
day | dd | 1-31
week | wk | 1-53
weekday | dw | 1-7 (Sun.-Sat.)
hour | hh | 0-23
minute | mi | 0-59
second | ss | 0-59
millisecond | ms | 0-999

If the year is given with two digits, <50 is the next century and >=50 is this century. So "25" is "2025," and "50" is "1950."

Milliseconds can be preceded by either a colon or a period. If preceded by a colon, the number means thousandths of a second. If preceded by a period, a single digit means tenths of a second, two digits mean hundredths of a second, and three digits mean thousandths of a second. For example, "12:30:20:1" means 20 and one-thousandth seconds past 12:30; "12:30:20.1" means 20 and one-tenth seconds past 12:30.

Use the datetime datatype for dates after January 1, 1753. When entering datetime values, always enclose them in quotation marks. Use char or varchar for earlier dates.

SQL Server automatically converts between character and datetime values when necessary ¾ for example, when you compare a character value with a datetime value.

The date part weekday or dw returns the day of the week (Sunday, Monday, and so on) when used with datename. It returns a corresponding number (Sunday = 1, Saturday = 7) when used with datepart. Using weekday or dw with DATEADD and DATEDIFF is not logical and produces spurious results. Use day or dd instead.

Because smalldatetime is accurate only to the minute, when a smalldatetime value is used with either datename or datepart seconds and milliseconds are always 0.

Remarks

Date functions can be used in the select list or in the WHERE clause of a query.

Use the datetime datatype only for dates after January 1, 1753. When entering datetime values, always enclose them in quotation marks. Store as character data for earlier dates. SQL Server recognizes a wide variety of date styles. For more information about date and time data, see the Datatypes topic and CONVERT Function.

Examples

A. DATEADD Function

This example prints a listing of a "timeframe." This timeframe represents the existing publication date plus 21 days.

SELECT timeframe = DATEADD(day, 21, pubdate)
    FROM titles
B. DATEDIFF Function

This example determines the difference in days between the current date and the publication date.

SELECT newdate = DATEDIFF(day, pubdate, getdate())
    FROM titles
C. DATEDIFF Function Changes in SQL Server 6.0

This example shows the difference in results of the new DATEDIFF function in SQL Server 6.0.

In earlier releases:

SELECT "Number of Minutes" = DATEDIFF(minute, 'jan 1 1995 22:30:16', 'jan 1 1995 23:30:15')
go
Number of Minutes
------------------------
59

In SQL Server 6.0

SELECT "Number of Minutes" = DATEDIFF(minute, 'jan 1 1995 22:30:16', 'jan 1 1995 23:30:15')
go
Number of Minutes
------------------------
60

The difference is minor; however, it accurately reflects that 60 "minute boundaries" were crossed.

D. DATENAME and DATEPART Functions

The GETDATE function returns the current date; however, the complete date is not always the information needed for comparison (often only a portion of the date is compared). This example shows the output of GETDATE( ) as well as some other date functions.

SELECT "Current Date" = getdate()
go
Current Date
---------------------------
Feb 18 1995 11:46PM

SELECT "Month Name" = DATENAME(month, getdate())
go
Month Name
------------------------------
February

SELECT "Month Number" = DATEPART(month, getdate())
go
Month Number
------------
2


Mathematical Functions

Mathematical functions return values commonly needed for operations on mathematical data. Mathematical function names are not keywords.

Syntax

function_name(parameters)

where

function_name
Specifies a mathematical function.

These are the mathematical functions:
Function | Parameters | Result
ABS | (numeric_expr) | Absolute value of the numeric expression. Results returned are of the same type as numeric_expr.
ACOS | (float_expr) | Angle (in radians) whose cosine is the specified approximate numeric (float) expression.
ASIN | (float_expr) | Angle (in radians) whose sine is the specified approximate numeric (float) expression.
ATAN | (float_expr) | Angle (in radians) whose tangent is the specified approximate numeric (float) expression.
ATN2 | (float_expr1, float_expr2) | Angle (in radians) whose tangent is (float_expr1/float_expr2) between two approximate numeric (float) expressions.
CEILING | (numeric_expr) | Smallest integer greater than or equal to the numeric expression. Result returned is the integer portion of the same type as numeric_expr.
COS | (float_expr) | Trigonometric cosine of the specified angle (in radians) in an approximate numeric (float) expression.
COT | (float_expr) | Trigonometric cotangent of the specified angle (in radians) in an approximate numeric (float) expression.
DEGREES | (numeric_expr) | Degrees converted from radians of the numeric expression. Results are of the same type as numeric_expr.
EXP | (float_expr) | Exponential value of the specified approximate numeric (float) expression.
FLOOR | (numeric_expr) | Largest integer less than or equal to the specified numeric expression. Result returned is the integer portion of the same type as numeric_expr.
LOG | (float_expr) | Natural logarithm of the specified approximate numeric (float) expression.
LOG10 | (float_expr) | Base-10 logarithm of the specified approximate numeric (float) expression.
PI ( ) Constant value of 3.141592653589793.
POWER | (numeric_expr, y) | Value of numeric expression to the power of y, where y is a numeric datatype (decimal, float, int, money, numeric, real, smallint, smallmoney, or tinyint). Result is of the same type as numeric_expr.
RADIANS | (numeric_expr) | Radians converted from degrees of the numeric expression. Result is of the same type as numeric_expr.
RAND | ([seed]) | Random approximate numeric (float) value between 0 and 1, optionally specifying an integer expression (tinyint, smallint, or int) as the seed.
ROUND (numeric_expr, length) Numeric expression rounded off to the length (or precision) specified as an integer expression (tinyint, smallint, or int). Result is of the same type as numeric_expr.

The ROUND function always returns a value even if the length is illegal. If the specified length is positive and longer than the digits after the decimal point, 0 is added after the fraction digits.

If the length is negative and larger than or equal to the digits before the decimal point, ROUND returns 0.00.
SIGN | (numeric_expr) | Returns the positive (+1), zero (0), or negative (-1) sign of the numeric expression. Result is of the same type as numeric_expr.
SIN | (float_expr) | Trigonometric sine of the specified angle (measured in radians) in an approximate numeric (float) expression.
SQRT | (float_expr) | Square root of the specified approximate numeric (float) expression.
TAN | (float_expr) | Trigonometric tangent of the specified angle (measured in radians) in an approximate numeric (float) expression.

where

numeric_expr
Is an expression of the decimal, float, int, money, numeric, real, smallint, smallmoney, or tinyint datatype.
float_expr
Is an expression of the float datatype.

Remarks

Internal conversion to float can cause loss of precision if the money datatype is used.

Error traps are provided to handle domain or range errors of these functions. A user can set the options ARITHABORT, which terminates the query, or ARITHIGNORE, which returns NULL, when a domain error occurs. No warning message is displayed. If neither of these options is set, SQL Server returns NULL and returns a warning message after the query is executed.

Examples

A. FLOOR Function

This example shows positive numeric, negative numeric, and money values with the FLOOR function. The result returned is the integer portion of the same datatype as the expression. Note that the money datatype always returns a two-place decimal value but no dollar sign ($).

Statement

Result

SELECT FLOOR(123.45)

123

SELECT FLOOR(-123.45)

-124

SELECT FLOOR($123.45)

123.00

B.    CEILING Function

This example shows positive numeric, negative numeric, and money values with the CEILING function. The result returned is the integer portion of the same datatype as the expression. Note that the money datatype always returns a two-place decimal value but no dollar sign ($).

Statement

Result

SELECT CEILING(123.45)

124

SELECT CEILING(-123.45)

-123

SELECT CEILING($123.45)

124.00

C.    The ROUND Function

This example shows rounding and approximations. The result returned is always the same datatype as the expression. Note that the money datatype always returns a two-place decimal value but no dollar sign ($).

Statement

Result

SELECT ROUND(123.4545, 2)

123.4500

SELECT ROUND(123.45, -2)

100.00

With the ROUND function, the last digit is always an estimate:

ROUND(123.9994, 3) = 123.9990

and

ROUND(123.9995, 3) = 124.0000


Row Aggregate Functions

Row aggregate functions generate summary values that appear as additional rows in the query results (unlike the aggregate function results, which appear as new columns). They allow you to see detail and summary rows in one set of results. Row aggregate functions (SUM, AVG, MIN, MAX, and COUNT) are used in a SELECT statement with the COMPUTE clause. You can calculate summary values for subgroups, and you can calculate more than one aggregate function for the same group. COMPUTE and the row aggregate functions are Transact-SQL enhancements to standard SQL.

Syntax

COMPUTE row_aggregate [, row_aggregate...]
[BY expression [, expression]...]

where

row_aggregate
Specifies the row aggregate function.

These are the row aggregate functions:
Aggregate
function
Result
SUM(expression) | Returns the total of the values in the numeric column.
AVG(expression) | Returns the average of the values in the numeric column.
COUNT(expression) | Returns the number of non-null values in the column.
MAX(expression) | Returns the highest value in the column.
MIN(expression) | Returns the lowest value in the column.

BY
Indicates that row aggregate function values are to be calculated for subgroups. Whenever the value of the BY item changes, row aggregate function values are generated. If you use BY, you must use ORDER BY. Listing more than one item after BY breaks a group into subgroups and applies a function at each group level.
expression
Follows the rules for expressions as defined in the Expressions topic; however, when used as a row aggregate function, an expression is usually the name of a column. The expression must be enclosed in parentheses. Only numeric expressions (expressions that result in a decimal, float, int, money, numeric, real, smallint, smallmoney, or tinyint datatype) can be used with SUM and AVG. One COMPUTE clause can apply the same function to several columns or several functions to one column. When using more than one function, use more than one COMPUTE clause.

Remarks

The row aggregate functions make it possible to retrieve detail rows and summary rows with one statement. The aggregate functions, in contrast, ordinarily produce a single value for all selected rows in the table or for each group, and these summary values are shown as new columns.

The columns in the COMPUTE clause must appear in the select list.

You can't use SELECT INTO in the same statement as a COMPUTE clause because statements that include COMPUTE generate tables that include the summary results, which are not stored in the database.

If you use COMPUTE BY, you must also use an ORDER BY clause. The columns listed after COMPUTE BY must be identical to or a subset of those listed after ORDER BY, and they must be in the same left-to-right order, start with the same expression, and not skip any expressions. For example, if the ORDER BY clause is:

ORDER BY a, b, c

The COMPUTE BY clause can be any or all of these:

COMPUTE BY a, b, c
COMPUTE BY a, b
COMPUTE BY a

You must use a column name or an expression in the ORDER BY clause.

The COMPUTE keyword can be used without BY to generate grand totals, grand counts, and so on. ORDER BY is optional if you use the COMPUTE keyword without BY.

When you sum or average integer data, SQL Server treats the result as an int value, even if the datatype of the column is smallint or tinyint.

Note To reduce the possibility of overflow errors in DB-Library programs, make all variable declarations for the results of averages or sums type int.

In a SELECT statement with a COMPUTE clause, the order of columns in the select list overrides the order of the aggregate functions in the COMPUTE clause. DB-Library programmers must be aware of this order requirement to put the aggregate function results in the correct place. For example:

SELECT a, b, c

FROM test

COMPUTE SUM(c), MAX(b), MIN(a)

a

b

c

---------

----------

----------

1

2

3

3

2

1

sum

=======

4

max

=======

2

min

=========

1

(3 rows affected)

Examples

A.    Aggregates and Row Aggregates

The following two examples illustrate the differences between aggregate functions and row aggregate functions. The first shows aggregate functions giving summary data only, and the second shows row aggregate functions giving detail and summary data.

Aggregate Functions

SELECT type, SUM(price), SUM(advance)
    FROM titles
        WHERE type LIKE '%cook'
            GROUP BY type

type

----------

----------

------------

mod_cook

22.98

15,000.00

trad_cook

47.89

19,000.00

(2 rows affected)

Row Aggregates

SELECT type, price, advance
    FROM titles
        WHERE type LIKE '%cook'
            ORDER BY type
            COMPUTE SUM(price), SUM(advance) BY type

type

price

advance

----------

------------

------------

mod_cook

2.99

15,000.00

mod_cook

19.99

0.00

sum

sum

------------

------------

22.98

15,000.00

type

price

advance

----------

------------

------------

trad_cook

20.95

7,000.00

trad_cook

14.99

8,000.00

trad_cook

11.95

4,000.00

sum

sum

------------

------------

47.89

19,000.00

(7 rows affected)

B.    Group Totals with COMPUTE BY

This example calculates the sum of the all prices (for prices over $10) for each type of cookbook, in order first by type of book and then by price of book.

SELECT type, price
    FROM titles
        WHERE price > $10
        AND type LIKE '%cook'
            ORDER BY type, price
            COMPUTE SUM(price) BY type

type

price

-----------

----------

mod_cook

19.99

sum

----------

19.99

type

price

------------

----------

trad_cook

11.95

trad_cook

14.99

trad_cook

20.95

sum

----------

47.89

(6 rows affected)


String Functions

String functions perform various operations on binary data, character data, and expressions. String functions can be used anywhere an expression is allowed to return values commonly needed for operations on character data and string concatenation. Various system functions, such as COL_LENGTH and DATALENGTH, can also prove useful. For details, see "System Functions," later in this topic.

With the exception of the PATINDEX function, string functions can be used only on char, varchar, binary, and varbinary datatypes, plus those datatypes that convert implicitly to char or varchar. The PATINDEX function can be used on char, varchar, and text datatypes. For functions specifically designed to manipulate text and image data, see the text and image Manipulation topic.

Syntax

function_name(parameters)

where

function_name
Specifies a string function.

These are the string functions:
Function | Parameters | Result
(expression expression) | Concatenates two character strings, binary strings, column names, or a combination of them. Enclose character strings in quotation marks. When concatenating non-character, non-binary expressions, always use the CONVERT function.
ASCII | (char_expr) | Indicates the ASCII code value of the leftmost character of a character expression.
CHAR | (integer_expr) | Converts a character from an ASCII code. The ASCII code should be a value from 0 through 255; otherwise, NULL is returned.
CHARINDEX | ('pattern', expression) | Returns the starting position of the specified pattern. A pattern is a char_expr. The second parameter is an expression, usually a column name, in which SQL Server searches for the pattern.
DIFFERENCE (char_expr1, char_expr2) Shows the difference between the values of two character expressions as returned by the SOUNDEX function.

The DIFFERENCE function compares two strings and evaluates the similarity between them, returning a value from 0 through 4. The value 4 is the best match, meaning that the SOUNDEX values of char_expr1 and char_expr2 are identical.

If the first character of SOUNDEX(char_expr1) is identical to the first character of SOUNDEX(char_expr2), then the starting DIFFERENCE value is 1; otherwise, it is 0. Then each numeric character of char_expr2 is compared to the numeric characters of char_expr1, adding 1 to the DIFFERENCE value if a match is found.
LOWER | (char_expr) | Converts uppercase character data to lowercase.
LTRIM | (char_expr) | Removes leading blanks.
PATINDEX | ('%pattern%', expression) | Returns the starting position of the first occurrence of pattern in the specified expression, or zeros if the pattern is not found. You can use wildcard characters in pattern, as long as the wildcard character % precedes and follows pattern (except when searching for first or last characters). The expression is usually a column name. You can use this function on text, char, and varchar data.
REPLICATE | (char_expr, integer_expr) | Repeats a character expression a specified number of times. If integer_expr is negative, a null string is returned.
REVERSE | (char_expr) | Returns the reverse of char_expr. This function takes a constant, variable, or column as its parameter.
RIGHT | (char_expr, integer_expr) | Part of a character string starting integer_expr characters from the right. If integer_expr is negative, a null string is returned.
RTRIM | (char_expr) | Removes trailing blanks.
SOUNDEX (char_expr) Returns a four-digit (SOUNDEX) code to evaluate the similarity of two strings.

The SOUNDEX function converts an alpha string to a four-digit code to find similar-sounding words or names. The first character of the code is the first character of char_expr and the second through fourth characters of the code are numbers. Vowels in char_expr are ignored unless they are the first letter of the string.

SPACE | (integer_expr) | Returns a string of repeated spaces. The number of spaces is equal to integer_expr. If integer_expr is negative, a null string is returned.
STR (float_expr [, length
[, decimal]]) 		Returns character data converted from numeric data. The length is the total length, including decimal point, sign, digits, and spaces. The decimal value is the number of spaces to the right of the decimal point. Both length and decimal are optional. The default for length is 10.

Do not use a function or subquery as the float_expr in the STR function. A short float_expr is right-justified in the specified length, and a long float_expr is truncated to the specified number of decimal places.
STUFF (char_expr1, start, length, char_expr2) Deletes length characters from char_expr1 at start and then inserts char_expr2 into char_expr1 at start.

If the start position or the length is negative, a null string is returned. If the start position is longer than char_expr1, a null string is returned. If the length to delete is longer than char_expr1, it is deleted to the first character in char_expr1.

SUBSTRING | (expression, start, length) | Returns part of a character or binary string. The first parameter can be a character or binary string, a column name, or an expression that includes a column name. (Do not use expressions that include functions.) The second parameter specifies where the substring begins. The third parameter specifies the number of characters in the substring.
UPPER | (char_expr) | Converts lowercase character data to uppercase.

where

char_expr
Is an alphanumeric expression of character data.
integer_expr
Is a positive whole number.
float_expr
Is an approximate numeric (float) datatype with a decimal point.

Remarks

String functions can be nested.

Examples

A. String Concatenation

Creating one result from multiple character columns can be achieved through string concatenation. This example creates a single column (under the column heading Name) in order of last name followed by first name with a comma after the last name in the authors table:

SELECT Name = (au_lname + ', ' + au_fname)
    FROM authors
B. SUBSTRING Function

This example shows how to return only a portion of a character string. From the authors table, this query will return the last name in one column with only the first initial in the second column.

SELECT au_lname, SUBSTRING(au_fname, 1, 1)
    FROM authors
C. Combining Functions and String Concatenation

This example creates a single column (under the column heading Name) in order of last name, first initial with a comma after the last name in the authors table.

SELECT Name = (au_lname + ', ' + SUBSTRING(au_fname, 1, 1) + '.')
    FROM authors
D. Combining Functions and Concatenation in Any Order

This example displays the first six characters of the concatenation of each pub_id and title_id. It displays all four characters of the pub_id and the first two characters of the title_id.

SELECT SUBSTRING ((pub_id + title_id), 1, 6)
    FROM titles
E. CHARINDEX Function

This example returns the position at which the pattern 'wonderful' begins in the notes column of titles:

SELECT CHARINDEX('wonderful', notes)
    FROM titles
        WHERE title_id = 'TC3218'
F. STUFF Function

This example returns a character string created by deleting three characters from the first string ('abcdef') starting at position 2 (at 'b') and inserts the second string at the deletion point. The resulting string is 'aijklmnef':

SELECT STUFF('abcdef', 2, 3, 'ijklmn')
G. SOUNDEX and DIFFERENCE Functions

This example shows the SOUNDEX function and the related DIFFERENCE function. In the first example, the standard SOUNDEX values are returned for all consonants. Returning the SOUNDEX for 'Smith' and 'Smythe' will return the same SOUNDEX result because all vowels (and y) are not included.

SELECT SOUNDEX ('Smith'), SOUNDEX ('Smythe')

-----

-----

S530

S530

The DIFFERENCE function compares the difference of the SOUNDEX pattern results. The first example shows two strings that differ only in vowels. The difference returned will be 4 (lowest possible difference).

SELECT DIFFERENCE('Smithers', 'Smothers')

In this example, the strings differ in consonants, so the difference returned will be 2 (higher difference).

SELECT DIFFERENCE('Smothers', 'Brothers')


System Functions

System functions return special information from the server or database.

Syntax

function_name(parameters)

where

function_name
Specifies a system function.

These are the system functions:
System
function
Parameters
Result
COALESCE | (expression1, expression2, ... expressionN) | Returns the first non-null expression. For details, see the CASE statement.
COL_LENGTH ('table_name',
'column_name') 		The defined length of a column.
COL_NAME (table_id,
column_id) 		The name of the column.
DATALENGTH | ('expression') | The actual length of an expression of any datatype. Because varchar, varbinary, text, and image datatypes can store variable-length data, DATALENGTH is especially useful with those datatypes. The DATALENGTH of any null data returns NULL. For all other datatypes, DATALENGTH reports their defined length (because NON NULL fixed-width character data is always right-padded with spaces).
DB_ID | (['database_name']) | The database identification number.
DB_NAME | ([database_id]) | The database name.
GETANSINULL | (['database_name']) | The default nullability for the database. This function returns 1 when the nullability is the ANSI NULL default. A column or datatype whose nullability is not explicitly defined will be set to allow null values.
HOST_ID ( ) The workstation identification number.
HOST_NAME ( ) The workstation name.
IDENT_INCR | ('table_or_view') | The increment value (returned as numeric(@@MAXPRECISION,0)) specified during creation of an identity column of a table or a view that includes an identity column..
IDENT_SEED | ('table_or_view') | The seed value (returned as numeric(@@MAXPRECISION,0)) specified during creation of an identity column of a table or a view that includes an identity column.
INDEX_COL ('table_name',
index_id, key_id) 		The indexed column name.
ISNULL | (expression, value) | Replaces NULL entries with the specified value.
NULLIF | (expression1, expression2) | The resulting expression is NULL when expression1 is equivalent to expression2. For details, see the CASE statement.
OBJECT_ID | ('object_name') | The database object identification number.
OBJECT_NAME | (object_id) | The database object name.
STATS_DATE | (table_id, index_id) | The date that the statistics for the specified index (index_id) were last updated.
SUSER_ID | (['login_name']) | The user's login identification number.
SUSER_NAME | ([server_user_id]) | The user's login identification name.
USER_ID | (['user_name']) | The user's database identification number.
USER_NAME | ([user_id]) | The user's database username.

Remarks

When the parameter to a system function is optional, the current database, host computer, server user, or database user is assumed. Built-in functions must always be followed by parentheses.

System functions can be used in the select list, in the WHERE clause, and anywhere an expression is allowed. For more information, see the Expressions topic.

The system administrator's server user identification number is always 1. Server user identification number -1 is always reserved for a guest account. The user identification number of the database owner is always 1.

Examples

A. USER_ID Function

This example returns Harold's identification number, 13.

SELECT USER_ID('Harold')
B. USER_NAME Function

This example returns the username for user number 13, Harold.

SELECT USER_NAME(13)
C. ISNULL Function

This example finds the average of the prices of all titles, substituting the value $10.00 for all null entries in the price column of the titles table.

SELECT AVG(ISNULL(price, $10.00))
    FROM titles
D. COL_LENGTH Function

This example finds the length of the title column in the titles table. The x gives a column heading to the result.

SELECT x = COL_LENGTH('titles', 'title')
E. DATALENGTH Function

This example finds the length of the pub_name column in the publishers table.

SELECT length = DATALENGTH(pub_name), pub_name
    FROM publishers
F. USER_NAME Function in WHERE Clause

This example finds the row in sysusers in which the name is equal to the result of applying the system function user_name to user identification number 1.

SELECT name
    FROM sysusers
        WHERE name = USER_NAME(1)
G. STATS_DATE Function

This example returns the date of the last time that the statistics were updated for the specified object (the distribution information was updated).

SELECT 'Index Name' = i.name,
    'Statistics Date' = STATS_DATE(i.id, i.indid)
        FROM sysobjects o, sysindexes i
            WHERE o.name = 'employee' AND o.id = i.id


Text and Image Functions

Text and image functions return values commonly needed for operations on text and image data only. Text and image built-in function names are not keywords.

Syntax

function_name(parameters)

where

function_name
Specifies a text or image function.

These are the text and image functions:
Function | Parameters | Result
TEXTPTR | (column_name) | The text-pointer value in varbinary format. The text pointer is checked to ensure that it points to the first text page.
TEXTVALID | ('table_name.column_name', text_ ptr) | Checks whether a given text pointer is valid. Returns 1 if the pointer is valid and 0 if the pointer is invalid. Note that the identifier for the text column must include the table name.

Remarks

If a text or image column has not been initialized by an INSERT or UPDATE statement, TEXTPTR returns a null pointer. Use TEXTVALID to check whether a text pointer exists. You cannot use UPDATETEXT, WRITETEXT, or READTEXT without a valid text pointer.

In addition to these specific text and image functions, the following functions and statement are also useful with text and image data:

Function or statement | Description
PATINDEX('%pattern%', expression) | The character position of a given character string in text columns. For details, see "String Functions" earlier in this topic.
DATALENGTH(expression) | The length of data in text and image columns. For details, see "System Functions," earlier in this topic.
SET TEXTSIZE | The limit, in bytes, of the text or image data to be returned with a SELECT statement. For details, see the SET statement.

Examples

A. TEXTPTR Function

This example uses the TEXTPTR function to locate the image column logo associated with New Moon Books in the pub_info table of the pubs database. The text pointer is put into a local variable @ptrval.

DECLARE @ptrval varbinary(16)
SELECT @ptrval = TEXTPTR(logo)
    FROM pub_info pr, publishers p
        WHERE p.pub_id = pr.pub_id
        AND p.pub_name = 'New Moon Books'
B. Return text Data

This example selects the pub_id column and the 16-byte text pointer of the pr_info column from the pub_info table.

SELECT pub_id, TEXTPTR(pr_info) FROM pub_info

To return the first 255 bytes of text:

SELECT pub_id, pr_info FROM pub_info
C. TEXTVALID Function

This example reports whether a valid text pointer exists for each value in the logo column of the pub_info table.

SELECT pub_id, 'Valid (if 1) Text data'
                = TEXTVALID ('pub_info.logo', TEXTPTR(logo))
    FROM pub_info


GRANT Statement

For SQL Server 6.5 information, see GRANT Statement in What's New for SQL Server 6.5.

Assigns permissions to users.

Syntax

Statement permissions:

GRANT {ALL | statement_list}
TO {PUBLIC | name_list}

Object permissions:

GRANT {ALL | permission_list}
ON {table_name [(column_list)] | view_name [(column_list)] |
stored_procedure_name | extended_stored_procedure_name}
TO {PUBLIC | name_list}

where

ALL
When used to assign object permissions, specifies that all permissions applicable to the specified object are granted or revoked. When used to assign statement permissions, only the system administrator can use ALL, since only the system administrator can grant or revoke CREATE DATABASE permission.
statement_list
Lists statements granted. The statement list can include CREATE DATABASE (if the user executing the statement is the system administrator), CREATE DEFAULT, CREATE PROCEDURE, CREATE RULE, CREATE TABLE, CREATE VIEW, DUMP DATABASE, and DUMP TRANSACTION.

If more than one statement is listed, separate them with commas.

PUBLIC
Specifies all users, including those who are a member of another group in addition to public.
name_list
Lists users' database names and/or group names, separated by commas. These names are stored in the database's sysusers table.
permission_list
Lists permissions granted. When permissions are granted on a table or a view, the permission list can include one or more of the following items: SELECT, INSERT, DELETE, and UPDATE.

Permissions granted on a table can also include REFERENCES. REFERENCES allows a user to create FOREIGN KEY constraints that reference another table without having SELECT permission on that table. REFERENCES permission needs to be granted only to the person creating the FOREIGN KEY.

When permissions are granted on columns, the permission list can include SELECT and/or UPDATE.

When permissions are granted on stored procedures, the permission list can include EXECUTE only.

If multiple permissions are listed, separate them with commas.

table_name
Specifies a table in the current database. Only one table can be listed for each GRANT statement.
column_list
Lists names of columns, separated by commas, to which the permissions apply. If columns are specified, only SELECT and UPDATE permissions can be granted.
view_name
Specifies a view in the current database. Only one view can be listed for each GRANT statement.
stored_procedure_name
Is the name of a stored procedure in the current database. Only one stored procedure can be listed for each GRANT statement.
extended_stored_procedure_name
Is the name of an extended stored procedure in the current database. Only one extended stored procedure can be listed for each GRANT statement.

Remarks

Permission to use a statement or object defaults to the system administrator, the database owner, the object owner, or the default group public. Some permissions are transferable. When possible, the user to whom the permissions default can transfer permission to other users. Users at higher levels (the database owner and system administrator) are either automatically granted the permission or (in the case of database owners) can temporarily obtain permissions.

By default, the system administrator has all permissions. The system administrator can assign a database owner by using the sp_changedbowner system stored procedure. Once assigned, a database owner (or the system administrator) can GRANT "statement" permissions to users within that database. Once a user has been given "statement" permissions, he or she can create an object. That user becomes the object owner of the object(s) he or she has created. Object owners always retain rights to their object(s). "Object" permissions must be granted to other users before they can access that object.

Database users can belong to only one group in addition to the group public. Users are always a member of the group public. For permissions that default to public, no permission is required ¾ that is, no explicit GRANT or REVOKE statement must be executed.

When permissions are given, information is stored within the sysprotects table. The sysprotects table manages permissions by updating rows based on each GRANT and REVOKE statement. You can grant or revoke permissions only on objects in the current database.

If permissions are granted to the group public, they will override any previous permissions given to any other user or group of that database. When permissions are given (or revoked) the permissions are order-sensitive. (The statement executed most recently is the one that takes effect.) This can produce undesired results if care is not taken in granting/revoking permissions. For best results, grant/revoke permissions to the least-selective group first (usually public), then grant/revoke permissions on a group-by-group basis, on an individual-by-individual basis, and then to/from the guest user.

A guest user can be added by using the sp_adduser system stored procedure to allow users with login IDs on SQL Server to use the database without a specific database username (and usually with limited permissions).

The sp_helprotect system stored procedure reports permissions on a database object or on a user. For details, see the sp_helprotect system stored procedure.

Permission

GRANT and REVOKE permission defaults to particular users and cannot be transferred.

The following table details permissions for Transact-SQL statements:

 | Defaults to |  |  |  | Can be granted /revoked
Statement | System admin | DB owner | Object owner | Public | Yes | No | N/A
ALTER DATABASE | ¾ | X | ¾ | ¾ | (1) | ¾ | ¾
ALTER TABLE | ¾ | ¾ | X | ¾ | ¾ | X | ¾
BEGIN TRANSACTION | ¾ | ¾ | ¾ | X | ¾ | ¾ | X
CHECKPOINT | ¾ | X | ¾ | ¾ | ¾ | X | ¾
COMMIT TRANSACTION | ¾ | ¾ | ¾ | X | ¾ | ¾ | X
CREATE DATABASE | X | ¾ | ¾ | ¾ | X | ¾ | ¾
CREATE DEFAULT | ¾ | X | ¾ | ¾ | X | ¾ | ¾
CREATE INDEX | ¾ | ¾ | X (3) | ¾ | ¾ | X | ¾
CREATE PROCEDURE | ¾ | X | ¾ | ¾ | X | ¾ | ¾
CREATE RULE | ¾ | X | ¾ | ¾ | X | ¾ | ¾
CREATE TABLE | ¾ | X | ¾ | (2) | X (2) | ¾ | ¾
CREATE TRIGGER | ¾ | ¾ | X (3) | ¾ | ¾ | X | ¾
CREATE VIEW | ¾ | X | ¾ | ¾ | X | ¾ | ¾
DBCC (4) | ¾ | X | ¾ | ¾ | ¾ | X | ¾
DELETE | ¾ | ¾ | X | ¾ | X | ¾ | ¾
DISK INIT | X | ¾ | ¾ | ¾ | ¾ | X | ¾
DISK MIRROR | X | ¾ | ¾ | ¾ | ¾ | X | ¾
DISK REFIT | X | ¾ | ¾ | ¾ | ¾ | X | ¾
DISK REINIT | X | ¾ | ¾ | ¾ | ¾ | X | ¾
DISK REMIRROR | X | ¾ | ¾ | ¾ | ¾ | X | ¾
DISK UNMIRROR | X | ¾ | ¾ | ¾ | ¾ | X | ¾
DROP any object | ¾ | ¾ | X | ¾ | ¾ | X | ¾
DUMP DATABASE | ¾ | X | ¾ | ¾ | X | ¾ | ¾
DUMP TRANSACTION | ¾ | X | ¾ | ¾ | X | ¾ | ¾
EXECUTE (5) | ¾ | ¾ | X | ¾ | X | ¾ | ¾
GRANT | ¾ | X | ¾ | ¾ | ¾ | X | ¾
GRANT on object | ¾ | ¾ | X | ¾ | ¾ | X | ¾
INSERT | ¾ | ¾ | X | ¾ | X | ¾ | ¾
KILL | X | ¾ | ¾ | ¾ | ¾ | X | ¾
LOAD DATABASE | ¾ | X | ¾ | ¾ | ¾ | X | ¾
LOAD TRANSACTION | ¾ | X | ¾ | ¾ | ¾ | X | ¾
PRINT | ¾ | ¾ | ¾ | X | ¾ | ¾ | X
RAISERROR | ¾ | ¾ | ¾ | X | ¾ | ¾ | X
READTEXT | ¾ | ¾ | X | ¾ | (6) | ¾ | ¾
RECONFIGURE | X | ¾ | ¾ | ¾ | ¾ | X | ¾
REFERENCES | ¾ | ¾ | X | ¾ | X | ¾ | ¾
REVOKE | ¾ | X | ¾ | ¾ | ¾ | X | ¾
REVOKE on object | ¾ | ¾ | X | ¾ | ¾ | X | ¾
ROLLBACK TRANSACTION | ¾ | ¾ | ¾ | X | ¾ | ¾ | X
SAVE TRANSACTION | ¾ | ¾ | ¾ | X | ¾ | ¾ | X
SELECT | ¾ | ¾ | X | ¾ | X | ¾ | ¾
SET | ¾ | ¾ | ¾ | X | ¾ | ¾ | X
SETUSER | ¾ | X | ¾ | ¾ | ¾ | X | ¾
SHUTDOWN | X | ¾ | ¾ | ¾ | ¾ | X | ¾
TRUNCATE TABLE | ¾ | ¾ | X | ¾ | ¾ | X | ¾
UPDATE | ¾ | ¾ | X | ¾ | X | ¾ | ¾
UPDATE STATISTICS | ¾ | ¾ | X | ¾ | ¾ | X | ¾
UPDATETEXT | ¾ | ¾ | X | ¾ | (7) | ¾ | ¾
WRITETEXT | ¾ | ¾ | X | ¾ | (7) | ¾ | ¾
(1) Transferred with CREATE DATABASE permission.
(2) Public can create temporary tables; no permission required.
(3) Defaults to the table owner.
(4) For the list of all DBCC statement permissions see the DBCC statement.
(5) Defaults to stored-procedure owner.
(6) Transferred with SELECT permission.
(7) Transferred with UPDATE permission.

Examples

A. Grant "Statement" Permissions

This example shows how to grant multiple statement permissions to multiple users.

GRANT CREATE DATABASE, CREATE TABLE
TO Mary, John
B. Grant "Object" Permissions/Permission Hierarchy

This example shows preferred ordering of permissions. First, SELECT permissions are given to the group public. After this, specific permissions are given to a few users. These users (Mary, John, and Tom) then have all permissions to the authors table.

GRANT SELECT
ON authors
TO public
go
GRANT INSERT, UPDATE, DELETE
ON authors
TO Mary, John, Tom

See Also

REVOKE | sp_changegroup
SETUSER | sp_dropgroup
sp_addgroup | sp_dropuser
sp_addlogin | sp_helpgroup
sp_adduser | sp_helprotect
sp_changedbowner | sp_helpuser


Identifiers

Identifiers define the naming convention used by SQL Server for server names; database names; and database objects such as tables, views, columns, indexes, triggers, procedures, defaults, rules, and so on.

Rules for Identifiers

Identifiers can contain from 1 to 30 characters, including letters, symbols, and numbers. Identifiers have the following requirements:

  • The first character of the identifier must be a letter or the symbols _ ,@ , #. The symbols @ and # have special meaning:
    • An identifier beginning with @ signifies a local variable.
    • An identifier beginning with # signifies a temporary object name. For a table or stored procedure, a single pound sign (#) signifies a local temporary object; a double pound sign (##) signifies a global temporary object. Names for temporary objects should not exceed 13 characters, including the # or ##, because SQL Server gives them an internal numeric suffix. For more information on creating these temporary objects, see the CREATE PROCEDURE and CREATE TABLE statements.
  • Characters following the first character can include letters, digits, or the symbols #, $, or _.
  • By default, no embedded spaces are allowed in identifiers; however, by using quoted identifiers, spaces and other special identifiers can be defined. For the rules and restrictions on quoted identifiers, see "Quoted Identifiers," later in this topic.

Identifiers as Object Names

Object names need not be unique in a database. However, column names and index names must be unique within a table or a view, and other object names must be unique for each owner within a database. Database names must be unique on SQL Server. You can uniquely identify a table or column by fully qualifying it¾the database name, the owner's name, and (for a column) the table or view name. Each of these qualifiers is separated from the next by a period:

[[database.]owner.]table_name
[[database.]owner.]view_name

The database and owner names are optional. The default value for owner is the current user; the default value for database is the current database.

Intermediate elements in a name can be omitted and their positions indicated by periods, as long as the system is given enough information to identify the object:

database..table_name
database..view_name

In the case of remote stored procedures, a procedure is qualified as follows:

server.database.owner.procedure

For example:

remotesvr.pubs.dbo.sp_who

Object Visibility (and Qualification) Rules

If you reference an object without qualifying it with the database name and owner name, SQL Server tries to find the object in the current database among the objects you own. If you don't own an object by that name, SQL Server looks for objects of that name owned by the database owner (qualified by database..obj_name). You need not use the database name to reference your objects in the current database. You must qualify objects owned by the database owner only if you own an object by the same name but want to use the object owned by the database owner. You must qualify objects owned by other users with the user's name.

The visibility for a stored procedure that begins with sp_ differ from regular procedures. For information, see the CREATE PROCEDURE statement.


Quoted Identifiers

Support for quoted identifiers has been added to SQL Server 6.0. According to ANSI syntax, use double quotation marks (") to delimit keywords (quoted identifiers), and use single quotation marks (') to delimit string constants. This resolves the conflict with quoted identifiers and string constants during expression evaluation at the parser level. This is included to provide ANSI compatibility for delimited identifiers. Additionally, although not recommended, keywords specified within double quotation marks can now be used as object names. If object names are desired using keywords, reserved words, database technology terms, or names that could cause conflict with future keywords, first attempt to resolve possible conflicts by choosing another word for the object name. When this is not possible, use quoted identifiers.

Quoted identifiers contain as many as 30 characters. The delimited string can contain any combination of characters represented by the current code page, except double quotation marks.

To enforce or remove quoted identifier and string constant resolution at the session level, use the SET statement. This causes the current session to differentiate between single and double quotation marks when evaluating an expression. When QUOTED_IDENTIFIER is turned ON, strings in double quotation marks (") will not be evaluated or checked against keywords.

When you use keywords for object names or portions of object names, the QUOTED_IDENTIFIER option must be set when creating that object, as well as when accessing that object.

Note If an object name or part of an object name (for example, a column) is created using a keyword when the SET QUOTED_IDENTIFIER option is turned ON, then all subsequent references to that object must be made with the SET QUOTED_IDENTIFIER option ON. In general, it is best to avoid using keywords as object names.

When qualifying a column name and a table name in the same statement, be sure to use the same qualifying expressions for each; they are evaluated as strings and must match or an error is returned.


INSERT Statement

For SQL Server 6.5 information, see INSERT Statement in What's New for SQL Server 6.5.

Adds a new row to a table or a view.

Syntax

INSERT [INTO]
{table_name | view_name} [(column_list)]
{DEFAULT VALUES | values_list | select_statement}

where

INTO
Is an optional keyword.
table_name | view_name =
[[database_name.]owner.]{table_name | view_name}

Specifies the name of the table or view used in the INSERT statement. If the table or view is not in the current database, use a fully qualified table_name or view_name (database_name.owner.object_name).

column_list
Lists one or more columns to which data is to be added. The columns can be listed in any order, but the incoming data (whether in a values_clause or a select_statement) must be in the same order as the columns.

The column_list is necessary only when some, but not all, columns in the table are to receive data. You can leave out items in the column_list and values_clause as long as the omitted columns are defined to allow null values or the columns have an associated default (a default or a DEFAULT constraint).

Enclose the column_list in parentheses. If column_list is not specified, all columns in the receiving table (in CREATE TABLE order) are assumed to be included.

DEFAULT VALUES
Inserts the default values for all columns. If the column has the IDENTITY property or the timestamp datatype, the next appropriate value will be inserted. If a default for the column does not exist and the column allows NULLs, NULL will be inserted. If any column of the table does not have a default or does not allow NULL, an error will be returned and the INSERT statement rejected.
values_list =
VALUES (DEFAULT | constant_expression
[, DEFAULT | constant_expression]...)
VALUES
Is a required keyword used to introduce the list of values for each column in the column_list or table.
DEFAULT
Inserts the default value for that column. For a column defined with the timestamp datatype, the next value will be inserted. If a default does not exist for the column and the column allows NULLs, NULL will be inserted.

DEFAULT is not valid for an identity column. Columns with the IDENTITY property should not be explicitly listed in the column_list or values_clause; the value for an identity column should not be explicitly entered. For more information, see the CREATE TABLE statement.

constant_expression
Contains an expression that will evaluate to a constant. The list of values must be enclosed in parentheses and must match the explicit or implicit columns list. Enclose non-numeric constants in quotation marks.
select_statement
Is a standard SELECT statement used to retrieve the values to be inserted from an existing table. For details, see the SELECT statement.

Remarks

INSERT adds new rows only. To modify column values in existing rows, use UPDATE.

When inserting rows, these rules apply:

  • Inserting an empty string (' ') into a varchar or text column inserts a single space. All char columns are right-padded to the defined length.

    All trailing spaces are removed from data inserted into varchar columns, except in strings that contain only spaces. These strings are truncated to a single space.

  • If an INSERT statement violates a constraint, default, or rule, or if it is the wrong datatype, the statement fails and SQL Server displays an error message.

    Constraints are defined with either the CREATE TABLE or ALTER TABLE statement. Defaults are created with the CREATE DEFAULT statement and rules are created with the CREATE RULE statement.

  • Inserting a null value into a text or image column does not create a valid text pointer, nor does it preallocate a 2K text page. For details on inserting text and image data, see the text and image Manipulation topic.
  • An INSERT statement must follow the rules for a batch. For details, see the Batches topic.

When you specify values for only some of the columns in the column_list, one of three things can happen to the columns that have no values:

  • A default value is entered if the column has a DEFAULT constraint, if a default is bound to the column, or a default is bound to the underlying user-defined datatype.
  • NULL is entered if the column allows NULLs and no default value exists for the column.
  • An error message is displayed and the row is rejected if the column is defined as NOT NULL and no default exists.

Permission

INSERT permission defaults to the table owner, who can transfer it to other users.

Examples

A. INSERT Specifying All Column Values

This example shows an INSERT into the titles table in the pubs database. All column values are specified in the values_clause.

INSERT titles
    VALUES('BU2222', 'Faster!', 'business', '1389',
        NULL, NULL, NULL, NULL, 'ok', '06/17/87')
B. INSERT with Column Titles

This example shows an insert into the titles table in the pubs database. Only the values for the columns listed in the column_list are shown in the values_list.

INSERT titles(title_id, title, type, pub_id, notes, pubdate)
    VALUES ('BU1237', 'Get Going!', 'business', '1389',
        'great', '06/18/86')
C. INSERT with Nested SELECT

This example inserts all rows from the authors table (for authors only in San Francisco) into the newauthors table.

INSERT INTO newauthors
    SELECT *
        FROM authors
            WHERE city = 'San Francisco'
D. INSERT with DEFAULT VALUES

This example shows the use (and failure) of the DEFAULT VALUES option for the INSERT statement.

INSERT publishers DEFAULT VALUES
go
Msg 233, Level 16, State 2
The column pub_id in table publishers may not be null.
E. INSERT with the DEFAULT Keyword

This example shows the use of DEFAULT as a placeholder to insert the DEFAULT value for a column(s).

INSERT employee
    VALUES ('KLT91469F', 'Katrina', 'L', 'Thompson', DEFAULT, DEFAULT,
         DEFAULT, '01/14/95')

See Also

CREATE TABLE statement | sp_bindefault system stored procedure
CREATE TRIGGER statement | sp_bindrule system stored procedure
Datatypes | sp_unbindefault system stored procedure
DELETE statement | sp_unbindrule system stored procedure
SELECT statement | UPDATE statement


Keywords

Keywords consist of words reserved by the server to be used to define, manipulate, and access database objects. Keywords can be used for the names of local variables and for stored procedure parameter names. However, until the addition of quoted identifiers, keywords could not be used for the names of databases or database objects, such as tables, rules, defaults, and so on. Quoted identifiers (also known as double quote delimited strings) enable keywords to be used for the names of databases or database objects.

Even though it is syntactically possible, using keywords as object names (with quoted identifiers), it is not recommended. For details, see the Identifiers topic.

Keywords new for SQL Server 6.0 appear in bold type.

ADD | ALL | ALTER
AND | ANY | AS
ASC | AVG | BEGIN
BETWEEN | BREAK | BROWSE
BULK | BY | CASE
CHECK | CHECKPOINT | CLOSE
CLUSTERED | COALESCE | COMMIT
COMMITTED | COMPUTE | CONFIRM
CONSTRAINT | CONTINUE | CONTROLROW
CONVERT | COUNT | CREATE
CURRENT | CURRENT_DATE | CURRENT_TIME
CURRENT_TIMESTAMP | CURRENT_USER | CURSOR
DATABASE | DBCC | DEALLOCATE
DECLARE | DEFAULT | DELETE
DESC | DISK | DISTINCT
DOUBLE | DROP | DUMMY
DUMP | ELSE | END
ERRLVL | ERROREXIT | EXCEPT
EXEC | EXECUTE | EXISTS
EXIT | FETCH | FILLFACTOR
FLOPPY | FOR | FOREIGN
FROM | GOTO | GRANT
GROUP | HAVING | HOLDLOCK
IDENTITY | IDENTITY_INSERT | IDENTITYCOL
IF | IN | INDEX
INSENSITIVE | INSERT | INTERSECT
INTO | IS | ISOLATION
KEY | KILL | LEVEL
LIKE | LINENO | LOAD
MAX | MIN | MIRROREXIT
NOCHECK | NONCLUSTERED | NOT
NULL | NULLIF | OF
OFF | OFFSETS | ON
ONCE | ONLY | OPEN
OPTION | OR | ORDER
OVER | PERM | PERMANENT
PIPE | PLAN | PRECISION
PREPARE | PRIMARY | PRINT
PROC | PROCEDURE | PROCESSEXIT
PUBLIC | RAISERROR | READ
RECONFIGURE | REFERENCES | REPEATABLE
REPLICATION | RETURN | REVOKE
ROLLBACK | ROWCOUNT | RULE
SAVE | SCROLL | SELECT
SERIALIZABLE | SESSION_USER | SET
SETUSER | SHUTDOWN | SOME
STATISTICS | SUM | SYSTEM_USER
TABLE | TAPE | TEMP
TEMPORARY | TEXTSIZE | THEN
TO | TRAN | TRANSACTION
TRIGGER | TRUNCATE | TSEQUAL
UNCOMMITTED | UNION | UNIQUE
UPDATE | UPDATETEXT | USE
USER | VALUES | VARYING
VIEW | WAITFOR | WHEN
WHERE | WHILE | WITH
WRITETEXT |  |


Reserved Words

Reserved words define possible future keywords that may be added for ANSI compliance and/or new features. Because these words may become keywords, they should not be used for object names. These words are reserved for future use:

ABSOLUTE | ACTION | ALLOCATE
ARE | ASSERTION | AT
AUTHORIZATION | BOTH | CASCADE
CASCADED | CAST | CATALOG
CHAR_LENGTH | CHARACTER | CHARACTER_LENGTH
COLLATE | COLLATION | COLUMN
CONNECT | CONNECTION | CONSTRAINTS
CORRESPONDING | DATE | DAY
DEFERRABLE | DEFERRED | DESCRIBE
DESCRIPTOR | DIAGNOSTICS | DISCONNECT
DOMAIN | END_EXEC | ESCAPE
EXCEPTION | EXPIREDATE | EXTERNAL
EXTRACT | FALSE | FILE
FIRST | FULL | GET
GLOBAL | HOUR | IMMEDIATE
INITIALLY | INNER | INPUT
INTERVAL | JOIN | LAST
LEADING | LEFT | LOCAL
MATCH | MINUTE | MONTH
NAMES | NATIONAL | NATURAL
NCHAR | NEXT | NO
OCTET_LENGTH | OUTER | OUTPUT
OVERLAPS | PAD | PARTIAL
POSITION | PRESERVE | PRIOR
PRIVILEGES | RELATIVE | RESTRICT
RETAINDAYS | RIGHT | ROWS
SCHEMA | SECOND | SESSION
SIZE | SPACE | SQLSTATE
TIME | TIMESTAMP | TIMEZONE_HOUR
TIMEZONE_MINUTE | TRAILING | TRANSLATE
TRANSLATION | TRUE | UNKNOWN
USAGE | USING | VALUE
VOLUME | WORK | WRITE
YEAR | ZONE |

See Also

Identifiers


KILL Statement

Terminates a user's process based on the system process ID.

Syntax

KILL spid

where

spid
Specifies the system process ID (spid) of the process you want to terminate. The spid is a unique integer (smallint) assigned to processes as they occur; no user is permanently assign a spid. When a process is active, it is stored in the sysprocesses system table.

In addition to storing the ID of the process, the sysprocesses table also stores other process information, such as status (runnable, waiting for a lock, sleeping, and so on), the suid (the server login ID of the user who executed the statement), program_name (the "host_name" of the application program ¾ if not explicitly assigned, usually returns the computer name), and so on.

Remarks

Because an spid is assigned only to active processes, you can get a report on the current processes by executing the sp_who system stored procedure.

This is a typical example:

spid   status     loginame hostname  blk   dbname     cmd
------ ---------- -------- --------- ----- ---------- ----------------
1      sleeping   sa                 0     master     MIRROR HANDLER
2      sleeping   sa                 0     master     LAZY WRITER
3      sleeping   sa                 0     master     CHECKPOINT SLEEP
4      sleeping   sa                 0     master     RA MANAGER
10     sleeping   Mary     WKSTA1    0     pubs       AWAITING COMMAND
11     runnable   Joe      WKSTA5    10    pubs       SELECT

The blk column contains the system process ID of a blocking process; if there is one, this value will reference the spid column of this table (self-referencing). A blocking process is one that is holding resources that another process needs. In this example, process 11 (a SELECT on a table) is blocked by process 10 (an uncommitted transaction). Although well-designed transactions should complete quickly and rarely block others, a transaction that does block another transaction can be terminated with the KILL statement.

System processes (MIRROR HANDLER, LAZY WRITER, CHECKPOINT SLEEP, and RA MANAGER) and processes running an extended stored procedure cannot be terminated.

You can get a report on the current locks and each spid of the process holding them by using the sp_lock system stored procedure. The following information is returned when the SA executes sp_lock:

spid   locktype             table_id    page        dbname
------ -------------------- ----------- ----------- ---------------
15     Sh_intent            313052151   0           master
10     Ex_table-blk         16003088    0           pubs

In this example, process 10 has a blocking, exclusive table-lock. Process 15 (the process running sp_lock has a shared intent lock on sysprocesses (the table from which this output is retrieved).

Permission

KILL permission defaults to the system administrator and is not transferable.

Example

This example shows how to terminate the system process ID 10.

KILL 10

See Also

SHUTDOWN | sp_who
sp_lock |


LOAD Statement

For SQL Server 6.5 information, see LOAD Statement in What's New for SQL Server 6.5.

Restores a backup copy of a user database and its transaction log (LOAD DATABASE) or only the transaction log (LOAD TRANSACTION) from a dump that was created using the DUMP statement. The LOAD statement can also be used to retrieve header information from a database dump (LOAD HEADERONLY).

Syntax

Loading a database:

LOAD DATABASE {dbname | @dbname_var}
FROM dump_device [, dump_device2 [..., dump_device32]]
[WITH options
[[,] STATS [ = percentage]]]

Loading a transaction log:

LOAD TRANSACTION {dbname | @dbname_var}
FROM dump_device [, dump_device2 [..., dump_device32]]
[WITH options]

Loading header information:

LOAD HEADERONLY
FROM dump_device

where

dump_device =
{ dump_device_name | @dump_device_namevar}
| {DISK | TAPE | FLOPPY | PIPE} =
{'temp_dump_device' | @temp_dump_device_var}}
[VOLUME = {volid | @volid_var}]
options =
[[,] {UNLOAD | NOUNLOAD}]
[[,] {SKIP | NOSKIP}]
[[,] {FILE = fileno}]
DATABASE
Specifies that the complete database and transaction log are to be restored.
TRANSACTION
Specifies that only the transaction log is to be applied to this database. Transaction logs must be applied in sequential order. SQL Server checks the timestamps on the dumped transaction log to make sure that the transactions are being loaded into the correct database and in the correct sequence.
HEADERONLY
Retrieves all the volume and dump header information for all dumps on a particular dump device. For details about the header information returned, see "Volume and Header Information," later in this topic.
dbname | @dbname_var
Specifies the database from which the transaction log or complete database is being dumped. This name can be specified as a string or as a char or varchar variable.
dump_device_name | @dump_device_namevar
Is the logical name of the dump device as created by sp_addumpdevice. The dump device name can be specified as a string or as a char or varchar variable.
fileno
Is the specific file number to be loaded from the tape or disk device that contains multiple database dumps. The default is 1; load the first dump on the device.
{DISK | TAPE | FLOPPY | PIPE} =
'temp_dump_device' | @temp_dump_device_var

Allows backups to be loaded directly from temporary dump devices. These devices must already exist when the load occurs; they do not have entries in sysdevices. The device types of DISK, TAPE, and FLOPPY should be specified with the actual address (for example, complete path and filename) of the device. A device type of PIPE should specify the name of the named pipe that will be used by the client application. If specified as a variable (@temp_dump_dev_var), the device name can be specified as a string or as a char or varchar variable. If you are using either a network server with a UNC name or a redirected drive letter, specify a device type of DISK.

Important When specifying a striped dump, you can use both logical device names (or variables) and temporary device names (or variables). PIPE devices have been added to allow third-party vendors a flexible and powerful way to connect their own software. For typical Transact-SQL use, the PIPE device will not be used.

VOLUME = volid | @volid_var
Specifies the volume ID, volid, a 6-byte character string. If dumping to a new tape, this value is the name of the ANSI VOL1 label. For SQL Server, the default is SQ0001. For subsequent dumps, this value is used to validate the volume name of the dump device. If specified as a variable (@volid_var), the volume name can be specified as a string or as a char or varchar variable. It is not necessary, or recommended, to explicitly specify the volume ID.
UNLOAD
Specifies that the tape is automatically rewound and unloaded when the dump is finished. UNLOAD is set by default when a new user session is started. It remains set until that user specifies NOUNLOAD. This option is used only for tape devices.
NOUNLOAD
Specifies that the tape will not be unloaded automatically from the tape drive after a dump. NOUNLOAD remains set until UNLOAD is specified. This option is used only for tape devices.
SKIP
Instructs the server not to read the ANSI TAPE device headers.
NOSKIP
Specifies that the server will read ANSI TAPE device headers. This is the default.
STATS = percentage
Returns the percentage of pages loaded in increments optionally set at the time of the load. If the percentage is not specified the statistics will be shown for each 10 percent of the load. This option is available only for database loads.

Remarks

During the load, the specified database must not be in use. Any data in the specified database is replaced by the loaded data.

You can use LOAD DATABASE to move a database to another device or another server as long as the same code page and sort order are running on both servers. If the code page or sort order differs, use the SQL Transfer Manager to move the data. If the sort order and code page are the same, the recipient database must be as large as, or larger than, the database to be loaded. If the recipient database is too small, SQL Server displays an error message that gives the required size. The device fragments that the new database uses for data and for the log must appear in the same order and have the same amount of space as the fragments in the original database. For example, if the original database had 10 MB of data (on any number of fragments), followed by 3 MB of log, followed by 6 more MB of space for data, the new database must have the same order by space and usage: that is, 10 MB for data, 3 for log, and 6 (or more) for data. The total size of the destination database must be at least as large and have at least as many fragments (assigned in the same order and have the same uses) as the load.

If the dumped database uses segments to store particular tables or indexes, the new database must include devices of the same size and page order for these segments and their related data in order for LOAD statement to work correctly. Execute the sp_helpdb system stored procedure with the database name to see the size and fragments. Select from the sysusages system table to determine the order of the device fragments. Then re-execute the CREATE DATABASE statement and the ALTER DATABASE statement to re-establish the fragments. For details on using the LOAD statement to restore or move databases, see the Microsoft SQL Server Administrator's Companion.

If a database will be loaded into a newly created database, use CREATE DATABASE FOR LOAD when creating the new database. The FOR LOAD option specifies that the data pages will not be zero-initialized because the only operations allowed against that database are ALTER DATABASE FOR LOAD or LOAD DATABASE. Any unused data pages will be initialized by the database load. For more information, see the CREATE DATABASE statement.

For compatibility, user database dumps from SQL Server 4.2x can be loaded into SQL Server 6.0, as long as the same sort order is running on both SQL Servers. The user database dump (the master database is not allowed to be loaded or upgraded from SQL Server 4.2x dumps) must be a full database dump, not a transaction log dump, and the dump must occur when there is no update activity taking place in the database. For this reason, it is recommended that the dump occur when SQL Server is started in single-user mode. After the database is successfully loaded, the database will be upgraded. For more information about database upgrades and potential compatibility issues, see Microsoft SQL Server Setup.

Important Cross-platform dumping and loading is not supported. For example, a database dumped on a MIPS-based computer cannot be loaded into an Intel-based computer. If you need to move data from one platform to another, use the Microsoft SQL Transfer Manager.

Permission

LOAD DATABASE and LOAD TRANSACTION permission default to the database owner and are not transferable.


Loading the master database

Loading the master database because it has been damaged is performed using a special procedure. For details about restoring the master database, see the Microsoft SQL Server Administrator's Companion.


Loading from a Diskette Device

When you execute LOAD statement to restore from diskette, the console command-line utility must be used to prompt the user and then waits for responses. If console is not running or if the user does not answer its questions, the load cannot proceed.


Volume and Header Information

Using LOAD HEADERONLY, any client can retrieve all the volume and dump header information for all dumps on a particular dump device. The header information is sent as a row by the server for each dump on a given dump device in a table with following columns:

Option | Datatype | Possible information
Dumptype | smallint | Database(1) or Transaction(2)
Database | varchar(30) | Database name
Striped | smallint | Striped dump(1), non-striped dump(0)
Compressed | smallint | Compressed(1), uncompressed(0)
Sequence | varchar(6) | Position of the dump in the volume
Volume | varchar(6) | Volume ID
Devicetype | smallint | Disk(2), Floppy(3), Tape(5) or Pipe(6)
Table | varchar(30) | Reserved for future use
Dumpsize | varchar(15) | Size of dump, in pages
Stripeset | varchar(2) | Number of devices in the stripeset
Stripesetname | varchar(30) | Stripeset ID, for future use
Curseq | char(13) | Current/old sequence number
Newseq | char(13) | New sequence number
CreationDate | char(15) | Creation date (Shortmonth DD, YY)
CreationTime | char(15) | Creation time (HH:MM)
ExpireDate | char(15) | Expiration date for the volume (Shortmonth DD, YY)

Note For any dump, only the appropriate columns will contain a value. All other columns will be NULL.


Null Values

A null value, or NULL, is not the same as 0 or blank. NULL means no entry has been made and usually implies that the value is either unknown or undefined. NULL allows you to distinguish between a deliberate entry of 0 (for numerical columns) or a blank (for character columns) and an unknown or inapplicable entry (NULL for both numerical and character columns). NULL indicates that the user did not explicitly make an entry or has explicitly entered NULL. For example, a null value in the price column of the titles table of the pubs sample database does not mean that the book is being given away free, it means that the price is not known or has not been set.

Syntax

In CREATE TABLE statements:
column_name datatype [NULL | NOT NULL]

In SELECT statements:
WHERE column_name IS [NOT] NULL

In INSERT statements:
VALUES({constant | DEFAULT | NULL}
[, {constant | DEFAULT | NULL}]...)

In UPDATE statements:
SET column_name = {expression | NULL}
[, column_name = {expression | NULL}...]

The ISNULL built-in function:
ISNULL(expression, value)

where

NULL
Indicates no entry has been made. The value is unknown (not blank or 0). In CREATE TABLE statements, specifying NULL after a column name means that if there is no default for this column, SQL Server assigns a null value whenever the user does not enter data for this column.

A user can enter NULL explicitly in an INSERT or UPDATE statement.

In SELECT statements, use IS [NOT] NULL to retrieve null values.

NOT NULL
Can also be used in a WHERE clause in any statement to retrieve all values except those that are NULL.

Remarks

If the user fails to make an entry in a column that allows null values, SQL Server supplies the value NULL (unless a default exists). A column defined with the keyword NULL also accepts an explicit entry of NULL from the user, no matter what datatype it is or if it has a default associated with it. Be careful when you enter NULL in character columns. If you put the value NULL inside single quotation marks ('NULL'), SQL Server interprets the entry as a character string rather than as the null value.

If an attempt to insert NULL is made against a column defined as NOT NULL, only the statement (INSERT or UPDATE) will be terminated. Any other statements within the batch will continue. In earlier releases of SQL Server, the entire batch was rejected at compile time. Although not recommended, the previous behavior of SQL Server (stopping the processing of the entire batch and rolling back any transactions) can be turned on with trace flag 243. For details, see the Trace Flags topic.

Defining columns as NULL provides a place holder for data you might not yet know. For example, in the titles table, price, advance, royalty, and ytd_sales are set up to allow null values. However, title_id and title do not allow null values because the lack of an entry in these columns would make the row meaningless and confusing. A price without a title makes no sense, but a title without a price simply means that the price is not available. When you create a table, define columns as NOT NULL when the information in the column is critical to the meaning of the other columns. When inserting data, the DEFAULT keyword can be used (for columns defined as allowing null values without a default) to insert NULL into a column. For details and examples, see the INSERT statement.

DEFAULT constraints defined on the table or user-defined defaults can be connected with either NULL or NOT NULL columns. For more information, see the CREATE TABLE statement, the ALTER TABLE statement, and the CREATE DEFAULT statement.

When you create NULL columns with certain datatypes, SQL Server automatically converts them to a different internal datatype to allow the storage of null values. SQL Server does not inform the user of the datatype change, and the user should be concerned about it only if querying the system tables.

Datatype | Converted to datatype
binary | varbinary
char | varchar
datetime | datetimn
decimal | decimaln
float | floatn
int | intn
money | moneyn
numeric | numericn
real | floatn
smalldatetime | datetimn
smallint | intn
smallmoney | moneyn
tinyint | intn

A column definition that allows null values inserts NULL even when the rule does not explicitly specify NULL. For example, a rule defined on a column that allows null values and that states the values should be greater than 2 (@variable > 2) will insert NULL when no value is entered for the column.

An expression with an arithmetic or bitwise operator evaluates to NULL if any of the operands is null. For example, 1 + column1 evaluates to NULL if column1 is NULL.

An expression with a comparison operator evaluates to false if any of the operands is NULL. This means that null values never match another value (not even another NULL) when used with a comparison operator. For example, WHERE column1 = column2 will evaluate to false when column1 is NULL, when column2 is NULL, and when column1 and column2 are both NULL. Use IS [NOT] NULL to find null values in queries (when the columns being searched are defined as allowing null values); do not use = NULL. Use the ISNULL system function to replace null values in an expression with another value (if desired). If you try to find null values in columns defined as NOT NULL, SQL Server generates an error message.

The result of an expression with a nested subquery that returns no rows is NULL. For more information on null values in a subquery, see the Subqueries topic. The default result of a divide-by-zero action is to return NULL, return a message, and continue processing the batch. To change how the session handles divide-by-zero, see the SET statement.

Aggregate functions ignore null values, except COUNT(*), which includes them. For example, in the calculation AVG(advance), null values in the advance column are not counted, either in calculating the total amount or the number of values.

The aggregate functions MIN, MAX, SUM, and AVG return NULL if the parameter specified for them is an empty set (that is, no rows satisfy the WHERE clause).

NULLs are considered to be duplicates only in the case of a GROUP BY clause, ORDER BY clause, or when using the DISTINCT keyword and come first in the ORDER BY clause.

Null values are never joined or referenced (in the case of a FOREIGN KEY constraint), not even to other null values.

The empty string (' ') or (" ") is always stored as a single space in variables and column data. 'abc' ' ' 'def' is equivalent to 'abc def', but not to 'abcdef'. The empty string is never evaluated as NULL.

If you have two tables identical in structure except that one has NULL fields and some null values, and the other has NOT NULL fields, this difference makes it impossible to use SELECT to insert the data from the table with columns that allow null values into the table with columns that do not allow null values. If any of the data is NULL, you cannot update a field that does not allow NULLs by selecting from a field that allows NULLs.

If you specify NOT NULL when you create a column and do not create a default for it, an error message occurs whenever a user fails to make an entry in that column. In addition, the user cannot insert or update such a column with NULL as a value. The following table illustrates the relationship between the existence of a default (created as a default constraint or as a default) and the definition of a column as NULL or NOT NULL:

Column definition | No entry, no DEFAULT | No entry, DEFAULT | Enter NULL, no DEFAULT | Enter NULL, DEFAULT
NULL | NULL | default | NULL | NULL
NOT NULL | error | default | error | error

The sp_help system stored procedure reports on a column's nullability (whether or not the column accepts null values).

A column of the text or image datatype, when inserted with a null value, does not initialize a text pointer or contain a value. When a null value is written in a text or image column with the UPDATE statement, the column is initialized, a valid text pointer to the column is inserted into the table, and a 2K data page is allocated to the column. Once the column is initialized, it can be accessed by the READTEXT statement and the WRITETEXT statement. For more information, see the Datatypes topic and the text and image Manipulation topic.

Examples

A. NULL Values with INSERT

The table created in this example shows two columns. The first will allow null values and the second will not. Because column t1 of table test is defined as accepting NULL in the CREATE TABLE statement, the three INSERT statements that follow are equivalent. The user can explicitly insert NULL, use the DEFAULT keyword, or allow the system to insert NULL. NULL is inserted in the t1 column whenever the user inserts rows but does not specify a value for the column.

CREATE TABLE test
(
    t1 char(10) NULL,
    t2 char(10) NOT NULL
)
INSERT test VALUES(NULL, 'Stuff')
INSERT test VALUES(DEFAULT, 'Stuff')
INSERT test(t2) VALUES ('Stuff')
B. NULL Values with SELECT

The SELECT statement retrieves all rows from test and displays null values in column t1 with the value unknown.

SELECT Col1 = ISNULL(t1, 'unknown'), Col2 = t2
    FROM test
go

Col1       Col2
---------- ----------
unknown    Stuff
unknown    Stuff

(2 row(s) affected)
C. NULL Values with UPDATE

This update uses NULL to define the value for the advance column in the titles table. Notice that quotation marks are not used when specifying NULL.

UPDATE titles
    SET advance = NULL
    WHERE title_id = 'TC3218'
D. NULL Values in a WHERE Clause
SELECT title_id, advance
    FROM titles
    WHERE advance < $5000 OR advance IS NULL
go

title_id advance
-------- --------------------------
MC2222   0.00
MC3026   NULL
PC9999   NULL
PS2091   2,275.00
PS3333   2,000.00
PS7777   4,000.00
TC3218   NULL
TC4203   4,000.00

(8 row(s) affected)

See Also

Aggregate Functions | SELECT statement
CREATE PROCEDURE statement | sp_help
CREATE TABLE | Subqueries
Expressions | Text and Image Functions
INSERT | UPDATE
Search Conditions |


Operators

Operators are symbols used to perform mathematical computations and/or comparisons between columns or variables. Comparisons can be made between like datatypes without any conversion, implicit conversion, or if necessary, explicit conversion. When comparisons are made between implicitly converted datatypes, the result will have the greater precision, the larger scale, and/or the larger/longer datatype. Operators can be combined and used in search conditions (within a WHERE clause or a HAVING clause). For more information, see the Search Conditions topic.

This section explains Arithmetic Operators, Bitwise Operators, Comparison Operators, Join Operators and concludes with an overview of Operator Precedence.


Arithmetic Operators

Arithmetic operators perform mathematical operations within Transact-SQL statements.

These are the arithmetic operators:

Symbol | Meaning | Can be used with
+ | Addition | int, smallint, tinyint, numeric, decimal, float, real, money, and smallmoney
- | Subtraction | int, smallint, tinyint, numeric, decimal, float, real, money, and smallmoney
* | Multiplication | int, smallint, tinyint, numeric, decimal, float, real, money, and smallmoney
/ | Division | int, smallint, tinyint, numeric, decimal, float, real, money, and smallmoney
% | Modulo* | int, smallint, and tinyint
* A modulo is the integer remainder after a division involving two integers. For example, 21 % 9 = 3 because 21 divided by 9 equals 2 with a remainder of 3.


Bitwise Operators

Bitwise operators perform mathematical operations between integer values as translated to binary expressions within Transact-SQL statements. All the bitwise operators translate the integer parameters into binary representation before evaluating them.

These are the bitwise operators:

Symbol | Meaning | Can be used on
& | Bitwise AND (two operands) | int, smallint, or tinyint columns only
| | Bitwise OR (two operands) | int, smallint, or tinyint columns only
^ | Bitwise exclusive OR (two operands) | int, smallint, or tinyint columns only
~ | Bitwise NOT (one operand) | int, smallint, tinyint, or bit columns only

The bitwise operators that require two operands (&, |, and ^) can be used on columns with these datatypes:

Left operand | Right operand
int | int, smallint, tinyint, binary, or varbinary
smallint | int, smallint, tinyint, binary, or varbinary
tinyint | int, smallint, tinyint, binary, or varbinary
varbinary | int, smallint, or tinyint
bit | int, smallint, tinyint, or bit
float (and real) | none
binary | int, smallint, or tinyint


Comparison Operators

Comparison operators contrast a specific difference between two expressions. Comparisons must only be made between variables, columns, and so on, of similar type.

These are the comparison operators:

Symbol | Meaning
= | Equal to
> | Greater than
< | Less than
>= | Greater than or equal to
<= | Less than or equal to
< > | Not equal to
!= | Not equal to (not ANSI standard)
!> | Not greater than (not ANSI standard)
!< | Not less than (not ANSI standard)

In comparing char and varchar data, < means closer to the beginning of the alphabet and > means closer to the end of the alphabet. In the ASCII collating sequence, lowercase letters are greater than uppercase letters, and uppercase letters are greater than numbers. However, case and special-character evaluations depend on the sorting sequence chosen when SQL Server was installed. For details about sorting sequence, see the Microsoft SQL Server Setup.

In comparing dates, < means earlier and > means later. Place quotation marks around all character and datetime data used with a comparison operator.


Outer Join Operators

New join operators are available in SQL Server 6.5. Because future versions of SQL Server may discontinue support for the "*=" and "=*" outer join operators, it is recommended that you use the ANSI-standard join clauses (LEFT OUTER JOIN, RIGHT OUTER JOIN, and FULL OUTER JOIN) instead. For SQL Server 6.5 information, see Joins and Select Statement in What's New for SQL Server 6.5.

Join operators compare two or more tables (or views) by specifying a column from each, comparing the values in those columns row by row, and concatenating rows in which the comparison is true. Comparisons must only be made between variables, columns, and so on, of similar type.

These are the join operators:

Symbol | Meaning
*= | Include in the results all rows from the first table that meet the statement's restrictions. The second table returns values if there is a match on the join condition. Otherwise, the second table generates null values.
=* | Include in the results all rows from the second table that meet the statement's restrictions. The first table returns values if there is a match on the join condition. Otherwise, the first table generates null values.

Remarks

Joins that preserve all rows from a table in the results set, regardless of whether there is a matching row in the table to which they're being joined (*= and =*), are called outer joins.

Since bit columns do not permit null values, a value of 0 appears in an outer join when there is no match for a bit column in the inner table. Joins cannot be used for columns containing text or image values.

Null values in tables or views being joined will never match each other.

Joins can also be stated as subqueries. For details, see the Subqueries topic.


String Operator

The string operator allows string concatenation with the symbol. All other string manipulation is handled through String functions. For details, see the Functions topic.

By default, the empty string (' ') is interpreted as a single blank in INSERT or assignment statements on varchar data. In concatenating varchar, char, or text data, the empty string is interpreted as a single space. For example, 'abc' + ' ' + 'def' is stored as 'abc def'. The empty string is never evaluated as NULL.


Operator Precedence

When multiple operators are combined, operator precedence becomes an issue. Operator precedence determines which computations or comparisons are performed first. Often, the order can make a significant difference in the resulting value.

Operators have the following precedence levels:

  • Primary grouping: ( )
  • Bitwise: ~
  • Multiplicative: * / %
  • Additive: -
  • Bitwise: ^
  • Bitwise: &
  • Bitwise: |
  • NOT
  • AND
  • OR

When all operators in an expression are of the same level, the precedence order is left to right. You can change the order of execution with parentheses (primary grouping); the most deeply nested expression is evaluated first.


PRINT Statement

Returns a user-defined message to the client's message handler.

Syntax

PRINT {'any ASCII text' | @local_variable | @@global_variable}

Remarks

The message can have as many as 255 characters.

The local variable must be of type char or varchar and must be declared within the batch or procedure in which it is used.

The global variable must be of type char or varchar or automatically convertible to those types, such as @@VERSION. Currently, @@VERSION is the only character-type global variable.

You can generate a "formatted" message with more than one parameter by using the concatenation operator.

To print a user-defined error message and have the error number stored in @@ERROR, use RAISERROR instead of PRINT.

Examples

A. Conditionally Executed Print (IF EXISTS)
IF EXISTS (SELECT zip
                FROM authors
                    WHERE zip = '94705')
PRINT 'Berkeley author'
B. Build and Display a String

This example defines a local variable (@returnmessage) and then builds the string (combining functions and strings) for display.

DECLARE @returnmessage        varchar(255)
SELECT @returnmessage = 'This record was updated on ' +
                RTRIM(CONVERT(char(30), GETDATE())) + '.'
PRINT @returnmessage

See Also

DECLARE | Variables
RAISERROR |


RAISERROR Statement

For SQL Server 6.5 information, see RAISERROR Statement in the What's New for SQL Server 6.5.

Returns a user-defined error message and sets a system flag to record that an error has occurred. RAISERROR lets the client retrieve an entry from the sysmessages table or build a message dynamically with user-specified severity and state information. Once defined, this message is sent back to the client as a server error message.

The RAISERROR statement has been updated in SQL Server 6.0. The earlier syntax structure is supported for compatibility.

Syntax

RAISERROR ({msg_id | msg_str}, severity, state
[, argument1 [, argument2]] )
[WITH LOG]

where

msg_id
Is a user-defined error message stored in the sysmessages table. To add user-defined error messages, use sp_addmessage system stored procedure. To delete user-defined error messages, use sp_dropmessage system stored procedure. If a sysmessages error is used and the message was created using the format shown for msg_str, then supplied arguments (argument1, argument2, and so on) will be passed to the message of the supplied msg_id. Error numbers for user-defined error messages should be greater than 50,000. Ad hoc messages will raise an error of 50,000. The maximum value is 2,147,483,647 (2 (31) - 1).

When an error is raised, the error number is placed in the global variable @@ERROR, which stores the error number most recently generated by the system.

msg_str
Is an ad hoc message with formatting similar to the C PRINTF format style. The error message can have as many as 255 characters. All ad hoc messages will have one standard message ID of 14000.

The following format is supported for msg_str:

% [[flag] [width] [precision] [{h | l}]] type

where

flag
Determines the spacing and justification.
Code | Prefix or Justification | Meaning
- (minus) | Left-justified | Left-justify the result within the given field width.
(plus) | (plus) or - (minus) prefix | Preface the output value with a sign (+ or -) if the output value is of signed type.
0 (zero) | Zero padding | If width is prefaced with 0, zeros are added until the minimum width is reached. If 0 and - appear, 0 is ignored. If 0 is specified with an integer format (i, u, x, X, o, d), 0 is ignored.
# (number) | 0x prefix for hexadecimal type of x or X | When used with the o, x, or X format, the # flag prefaces any nonzero value with 0, 0x, or 0X, respectively. When d, i, or u are prefaced by the # flag, the flag is ignored.
' ' (blank) | Space padding | Preface the output value with blank spaces if the value is signed and positive. This will be ignored if included with the + flag.

width
Defines the minimum width. An asterisk (*) allows the following argument to determine the width.
precision
Specifies the maximum number of characters printed for the output field or the minimum number of digits printed for integer values. An asterisk (*) allows the argument to determine the precision.
{h | 1} type
Used with types d, i, o, x, X, or u, creates short int (h) or long int values (l).
Type | Represents
d or i | Signed integer
o | Unsigned octal
p | Pointer
s | String
u | Unsigned integer
x or X | Unsigned hexadecimal

Note that float, double-, and single-character types are not supported.

severity
Represents the user-defined severity level associated with this message. Severity levels from 0 through 18 can be used by any user. For severity levels 19 through 25, the WITH LOG option is required. Only the system administrator can issue RAISERROR with a severity level of 19 through 25. For a list of SQL Server error severity levels, see the Microsoft SQL Server Administrator's Companion

Caution For a severity of 19 through 25, which are considered "fatal," the client connection will be terminated after receiving the message and the error will be logged in the error log and the event log.

state
Is an integer value from 1 through 127 that represents information about the invocation state of the error. A negative value for state will default to 1.
argument
Defines the parameters used in the substitution for variables defined in the msg_str or the message corresponding to the msg_id. There can be zero or more substitution parameters; however, the total number of substitution parameters cannot exceed 20. Each substitution parameter can be a local variable or any of these datatypes: int1, int2, int4, char, varchar, binary, or varbinary. No other datatypes are supported.
WITH LOG
Logs the error in the server error log and the event log. This option is required for messages with a severity of 19 through 25, and it can be issued only by the system administrator. The xp_eventlog extended stored procedure provides similar functionality.

Examples

A. Ad Hoc Messages

This example shows two errors that can be raised. The first is a simple error with a static message. The second error is dynamically built based on the attempted modification.

CREATE TRIGGER employee_insupd
ON employee
FOR INSERT, UPDATE
AS
/* Get the range of level for this job type from the jobs table. */
DECLARE @min_lvl tinyint,
    @max_lvl tinyint,
    @emp_lvl tinyint,
    @job_id smallint
SELECT @min_lvl = min_lvl,
    @max_lvl = max_lvl,
    @emp_lvl = i.job_lvl,
    @job_id = i.job_id
FROM employee e, jobs j, inserted i
WHERE e.emp_id = i.emp_id AND i.job_id = j.job_id
IF (@job_id = 1) and (@emp_lvl <> 10)
BEGIN
    RAISERROR ('Job id 1 expects the default level of 10.',16,-1)
    ROLLBACK TRANSACTION
END
ELSE
IF NOT (@emp_lvl BETWEEN @min_lvl AND @max_lvl)
BEGIN
    RAISERROR ('The level for job_id:%d should be between %d and %d.',
        16, -1, @job_id, @min_lvl, @max_lvl)
    ROLLBACK TRANSACTION
END
B. Messages Raised from sysmessages

This example shows how the employee_insupd trigger could achieve the same results using parameters passed to a message stored in the sysmessages table. The message was added to the sysmessages table with the sp_addmessage system stored procedure as message number 50005.

RAISERROR (50005, 16, -1, @@job_id, @@min_lvl, @@max_lvl)

See Also

DECLARE | sp_dropmessage
PRINT | Variables
sp_addmessage | xp_logevent


RECONFIGURE Statement

Installs a changed configuration option used only with the sp_configure system stored procedure.

Syntax

RECONFIGURE [WITH OVERRIDE]

where

WITH OVERRIDE
Instructs SQL Server to accept the values for system variables supplied by the user (with the sp_configure stored procedure). If the user supplies values that SQL Server cannot accept, an error message telling the user to re-execute sp_configure is displayed.

The WITH OVERRIDE clause must always be used when the system administrator sets the allow updates option to 1.

Note Never use the RECONFIGURE statement to change the default sort order of SQL Server.

See Also

sp_configure System Stored Procedure


REVOKE Statement

For SQL Server 6.5 information, see REVOKE Statement in What's New for SQL Server 6.5.

Revokes object and statement permissions from users.

Syntax

Statement permissions:

REVOKE {ALL | statement_list}
FROM {PUBLIC | name_list}

Object permissions:

REVOKE {ALL | permission_list}
ON {table_name [(column_list)] | view_name [(column_list)] |
stored_procedure_name | extended_stored_procedure_name}
FROM {PUBLIC | name_list}

where

ALL
Specifies that all permissions applicable to the specified object are revoked when used to revoke object permissions. When used to revoke statement permissions specifies that all statement permissions are revoked. (CREATE DATABASE permission can be granted only by the system administrator.)
statement_list
Lists granted statements. The statement list can include CREATE DATABASE (which can be granted only by the system administrator), CREATE DEFAULT, CREATE PROCEDURE, CREATE RULE, CREATE TABLE, CREATE VIEW, DUMP DATABASE, and DUMP TRANSACTION. If more than one statement is listed, separate them with commas.
PUBLIC
Represents all users, including those who are members of other groups.
name_list
Lists usernames and/or group names, separated by commas.
permission_list
Lists granted permissions. When permissions are revoked on a table or a view, the permission list can include SELECT, INSERT, DELETE, UPDATE, and/or REFERENCES. When permissions are revoked on columns, the permission list can include SELECT and/or UPDATE. When permissions are revoked on stored procedures, the permission list can include only EXECUTE. If more than one permission is listed, separate them with commas.
table_name
Is the name of the table in the current database to which the permissions apply.
column_list
Lists names of columns, separated by commas, to which the permissions apply. If columns are specified, only SELECT and UPDATE permissions can be granted.
view_name
Is the name of the view in the current database to which the permissions apply.
stored_procedure_name
Is the name of the stored procedure in the current database to which the permissions apply.
extended_stored_procedure_name
Is the name of an extended stored procedure in the current database to which the permissions apply.

Remarks

When permissions are given, information is stored within the sysprotects database table. The sysprotects table manages permissions by updating rows based on each GRANT and REVOKE statement. You can grant or revoke permissions only on objects in the current database.

If permissions are granted to the group public, those permissions will override any previous permissions given to any other user or group of that database. When permissions are given (or revoked), the permissions are order-sensitive. (The statement executed most recently is the one that takes effect.) This can produce undesired results if care is not taken when granting/revoking permissions. For best results, grant/revoke permissions to the least-selective group first (usually public), and then grant/revoke permissions on a group-by-group basis, and then on an individual-by-individual basis, and then to/from the guest user.

The sp_helprotect system stored procedure reports permissions on a database object or on a user. For details, see the sp_helprotect system stored procedure.

Example

This example shows how to revoke multiple statement permissions from multiple users.

REVOKE CREATE TABLE, CREATE DEFAULT
FROM Mary, John

See Also

GRANT | sp_dropgroup
SETUSER | sp_dropuser
sp_addgroup | sp_helpgroup
sp_adduser | sp_helprotect
sp_changedbowner | sp_helpuser
sp_changegroup |


Search Conditions

Set the conditions for data retrieval or modification. Search conditions immediately follow the keyword WHERE in a SELECT, INSERT, UPDATE, or DELETE statement or follow the keyword HAVING in a SELECT statement. If you use more than one of the search conditions in a single statement, connect the conditions with AND or OR. Joins and subqueries can be specified in the search conditions.

Syntax

{WHERE | HAVING} [NOT] Boolean_expression
{WHERE | HAVING} [NOT] Boolean_expression {AND | OR} Boolean_expression
{WHERE | HAVING} [NOT] column_name IS [NOT] NULL
{WHERE | HAVING} [NOT] column_name join_operator column_name
{WHERE | HAVING} [NOT] column_name [NOT] LIKE 'match_string'
{WHERE | HAVING} [NOT] EXISTS (subquery)
{WHERE | HAVING} [NOT] expression comparison_operator expression
{WHERE | HAVING} [NOT] expression [NOT] BETWEEN expression AND expression
{WHERE | HAVING} [NOT] expression [NOT] IN (value_list | subquery)
{WHERE | HAVING} [NOT] expression comparison_operator {ANY | ALL} (subquery)
{WHERE CURRENT OF cursor_name}

where

Boolean_expression
Is an expression that returns TRUE or FALSE. Boolean_expressions have the following format:

expression comparison_operator [ANY | ALL] (subquery)
expression [NOT] IN expression
[NOT] EXISTS expression
expression [NOT] BETWEEN expression AND expression
expression [NOT] LIKE expression
NOT expression LIKE expression
expression IS [NOT] NULL
Boolean_expression {AND | OR} Boolean_expression
[NOT] Boolean_function

where

Boolean_function
Is a function that returns TRUE or FALSE.
expression
Is a column name, a constant, a function, a variable, a subquery, any combination of column names, constants, and functions connected by an operator(s) or a subquery. The expression may also contain the CASE expression. For details, see the CASE Expression, Operators, and the Subqueries topics.
column_name
Is the name of a column used in the comparison. If there is any ambiguity, qualify the column name with its table or view name.
match_string
Is a string of characters and wildcard characters enclosed in quotation marks. For details, see the Wildcard Characters topic.
comparison_operator
Is a symbol used to contrast two expressions. For details, see the Operators topics.
value_list
Is a list of values. Place quotation marks around char, varchar, and datetime values, and separate values with commas.
subquery
Is a restricted SELECT statement (the ORDER BY clause, the COMPUTE clause, and the INTO keyword are not allowed). For more information, see the Subqueries topic.
cursor_name
Specifies the name of the cursor that points to the row where the statement should be applied. The WHERE CURRENT OF clause is available with the DELETE and UPDATE statements. For details, see the Cursors topic.
AND
Joins two conditions and returns results when both of the conditions are true. When more than one logical operator is used in a statement, AND operators are evaluated first. You can change the order of evaluation by using parentheses.
ALL
Is used with <, >, <>, >=, or <= and a subquery. It evaluates to TRUE or FALSE when all values retrieved in the subquery match the value in the WHERE or HAVING clause or when the subquery returns no rows of the outer statement. For details, see the Subqueries topic.
ANY
Is used with <, >, <>, >=, <=, or = and a subquery. It evaluates to TRUE when any value retrieved in the subquery satisfies the comparison predicate in the WHERE or HAVING clause of the outer statement. For details, see the Subqueries topic.
BETWEEN
Is the range-start keyword. Use AND for the range-end value. A range of expression BETWEEN x AND y, unlike a range of expression > x and expression < y, is inclusive.
EXISTS
Is used with a subquery to test for the existence of rows returned by the subquery. For details, see the Subqueries topic.
IN
Allows you to select values that match any one of a list of values. The expression can be a constant or a column name, and the list can be a set of constants or, more commonly, a subquery. Enclose the list of values in parentheses.

If there are 16 or more values in an IN predicate, the values are sorted and binary search is used to evaluate the predicate. This can result in limiting the overall number of comparisons performed. For information about using IN with a subquery, see the Subqueries topic.

IS [NOT] NULL
Are keywords that search for null values (or all values except null values). An expression with a bitwise or arithmetic operator evaluates to NULL if any of the operands is NULL.
LIKE
Indicates that the following character string (enclosed by quotation marks) is to be used with pattern matching. You can use the LIKE keyword and wildcard characters with datetime data as well as with char and varchar. When you use LIKE with datetime values, SQL Server converts the dates to the standard datetime format and then to varchar. Since the standard storage format doesn't include seconds or milliseconds, you cannot search for seconds or milliseconds with LIKE and a pattern.

It is a good idea to use LIKE when you search for datetime values, since datetime entries can contain a variety of date parts. For example, if you insert the value 9:20 into a column named arrival_time, the clause WHERE arrival_time = '9:20' can't find it because SQL Server converts the entry into 'Jan 1, 1900 9:20AM'. However, the clause WHERE arrival_time LIKE '%9:20%' does find it.

Note When performing string comparisons with LIKE, all characters in the pattern string are significant, including every leading and/or trailing blank (space). If a comparison to return all rows with a string LIKE 'abc ' (abc followed by a single space) is requested, a row where the value of that column is 'abc' (abc without a space) will not be returned. The reverse, however, is not true. Trailing blanks in the expression to which the pattern is matched are ignored. If a comparison to return all rows with a string LIKE 'abc' (abc without a space) is requested, all rows that start with 'abc' and have zero or more trailing blanks would be returned.

NOT
Negates any Boolean expression (which can include keywords, such as LIKE, NULL, BETWEEN, IN, and EXISTS).
OR
Joins two conditions and evaluates to TRUE when either of the conditions is true. When more than one logical operator is used in a statement, OR operators are normally evaluated after AND operators. However, you can change the order of evaluation by using parentheses.

Examples

A. Arithmetic Operators

In this example, the WHERE clause affects only those titles that have year-to-date sales more than twice the advance given:

WHERE advance * 2 > ytd_sales
B. Wildcard with the NOT LIKE Condition

In this example, only phone numbers that do not begin with the 415 prefix are affected in the results set:

WHERE phone NOT LIKE '415%'
C. Specific Character Wildcards with the LIKE Condition

This example finds the rows for authors named Carson, Carsen, Karsen, and Karson:

WHERE au_lname LIKE '[CK]ars[eo]n'
D. Boolean (OR) and Comparison Operators (< and IS NULL)

This example finds titles that have an advance less than $5000 and includes those titles that have no specific advance entered (NULL values):

WHERE advance < $5000 OR advance IS NULL
E. Grouping Boolean Expressions

Using parentheses always takes precedence over other operators. Without the parentheses, the following WHERE clause would have totally different meaning because AND takes a higher precedence than OR.

This example affects only books with an advance greater than $5500 and are either business or psychology books. If the parentheses were not included, the WHERE clause would affect all business books OR psychology books that have an advance greater than $5500.

WHERE (type = 'business' OR type = 'psychology') AND
    advance > $5500
F. Between Condition

This example returns all titles with year-to-date sales between and including 4095 through 12000.

WHERE ytd_sales BETWEEN 4095 AND 12000
G. IN Condition

This example finds the rows in which the state is California (CA), Indiana (IN), or Maryland (MD).

WHERE state IN ('CA', 'IN', 'MD')

See Also

DELETE | Operators
EXECUTE | SELECT
Expressions | UPDATE
Functions | Wildcard Characters
INSERT |


SELECT Statement

For SQL Server 6.5 information, see SELECT Statement, CUBE Operator, and ROLLUP Operator in What's New for SQL Server 6.5.

Retrieves rows from the database.

Syntax

SELECT [ALL | DISTINCT] select_list
[INTO [new_table_name]]
[FROM {table_name | view_name}[(optimizer_hints)]
[[, {table_name2 | view_name2}[(optimizer_hints)]
[..., {table_name16 | view_name16}[(optimizer_hints)]]]
[WHERE clause]
[GROUP BY clause]
[HAVING clause]
[ORDER BY clause]
[COMPUTE clause]
[FOR BROWSE]

where

ALL
Retrieves all rows in the results. ALL is the default.
DISTINCT
Includes only unique rows in the results. Null values are considered equal for the purposes of the DISTINCT keyword; only one NULL is selected no matter how many are encountered.
select_list
Specifies the columns to select. Can be one or more of the following:
  • Asterisk (*), representing all columns listed in the order in which they were specified in the CREATE TABLE statement for all tables in the FROM clause, in the order they appear.
  • A list of column names, specified in the order in which you want to see them. If the select_list contains multiple column names, separate the names with commas.
  • A column name and column heading that will replace the default column heading (the column name), in the following form:

    column_heading = column_name

    or

    column_name column_heading

    The column_heading must be in quotation marks if spaces are used. For example:

    SELECT 'Author Last Name' = au_lname
FROM authors
  • An expression (a column name, constant, function, or any combination of column names, constants, and functions connected by an operator(s), a CASE expression, or a subquery). For details, see the Expressions topic.
  • The IDENTITYCOL keyword instead of the name of a column that has the IDENTITY property. For details, see the CREATE TABLE statement.
  • A local or global variable. For details, see the Variables topic.
  • A local variable assignment, in the form:

    @variable = expression

Note When the select_list includes a variable assignment(s), it cannot be combined with data-retrieval operations.

INTO new_table_name
Creates a new table based on the columns specified in the select_list and the rows chosen in the WHERE clause. To select into a permanent table, the select into/bulkcopy option must be on (by executing the sp_dboption system stored procedure). By default, the select into/bulkcopy option is off in newly created databases. The new table name (new_table_name) must follow the same rules as table_name (described later in this section) with these exceptions:
  • If select into/bulkcopy is on in the database where the table is to be created, a permanent table is created. The table name must be unique in the database and conform to the rules for Identifiers.
  • If select into/bulkcopy is not on in the database where the table is to be created, permanent tables cannot be created using SELECT INTO; only local or global temporary tables can be created. To create a temporary table, the table name must begin with a pound sign (#). For details on temporary tables, see the CREATE TABLE statement.

SELECT INTO is a two-step operation. The first step creates the table. The user executing the statement must have CREATE TABLE permission in the destination database. The second step inserts the specified rows into the new table. If the second step fails for any reason (hardware failure, exceeding a system resource, and so on), the new table will exist but have no rows.

You can use SELECT INTO to create an identical table definition (different table name) with no data by having a false condition in the WHERE clause.

You cannot use SELECT INTO with the COMPUTE clause or inside a user-defined transaction. For details about user-defined transactions, see the Transactions topic.

When selecting an existing identity column into a new table, the new column inherits the IDENTITY property unless one of the following conditions is true:

  • The SELECT statement contains a join, GROUP BY clause, or aggregate function.
  • Multiple SELECT statements are joined with UNION.
  • The identity column is listed more than once in the select_list.
  • The identity column is part of an expression.

If any of these conditions is true, the column is created NOT NULL instead of inheriting the IDENTITY property. If none of the conditions is true, the new table will inherit the identity column. All rules, restrictions, and so on, for the identity columns apply to the new table.

FROM
Indicates the specific table(s) and view(s) that are used in the SELECT statement. FROM is required except when the select_list contains only constants, variables, and arithmetic expressions (no column names). The FROM clause allows a maximum of 16 tables and views. Tables in subqueries are counted as part of this total.
table_name | view_name =
[[database.]owner.]{table_name. | view_name.}

Specifies the name(s) of the table(s) and view(s) used in the SELECT statement. If the list contains more than one table or view, separate the names with commas. If the table(s) or view(s) exist in another database(s), use a fully qualified table or view name (database_name.owner.object_name).

Each table_name or view_name can be given an alias, either for convenience or to distinguish the different roles that a table or view plays in a self-join or subquery. Aliases (when defined) must be used for any ambiguous column references and must always match the alias reference (the full table name cannot be used if an alias has been defined). To use an alias, specify the object name, and then a space, and then the alias name, like this:

SELECT au_lname, au_fname, title
FROM titles t, authors a, titleauthor ta
WHERE ta.title_id = t.title_id
AND ta.au_id = a.au_id
ORDER BY title, au_lname, au_fname

The order of the tables and views after the FROM keyword does not affect the results set returned.

(optimizer_hints)
Indicate that a specific locking method, a specific index, or no index (table scan) should be used (by the optimizer) with this table for this SELECT. Although this is an allowable option, in most cases you should allow the optimizer to pick the best optimization method.

Important You can use the optimizer_hints in any combination, but some of them do not make sense to use together¾for example, TABLOCK and PAGLOCK. When multiple options are specified, separate them with a space; the more restrictive option will take precedence.

An optimizer_hint can be one (or more) of the following:

INDEX = {index_name | index_id}
Specifies the index name or ID to use for that table. An index_id of 0 forces a table scan, 1 forces the use of a clustered index (if one exists).
NOLOCK
Allows "dirty reads," which means that no shared locks are issued and no exclusive locks are honored. This can result in higher concurrency, but at the cost of lower consistency. If this option is specified, it is possible to read an uncommitted transaction or to read a set of pages that are rolled back in the middle of the read, so error messages might result. If you receive error messages 605, 606, 624, or 625 when NOLOCK is specified, resolve them as you would a deadlock error (1205) and retry your statement.
HOLDLOCK
Makes a shared lock more restrictive by holding it until the completion of a transaction (instead of releasing the shared lock as soon as the required table or data page is no longer needed, whether or not the transaction has been completed). The HOLDLOCK option applies only to the table or view for which it is specified and only for the duration of the transaction defined by the statement in which it is used. You cannot use HOLDLOCK in a SELECT statement that includes the FOR BROWSE option.
UPDLOCK
Takes update locks instead of shared locks while reading the table and holds them until the end-of-command or end-of-transaction.
TABLOCK
Takes a shared lock on the table that is held until the end-of-command. If HOLDLOCK is also specified, the shared lock is held until the end of the transaction.
PAGLOCK
Takes shared page locks where a single shared table lock would normally be taken.
TABLOCKX
Takes an exclusive lock on the table that is held until the end-of-command or end-of-transaction.
FASTFIRSTROW
Causes the optimizer to use the nonclustered index if one matches the ORDER BY clause. With sorting enhanced by the new asynchronous read ahead capability, the optimizer picks table scan and sort over using a nonclustered index in many cases because the total throughput for the sort is faster. If there is a sort, the first row cannot be sent until totally sorted. With this method, if the sort is large, there may be a considerable delay before the first row appears. FASTFIRSTROW causes the optimizer to use the nonclustered index; the first row will appear quickly, but the total return time for this option may be slower.
WHERE clause =
WHERE search_conditions

Specifies the restricting conditions for the rows returned in the results set. There is no limit to the number of search_conditions that can be included in an SQL statement. For more information, see the Search Conditions topic.

GROUP BY clause =
GROUP BY [ALL] aggregate_free_expression
[, aggregate_free_expression]...
GROUP BY
Specifies the groups into which the table will be partitioned and, if aggregate functions are included in the select_list, finds a summary value for each group. You can refer to these new summary columns in the HAVING clause. The text and image datatypes cannot be used in a GROUP BY clause.

When a GROUP BY clause is used, each item in the select_list must produce a single value for each group. A table can be grouped by any combination of columns; however, you cannot group by a column heading¾you must use a column name or an expression. In Transact-SQL, any expression is valid (although not with column headings). With standard SQL, you can group only by a column.

You can use GROUP BY for a column or expression that does not appear in the select_list. Null values in the GROUP BY column are put into a single group.

The aggregate functions, which calculate summary values from the non-null values in a column, can be divided into two groups:
Scalar | Aggregate functions are applied to all the rows in a table (producing a single value per function). An aggregate function in the select_list with no GROUP BY clause applies to the whole table and is one example of a scalar.
Vector | Aggregate functions are applied to all rows that have the same value in a specified column or expression with the GROUP BY clause and, optionally, the HAVING clause (producing a value for each group per function).

For the details about aggregate functions, see the Functions topic.

ALL
Includes all groups in the results, even those that don't have any rows that meet the search_conditions.
aggregate_free_expression
Is an expression that includes no aggregate functions. Aggregate functions can be used in the select_list preceding the GROUP BY clause.

For the details about aggregate functions, see the Functions topic.

HAVING clause =
HAVING search_conditions

Specifies a different type of restriction for aggregate functions in the select_list; the search_conditions restrict the rows returned by the query but do not affect the calculation(s) of the aggregate function(s). When a WHERE clause is used, the search_conditions restrict the rows that are included in the calculation of the aggregate function but do not restrict the rows returned by the query. The text and image datatypes cannot be used in a HAVING clause.

There is no limit on the number of conditions that can be included in search_conditions. You can use a HAVING clause without a GROUP BY clause. When the HAVING clause is used with GROUP BY ALL, the HAVING clause negates the meaning of ALL.

ORDER BY clause =
ORDER BY {{table_name. | view_name.}column_name
| select_list_number | expression} [ASC | DESC]
[...{{table_name16. | view_name16.}column_name
| select_list_number | expression} [ASC | DESC]]

Sorts the results by columns. You can sort as many as 16 columns. In Transact-SQL, the ORDER BY clause can include items that do not appear in the select_list. You can sort by a column name, a column heading (or alias), an expression, or a number representing the position of the item in the select_list (the select_list_number). If you sort by select_list_number, the columns to which the ORDER BY clause refers must be included in the select_list. The select_list can be a single asterisk (*). If you use COMPUTE BY, you must also specify an ORDER BY clause.

Null values are sorted before all others, and text or image columns cannot be used in an ORDER BY clause. Subqueries and view definitions cannot include an ORDER BY clause, a COMPUTE clause, or the INTO keyword. However, through Transact-SQL extensions, you can sort by expressions and aggregates if you use their select_list_number in the ORDER BY clause.

COMPUTE clause =
COMPUTE row_aggregate(column_name)
[, row_aggregate(column_name)...]
[BY column_name [, column_name]...]
COMPUTE
Used with row aggregate functions (SUM, AVG, MIN, MAX, and COUNT) to generate control-break summary values. The summary values appear as additional rows in the query results, allowing you to see detail rows and summary rows within one results set. You can calculate summary values for subgroups, and you can calculate more than one aggregate function for the same group.

The COMPUTE clause cannot be used with INTO and cannot contain aliases for column names, although aliases can be used in the select_list.

The COMPUTE keyword can be used without BY to generate grand totals, grand counts, and so on. The ORDER BY clause is optional only if you use the COMPUTE keyword without BY.

BY
Indicates that values for row aggregate functions are to be calculated for subgroups. Whenever the value of BY changes, row aggregate function values are generated. If you use BY, you must also use an ORDER BY clause. Listing more than one item after BY breaks a group into subgroups and applies a function at each level of grouping. The columns listed after COMPUTE clause must be identical to or a subset of those listed after ORDER BY clause, and must be in the same left-to-right order, start with the same expression, and not skip any expression.

For example, if the ORDER BY clause is:

ORDER BY a, b, c

The COMPUTE clause can be any (or all) of these:

COMPUTE BY a, b, c
COMPUTE BY a, b
COMPUTE BY a
FOR BROWSE
Allows you to perform updates while viewing data in client application programs using DB-Library.

A table can be browsed in an application under the following conditions:

  • The table includes a time-stamped column (defined with the timestamp datatype).
  • The table has a unique index.
  • The FOR BROWSE option is at the end of the SELECT statement(s) sent to SQL Server.
  • For details, see Microsoft SQL Server Programming DB-Library for C.

Do not use the optimizer_hint HOLDLOCK in a SELECT statement that includes the FOR BROWSE option.

The FOR BROWSE option cannot appear in SELECT statements joined by the UNION operator.

Remarks

The length returned for text columns included in the select_list defaults to whichever is the smallest ¾ the actual size of the text, the default TEXTSIZE session setting, or the hardcoded application limit. To change the length of returned text for the session, use the SET statement. By default, the limit on the length of text data returned with a SELECT statement is 4K.

To retrieve data from remote SQL Servers, you can call remote stored procedures. For more information, see the CREATE PROCEDURE and EXECUTE statements.

Using the GROUP BY clause and the HAVING clause

The following list shows the requirements for processing a SELECT with the GROUP BY clause and the HAVING clause, and it shows how the rows returned in the results set are derived:

  1. The WHERE clause excludes rows that do not meet its search_conditions.
  2. The GROUP BY clause collects the surviving rows into one group for each unique value in the GROUP BY clause. Omitting the GROUP BY clause creates a single group for the whole table.
  3. The HAVING clause excludes rows that do not meet its search_conditions. The HAVING clause tests only rows, but the presence or absence of a GROUP BY clause can make the behavior of a HAVING clause appear contradictory. For example:
    • When the query includes a GROUP BY clause, the HAVING clause excludes groups from the results.
    • By default, the HAVING clause can refer to aggregates only when the query contains no GROUP BY clause.
    • To allow queries that contain aggregates or a GROUP BY clause with items in the select_list that are not in the GROUP BY clause and are not aggregate functions, set trace flag 204. For details, see the Trace Flags topic.
  4. Aggregate functions specified in the select_list calculate summary values for each surviving group.

For the GROUP BY clause, the HAVING clause, and aggregate functions to accomplish the goal of one row and one summary value per group, ANSI-standard SQL requires:

  • Columns in a select_list must also be in the GROUP BY clause or be parameters of aggregate functions.
  • Columns in a HAVING clause must have only one value.
  • A query with a HAVING clause should have a GROUP BY clause. But if it doesn't, all the rows not excluded by the WHERE clause are considered to be a single group.

Transact-SQL extensions to standard SQL make displaying data more flexible by allowing references to columns and expressions that are not used for creating groups or summary calculations. For example:

  • The GROUP BY clause can include expressions.
  • GROUP BY ALL displays all groups, even those excluded from calculations by a WHERE clause.

Permission

SELECT permission defaults to the owner of the table or view, who can grant it to other users using the GRANT statement. If the INTO clause is used to create a permanent table, then the user must have CREATE TABLE permission in the destination database.

Examples

A. Simple SELECT: All Rows, All Columns

This example returns all rows (no WHERE clause) and all columns (*) from the publishers table in the pubs database.

SELECT * FROM publishers
B. Simple SELECT: Subset of Columns, All Rows

This example returns all rows (no WHERE clause) and only a subset of the columns (pub_id, pub_name, city, state) from the publishers table in the pubs database.

SELECT pub_id, pub_name, city, state
        FROM publishers
C. Simple SELECT: Subset of Rows, Subset of Columns

This examples returns only the rows where the advance given is less than $10,000 and there are current year-to-date sales.

SELECT pub_id, total = sum (ytd_sales)
        FROM titles
            WHERE advance < $10000
            AND ytd_sales IS NOT NULL
D. SELECT with GROUP BY, COMPUTE, and ORDER BY Clauses

This example returns only those rows with current year-to-date sales and then computes the average book cost and total advances in descending order by type. Four columns of data are returned including a truncated title. Notice that all computed columns appear within the select_list.

SELECT title = CONVERT(char(20), title), type, price, advance
        FROM titles
            WHERE ytd_sales IS NOT NULL
            ORDER BY type DESC
                COMPUTE AVG(price), SUM(advance) BY type
                COMPUTE SUM(price), SUM(advance)
go
title    type    price    advance
---------------------- ----------------- ------- ----------
Fifty Years in Bucki    trad_cook    11.95    4,000.00
Onions, Leeks, and G    trad_cook    20.95    7,000
Sushi, Anyone?    trad_cook    14.99    8,000.00

            avg
            =========
            15.96
                sum
                =========
                19,000.00

title    type    price    advance
---------------------- ----------------- ------- ----------
Computer Phobic AND    psychology    21.59    7,000.00
Emotional Security:    psychology    7.99    4,000.00
Is Anger the Enemy?    psychology    10.95    2,275.00
Life Without Fear    psychology    7.00    6,000.00
Prolonged Data Depri    psychology    19.99    2,000.00

            avg
            =========
            13.50
                sum
                =========
                21,275.00

title    type    price    advance
---------------------- ----------------- ------- ----------
But Is It User Frien    popular_comp    22.95    7,000.00
Secrets of Silicon V    popular_comp    20.00    8,000.00

            avg
            =========
            21.48
                sum
                =========
                15,000.00

title    type    price    advance
---------------------- ----------------- ------- ----------
Silicon Valley Gastr    mod_cook    19.99    0.00
The Gourmet Microwav    mod_cook    2.99    15,000.00

            avg
            =========
            11.49
                sum
                =========
                15,000.00

title    type    price    advance
---------------------- ----------------- ------- ----------
Cooking with Compute    business    11.95    5,000.00
Straight Talk About    business    19.99    5,000.00
The Busy Executive's    business    19.99    5,000.00
You Can Combat Compu    business    2.99    10,125.00

            avg
            =========
            13.73
                sum
                =========
                25,125.00

            sum
            =========
            236.26
                sum
                =========
                88,400.00
(22 row(s) affected)
E. All Rows with Computed Sums

This example shows only three columns in the select_list and gives totals based on all prices and all advances at the end of the results.

SELECT type, price, advance
        FROM titles
            COMPUTE SUM(price), SUM(advance)
go
type         price                      advance
------------ -------------------------- --------------------------
business     19.99                      5,000.00
business     11.95                      5,000.00
business     2.99                       10,125.00
business     19.99                      5,000.00
mod_cook     19.99                      0.00
mod_cook     2.99                       15,000.00
UNDECIDED    (null)                     (null)
popular_comp 22.95                      7,000.00
popular_comp 20.00                      8,000.00
popular_comp (null)                     (null)
psychology   21.59                      7,000.00
psychology   10.95                      2,275.00
psychology   7.00                       6,000.00
psychology   19.99                      2,000.00
psychology   7.99                       4,000.00
trad_cook    20.95                      7,000.00
trad_cook    11.95                      4,000.00
trad_cook    14.99                      8,000.00

             sum
             ==========================
             236.26
                                        sum
                                        ==========================
                                        95,400.00

(19 row(s) affected)
F. Create a Temporary Table with SELECT INTO

This example causes a temporary table to be created in tempdb. To use this table, always refer to it with the exact name shown, including the pound sign (#).

SELECT *
    INTO #coffeetabletitles
        FROM titles
            WHERE price < $20
go
SELECT name FROM sysobjects WHERE name LIKE '#c%'
go
name
------------------------------

(0 row(s) affected)
SELECT name FROM tempdb..sysobjects WHERE name LIKE '#c%'
go
name
------------------------------
#coffeetabletitles__0000EC153E

(1 row(s) affected)
G. Create a Permanent Table with SELECT INTO

This example shows the steps needed to create a permanent table.

USE master
go
sp_dboption 'pubs', 'select into', TRUE
go
CHECKPOINTing database that was changed.
USE pubs
go
SELECT *
    INTO newtitles
        FROM titles
            WHERE price > $25
            OR price < $20
go
(12 row(s) affected)
SELECT name FROM sysobjects WHERE name LIKE 'new%'
go
name
------------------------------
newtitles

(1 row(s) affected)
H. Optimizer Hints: TABLOCK and HOLDLOCK

The following partial transaction shows how to place an explicit shared table lock on t1 without the overhead of reading any records from it.

BEGIN TRAN
SELECT count(*) FROM t1 (TABLOCK HOLDLOCK)
I. Optimizer Hints: Using the Name of an Index

This example shows how to force the optimizer to use a nonclustered index to retrieve rows from a table.

SELECT au_lname, au_fname, phone
    FROM authors (INDEX = aunmind)
        WHERE au_1name = 'Smith'
J. Optimizer Hints: Forcing a Table Scan

This example shows that using an index of 0 will force a table scan.

SELECT emp_id, fname, lname, hire_date
    FROM employee (index = 0)
        WHERE hire_date > '10/1/1994'

See Also

CREATE TABLE statement | Search Conditions
CREATE TRIGGER statement | sp_dboption
CREATE VIEW statement | Subqueries
DELETE statement | UNION operator
Expressions | UPDATE statement
Functions | Variables
INSERT statement | Wildcard Characters


SET Statement

For SQL Server 6.5 information, see SET Statement in What's New for SQL Server 6.5.

Sets SQL Server query-processing options for the duration of the user's work session, or for the duration of a running trigger or a stored procedure.

Syntax

SET {
{{{ANSI_NULL_DFLT_OFF | ANSI_NULL_DFLT_ON}
| ARITHABORT
| ARITHIGNORE
| FMTONLY
| FORCEPLAN
| IDENTITY_INSERT [database.[owner.]]tablename
| NOCOUNT
| NOEXEC
| OFFSETS {keyword_list}
| PARSEONLY
| PROCID
| QUOTED_IDENTIFIER
| SHOWPLAN
| STATISTICS IO
| STATISTICS TIME}
{ON | OFF}}
| DATEFIRST number
| DATEFORMAT format
| DEADLOCKPRIORITY {LOW | NORMAL}
| LANGUAGE language
| ROWCOUNT number
| TEXTSIZE number
| TRANSACTION ISOLATION LEVEL {READ COMMITTED | READ
UNCOMMITTED | REPEATABLE READ | SERIALIZABLE}}

where

ANSI_NULL_DFLT_OFF
Alters the session's behavior not to use ANSI compatibility for nullability. When this session option is turned on, it overrides the default database nullability configured by the sp_dboption system stored procedure. New columns defined without explicit nullability will be defined not to allow NULLs (as long as the underlying datatype is nullable). For more information on datatypes, see the Datatypes topic.
ANSI_NULL_DFLT_ON
Alters the sessions behavior to ANSI compatibility for nullability. When this session option is turned on, it overrides the default database nullability configured by the sp_dboption system stored procedure. New columns defined without explicit nullability will be defined to allow NULLs.

Note ANSI_NULL_DFLT_ON and ANSI_NULL_DFLT_OFF are mutually exclusive options, yet both options exist to determine whether or not the database option should be overridden. When turned ON, each option forces the opposite option to OFF. Neither option, when set OFF, turns the opposite option ON. Instead, turning an option OFF only discontinues the current ON setting.

ARITHABORT
Terminates a query when an overflow or divide-by-zero error occurs during query execution. It is possible for rows in a results set to be returned prior to the overflow or divide-by-zero occurrence.
ARITHIGNORE
Returns NULL when an overflow or divide-by-zero error occurs during a query. No warning message is returned.

Note If neither ARITHABORT nor ARITHIGNORE is set, SQL Server returns NULL and returns a warning message after the query is executed.

FMTONLY
Returns only metadata to the client. No rows will be processed or sent to the client as a result of the request when FMTONLY is turned ON.
FORCEPLAN
Makes the SQL Server optimizer process joins in the same order as tables appear in the FROM clause. FORCEPLAN essentially overrides the optimizer.
IDENTITY_INSERT [database.[owner.]]tablename
Specifies the database, owner and table in which explicit identity values can be inserted. Only one table per user can have the IDENTITY_INSERT option set. If the value inserted is larger than the current identity value for the table, SQL Server will automatically use the new inserted value as the current identity value. For details, see the IDENTITY property.
NOCOUNT
Turns off the message returned at the end of each statement that states how many rows were affected by the statement. The global variable @@ROWCOUNT is updated even when NOCOUNT is turned ON.

In SQL Server, SET NOCOUNT ON eliminates the sending of DONE_IN_PROC messages to the client for each statement in a stored procedure. For stored procedures that contain several statements that do not return much actual data, this can provide a significant performance boost because network traffic is greatly reduced.

NOEXEC
Compiles each query but does not execute it. NOEXEC is often used with SHOWPLAN. Once NOEXEC is turned on, no subsequent statements are executed (including other SET statements) until NOEXEC is turned OFF.

Statement processing consists of two phases, compilation and execution. NOEXEC stops the processing after compilation.

OFFSETS
Returns the keyword_list offset (position in relation to the beginning of the query) of specified keywords in SQL statements. The keyword_list is a list, separated with commas, that can include any of these SQL constructs: SELECT, FROM, ORDER, COMPUTE, TABLE, PROCEDURE, STATEMENT, PARAM, and EXECUTE.

The OFFSETS option is used only in a DB-Library application.

PARSEONLY
Checks the syntax of each query and returns any error messages without generating a sequence tree, compiling, or executing the query. Do not use PARSEONLY in a stored procedure or a trigger. PARSEONLY returns offsets if the OFFSETS option is ON and no errors occur.
PROCID
Returns the identification number of the stored procedure to DB-Library (not to the user) before sending rows generated by that stored procedure.
QUOTED_IDENTIFIER
Causes the current session to differentiate between single and double quotation marks when evaluating an expression. When QUOTED_IDENTIFIER is turned ON, strings with double quotation marks (") will not be evaluated or checked against keywords. For details, see the Identifiers topic.
SHOWPLAN
Generates a description of the processing plan for the query and immediately processes it unless NOEXEC is set. This option can indicate whether an index is being used to retrieve query results.
STATISTICS IO
Displays the number of scans, the number of logical reads (pages accessed in cache), and the number of physical reads (number of times the disk was accessed) for each table referenced in the statement.
STATISTICS TIME
Displays the time, in milliseconds, required to parse and compile each command and the time required to execute each step of the command.
DATEFIRST number
Sets the first weekday to a number from 1 through 7. The U.S. English default is 7 (Sunday).
DATEFORMAT format
Sets the order of the date parts (month/day/year) for entering datetime or smalldatetime data. Valid parameters include mdy, dmy, ymd, ydm, myd, and dym. The U.S. English default is mdy.
DEADLOCKPRIORITY {LOW | NORMAL}
Controls how this session reacts when in a deadlock situation. If set to LOW, this process will be the preferred victim of a deadlock situation. Use the NORMAL option to return the session to the default deadlock-handling method.
LANGUAGE language
Specifies the language in which system messages are displayed. The language must be available on the server. The default is us_english.
ROWCOUNT number
Causes SQL Server to stop processing the query after the specified number of rows are returned. To turn this option off (so that all rows are returned), use SET ROWCOUNT 0.

Note Setting the ROWCOUNT option causes all Transact-SQL statements to stop processing when they have each affected number rows. This includes triggers and data modification statements such as INSERT, UPDATE, and DELETE as well as the filling of a keyset cursor at the specified number of rows. This option should be used with caution and primarily with the SELECT statement.

TEXTSIZE number
Specifies the size, in bytes, of text data to be returned with a SELECT statement. If you specify a TEXTSIZE of 0, the size is reset to the default (4K). Setting TEXTSIZE affects the global variable @@TEXTSIZE.

The DB-Library variable DBTEXTLIMIT also limits the size of text data returned with a SELECT statement. If DBTEXTLIMIT is set to a smaller size than TEXTSIZE, only the amount specified by DBTEXTLIMIT is returned. For more information, see Microsoft SQL Server Programming DB-Library for C.

TRANSACTION ISOLATION LEVEL
Controls the default transaction locking behavior for all SQL Server SELECT statements for this connection. Only one of the options can be set at a time, and it remains set for that connection unless it is explicitly changed. This becomes the default behavior unless an optimization option is specified at the table level in the FROM clause of your statement. For details, see the SELECT statement. To see what isolation level is currently set, use DBCC USEROPTIONS. For more information on DBCC, see the DBCC statement.

where

READ COMMITTED
Is the default mode for SQL Server. Setting this option returns transaction locking behavior to the SQL Server default, and you will not encounter "dirty reads." However, because shared locks do not exclusively hold records until the completion of a transaction, you might still encounter non-repeatable reads and phantom values later within your transaction.
READ UNCOMMITTED
Implements "dirty read," or isolation level 0 locking, which means that no shared locks are issued and no exclusive locks are honored. When this option is set, it is possible to read uncommitted data, have values change if reread in the same transaction, and have phantom values.
REPEATABLE READ | SERIALIZABLE
Are currently implemented identically. In some database systems, REPEATABLE READ means that "dirty reads" and non-repeatable reads are not possible but phantoms are possible. However, because REPEATABLE READ is a synonym for SERIALIZABLE in SQL Server's implementation, phantoms are not allowed when one of these is set. Because concurrency is lower, use these options only when necessary.

These options have the same effect as setting HOLDLOCK on all tables in all SELECT commands within a transaction.

Remarks

If you use the SET statement inside a trigger or a stored procedure, the option reverts to its former setting after the trigger or stored procedure is executed.

Options changed with the SET statement take effect at the end of the batch. You can combine SET statements and queries in the same batch, but the SET options won't apply to the queries in that batch.

Examples

A. SHOWPLAN

This example shows that setting the SHOWPLAN returns a description of the processing plan for each query prior to returning the results set. Notice that the SET option must be turned on prior to the execution of the SELECT statement.

SET SHOWPLAN ON
go
select * from publishers
go
STEP 1
The type of query is SELECT
FROM TABLE
publishers
Nested iteration
Table Scan
pub_id pub_name                  city          state    country
------ ------------------------- ------------- -------- ------------
0736   New Moon Books            Boston        MA       USA
0877   Binnet & Hardley          Washington    DC       USA
1389   Algodata Infosystems      Berkeley      CA       USA
1622   Five Lakes Publishing     Chicago       IL       USA
1756   Ramona Publishers         Dallas        TX       USA
9901   GGG&G                     München       (null)   Germany
9952   Scootney Books            New York      NY       USA
9999   Lucerne Publishing        Paris         (null)   France

(8 row(s) affected)
B. SHOWPLAN and NOEXEC

This example shows how the query plan can be viewed without returning the results.

SET SHOWPLAN ON
SET NOEXEC ON
go
SELECT * FROM publishers
go
STEP 1
The type of query is SELECT
FROM TABLE
publishers
Nested iteration
Table Scan
C. ROWCOUNT

ROWCOUNT stops processing after the specified number of rows. In this example, note that x rows meet the criteria of advances less than or equal to $5,000; however, from the number of rows returned by the update, you can see that not all rows were processed. ROWCOUNT affects all Transact-SQL statements.

SELECT Count = count(*)
    FROM titles
        WHERE advance >= 5000
go

Count
-----------
10

(1 row(s) affected)
SET ROWCOUNT 4
go
UPDATE titles
    SET advance = 5000
        WHERE advance >= 5000
go
(4 row(s) affected)
D. ANSI NULL Default, Create Tables and sp_help

The publishers table is created without explicitly defining the nullability for each of the columns. In the INSTPUBS.SQL script, all nullability is explicitly defined. But for this example, all NULL definitions were replaced by a single SET option defined prior to the CREATE TABLE batch. Also note that the SET option is explicitly turned off within the script.

In scripts run against databases where nullability may be changed, make sure to do one of the following:

  • Explicitly define the nullability for each column.
  • Manually set the nullability for the script's session using one of the ANSI NULL default options.
SET ANSI_NULL_DFLT_ON ON
go
CREATE TABLE publishers
(
    pub_id char(4) NOT NULL
        CONSTRAINT UPKCL_pubind PRIMARY KEY CLUSTERED
        CHECK (pub_id in ('1389', '0736', '0877', '1622', '1756')
            OR pub_id like '99[0-9][0-9]'),
    pub_name        varchar(40),
    city            varchar(20),
    state        char(2),
    country        varchar(30)            DEFAULT('USA')
)
go
sp_help publishers
go

/* For simplicity only a subset of the results of sp_help is
    shown here. */
Column_name    Nullable
------------- --------------
pub_id    no
pub_name    yes
city    yes
state    yes
country    yes
SET ANSI_NULL_DFLT_ON OFF
E. TRANSACTION ISOLATION LEVEL in an Explicit Transaction

In this example, the TRANSACTION ISOLATION LEVEL is set for the session. For each Transact-SQL statement that follows, SQL Server will hold all of the shared locks until the end of the transaction.

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
go
BEGIN TRANSACTION
SELECT * FROM publishers
SELECT * FROM authors
...
COMMIT TRANSACTION
F. Arithmetic Handling

In this example, all arithmetic SET options and the results displayed by an invalid entry are shown. Table t1 is created with only one column of type tinyint. In the statements that follow, the default SQL Server behavior, and ARITHABORT and ARITHIGNORE are shown.

CREATE TABLE t1
(
    col1        tinyint        NOT NULL
)
go
INSERT t1 VALUES(-1)
go
Arithmetic overflow occurred.
(0 row(s) affected)
SET ARITHABORT ON
go
INSERT t1 VALUES(-1)
go
Arithmetic overflow error for type tinyint, value = -1.
SET ARITHABORT OFF
SET ARITHIGNORE ON
go
INSERT t1 VALUES(-1)
go
(0 row(s) affected)

See Also

Batches | Keywords
CREATE PROCEDURE | NULL Values
CREATE TRIGGER | Quoted Identifiers
IDENTITY |


SETUSER Statement

Allows a database owner to impersonate another user. The SETUSER statement is used by the system administrator or a database owner when he or she wants to adopt the identity of another user in order to use another user's database object, to grant permissions to that object, to create an object, and so on.

Syntax

SETUSER ['username' [WITH NORESET]]

where

username
Specifies the name of the user who will be impersonated by the system administrator or the database owner. The username supplied must be listed in the sysusers table. When no username is specified, the original identity of the system administrator or database owner is re-established.
NORESET
Specifies that subsequent SETUSER statements (with no specified username) will not reset to the system administrator or database owner.

Remarks

Using SETUSER to impersonate a user, a database owner, or system administrator will have only those rights given to the user being impersonated. Because the owner of an object always retains the rights to that object, no users, other than those given explicit permission to that object, can access it. Because a database owner and the system administrator always have supervisory permission over their database (or the system) they can temporarily adopt another database user's identity. The database owner or system administrator can act as that user, create objects in that user's name, and test permissions as given to that user. The SETUSER statement remains in effect until another SETUSER statement is issued or until the current database is changed with the USE statement.

In SQL Server 6.0, the SETUSER statement does not need to be used to drop objects owned by another user. The database owner and system administrator can drop user's objects by explicitly qualifying the object name with the owner's name. For details, see the DROP statements (DROP DEFAULT, DROP PROCEDURE, DROP TABLE, and so on).

In earlier releases of SQL Server, the system administrator retained full system administrator permissions and could not use SETUSER to acquire another user's permissions. If you want to maintain compatibility with this previous behavior, use trace flag 206. For details, see the Trace Flags topic.

Permission

Execute permission defaults to the database owner and is not transferable.

Examples

A. SETUSER

In this example, Mary (the database username of mary) has created a table called computer_types. Mary happens to be out of town and another user (Joe) needs to access Mary's computer_types table. The database owner or system administrator can execute:

SETUSER 'mary'
go
GRANT SELECT ON computer_types TO joe
go
SETUSER
B. NORESET Option

In this example, the database owner needs to create some objects and then test their usability with minimal permissions. For simplicity, the database owner wants to maintain only Mary's permission for the entire session. The database owner or system administrator can execute:

SETUSER 'mary' WITH NORESET
go
CREATE TABLE computer_types2
.
.
.
GRANT ...
go
SETUSER        /* This statement will have no effect. */

The only way the database owner or system administrator can re-establish his or her own rights is to log off and then log on again.

See Also

GRANT | USE
REVOKE |


SHUTDOWN Statement

Stops SQL Server. Only the system administrator can execute this statement.

Syntax

SHUTDOWN [WITH NOWAIT]

where

WITH NOWAIT
Shuts down SQL Server immediately, without performing checkpoints in every database. SQL Server exits after attempting to terminate all user processes and roll back any active transactions.

Remarks

Unless the system administrator uses the WITH NOWAIT option, SHUTDOWN tries to shut down SQL Server in an orderly fashion by:

  1. Disabling logins (except for the system administrator). To see a listing of all current users, use the sp_who system stored procedure.
  2. Waiting for currently executing Transact-SQL statements or stored procedures to finish. To see a listing of all active processes and locks, use the sp_lock and sp_who system stored procedures.
  3. Performing a checkpoint in every database.

Using the SHUTDOWN statement minimizes the amount of automatic recovery work needed when the system administrator restarts SQL Server.

The following tools and methods can also be used to stop SQL Server. Each of these performs a checkpoint in all databases and then a SHUTDOWN WITH NOWAIT to flush all committed data from data cache and stop the server quickly.

  • SQL Enterprise Manager.
  • NET STOP MSSQLSERVER from a Win32 command prompt.

SQL Server can also be stopped by the following methods. Because these methods do not perform checkpoints in each database prior to shutdown, they are not recommended and may increase the recovery time needed the next time the server is restarted. You can stop SQL Server in these additional ways:

  • By using the Services application from the Windows NT Control Panel.
  • By pressing ctrl+c if sqlservr.exe was started from the command-line.

Permission

SHUTDOWN permission defaults to the system administrator and cannot be transferred.

See Also

sqlservr Command-line Executable | sp_who System Stored Procedure
sp_lock System Stored Procedure |


Stored Procedures

Catalog Stored Procedures

Extended Stored Procedures

Replication Stored Procedures

SQL Executive Stored Procedures

System Stored Procedures


Stored Procedures - Catalog Stored Procedures

Stored Procedures–Catalog Stored Procedures

Catalog stored procedures provide a uniform catalog interface for accessing database gateways as well as SQL Server from the same application. These stored procedures are compatible with the catalog interface for the Microsoft Open Database Connectivity (ODBC) API.

These are the SQL Server catalog stored procedures:

sp_column_privileges | sp_special_columns
sp_columns | sp_sproc_columns
sp_databases | sp_statistics
sp_datatype_info | sp_stored_procedures
sp_fkeys | sp_table_privileges
sp_pkeys | sp_tables
sp_server_info |

Some of these stored procedures support wildcard pattern matching for some parameters. Wildcard pattern matching allows you to substitute the % and _ characters for one or more characters in the parameter, just as in a LIKE expression in Transact-SQL. For example, to find all tables in the current database starting with the letter s, type:

sp_tables 's%'

For details about catalog stored procedures, see the description of the specific catalog stored procedure in the following sections or see the Microsoft ODBC Programmer's Reference and SDK Guide, available separately.


sp_column_privileges Catalog Stored Procedure

For SQL Server 6.5 information, see sp_column_privileges in What's New for SQL Server 6.5.

Returns column privilege information for a single table in the current environment.

Syntax

sp_column_privileges table_name [, table_owner] [, table_qualifier]
[, column_name]

where

table_name
Specifies the table used to return catalog information. The table_name can be a variable-length character name with a maximum of 32 characters. Wildcard pattern matching is not supported.
table_owner
Specifies the table owner of the table used to return catalog information. The table_owner can be a variable-length character name with a maximum 32 characters. Wildcard pattern matching is not supported. If the table_owner is not specified, the default table visibility rules of the underlying database management system (DBMS) apply.

In Microsoft SQL Server, if the current user owns a table with the specified name, that table's columns are returned. If the table_owner is not specified and the current user does not own a table with the specified table_name, this procedure will look for a table with the specified table_name owned by the database owner. If one exists, that table's columns are returned.

table_qualifier
Is the name of the table qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name. In some products, it represents the server name of the table's database environment.
column_name
Specifies a single column and is used when only one column of catalog information is desired. If column_name is not specified, all columns will be returned. In Microsoft SQL Server, this column_name represents the column name as listed in the syscolumns table. The value specified can include wildcard characters using the underlying DBMS's wildcard matching patterns. For maximum interoperability, the gateway client should assume only ANSI-standard SQL pattern matching (the % and _ wildcard characters).

Remarks

With SQL Server, privileges are given with the GRANT statement and taken away by the REVOKE statement.

The sp_column_privileges catalog stored procedure is equivalent to SQLColumnPrivileges in ODBC. The results returned are order by TABLE_QUALIFIER, TABLE_OWNER, TABLE_NAME, COLUMN_NAME, and PRIVILEGE.

This is the results set:

Column | Datatype | Description
TABLE_QUALIFIER | varchar(32) | Is the name of the table qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name. In some products, it represents the server name of the table's database environment. This field can be NULL.
TABLE_OWNER | varchar(32) | Is the name of the table owner. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the name of the database user who created the table. This field will always return a value.
TABLE_NAME | varchar(32) | Is the name of the table. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the table name as listed in the sysobjects table. This field will always return a value.
COLUMN_NAME | varchar(32) | Is the name of the column, for each column of the TABLE_NAME returned. In Microsoft SQL Server, this column represents the column name as listed in the syscolumns table. This field will always return a value.
GRANTOR | varchar(32) | Is the name of the database user who has granted permissions on this COLUMN_NAME to the listed GRANTEE. In Microsoft SQL Server, this column will always be the same as the TABLE_OWNER. This field will always return a value.
GRANTEE | varchar(32) | Is the name of the database user who has been granted permissions on this COLUMN_NAME by the listed GRANTOR. In Microsoft SQL Server, this column will always include a database user from the sysusers table. This field will always return a value.
PRIVILEGE varchar(32) Is one of the available column privileges. Column privileges can be one of the following values (or other values supported by the data source when implementation is defined):

SELECT The GRANTEE can retrieve data for the columns.

INSERT The GRANTEE can provide data for this column when new rows are inserted (by the GRANTEE) into the table.

UPDATE The GRANTEE can modify existing data in the column.

REFERENCES The GRANTEE can reference a column in a foreign table in a primary key/foreign key relationship. In SQL Server 6.0, primary key/foreign key relationships are defined with table constraints.
IS_GRANTABLE | varchar(3) | Indicates whether the GRANTEE is permitted to grant privileges to other users (often referred to as "grant with grant" permission). Can be YES, NO, or NULL. An unknown (or NULL) value refers to a data source where "grant with grant" is not applicable. In SQL Server 6.0, "grant with grant" permission is not supported.


sp_columns Catalog Stored Procedure

For SQL Server 6.5 information, see sp_columns in What's New for SQL Server 6.5.

Returns column information for a single object that can be queried in the current environment. The returned columns belong to a table or a view.

Syntax

sp_columns object_name [, object_owner] [, object_qualifier] [, column_name]

where

object_name
Is the name of the table or view used to return catalog information. The object_name can be a variable character name with a maximum of 32 characters. Wildcard pattern matching is not supported.
object_owner
Specifies the object owner of the table or view used to return catalog information. The object_owner can be a variable character name with a maximum of 32 characters. Wildcard pattern matching is not supported. If object_owner is not specified, the default table or view visibility rules of the underlying DBMS apply.

In Microsoft SQL Server, if the current user owns a table or view with the specified name, that table's columns are returned. If object_owner is not specified and the current user does not own a table or view with the specified object_name, this procedure looks for a table or view with the specified object_name owned by the database owner. If one exists, that table's columns are returned.

object_qualifier
Specifies the name of the table or view qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name. In some products, it represents the server name of the table's database environment.
column_name
Specifies a single column and is used when only one column of catalog information is desired. If column_name is not specified, all columns will be returned. In Microsoft SQL Server, this column_name represents the column name as listed in the syscolumns table. The value specified can include wildcard characters using the underlying DBMS's wildcard matching patterns. For maximum interoperability, the gateway client should assume only ANSI-standard SQL pattern matching (the % and _ wildcard characters).

Remarks

The sp_columns catalog stored procedure is equivalent to SQLColumns in ODBC. The results returned are ordered by TABLE_QUALIFIER, TABLE_OWNER, and TABLE_NAME.

This is the results set:

Column | Datatype | Description
TABLE_QUALIFIER | varchar(32) | Is the name of the table or view qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name. In some products, it represents the server name of the table's database environment. This field can be NULL.
TABLE_OWNER | varchar(32) | Is the name of the table or view owner. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the name of the database user that created the table. This field will always return a value.
TABLE_NAME | varchar(32) | Is the name of the table or view. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the table or view name as listed in the sysobjects table. This field will always return a value.
COLUMN_NAME | varchar(32) | Is the name of the column, for each column of the TABLE_NAME returned. In Microsoft SQL Server, this column represents the column name as listed in the syscolumns table. This field will always return a value.
DATA_TYPE | smallint | Is an integer code for ODBC datatype. If this is a datatype that cannot be mapped to an ODBC type, it is NULL. The native datatype name is returned in the TYPE_NAME column.
TYPE_NAME | varchar(13) | Is a string representing a datatype. The underlying DBMS presents this datatype name.
PRECISION | int | Is the number of significant digits.
LENGTH | int | Is the transfer size of the data. (*)
SCALE | smallint | Is the number of digits to the right of the decimal point.
RADIX | smallint | Is the base for numeric types.
NULLABLE | smallint | Specifies nullability. 1 means NULL is possible; 0 means NOT NULL.
REMARKS | varchar(254) | For Microsoft SQL Server, this field will always return NULL.
SS_DATA_TYPE | tinyint | Is a SQL Server datatype, as defined in Microsoft SQL Server Programming Open Data Services, used by ODS gateway applications. The gateway converts the underlying data to this SQL Server datatype as the default. If the gateway supports configurable datatype conversions, either per installation or per session, then the conversion type is returned when the stored procedure is executed.
COLID | tinyint | Is a SQL Server - specific column appended to the result set. This column does not need to appear in Open Data Services gateway implementations of catalog stored procedures.
* For details about length, see the Microsoft ODBC Programmer's Reference and SDK Guide, available separately.


sp_databases Catalog Stored Procedure

Lists databases present in the SQL Server installation or accessible through a database gateway.

Syntax

sp_databases

Remarks

In SQL Server, sp_databases returns the databases listed in the sysdatabases system table. Because some DBMS systems accessed by database gateways do not have the concept of a database, this stored procedure may return no rows if sent to a Microsoft Open Data Services - based gateway.

Database names that are returned can be used as parameters in the USE statement to change the current database context.

The sp_databases catalog stored procedure has no equivalent in ODBC.

This is the results set:

Column | Datatype | Description
DATABASE_NAME | char(32) | Is the name of the database. In Microsoft SQL Server, this column represents the database name as stored in the sysdatabases system table.
DATABASE_SIZE | int | Is the size of database, in kilobytes.
REMARKS | int | For Microsoft SQL Server, this field will always return NULL.


sp_datatype_info Catalog Stored Procedure

For SQL Server 6.5 information, see sp_datatype_info in What's New for SQL Server 6.5.

Returns information about the datatypes supported by the current environment.

Syntax

sp_datatype_info [data_type]

where

data_type
Is the code number for the specified datatype. The value supplied should be an integer value.

Remarks

The sp_datatype_info catalog stored procedure is equivalent to SQLGetTypeInfo in ODBC. The results returned are ordered by DATA_TYPE and then by how closely the datatype maps to the corresponding ODBC SQL data type.

This is the results set:

Column | Datatype | Description
TYPE_NAME | varchar(30) | Is a DBMS-dependent datatype name (the same as the TYPE_NAME column in the sp_columns results set).
DATA_TYPE | smallint | Is a code for the ODBC type to which all columns of this type are mapped.
PRECISION | int | Is the maximum precision of the datatype on the data source. NULL is returned for datatypes where precision is not applicable.
LITERAL_PREFIX | varchar(32) | Are character(s) used before a literal. For example, a single quotation mark (') for character types and 0x for binary in SQL Server.
LITERAL_SUFFIX | varchar(32) | Are character(s) used to terminate a literal. For example, a single quotation mark (') for character types and none for binary.
CREATE_PARAMS | varchar(32) | Is a description of the creation parameters for this datatype. For example, decimal is "precision, scale", float is NULL, and varchar is "max_length".
NULLABLE | smallint | Specifies nullability. 1 means this datatype can be created allowing null values; 0 means null values are not allowed.
CASE_SENSITIVE | smallint | Specifies case sensitivity. 1 means all columns of this type are case-sensitive (for collations); 0 means they are case-insensitive.
SEARCHABLE | smallint | Is a column type. 1 means columns of this type can be used in a WHERE clause.
UNSIGNED_ATTRIBUTE | smallint | Specifies the sign of the datatype. 1 means the datatype is unsigned; 0 means the datatype is signed.
MONEY | smallint | Specifies the money datatype. 1 means it is a money datatype; 0 means it is not.
AUTO_INCREMENT | smallint | Specifies auto-incrementing. 1 means the datatype is auto-incrementing; 0 means the datatype is not. NULL is returned if the attribute is not applicable to the datatype. An application can insert values into a column that has this attribute, but it cannot update the values in the column. This attribute is valid only for numeric datatypes.
LOCAL_TYPE_NAME | varchar(128) | Is the localized version of the data source-dependent name of the datatype. For example, DECIMAL is DECIMALE in French. NULL is returned if a localized name is not supported by the data source.
MINIMUM_SCALE | smallint | Is the minimum scale of the datatype on the data source. If a datatype has a fixed scale, the MINIMUM_SCALE and MAXIMUM_SCALE columns both contain this value. NULL is returned where scale is not applicable. For more information, see the Datatypes topic.
MAXIMUM_SCALE | smallint | Is the maximum scale of the datatype on the data source. If the maximum scale is not defined separately on the data source, but is instead defined to be the same as the maximum precision, this column contains the same value as the PRECISION column. For more information, see the Datatypes topic.
USERTYPE | smallint | The identifier for the datatype. In SQL Server 6.0, this is the uid of the datatype from the syscomments table.


sp_fkeys Catalog Stored Procedure

For SQL Server 6.5 information, see sp_fkeysin What's New for SQL Server 6.5.

Returns logical foreign key information for the current environment.

Syntax

sp_fkeys [pktable_name] [, pktable_owner] [, pktable_qualifier]
[, fktable_name] [, fktable_owner] [, fktable_qualifier]

where

pktable_name
Specifies the table (with the primary key) used to return catalog information. The pktable_name can be a variable character name with a maximum 32 characters. Wildcard pattern matching is not supported. This parameter or the fktable_name parameter, or both, must be supplied.
pktable_owner
Is the name of the owner of the table (with the primary key) used to return catalog information. The pktable_owner parameter can be a variable character name with a maximum 32 characters. Wildcard pattern matching is not supported. If pktable_owner is not specified, the default table visibility rules of the underlying DBMS apply.

In Microsoft SQL Server, if the current user owns a table with the specified name, that table's columns are returned. If the pktable_owner is not specified and the current user does not own a table with the specified pktable_name, the procedure looks for a table with the specified pktable_name owned by the database owner. If one exists, that table's columns are returned.

pktable_qualifier
Is the name of the table (with the primary key) qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name. In some products, it represents the server name of the table's database environment.
fktable_name
Specifies the name of the table (with a foreign key) used to return catalog information. The fktable_name can be a variable character name with a maximum of 32 characters. Wildcard pattern matching is not supported. This parameter or the pktable_name parameter, or both, must be supplied.
fktable_owner
Is the name of the owner of the table (with a foreign key) used to return catalog information. The fktable_owner can be a variable character name with a maximum of 32 characters. Wildcard pattern matching is not supported. If fktable_owner is not specified, the default table visibility rules of the underlying DBMS apply.

In Microsoft SQL Server, if the current user owns a table with the specified name, that table's columns are returned. If fktable_owner is not specified and the current user does not own a table with the specified fktable_name, the procedure looks for a table with the specified fktable_name owned by the database owner. If one exists, that table's columns are returned.

fktable_qualifier
Specifies the name of the table (with a foreign key) qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name. In some products, it represents the server name of the table's database environment.

Remarks

If the primary key table name is supplied and the foreign key table name is NULL, this procedure returns all tables that include a foreign key to the given table. If the foreign key table name is supplied and the primary key table name is NULL, the procedure returns all tables related by a primary key/foreign key relationship to foreign keys in the foreign key table. Note that this procedure does not support the common key type as specified in the SQL Server syskeys system table.

The sp_fkeys stored procedure is equivalent to SQLForeignKeys in ODBC. The results returned are ordered by FKTABLE_QUALIFIER, FKTABLE_OWNER, FKTABLE_NAME, and KEY_SEQ.

This is the results set:

Column | Datatype | Description
PKTABLE_QUALIFIER | varchar(32) | Is the name of the table (with the primary key) qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name for the table with a PRIMARY KEY constraint. In some products, it represents the server name of the table's database environment. This field can be NULL.
PKTABLE_OWNER | varchar(32) | Is the name of the table (with the primary key) owner. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the name of the database user that created the table (with a PRIMARY KEY constraint). This field will always return a value.
PKTABLE_NAME | varchar(32) | Is the name of the table (with the primary key). Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the table name (with a PRIMARY KEY constraint) as listed in the sysobjects table. This field will always return a value.
PKCOLUMN_NAME | varchar(32) | Is the name of the primary key column(s), for each column of the TABLE_NAME returned. In Microsoft SQL Server, this column represents the column name as listed in the syscolumns table. This field will always return a value.
FKTABLE_QUALIFIER | varchar(32) | Is the name of the table (with a foreign key) qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name for the table (with a FOREIGN KEY constraint). In some products, it represents the server name of the table's database environment. This field can be NULL.
FKTABLE_OWNER | varchar(32) | Is the name of the table (with a foreign key) owner. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the name of the database user that created the table (with a FOREIGN KEY constraint). This field will always return a value.
FKTABLE_NAME | varchar(32) | Is the name of the table (with a foreign key). Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the table name as listed in the sysobjects table (with a FOREIGN KEY constraint). This field will always return a value.
FKCOLUMN_NAME | varchar(32) | Is the name of the foreign key column(s), for each column of the TABLE_NAME returned. In Microsoft SQL Server, this column represents the column name as listed in the syscolumns table. This field will always return a value.
KEY_SEQ | smallint | Is the sequence number of the column in a multicolumn primary key. This field will always return a value.
UPDATE_RULE | smallint | Is the action applied to the foreign key when the SQL operation is UPDATE. SQL Server returns 1 for these columns. Open Data Services gateways can return non-null values of 0, 1, or 2: 0 CASCADE changes to foreign key. 1 RESTRICT changes if foreign key is present. 2 SET_NULL; set foreign key to NULL.
DELETE_RULE | smallint | Is that action applied to the foreign key when the SQL operation is DELETE. SQL Server returns 1 for these columns. Open Data Services gateways can return non-null values of 0, 1, or 2: 0 CASCADE changes to foreign key. 1 RESTRICT changes if foreign key is present. 2 SET_NULL; set foreign key to NULL.
FK_NAME | varchar(128) | Is a foreign key identifier. It is NULL if not applicable to the data source. SQL Server 6.0 returns the FOREIGN KEY constraint name.
PK_NAME | varchar(128) | It is a primary key identifier. It is NULL if not applicable to the data source. SQL Server 6.0 returns the PRIMARY KEY constraint name.


sp_pkeys Catalog Stored Procedure

Returns primary key information for a single table in the current environment.

Syntax

sp_pkeys table_name [, table_owner] [, table_qualifier]

where

table_name
Specifies the table used to return catalog information. The table_name can be a variable-length character name with a maximum of 32 characters. Wildcard pattern matching is not supported.
table_owner
Specifies the table owner of the table used to return catalog information. The table_owner can be a variable character name with a maximum of 32 characters. Wildcard pattern matching is not supported. If the table_owner is not specified the default table visibility rules of the underlying DBMS apply.

In Microsoft SQL Server, if the current user owns a table with the specified name, that table's columns are returned. If the table_owner is not specified and the current user does not own a table with the specified table_name, this procedure will look for a table with the specified table_name owned by the database owner. If one exists, that table's columns are returned.

table_qualifier
Is the name of the table qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name. In some products, it represents the server name of the table's database environment.

Remarks

In SQL Server 6.0, sp_pkeys returns information about columns explicitly defined with a PRIMARY KEY constraint. Because not all systems support explicitly named primary keys, the gateway implementor determines what constitutes a primary key. Note that the term "primary key" refers to a logical primary key for a table. It is expected that every key listed as being a logical primary key has a unique index defined on it and that this unique index is also returned in sp_statistics.

The sp_pkeys stored procedure is equivalent to SQLPrimaryKeys in ODBC. The results returned are ordered by TABLE_QUALIFIER, TABLE_OWNER, TABLE_NAME, and KEY_SEQ.

This is the results set:

Column | Datatype | Description
TABLE_QUALIFIER | varchar(32) | Is the name of the table qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name. In some products, it represents the server name of the table's database environment. This field can be NULL.
TABLE_OWNER | varchar(32) | Is the name of the table owner. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the name of the database user who created the table. This field will always return a value.
TABLE_NAME | varchar(32) | Is the name of the table. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the table name as listed in the sysobjects table. This field will always return a value.
COLUMN_NAME | varchar(32) | Is the name of the column, for each column of the TABLE_NAME returned. In Microsoft SQL Server, this column represents the column name as listed in the syscolumns table. This field will always return a value.
KEY_SEQ | smallint | Is the sequence number of the column in a multicolumn primary key. NOT NULL.
PK_NAME | varchar(32) | Is a primary key identifier. Returns NULL if not applicable to the data source.


sp_server_info Catalog Stored Procedure

Returns a list of attribute names and matching values for SQL Server, the database gateway, and/or the underlying data source.

Syntax

sp_server_info [@attribute_id = ] attribute_id]

where

@attribute_id = attribute_id
Is the integer ID of the attribute.

Remarks

The sp_server_info stored procedure is a subset of the information provided by SQLGetInfo in ODBC.

This is the results set:

Column | Datatype | Description
ATTRIBUTE_ID | int | NOT NULL
ATTRIBUTE_NAME | varchar(60) | NOT NULL
ATTRIBUTE_VALUE | varchar(255) |

These are the rows in this results set. Microsoft DB-Library and ODBC client libraries currently use attributes 1, 2, 18, 22, and 500 at connection time.

ATTRIBUTE_ID | ATTRIBUTE_NAME Description | ATTRIBUTE_VALUE
1 | DBMS_NAME Name of the DBMS accessed by the gateway. | Microsoft SQL Server
2 | DBMS_VER Version of the DBMS accessed by the gateway. | @@version string
10 | OWNER_TERM DBMS vendor's term for a table owner (the second part of a three-part name). | Owner
11 | TABLE_TERM DBMS vendor's term for a table (the second part of a three-part name). | Table
12 | MAX_OWNER_NAME_LENGTH Maximum length of the name for a table owner (the second part of a three-part name). | 30
16 | IDENTIFIER_CASE The case-sensitivity of user-defined names (table names, column names, stored procedure names) in the database (the case in which these objects are presented in the system catalogs). | MIXED
15 | COLUMN_LENGTH Maximum number of characters for a column name. | 30
13 | TABLE_LENGTH Maximum number of characters for a table name. | 30
100 | USERID_LENGTH Maximum number of characters for a username. | 30
17 | TX_ISOLATION Initial transaction isolation level the server assumes, corresponding to an isolation level defined in ANSI SQL-92. | 2
18 | COLLATION_SEQ Assumed ordering of the character set for this server. | charset ID
14 | MAX_QUAL_LENGTH Maximum length of the name for a table qualifier (the first part of a three-part table name). | 30
101 | QUALIFIER_TERM DBMS vendor's term for a table qualifier (the first part of a three-part name). | Database
19 | SAVEPOINT_SUPPORT Specifies whether the underlying DBMS supports named savepoints. | Y
20 | MULTI_RESULT_SETS Specifies whether the underlying database or the gateway itself supports multiple results sets (multiple statements can be sent through the gateway with multiple results sets returned to the client). | Y
102 | NAMED_TRANSACTIONS Specifies whether the underlying DBMS supports named transactions. | Y
103 | SPROC_AS_LANGUAGE Specifies whether stored procedures can be executed as language events. | Y
113 | REMOTE_SPROC Specifies whether stored procedures can be executed through the remote stored procedure functions in DB-Library. | Y
22 | ACCESSIBLE_TABLES Specifies whether in the sp_tables stored procedure, the gateway returns only tables, views, and so on that are accessible by the current user (that is, the user who has at least SELECT privileges for the table). | Y
104 | ACCESSIBLE_SPROC Specifies whether in the sp_stored_procedures stored procedure, the gateway returns only stored procedures that are executable by the current user. | Y
105 | MAX_INDEX_COLS Maximum number of columns in an index for the DBMS. | 16
106 | RENAME_TABLE Specifies whether tables can be renamed. | Y
107 | RENAME_COLUMN Specifies whether columns can be renamed. | Y
108 | DROP_COLUMN Specifies whether columns can be dropped. | N
109 | INCREASE_COLUMN_LENGTH Specifies whether column size can be increased. | N
110 | DDL_IN_TRANSACTION Specifies whether DDL statements can appear in transactions. | N
111 | DESCENDING_INDEXES Specifies whether descending indexes are supported. | N
112 | SP_RENAME Specifies whether a stored procedure can be renamed. | Y
500 | SYS_SPROC_VERSION The version of the catalog stored procedures currently implemented. | Current version number


sp_special_columns Catalog Stored Procedures

Returns the optimal set of columns that uniquely identify a row in the table and columns that are automatically updated when any value in the row is updated by a transaction.

Syntax

sp_special_columns table_name [, table_owner] [, table_qualifier] [, col_type] [, scope] [, nullable]

where

table_name
Specifies the table used to return catalog information. The table_name can be a variable character length name with a maximum of 32 characters. Wildcard pattern matching is not supported.
table_owner
Specifies the table owner of the table used to return catalog information. The table_owner can be a variable character name with a maximum 32 characters. Wildcard pattern matching is not supported. If the table_owner is not specified, the default table visibility rules of the underlying DBMS apply.

In Microsoft SQL Server, if the current user owns a table with the specified name, that table's columns are returned. If the table_owner is not specified and the current user does not own a table with the specified table_name, this procedure will look for a table with the specified table_name owned by the database owner. If one exists, that table's columns are returned.

table_qualifier
Is the name of the table qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name. In some products, it represents the server name of the table's database environment.
col_type
Specifies the column type, either R or V. Type R returns the optimal column or set of columns that, by retrieving values from the column or columns, allows any row in the specified table to be uniquely identified. A column can be either a pseudo column specifically designed for this purpose, or the column or columns of any unique index for the table. Type V returns the column or columns in the specified table, if any, that are automatically updated by the data source when any value in the row is updated by any transaction.
scope
Specifies the minimum required scope of the ROWID, either C or T. Scope C specifies that the ROWID is valid only when positioned on that row. Scope T specifies that the ROWID is valid for the transaction.
nullable
Specifies whether or not the special column can accept a null value, either U or O. Nullable U specifies that this special column allows null values. Nullable O is a special column that does not allow null values.

Remarks

The sp_special_columns stored procedure is equivalent to SQLSpecialColumns in ODBC. The results returned are ordered by SCOPE.

This is the results set:

Column | Datatype | Description
SCOPE int Is the actual scope of the row ID. Can be 0, 1, or 2. SQL Server always returns 0. This field will always return a value.

0 SQL_SCOPE_CURROW. The row
ID is guaranteed to be valid only
while positioned on that row. A
later reselect using the row ID may
not return a row if the row was
updated or deleted by another
transaction.

1 SQL_SCOPE_TRANSACTION.
The row ID is guaranteed to be
valid for the duration of the current
transaction.

2 SQL_SCOPE_SESSION. The
row id is guaranteed to be valid for
the duration of the session (across
transaction boundaries).
COLUMN_NAME | varchar(32) | Is the name of the column, for each column of the TABLE_NAME returned. In Microsoft SQL Server, this column represents the column name as listed in the syscolumns table. This field will always return a value.
DATA_TYPE | smallint | Is an ODBC SQL datatype.
TYPE_NAME | varchar(13) | Is a data source-dependent datatype name; for example, 'CHAR', 'VARCHAR', 'MONEY', or 'TEXT'.
PRECISION | int | Is the precision of the column on the data source. This field will always return a value.
LENGTH | int | Is the length, in bytes, required for the datatype in its binary form in the data source. For example, 10 for CHAR(10), 4 for INTEGER, and 2 for SMALLINT.
SCALE | smallint | Is the scale of the column on the data source. NULL is returned for datatypes where scale is not applicable.
PSEUDO_COLUMN smallint Indicates whether the column is a pseudo column. SQL Server 6.0 always returns 2. Can be:

0 SQL_PC_UNKNOWN
1 SQL_PC_PSEUDO
2 SQL_PC_NOT_PSEUDO


sp_sproc_columns Catalog Stored Procedures

For SQL Server 6.5 information, see sp_sproc_columns in What's New for SQL Server 6.5.

Returns column information for a single stored procedure in the current environment.

Syntax

sp_sproc_columns procedure_name [, procedure_owner] [, procedure_qualifier] [, column_name]

where

procedure_name
Is the name of the procedure used to return catalog information. The procedure_name can be a variable character name with a maximum of 42 characters. Wildcard pattern matching is not supported.
procedure_owner
Is the name of the owner of the procedure used to return catalog information. The procedure_owner can be a variable character name with a maximum of 30 characters. Wildcard pattern matching is not supported. If procedure_owner is not specified, the default procedure visibility rules of the underlying DBMS apply.

In Microsoft SQL Server, if the current user owns a procedure with the specified name, that table's columns are returned. If procedure_owner is not specified and the current user does not own a procedure with the specified procedure_name, this procedure looks for a procedure with the specified procedure_name owned by the database owner. If one exists, that table's columns are returned.

procedure_qualifier
Specifies the name of the procedure qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name. In some products, it represents the server name of the table's database environment.
column_name
Specifies a single column and is used when only one column of catalog information is desired. If column_name is not specified, all columns will be returned. In Microsoft SQL Server, this column_name represents the column name as listed in the syscolumns table. The value specified can include wildcard characters using the underlying DBMS's wildcard matching patterns. For maximum interoperability, the gateway client should assume only ANSI-standard SQL pattern matching (the % and _ wildcard characters).

Remarks

The returned columns belong to the parameters or results set of a stored procedure. If the SP_NUM_PARAMETERS and SP_NUM_RESULT_SETS columns returned by sp_stored_procedure for a particular stored procedure are -1 (indeterminate), sp_proc_columns returns no rows for that stored procedure. In SQL Server 6.0, only the column information about input and output parameters for the stored procedure are returned.

The sp_sproc_columns catalog stored procedure is equivalent to SQLProcedureColumns in ODBC. The results returned are ordered by PROCEDURE_QUALIFIER, PROCEDURE_OWNER, PROCEDURE_NAME, and the order that the parameters appear in the procedure definition.

This is the results set:

Column | Datatype | Description
PROCEDURE_QUALIFIER | char(32) | Is the name of the procedure qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name. In some products, it represents the server name of the table's database environment. This field can be NULL.
PROCEDURE_OWNER | char(32) | Is the name of the procedure owner. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the name of the database user that created the table. This field will always return a value.
PROCEDURE_NAME | char(41) | Is the name of the procedure. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the procedure name as listed in the sysobjects table. This field will always return a value.
COLUMN_NAME | char(32) | Is the name of the column, for each column of the TABLE_NAME returned. In Microsoft SQL Server, this column represents the column name as listed in the syscolumns table. This field will always return a value.
COLUMN_TYPE | smallint | This field will always return a value. Can be: 0 SQL_PARAM_TYPE_UNKNOWN 1 SQL_PARAM_TYPE_INPUT 2 SQL_PARAM_TYPE_OUTPUT 3 SQL_RESULT_COL 4 SQL_PARAM_OUTPUT 5 SQL_RETURN_VALUE
DATA_TYPE | smallint | Is an integer code for an ODBC datatype. If this datatype cannot be mapped to an ANSI type, the value will be NULL. The native datatype name is returned in the TYPE_NAME column.
TYPE_NAME | char(30) | Is the string representation of the datatype. This is the datatype name as presented by the underlying DBMS.
PRECISION | int | Is the number of significant digits.
LENGTH | int | Is the transfer size of the data.
SCALE | smallint | Is the number of digits to the right of the decimal point.
RADIX | smallint | Is the base for numeric types.
NULLABLE | smallint | Specifies nullability. 1 means this datatype can be created allowing null values; 0 means null values are not allowed.
REMARKS | varchar(254) | Is a description of the procedure column. SQL Server will not return a value for this column.
SS_DATA_TYPE | tinyint | Is a SQL Server datatype, as defined in Microsoft SQL Server Programming DB-Library for C. The gateway converts the underlying data to this SQL Server datatype as the default, for use by Open Data Services gateway implementations of catalog stored procedures. If the gateway supports configurable datatype conversions, either per installation or per session, the conversion type when the stored procedure is executed is returned.
COLID | tinyint | Is a SQL Server - specific column added to the result set. This column does not need to appear in Open Data Services gateway implementations of catalog stored procedures.


sp_statistics Catalog Stored Procedures

Returns a list of all indexes on a specified table.

Syntax

sp_statistics table_name [, table_owner] [, table_qualifier]
[, index_name] [, is_unique]

where

table_name
Specifies the table used to return catalog information. The table_name can be a variable character length name with a maximum of 32 characters. Wildcard pattern matching is not supported.
table_owner
Specifies the table owner of the table used to return catalog information. The table_owner can be a variable character name with a maximum 32 characters. Wildcard pattern matching is not supported. If the table_owner is not specified, the default table visibility rules of the underlying DBMS apply.

In Microsoft SQL Server, if the current user owns a table with the specified name, that table's columns are returned. If the table_owner is not specified and the current user does not own a table with the specified table_name, this procedure will look for a table with the specified table_name owned by the database owner. If one exists, that table's columns are returned.

table_qualifier
Is the name of the table qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name. In some products, it represents the server name of the table's database environment.
index_name (varchar(32))
Is the index name. Wildcard pattern matching is not supported.
is_unique (char(1))
Identifies indexes to be returned. Enter Y if only unique indexes are to be returned.

Remarks

The indexes in the results set appear in ascending order by the columns NON_UNIQUE, TYPE, INDEX_NAME, and SEQ_IN_INDEX.

The index type clustered refers to an index in which table data is stored in the order of the index. This corresponds to SQL Server clustered indexes.

The index type hashed accepts exact match or range searches, but pattern matching searches do not use the index.

The sp_statistics stored procedure is equivalent to SQLStatistics in ODBC. The results returned are ordered by NON_UNIQUE, TYPE, INDEX_QUALIFIER, INDEX_NAME, and SEQ_IN_INDEX.

This is the results set:

Column | Datatype | Description
TABLE_QUALIFIER | varchar(32) | Is the name of the table qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name. In some products, it represents the server name of the table's database environment. This field can be NULL.
TABLE_OWNER | varchar(32) | Is the name of the table owner. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the name of the database user who created the table. This field will always return a value.
TABLE_NAME | varchar(32) | Is the name of the table. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the table name as listed in the sysobjects table. This field will always return a value.
NON_UNIQUE | smallint | NOT NULL. 0 means unique; 1 means non unique.
INDEX_QUALIFIER | varchar(32) | Is the name of the index owner. Some DBMS products allow users other than the table owner to create indexes. In Microsoft SQL Server, this column will always be the same as TABLE_OWNER.
INDEX_NAME | varchar(32) | Is the name of the index. This field will always return a value.
TYPE | smallint | This field will always return a value. SQL Server 6.0 returns 0, 1, or 3. Can be: 0 Statistics for a table 1 Clustered 2 Hashed 3 Other
SEQ_IN_INDEX | smallint | Is the position of the column within the index.
COLUMN_NAME | varchar(32) | Is the name of the column, for each column of the TABLE_NAME returned. In Microsoft SQL Server, this column represents the column name as listed in the syscolumns table. This field will always return a value.
COLLATION | char(1) | Is the order used in collation. SQL Server 6.0 always returns A. Can be: A Ascending D Descending NULL Not applicable
CARDINALITY | int | Is the number of rows in the table or unique values in the index.
PAGES | int | Is the number of pages to store the index or table.
FILTER_CONDITION | varchar(128) | SQL Server 6.0 does not return a value.


sp_stored_procedures Catalog Stored Procedures

Returns a list of stored procedures in the current environment.

Syntax

sp_stored_procedures [procedure_name] [, procedure_owner] [, procedure_qualifier]

where

procedure_name
Is the name of the procedure used to return catalog information. The procedure_name can be a variable character name with a maximum of 42 characters. Wildcard pattern matching is supported.
procedure_owner
Is the name of the owner of the procedure used to return catalog information. The procedure_owner can be a variable character name with a maximum of 30 characters. Wildcard pattern matching is supported. If procedure_owner is not specified, the default procedure visibility rules of the underlying DBMS apply.

In Microsoft SQL Server, if the current user owns a procedure with the specified name, that table's columns are returned. If procedure_owner is not specified and the current user does not own a procedure with the specified procedure_name, this procedure looks for a procedure with the specified procedure_name owned by the database owner. If one exists, that table's columns are returned.

procedure_qualifier
Specifies the name of the procedure qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name. In some products, it represents the server name of the table's database environment.

Remarks

For maximum interoperability, the gateway client should assume only ANSI-standard SQL pattern matching (the % and _ wildcards).

The privilege information about the current user's execute access to a specific stored procedure is not necessarily checked, so access is not guaranteed. Note that only three-part naming is used, so that only local stored procedures, not remote stored procedures (which need four-part naming), are returned when implemented against SQL Server. If the server attribute ACCESSIBLE_SPROC is Y in the results set for sp_server_info, then only stored procedures that can be executed by the current user are returned.

The sp_stored_procedures stored procedure is equivalent to SQLProcedures in ODBC. The results returned are ordered by PROCEDURE_QUALIFIER, PROCEDURE_OWNER, and PROCEDURE_NAME.

This is the results set:

Column | Datatype | Description
PROCEDURE_QUALIFIER | varchar(32) | Is the name of the procedure qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name. In some products, it represents the server name of the table's database environment. This field can be NULL.
PROCEDURE_OWNER | varchar(32) | Is the name of the procedure owner. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the name of the database user that created the table. This field will always return a value.
PROCEDURE_NAME | varchar(41) | Is the name of the procedure. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the procedure name as listed in the sysobjects table. This field will always return a value.
NUM_INPUT_PARAMS | int | Reserved for future use.
NUM_OUTPUT_PARAMS | int | Reserved for future use.
NUM_RESULT_SETS | int | Reserved for future use.
REMARKS | varchar(254) | Is a description of the procedure. SQL Server will not return a value for this column.
PROCEDURE_TYPE | smallint | Is the procedure type. SQL Server 6.0 always returns 2.0. Can be: 0 SQL_PT_UNKNOWN 1 SQL_PT_PROCEDURE 2 SQL_PT_FUNCTION


sp_table_privileges Catalog Stored Procedures

For SQL Server 6.5 information, see sp_table_privileges in What's New for SQL Server 6.5.

Returns privilege information for a single table in the current environment.

Syntax

sp_table_privileges table_name [, table_owner] [, table_qualifier]

where

table_name
Specifies the table used to return catalog information. The table_name can be a variable character length name with a maximum of 32 characters. Wildcard pattern matching is supported.
table_owner
Specifies the table owner of the table used to return catalog information. The table_owner can be a variable character name with a maximum of 32 characters. Wildcard pattern matching is supported. If the table_owner is not specified, the default table visibility rules of the underlying DBMS apply.

In Microsoft SQL Server, if the current user owns a table with the specified name, that table's columns are returned. If the table_owner is not specified and the current user does not own a table with the specified table_name, this procedure will look for a table with the specified table_name owned by the database owner. If one exists, that table's columns are returned.

table_qualifier
Is the name of the table qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name. In some products, it represents the server name of the table's database environment.

Remarks

SQL Server does not support the ability to grant privileges through SELECT_GRANTABLE, INSERT_GRANTABLE, UPDATE_GRANTABLE, DELETE_GRANTABLE, and REFERENCES_GRANTABLE.

The sp_table_privileges stored procedure is equivalent to SQLTablePrivileges in ODBC. The results returned are ordered by TABLE_QUALIFIER, TABLE_OWNER, TABLE_NAME, and PRIVILEGE.

This is the results set:

Column | Datatype | Description
TABLE_QUALIFIER | varchar(32) | Is the name of the table qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name. In some products, it represents the server name of the table's database environment. This field can be NULL.
TABLE_OWNER | varchar(32) | Is the name of the table owner. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the name of the database user who created the table. This field will always return a value.
TABLE_NAME | varchar(32) | Is the name of the table. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the table name as listed in the sysobjects table. This field will always return a value.
GRANTOR | varchar(32) | Is the name of the database user who has granted permissions on this TABLE_NAME to the listed GRANTEE. In Microsoft SQL Server, this column will always be the same as the TABLE_OWNER. This field will always return a value.
GRANTEE | varchar(32) | Is the name of the database user who has been granted permissions on this TABLE_NAME by the listed GRANTOR. In Microsoft SQL Server, this column will always include a database user from the sysusers table. This field will always return a value.
PRIVILEGE varchar(32) Is one of the available table privileges. Table privileges can be one of the following values (or other values supported by the data source when implementation is defined):

SELECT The GRANTEE can retrieve data for one or more of the columns.

INSERT The GRANTEE can provide data for new rows for one or more of the columns.

UPDATE The GRANTEE can modify existing data for one or more of the columns.

DELETE The GRANTEE can remove rows from the table.

REFERENCES The GRANTEE can reference a column in a foreign table in a primary key/foreign key relationship. In SQL Server 6.0, primary key/foreign key relationships are defined with table constraints.

The scope of action given to the GRANTEE by a given table privilege is data-source dependent. For example, the UPDATE privilege might permit the GRANTEE to update all columns in a table on one data source and only those columns for which the GRANTOR has UPDATE privilege on another data source.
IS_GRANTABLE | varchar(3) | Indicates whether or not the GRANTEE is permitted to grant privileges to other users (often referred to as "grant with grant" permission). Can be YES, NO, or NULL. An unknown (or NULL) value refers to a data source where "grant with grant" is not applicable. In SQL Server 6.0, "grant with grant" permission is not supported.


sp_tables Catalog Stored Procedures

Returns a list of objects that can be queried in the current environment (that is, any object that can appear in a FROM clause).

Syntax

sp_tables [table_name] [, table_owner] [, table_qualifier] [, table_type]

where

table_name
Specifies the table used to return catalog information. The table_name can be a variable character length name with a maximum of 32 characters. Wildcard pattern matching is supported.
table_owner
Specifies the table owner of the table used to return catalog information. The table_owner can be a variable character name with a maximum of 32 characters. Wildcard pattern matching is supported. If the table_owner is not specified, the default table visibility rules of the underlying DBMS apply.

In Microsoft SQL Server, if the current user owns a table with the specified name, that table's columns are returned. If the table_owner is not specified and the current user does not own a table with the specified table_name, this procedure will look for a table with the specified table_name owned by the database owner. If one exists, that table's columns are returned.

table_qualifier
Is the name of the table qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name. In some products, it represents the server name of the table's database environment.
table_type (varchar(60))
Is a list of values, separated by commas, that gives information about all tables of the table type(s) specified, including 'TABLE', 'SYSTEM TABLE', and/or 'VIEW'.

Note Single quotation marks must surround each table type, and double quotation marks must enclose the entire parameter. Table types must be uppercase. If QUOTED_IDENTIFIER is on, each single quotation mark must be doubled and the entire parameter must be surrounded by single quotation marks.

Remarks

For maximum interoperability, the gateway client should assume only ANSI-standard SQL pattern matching (the % and _ wildcards).

Privilege information about the current user's read or write access to a specific table is not always checked, so access is not guaranteed. This results set includes not only tables and views, but also synonyms and aliases for gateways to DBMS products that support those types. If the server attribute ACCESSIBLE_TABLES is Y in the results set for sp_server_info, only tables that are accessible by the current user are returned.

The sp_tables stored procedure is equivalent to SQLTables in ODBC. The results returned are ordered by TABLE_TYPE, TABLE_QUALIFIER, TABLE_OWNER, and TABLE_NAME.

This is the results set:

Column | Datatype | Description
TABLE_QUALIFIER | varchar(32) | Is the name of the table qualifier. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the database name. In some products, it represents the server name of the table's database environment. This field can be NULL.
TABLE_OWNER | varchar(32) | Is the name of the table owner. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the name of the database user who created the table. This field will always return a value.
TABLE_NAME | varchar(32) | Is the name of the table. Various DBMS products support three-part naming for tables (qualifier.owner.name). In Microsoft SQL Server, this column represents the table name as listed in the sysobjects table. This field will always return a value.
TABLE_TYPE | varchar(32) | Is a table, system table or view.
REMARKS | varchar(254) | SQL Server does not return a value for this column.


Stored Procedures - Extended Stored Procedures

Stored Procedures–Extended Stored Procedures

Extended stored procedures provide a way to dynamically load and execute a function within a dynamic-link library (DLL) in a manner similar to that of a stored procedure, seamlessly extending SQL Server functionality. Actions outside of SQL Server can be easily triggered and external information returned to SQL Server. Return status codes and output parameters (identical to their counterparts in regular stored procedures) are also supported. SQL Server includes system stored procedures that add (sp_addextendedproc), drop (sp_dropextendedproc), and provide information about (sp_helpextededproc) extended stored procedures.

For better performance, extended stored procedures are implemented as DLLs rather than as separate processes. A separate process requires a context switch as well as additional security overhead. Instead, the DLL is executed by the user thread and is part of the SQL Server process, and therefore shares its address space and Windows NT system security privileges. However, the DLL does not know of, or have direct access to, SQL Server data structures.

Extended stored procedures are categorized by their use. The categories of extended procedures are:

Integrated Security

These are the Integrated Security extended stored procedures:

xp_enumgroups | xp_logininfo
xp_grantlogin | xp_revokelogin
xp_loginconfig |

SQL Mail

These are the SQL Mail extended stored procedures:

xp_deletemail | xp_sendmail
xp_findnextmsg | xp_startmail
xp_readmail | xp_stopmail

General

These are the general extended stored procedures:

xp_cmdshell | xp_sprintf
xp_logevent | xp_sscanf
xp_msver |

Internal

A number of additional extended stored procedures exist for internal use by other stored procedures (replication, system, and so on). Although these procedures can be executed separately, they are not guaranteed to be included in future releases.

User-defined

Additional extended stored procedures can be created by programmers using Microsoft Open Data Services. For information about creating extended stored procedures, see Microsoft SQL Server Programming Open Data Services.

An additional level of security is added to the DLL by the SQL Server exception handler, which prevents the entire SQL Server from being stopped if an extended stored procedure causes a protection violation (typically, only that thread would be affected). SQL Server is protected from DLLs that might affect memory or harm the running SQL Server process. However, because SQL Server and all DLLs do share address space, there is always some small risk that a poorly written or insufficiently tested DLL could disrupt the entire system. It is important that the DLL (and all extended stored procedures within it) be well written and tested extensively. For this reason, only the SA can add extended stored procedures (using sp_addextendedproc).

Important Because extended stored procedures are external to SQL Server, they must be specified in the case (lowercase for all SQL Server-supplied extended stored procedures) in which they were designed.

Each of the following sections describe these extended stored procedures.


xp_cmdshell Extended Stored Procedure

Executes a given command string as an operating-system command shell and returns any output as rows of text.

Syntax

xp_cmdshell command_string [, no_output]

where

command_string
Specifies the command string to execute at the operating-system command shell.
no_output
Is an optional parameter that executes the given command_string but does not return any output to the client.

Remarks

Be aware that when you grant execute permission for xp_cmdshell to users, the users will be able to execute any operating-system command at the Windows NT command shell that the account running SQL Server (typically local system) has privilege to execute.

To restrict xp_cmdshell access to users who have administrator permission on the Windows NT-based computer where SQL Server is running, use SQL Setup or SQL Enterprise Manager to set the server options, selecting the "xp_cmdshell - Impersonates Client" option. With this option selected, only users who have connected to SQL Server via a trusted connection and are members of the local Administrators group on that computer are allowed to use xp_cmdshell. The commands run by xp_cmdshell continue to execute in the server's security context.

Examples

A. Return a List of Executable Files

This example shows the xp_cmdshell extended stored procedure executing a directory command.

EXEC master..xp_cmdshell "dir *.exe"
B. Use Windows NT net Commands

This example shows the use of xp_cmdshell in a stored procedure. This example notifies users (with net send) that SQL Server is about to be shut down, pauses the server (with net pause), and then shuts the server down (with net stop):

CREATE PROC shutdown10
AS
EXEC xp_cmdshell "net send /domain:SQL_USERS 'SQL Server shutting down
    in 10 minutes. No more connections     allowed.'", no_output
EXEC xp_cmdshell "net pause sqlserver"
WAITFOR DELAY "00:05:00"
EXEC xp_cmdshell "net send /domain: SQL_USERS 'SQL Server shutting down
    in 5 minutes.'", no_output
WAITFOR DELAY "00:04:00"
EXEC xp_cmdshell "net send /domain:SQL_USERS 'SQL Server shutting down
    in 1 minute. Log off now.'", no_output
WAITFOR DELAY "00:01:00"
EXEC xp_cmdshell "net stop sqlserver", no_output
C. Do Not Return Output

This example uses xp_cmdshell to execute a command string without returning the output to the client.

EXEC xp_cmdshell "copy c:\sqldumps\pubs.dmp \\server2\backups\sqldumps",
    NO_OUTPUT
D. Use Return Status

In this example, the xp_cmdshell extended stored procedure also suggests return status.

DECLARE @result int
EXEC @result = xp_cmdshell "dir *.exe"
IF (@result = 1)
    PRINT "Success"
ELSE
    PRINT "Failure"

Permission

Execute permission defaults to the system administrator, who can grant permission to other users.

See Also

CREATE PROCEDURE | EXECUTE
CREATE TRIGGER |


xp_deletemail Extended Stored Procedure

Deletes a message from the SQL Server inbox. This procedure is used by the sp_processmail system stored procedure to process mail in the SQL Server inbox.

Syntax

xp_deletemail [@msg_id = ] msg_id

where

@msg_id = msg_id
Specifies the ID (as assigned by xp_findnextmsg) of the mail message in the inbox that should be deleted.

Remarks

This extended stored procedure returns a successful (0) or failed (1) status. Any failure except an invalid parameter is logged to the Windows NT application event log.

Example

This example deletes the message ID as supplied from xp_findnextmsg. In this example, the value from xp_findnextmsg is placed in a local variable named @message_id.

xp_deletemail @message_id

Permission

Execute permission defaults to the system administrator, who can grant permission to other users.

See Also

sp_processmail | xp_sendmail
xp_findnextmsg | xp_startmail
xp_readmail | xp_stopmail


xp_enumgroups Extended Stored Procedure

Provides a list of local Windows NT - based groups or a list of groups defined in a specified Windows NT domain.

Syntax

xp_enumgroups [domain_name]

where

domain_name
Is the name of the Windows NT domain to enumerate a list of groups for.

Remarks

The xp_enumgroups extended stored procedure enumerates the global groups in a domain. If domain_name is the name of the Windows NT - based computer on which SQL Server is running, xp_enumgroups enumerates the computer's local groups. If no domain name is specified, the computer's local groups are enumerated.

Example

This example enumerates the groups in the salesdomain domain.

xp_enumgroups salesdomain

Permission

Execute permission defaults to the system administrator and can be granted to other users.

See Also

xp_grantlogin | xp_logininfo
xp_loginconfig | xp_revokelogin


xp_findnextmsg Extended Stored Procedure

Accepts a message ID for input and returns the message ID for output. This extended stored procedure is used with the sp_processmail system stored procedure in order to process mail in the SQL Server inbox.

Syntax

xp_findnextmsg [@msg_id = msg_id [OUTPUT]]
[, @type = type]
[, @unread_only = {'true' | 'false'}])

where

@msg_id = msg_id
Is an input and output parameter; specifies the string of the message on input and the string of the next message on output.
OUTPUT
When specified, places the value of the msg_id in the output parameter. When not specified, the msg_id is returned as a single-column, single-row results set.
@type = type
Is the input message type based on the MAPI mail definition:
IP[M | C].Vendorname.subclass

Message types beginning with IPM will appear in the inbox of the mail client, and will be found or read by xp_findnextmsg if the @type is NULL. Message types beginning with IPC do not appear in the inbox of the mail client and must be found or read by setting the @type parameter. The default is NULL.

@unread_only = 'true' | 'false'
Specifies that only unread messages are considered. The default is true.

Remarks

This extended stored procedure returns a successful (0) or failed (1) status. Any failure except an invalid parameter is logged to the Windows NT application event log.

Example

This example returns the status when searching for the next message ID (for only unread messages). In this example, the value from xp_findnextmsg is placed in a local variable named @message_id.

EXEC @status = xp_findnextmsg @msg_id = @message_id OUTPUT

Permission

Execute permission defaults to the system administrator, who can grant permission to other users.

See Also

sp_processmail | xp_sendmail
xp_deletemail | xp_startmail
xp_readmail | xp_stopmail


xp_grantlogin Extended Stored Procedure

Grants SQL Server access to a Windows NT - based group or user.

Syntax

xp_grantlogin 'account_name' [, {'admin' | 'repl' | 'user'}]

where

account_name
Specifies the Windows NT - based group or user. The group or user must already be defined in Windows NT. If the group or username does not include a domain name and a backslash (\), Windows NT initially searches for a matching user on the local computer, then on the primary domain controller, and then on trusted domains.
admin
Gives account_name system administrator privilege.
repl
Gives account_name privilege to log on as repl_publisher.
user
Explicitly gives account_name user privilege. If no parameter is specified, user privilege is granted.

Remarks

You can change accounts from one privilege level to another by executing xp_grantlogin.

Example

This example grants SQL Server access to the sqladmins group and gives the group system administrator privilege.

xp_grantlogin 'sqladmins', 'admin'

Permission

Execute permission defaults to the system administrator and can be granted to other users.

See Also

xp_enumgroups | xp_logininfo
xp_loginconfig | xp_revokelogin


xp_logevent Extended Stored Procedure

Logs a user-defined message in the SQL Server log file and/or in the Windows NT Event Viewer. When sending messages from Transact-SQL procedures, triggers, batches, and so on, use the RAISERROR statement instead of xp_logevent. If raising an error to the client is not desired, xp_logevent can be used to send an alert without sending a message to the client.

Syntax

xp_logevent error_number, message, [severity]

where

error_number
Is a user-defined error number greater than 50,000. The maximum value is 1,073,741,823 (2 (30) - 1).
message
Is a character string less than 255 characters. This message is logged in the SQL Server log file and/or in the Windows NT Event Viewer.
severity
Is one of three character strings: Informational, Warning, or Error. This parameter is optional; the default is Informational.

Remarks

The xp_logevent extended stored procedure does not call a client's message handler or set @@ERROR. To write messages to the Windows NT Event Viewer and/or to the SQL Server error log file with SQL Server 6.0, you can execute the RAISERROR statement. For details, see the RAISERROR statement.

Example

This example logs the message (with variables passed to the message) in the Windows NT Event Viewer.

DECLARE @tabname varchar(30)
DECLARE @username varchar(30)
DECLARE @message varchar(255)
SELECT @tabname = 'titles'
SELECT @username = USER_NAME()
SELECT @message = 'The table "'  @tabname  '" is not owned by the user
    "'  @username  '."'

EXEC xp_logevent 60000, @message, informational

Permission

Execute permission defaults to the system administrator and can be granted to other users.

See Also

PRINT | RAISERROR


xp_loginconfig Extended Stored Procedure

Reports the login security configuration of the server.

Syntax

xp_loginconfig ['config_name']

where

config_name
Specifies the configuration value about which to display information. If no config_name is specified, all configuration values are reported. These values are valid:
Configuration
value
Description
login mode | The login security mode. Possible values are standard, integrated, and mixed.
default login | The name of the default SQL Server login ID for authorized users of trusted connections (for users without matching login names in the syslogins table). This value is NULL if no default is allowed (users without matching login names in syslogins will not be allowed to connect) or if the login mode is standard.
default domain | The name of the default Windows NT domain for network users of trusted connections. This value is NULL if the login mode is standard.
audit level | The audit level. Possible values are none, success, failure, and all. Audits are written to the error log and/or to the Windows NT Event Viewer.
set hostname | Indicates whether the hostname from the client login record is replaced with the Windows NT network username for users under integrated security. Possible values are true or false. If this is set, the network username appears in output from sp_who.
map _ | Reports which special Windows NT characters are mapped to the valid SQL Server character _ (underscore). Possible values are domain separator, space, null, or any single character.
map # | Reports which special Windows NT characters are mapped to the valid SQL Server character # (pound sign). Possible values are domain separator, space, null, or any single character.
map $ | Reports which special Windows NT characters are mapped to the valid SQL Server character $ (dollar sign). Possible values are domain separator, space, null, or any single character.

Remarks

The xp_loginconfig extended stored procedure cannot be used to set configuration values. Use the SQL Server setup program to change configuration settings.

Examples

A. Report All Configuration Values

This example shows all of the currently configured settings for integrated login security.

xp_loginconfig

name

config_value

----------------

-------------------------

login mode

integrated

default login

guest

default domain

REDMOND

audit level

none

set hostname

false

map _

domain separator

map $

NULL

map #

-

B.    Report Login Mode Configuration Value

This example shows the setting for only the login mode.

xp_loginconfig 'login mode'

    name

config_value

    ----------------

-------------------------

    login mode

standard

Permission

Execute permission defaults to the system administrator and can be granted to other users.

See Also

xp_grantlogin | xp_revokelogin
xp_logininfo |


xp_logininfo Extended Stored Procedure

Reports the account, the type of account, the privilege level of the account, the map name of the account, and the permission path by which the account has access to SQL Server.

Syntax

xp_logininfo ['account_name' [, 'all' | 'members']
[, [@privilege] = variable_name OUTPUT]]

where

account_name
Is the name of a Windows NT - based group or user granted SQL Server access. If no account_name is given, all groups and users that have been explicitly granted login permission are reported.
all | members
Specifies whether to report information on all permission paths for the account, or to report information on the members of the group.
@privilege = variable_name
Is an optional output parameter that returns the privilege level of the specified Windows NT account. The privilege level returned is 'user', 'admin', or 'repl'.

Remarks

If an account_name is specified as the first parameter, xp_logininfo reports the highest privilege level access for that account. If a user has access as a system administrator and as a user, only the system administrator level (highest privilege) entry is reported. If the user is a member of multiple groups that have the same privilege level, only the first group that matches is reported (the order of the groups is the order in which the groups were granted access to SQL Server). A maximum of one result row is returned. If account_name is a valid Windows NT account but that account does not have permission to access SQL Server, an empty result set is returned. If account_name cannot be identified as a valid Windows NT account, an error message is returned.

If account_name is specified as the first parameter and all is specified as the second parameter, all permission paths for that account are listed. If a given username is a member of multiple groups, all of which have been granted access to SQL Server, multiple rows are returned. The system administrator privilege rows are reported before the user privilege rows, and within a privilege level the row order is the order in which the accounts were granted access to SQL Server. This parameter applies to both individual users and groups.

If account_name is specified as the first parameter and members is specified as the second parameter, then a list of the next-level members of the group is returned. If account_name is a local group, the listing can include local users, domain users, and global groups. If account_name is a global account, the list consists of domain users. If account_name is a user account, an error message is returned.

Examples

A. Login Information for a Single Group

This example returns information about only a single group (admin).

EXEC xp_logininfo 'admin'
go

account name    type    privilege    mapped login name    permission path
-------------    ------    ---------    -----------------    ----------------
SQLSRV\admin    user    (null)    (null)    Everyone

(1 row(s) affected)

These are the results columns for xp_logininfo:

Column heading | Description
account name | The fully qualified account name as known to Windows NT.
type | The type of Windows NT account. Valid values are user, local group, global group, and well-known group.
privilege | The access privilege for SQL Server. Valid values are admin, repl, or user.
mapped login name | For user accounts with user privilege, mapped login name shows the mapped login name that SQL Server will try to use when logging in with this account, using the mapped rules with the domain name added before it.
permission path | The group membership that allowed the account access.

B. Windows NT Account Information

This example shows how the optional output parameter that returns the privilege level of the specified Windows NT account might be used:

DECLARE @value varchar (30)
SELECT @value = NULL
EXEC xp_logininfo '\nwind1\plato', 'all', @value OUTPUT
SELECT 'The NT account nwind1\plato has '''  @value  ''' privilege.'

Permission

Execute permission defaults to the system administrator and can be granted to other users.

See Also

xp_grantlogin | xp_revokelogin
xp_loginconfig |


xp_msver Extended Stored Procedure

Returns and allows to be queried SQL Server version information. In addition to version information regarding the actual build number of the server, various environment information is also returned. This information can be used within Transact-SQL statements, batches, stored procedures, and so on, to enhance logic for platform-independent code.

Syntax

xp_msver [optname]

where

optname
Specifies one of these option names:

Option name 		Internal version Example of
string description
ProductName | NULL | Microsoft SQL Server
ProductVersion | 393216 | 6.00.105 (6.00 is the version, 105 is the internal build number used by Microsoft)
Language | 1033 | U.S. English
Platform | NULL | NT INTEL X86
Comments | NULL | NT INTEL X86
CompanyName | NULL | Microsoft Corporation
FileDescription | NULL | SQL Server Windows NT
FileVersion | NULL | 1995.04.28
InternalName | NULL | SQLSERVR
LegalCopyright | NULL | Copyright © Microsoft Corp. 1995
LegalTrademarks | NULL | Microsoft® is a registered trademark of Microsoft Corporation
OriginalFilename | NULL | SQLSERVR.EXE
PrivateBuild | NULL | NULL
SpecialBuild | 0 | NULL
WindowsVersion | 65680131 | 3.51 (1002) (3.51 is the Windows NT version, 1002 is the internal build number used by Microsoft)
ProcessorCount | 1 | 1
ProcessorActiveMask | 1 | 00000001
ProcessorType | 486 | PROCESSOR_INTEL_486
PhysicalMemory | 32 | 32 (33357821)
Product ID | NULL | 12345-1234567890

Remarks

The Product ID (PID) is specified during installation. The number entered is located on a sticker on the original SQL Server CD case.

Permissions

Execute permission defaults to the public group.


xp_readmail Extended Stored Procedure

Reads a mail message from the SQL Server mail inbox. This procedure is used by the sp_processmail system stored procedure to process all mail in the SQL Server inbox.

Syntax

xp_readmail ([@msg_id = msg_id] [, @type = type [OUTPUT]]
[, @peek = {'true' | 'false'}]
[, @suppress_attach = {'true' | 'false'}]
[, @originator = @sender OUTPUT]
[, @subject = @subject_line OUTPUT]
[, @message = @body_of_message OUTPUT]
[, @recipients = @recipient_list OUTPUT]
[, @cc_list = @cc_list OUTPUT]
[, @bcc_list = @bcc_list OUTPUT]
[, @date_received = @date OUTPUT]
[, @unread = {'true' | 'false'}]
[, @attachments = @temp_file_paths OUTPUT])
[, @skip_bytes = @bytes_to skip OUTPUT]
[, @msg_length = @length_in_bytes OUTPUT])

where

@msg_id = msg_id
Specifies the ID of the message to read.
@type = type
Returns the message class based on the MAPI mail definition:
IP[M | C].Vendorname.subclass

If used on input, this must define the type for a specific message; this parameter is ignored on input if the msg_id is NULL.

The default type is NULL.

@peek = {'true' | 'false'}
Allows SQL Server to return the message of the mail without changing the mail status to read. The default is false (treat the mail as though it has been read).
@suppress_attach = {'true' | 'false'}
Suppresses mail attachments. When set to true, prevents the creation of temporary files when xp_readmail reads a message with attachments. The default is true (do not create temporary files).
@originator = @sender
Is the variable in which the mail address of the sender will be returned. Define this variable as varchar(255).
@subject = @subject_line
Is the variable in which the subject of the mail message will be returned. Define this variable as varchar(255).
@message = @body_of_message
Is the variable in which the body (the actual text) of the mail message will be returned. Define this variable as varchar(255).
@recipients = @recipient_list
Is the variable in which the list of the recipients of the mail message will be returned. Recipients' names are separated by a semicolon (;). Define this variable as varchar(255).
@cc_list = @cc_list
Is the variable in which the list of the copied recipients (cc:'ed) of the mail message will be returned. Recipients' names are separated by a semicolon (;). Define this variable as varchar(255).
@bcc_list = @bcc_list
Is the variable in which the list of the blind copy recipients (bcc:'ed) of the mail message will be returned. Recipients' names are separated by a semicolon (;). Define this variable as varchar(255).
@date_received = @date
Is the variable in which the date of the mail message will be returned. Define this variable as varchar(255).
@unread = 'true' | 'false'
Specifies that only unread messages are considered. The default is true.
@attachments = @temp_file_paths
Is the variable in which the temporary paths of the mail attachments will be returned. Temporary paths are separated by a semicolon (;). Define this variable as varchar(255).
@skip_bytes = @bytes_to skip OUTPUT
If a value other than 0 is passed for input, this parameter specifies the number of bytes to skip before reading the next 255 bytes (max) of the message into the @body of message output parameter. When @skip_bytes is used, @body_of_message will include the next portion of the message and @bytes_to_skip will return with the next starting point within the message (the previous @bytes_to_skip plus the length of @body_of_message).
@msg_length = @length_in_bytes OUTPUT
Returns the total length of the message, in bytes. When used with @skip_bytes in a stored procedure, this parameter will allow messages to be read in chunks of 255 bytes.

Remarks

This extended stored procedure returns a successful (0) or failed (1) status. Any failure except an invalid parameter is logged to the Windows NT application event log.

Example

This example returns the status when reading a message. In this example, the value of a message ID from xp_findnextmsg is placed in a local variable named @message_id and passed to xp_readmail.

EXEC @status = xp_readmail @msg_id = @message_id,
        @originator = @originator OUTPUT,
        @cc_list = @cc_list OUTPUT,
        @subject = @msgsubject OUTPUT,
        @message = @query OUTPUT,
        @peek = 'TRUE',
        @suppress_attach = 'TRUE'

Permission

Execute permission defaults to the system administrator, who can grant permission to other users.

See Also

sp_processmail | xp_sendmail
xp_deletemail | xp_startmail
xp_findnextmsg | xp_stopmail


xp_revokelogin Extended Stored Procedure

Revokes SQL Server access from a Windows NT - based group or user.

Syntax

xp_revokelogin 'account_name'

where

account_name
Specifies the Windows NT - based group or username for which to revoke access. If the group or username does not include a domain name and a backslash (\), Windows NT initially searches for a matching user on the local computer, then on the primary domain controller, and then on trusted domains.

Remarks

You can revoke permission only on an account on which you have been explicitly granted permission through xp_grantlogin.

Example

This example revokes SQL Server access from the SQL Server Administrator group.

xp_revokelogin 'SQL Server administrator'

Permission

Execute permission defaults to the system administrator and can be granted to other users.

See Also

xp_grantlogin | xp_logininfo
xp_loginconfig |


xp_sendmail Extended Stored Procedure

Sends a message, and/or a query results set, and/or an attachment to the specified recipients.

Syntax

xp_sendmail @recipient = recipient [; recipient2; [...; recipientn]]
[, @message = message]
[, @query = query]
[, @attachments = attachments]
[, @copy_recipients = recipient [; recipient2; [...; recipientn]]]
[, @blind_copy_recipients = recipient [; recipient2; [...; recipientn]]]
[, @subject = subject]
[, @type = type]
[, @attach_results = {'true' | 'false'}]
[, @no_output = {'true' | 'false'}]
[, @no_header = {'true' | 'false'}]
[, @width = width]
[, @separator = separator]
[, @echo_error = {'true' | 'false'}]
[, @set_user = user]
[, @dbuse = dbname]

where

@recipient = recipient
Is a required parameter specifying the people to whom you are sending the mail. If you specify more than one name, separate the names with semicolons.
@message = message
Is an optional parameter that specifies the message to be sent.
@query = query
Is an optional parameter that specifies a valid SQL Server query, the result of which will be sent in mail.
@attachments = attachments
Is an optional parameter that specifies a file to attach to the mail.
@copy_recipients
Is an optional parameter that identifies recipients to whom you are sending a copy of the mail (cc:'ing).
@blind_copy_recipients
Is an optional parameter that identifies recipients to whom you are sending a blind copy of the mail (bcc:'ing).
@subject = subject
Is an optional parameter that specifies the subject of the mail. If you do not specify a subject, "SQL Server Message" is used as the subject.
@type = type
Is the input message type based on the MAPI mail definition:
IP[M | C].Vendorname.subclass

Message types beginning with IPM will appear in the inbox of the mail client, and will be found or read by xp_findnextmsg if the @type is NULL. Message types beginning with IPC do not appear in the inbox of the mail client and must be found or read by setting the @type parameter. The default is NULL.

For details about using custom message types, see the Microsoft Windows NT Resource Kit or the Microsoft Mail Technical Reference, available separately.

@attach_results = {'true' | 'false'}
Is an optional parameter that specifies that the results set of a query should be sent in mail as an attached file instead of being appended to the mail. If @attachments is not NULL and @attach_results is true, the first filename in @attachments will be used as the filename for the results. If @attachments is NULL, a filename will be generated with a .TXT extension. The default for this parameter is false, which means that the results set is appended to the message.
@no_output = {'true' | 'false'}
Is an optional parameter that sends the mail but does not return any output to the client session that sent the mail. The default is false, which means that the client session of SQL Server receives output.
@no_header = {'true' | 'false'}
Is an optional parameter that sends the query results in mail but does not send column header information with the query results. The default is false, which means that column header information is sent with the query results.
@width = width
Is an optional parameter that sets the line width of the output text for an @query message. This parameter is identical to the /w parameter in isql. For queries that produce long output rows, use @width together with @attach_results to send the output without line breaks in the middle of output lines. The default width is 80 characters.
@separator = separator
Specifies the column separator (field terminator) for each column of the results set. This allows the files to be accessible by spreadsheet applications for formatting, and so on. This parameter is identical to the /t parameter in isql. For example, use @separator with @attach_results to send files with comma-separated values.
@echo_error = {'true' | 'false'}
When true, causes SQLMail to capture any server messages or DB-Library errors encountered while running the @query and append them to the mail message rather than writing them to the error log. Also, a count of rows returned/rows affected will be appended to the mail message.

Note If @echo_error is true, xp_sendmail returns a status of 0 (success) if the mail is successfully sent, even if DB-Library errors or messages are encountered or the query returns no results.

@set_user = user
Specifies the security context in which the query should be run. The default is 'guest' (the guest user).
@dbuse = dbname
Specifies the database context in which the query should be run. The default is NULL (which means the user is placed in his or her default database).

Remarks

The SQLMail session must be started prior to executing xp_sendmail. Sessions can be started either automatically (using the Auto Start Mail Client option in the Set Server Options dialog box of setup) or with xp_startmail. One SQLMail session supports all users on the SQL Server, but only one user at a time can send a message. Other users sending mail messages will automatically wait their turns until the first user's message is sent.

If @query is specified, xp_sendmail logs in to SQL Server as a client and executes the specified query. SQLMail makes a separate connection to SQL Server; it does not share the same connection as the original client connection that issued xp_sendmail. Note that @query can be blocked by a lock held by the client connection that issued xp_sendmail. For example, if you are updating a table within a transaction and you create a trigger for that update that attempts to select the updated row information as the @query parameter, the SQLMail connection will be blocked by the exclusive lock held on that row by the initial client connection.

For details, see the Microsoft SQL Server Administrator's Companion.

Examples

A. With No Variables

This example sends a message to user1 that the master database is full.

xp_sendmail 'user1', 'The master database is full.'
B. With Variables

This example sends the message to user1 and user2, with copies sent to user3 and user4. It also specifies a subject line for the message.

xp_sendmail @recipients = 'user1;user2',
@message = 'The master database is full.',
@copy_recipients = 'user3;user4',
@subject = 'Master Database Status'
C. Send Results

This example sends the results of the sp_configure system stored procedure to user1.

xp_sendmail 'user1', @query = 'sp_configure'
D. Send Results as an Attached File

This example sends the results of the query SELECT * from sysobjects as a text file attachment to user1. It includes a subject line for the mail and a message that will appear before the attachment. The @width option is used to prevent line breaks in the output lines.

xp_sendmail @recipients = 'user1',
@query = 'select * from sysobjects',
@subject = 'SQL Server Report',
@message = 'The contents of sysobjects:',
@attach_results = 'TRUE', @width = 250
E. Send Messages Longer than 255 Characters

This example shows how to send a message longer than 255 characters. Because the @message parameter is limited to the length of a varchar (as are all stored procedure parameters), this example writes the long message into a global temporary table consisting of a single text column. The contents of this temporary table are then sent in mail using the @query parameter.

CREATE TABLE ##texttab (c1 text)
INSERT ##texttab values ('Put your long message here.')
DECLARE @cmd varchar(56)
SELECT @cmd = 'SELECT c1 FROM ##texttab
EXEC master.dbo.xp_sendmail 'user1',
    @query = @cmd, @no_header= 'TRUE'
DROP TABLE ##texttab

Permission

Execute permission defaults to the system administrator, who can grant permission to other users.

See Also

sp_processmail | xp_readmail
xp_deletemail | xp_startmail
xp_findnextmsg | xp_stopmail


xp_sprintf Extended Stored Procedure

Formats and stores a series of characters and values in the string output parameter. Each format argument is replaced with the corresponding argument.

Syntax

xp_sprintf @string OUTPUT, format [, argument]...

where

@string OUTPUT
Is a varchar OUTPUT parameter that will return the result string.
format
Is a format character string similar to that supported by the C-language sprintf. Currently, only the '%s' format argument is supported.
argument
Is a character string that represents the value of the corresponding format argument. As many as 50 arguments can be specified.

Example

Sending an INSERT

This example uses the @string parameter to send an INSERT statement. The actual value of @string will contain 'INSERT table1 VALUES(1, 2).'

DECLARE @string varchar (255)
EXEC xp_sprintf @string OUTPUT, 'INSERT INTO %s VALUES (%s, %s)', 'table1', '1', '2'

Permission

Execute permission defaults to the public group.

See Also

xp_sscanf


xp_sscanf Extended Stored Procedure

Reads data from the string into the argument locations given by each format argument.

Syntax

xp_sscanf string, format, [, argument]...

where

string
Is the character string to read the argument values from.
format
Is a formatted character string similar to what is supported by the C-language sscanf. Currently only the '%s' format argument is supported.
argument
Is a varchar output parameter that will return the value of the corresponding format argument. Up to 50 arguments can be specified.

Example

In this example, the @filename parameter will contain the value authors10.tmp.

DECLARE @filename varchar (255)
EXEC xp_sscanf 'sync -b -fauthors10.tmp', 'sync -b -f%s',
@argument1=@filename OUTPUT

Permission

Execute permission defaults to the public group.

See Also

xp_sprintf


xp_startmail Extended Stored Procedure

Starts a SQL Server mail client session.

Syntax

xp_startmail ['user'] [, 'password']

where

user
Is an optional parameter specifying a mail username.
password
Is the mail password for the named user. NULL is allowed when the mail client is started (on the same computer) before running xp_startmail.

Remarks

If user and password are provided, SQL Server attempts to log on to Windows NT Mail (or other MAPI provider) using that username and password. If user and password are provided but are incorrect, an error message is returned. If no user or password are provided, SQL Server uses the username and password specified in SQL Setup, using the Mail Login dialog box under Server Options.

If there is an existing mail session, xp_startmail will not start a new one. If mail is being used on the same computer on which SQL Server is also running, the mail client must be started before xp_startmail is used or before SQL Server (if using the Set Server Options "Auto Start Mail Client" option found in SQL Setup). For more information, see the Microsoft SQL Server Administrator's Companion.

Examples

A. No Variables with xp_startmail

This example starts mail using the username and password specified in SQL Setup.

xp_startmail
B. Variables with xp_startmail

This example starts mail using the username mailuser and the password abc12345.

xp_startmail 'mailuser', 'abc12345'

Permission

Execute permission defaults to the system administrator, who can grant permission to other users.

See Also

sp_processmail | xp_readmail
xp_deletemail | xp_sendmail
xp_findnextmsg | xp_stopmail


xp_stopmail Extended Stored Procedure

Stops a SQL Server mail client session.

Syntax

xp_stopmail

Remarks

If there is no existing SQL Server mail session to stop, a message is returned.

Permission

Execute permission defaults to the system administrator, who can grant permission to other users.

See Also

sp_processmail | xp_readmail
xp_deletemail | xp_sendmail
xp_findnextmsg | xp_startmail


Stored Procedures - Replication Stored Procedures

Stored Procedures–Replication Stored Procedures

This section describes the stored procedures used by replication to implement and initiate replication on a SQL Server 6.0 server. Replication uses stored procedures to perform:

  • Server configuration
  • Publication administration tasks
  • Subscription administration tasks
  • Replication operations
  • Replicated transaction management
  • Scheduling
Stored Procedures Used for Server Configuration

These are the stored procedures used by replication for server configuration:

sp_addpublisher | sp_dropsubscriber
sp_addsubscriber | sp_helpdistributor
sp_changesubscriber | sp_helpserver
sp_dboption | sp_helpsubscriberinfo
sp_droppublisher | sp_replsync

Stored Procedures Used for Publication Administration

These are the stored procedures used by replication for publication administration tasks:

sp_addarticle | sp_helparticle
sp_addpublication | sp_helparticlecolumns
sp_articlecolumn | sp_helppublication
sp_changearticle | sp_helppublicationsync
sp_changepublication | sp_helpreplicationdb
sp_droparticle | sp_replflush
sp_droppublication | sp_replstatus
sp_enumfullsubscribers |

Stored Procedures Used for Subscription Administration

These are the stored procedures used by replication for subscription administration tasks:

sp_addsubscription | sp_helpsubscription
sp_changesubscription | sp_subscribe
sp_changesubstatus | sp_unsubscribe
sp_dropsubscription | sp_helpreplicationdb

Stored Procedures Used for Replication Operations

These are the stored procedures used for replication operations:

sp_distcounters | sp_replica
sp_replcleanup | sp_replsync

Stored Procedures Used for Replicated Transaction Management

These are the extended stored procedures used to manage and return information about replicated transactions:

sp_MSkill_job | sp_repldone
sp_replcmds | sp_repltrans
sp_replcounters |

Stored Procedures Used for Replication Scheduling

These are the stored procedures used for scheduling of replication tasks in the msdb database:

sp_addtask | sp_helptask
sp_droptask |

For details, see the SQL Executive stored procedures.


sp_addarticle Replication Stored Procedure

Creates an article and adds it to a publication.

Syntax

sp_addarticle publication, article, source_table [, destination_table]
[, vertical_partition] [, type] [, filter] [, sync_object] [, ins_cmd]
[, del_cmd] [, upd_cmd] [, creation_script] [, description]
[, pre_creation_cmd] [, filter_clause]

where

publication
Specifies the name of the publication that will contain the article. This name must be unique in the database.
article
Is the article's name. The name must be unique within the publication.
source_table
Specifies the name of the underlying table represented by the article.
destination_table
Is the name of the destination (subscription) table, if different from source_table.
vertical_partition
Determines the vertical position. If set to false, indicates there is no vertical partition, will publish all columns. If set to true, clears all columns except the declared primary key. Columns are added using the sp_articlecolumn replication stored procedure.
type
Specifies the type of article. Can be:
1 Log-based article (the default)
3 Log-based article with manual filter
5 Log based article with manual view
7 Log-based article with manual filter and manual view
filter
Specifies the stored procedure (created with FOR REPLICATION) used to filter the table (horizontal partition). The default is NULL, which means that sp_articlefilter will be called to automatically generate the filter. This occurs after adding any columns with sp_articlecolumn. If not NULL, the filter procedure will not be created (assumes manual stored procedure creation).
sync_object
Is the name of the table or view used for producing a synchronization output file. The default is NULL, which means that sp_articleview will be called to automatically create the view that will synchronize the output file. This occurs after adding any columns with sp_articlecolumn. If not NULL, a view will not be created (assumes manual view creation).
ins_cmd
Specifies the command to execute upon insert; otherwise, the insert is constructed from the log. The default is SQL.
del_cmd
Specifies the command to execute upon delete; otherwise, the delete is constructed from the log. The default is SQL.
upd_cmd
Specifies command to execute upon update; otherwise, the update is constructed from the log. The default is SQL.
creation_script
Is the path and name of an article schema script used to create target tables. The default is NULL.
description
Is an optional descriptive entry for the article.
pre-creation_cmd
Is a pre-creation command for drop table, delete table, or truncate. Can be:

0 None
1 Drop (the default)
2 Delete
3 Truncate

filter_clause
Is a WHERE clause specifying the horizontal partitioning.

Remarks

If vertical_partition is false and filter_clause is not NULL, a view is created and a filter procedure on the source table using the filter_clause is created. If vertical_partition is true, sp_addarticle defers the creation of the view until sp_articleview is called (after the last sp_articlecolumn is added).

Example

This example creates the article authors and adds it to the authors_publication publication.

sp_addarticle authors_publication, authors, authors,
@creation_script='c:\sql95\repldata\authors.sch'
@description='Authors Table Article'

Permission

Execute permission defaults to the database owner and the system administrator.

Tables Used

sysobjects, sysarticles, syspublications

See Also

sp_addpublication | sp_droparticle
sp_articlecolumn | sp_droppublication
sp_articlefilter | sp_enumfullsubscribers
sp_articlecolumn | sp_helparticle
sp_changearticle | sp_helparticlecolumns
sp_changepublication | sp_helppublication


sp_addpublication Replication Stored Procedure

Creates a publication.

Syntax

sp_addpublication publication, taskid,
[, @restricted = {'true' | 'false'}
[, @sync_method = {'native' | 'character'}
[, @repl_freq = {'continuous' | 'snapshot'}
[, @description = 'string description'
[, @status= {'inactive' | 'active'}]]]]]

where

publication
Names the publication to create. The name must be unique within the database.
taskid
Is a unique scheduler task ID (must be created before the publication).
restricted
Specifies who can view the publication. If set to false (the default), the publication can be viewed by all (open enrollment). If set to true, the publication can be viewed only by authorized subscription servers.
sync_method
Specifies the synchronization mode. If set to native (the default), produces native-mode BCP output of all tables. If set to character, produces character-mode BCP output of all tables.
repl_freq
Specifies that if set to continuous (the default), the publisher provides output of all log-based transactions. If set to snapshot, the publisher produces only scheduled synchronization events.
description
Is an optional descriptive entry for the publication job.
status
Specifies when publication data will be available. If set to inactive (the default), publication data will not be available for subscribers when the publication is first created (they can subscribe, but the subscription will not be processed). If set to active, publication data will immediately be available for subscribers.

Remarks

Only the system administrator or the database owner can add a publication.

Example

This example creates the publication authors_publication, using a preexisting sync task with taskid equal to 1.

sp_addpublication authors_publication, 1, @status=active,
@description='Full Authors Table'

Permission

Execute permission defaults to the database owner and the system administrator.

Tables Used

syspublications, sysdatabases

See Also

sp_addarticle | sp_droppublication
sp_articlecolumn | sp_enumfullsubscribers
sp_changearticle | sp_helparticle
sp_changepublication | sp_helparticlecolumns
sp_droparticle | sp_helppublication


sp_addpublisher Replication Stored Procedure

Adds a new publication server.

Syntax

sp_addpublisher publisher [, 'dist']

where

publisher
Is the name of the server to be added.
dist
Defines the specified server as a potential publisher to this distribution server. This is true if the local server is set up with a distribution database. (Sets the server option to dpub, and adds a remote login mapping of SA to SA with the trusted option.)

Remarks

If 'dist' is not specified the publisher's distributor (SQL Executive) user account will be granted repl privilege. Only the system administrator can add a server to master.sysservers as a publication server.

Example

This example adds the publication server WOLFHOUND and defines it as a potential publisher.

sp_addpublisher WOLFHOUND, 'dist'

Permission

Execute permission defaults to the system administrator.

Table Used

sysservers

See Also

sp_addremotelogin | sp_dropsubscriber
sp_addserver | sp_helpdistributor
sp_addsubscriber | sp_helpserver
sp_changesubscriber | sp_helpsubscriberinfo
sp_dboption | sp_remoteoption
sp_droppublisher | sp_serveroption


sp_addsubscriber Replication Stored Procedure

For SQL Server 6.5 information, see sp_addsubscriber in What's New for SQL Server 6.5.

Adds a new subscription server and sets up a trusted remote login mapping from SA of the subscriber to the repl_subscriber login ID on the publisher (unless system administrator on the subscriber is already mapped to system administrator on the publisher).

Syntax

sp_addsubscriber subscriber [, type] [, login] [, password] [, commit_batch_size]
[, status_batch_size] [, flush_frequency] [, frequency_type]
[, frequency_interval] [, frequency_relative_interval]
[, frequency_recurrence_factor] [, frequency_subday]
[, frequency_subday_interval] [, active_start_time_of_day]
[, active_end_time_of_day] [, active_start_date] [, active_end_date]

where

subscriber
Specifies the name of the server to be added as a valid subscriber to this server's publications.
type
Specifies the type of subscription server: 0 indicates a SQL Server 6.0 subscription server; 1 indicates a non-SQL Server 6.0 or other ODBC data source server. The default is 0.
login
Is reserved for future use.
password
Is reserved for future use.
commit_batch_size
Specifies the maximum number of transactions that will be sent to the subscription server as a single unit. The default is 20.
status_batch_size
Is reserved for future use.
flush_frequency
Specifies the frequency with which transactions will be removed from the distribution database tables after they have been successfully distributed to the subscriber's database. The default is 0.
frequency_type
Specifies the frequency with which to schedule the distribution task. The default is 4 (daily). The value can be:
1One Time
2On Demand
4Daily
8Weekly
16Monthly
32Monthly Relative
64Autostart
124Recurring
frequency_interval
Is the value to apply to the frequency set by frequency_type. The default is 1.
frequency_relative_interval
Specifies the date of the distribution task. Used when frequency_type is set to 32 (monthly relative). The default is 1. The value can be:

1First
2Second
4Third
8Fourth
16Last

frequency_recurrence_factor
Is the recurrence factor used by frequency_type. The default is 0.
frequency_subday
Specifies how often to reschedule during the defined period. The default is 4 (minute).
1Once (default)
2Second
4Minute
8Hour
frequency_subday_interval
Is the interval for frequency_subday. The default is 5.
active_start_time_of_day
Specifies when the distribution task will first be scheduled. Formatted as HHMMSS. The default is 0.
active_end_time_of_day
Specifies when the distribution task will stop being scheduled. Formatted as HHMMSS. The default is 235939.
active_start_date
Specifies the date when the distribution task will first be scheduled. Formatted as YYYYMMDD. The default is 0.
active_end_date
Specifies the date when the distribution task will stop being scheduled. Formatted as YYYYMMDD. The default is 99991231.

Remarks

This stored procedure writes to the MSsubscriber_info table in the distribution database.

Example

This example sets up BLOODHOUND as a subscription server.

sp_addsubscriber BLOODHOUND

Permission

Execute permission defaults to the system administrator.

Tables Used

sysservers, sysremotelogins

See Also

sp_addpublisher | sp_dropsubscriber
sp_addremotelogin | sp_helpdistributor
sp_addserver | sp_helpserver
sp_changesubscriber | sp_helpsubscriberinfo
sp_dboption | sp_remoteoption
sp_droppublisher | sp_serveroption


sp_addsubscription Replication Stored Procedure

For SQL Server 6.5 information, see sp_addsubscription in What's New for SQL Server 6.5.

Adds a subscription to an article and sets the subscriber's status.

Syntax

sp_addsubscription publication [, 'article'] , subscriber [, destination_db]
[, @sync_type = {'automatic' | 'manual' | 'none'}]
[, @status = {'inactive' | 'active' | 'subscribed'}]

where

publication
Specifies the name of the publication.
article
Specifies the article that will be subscribed to. The article name must be unique within the publication. If set to all or not supplied, a subscription is added to all articles in that publication.
subscriber
Is the name of the subscription server subscribing to this article.
destination_db
Is the name of the destination database in which to place replicated data. The default uses the same name as the publication database.
@sync_type
Is the subscription synchronization type. When set to automatic (the default), synchronization is applied to the subscription server via the distribution process. When set to manual, a synchronization file is automatically produced, but it must be manually applied to the subscription server. This parameter can also be set to none (no initial synchronization).
@status
Is the subscription status. If sync_type = none, the default for status is active; otherwise the default is subscribed. To enable a subscriber to see articles in a restricted publication article, a "placeholder" subscription must be created with inactive status.

Remarks

Only the system administrator or database owner can locally add a subscription to an existing article.

Example

This example adds the subscriber AIREDALE to the article authors in the publication authors_publication.

sp_addsubscription authors_publication, authors, AIREDALE

Permission

Execute permission defaults to the system administrator and database owner.

Tables Used

sysarticles, syspublications, syssubscriptions, sysservers

See Also

sp_changesubscription | sp_helpsubscription
sp_changesubstatus | sp_subscribe
sp_dropsubscription | sp_unsubscribe


sp_articlecolumn Replication Stored Procedure

Modifies columns for an article. Use sp_articlecolumn to create vertical partitions.

Syntax

sp_articlecolumn publication, article [, 'column'
[, @operation = {'add' | 'drop'}]]

where

publication
Is the name of the publication that contains this article.
article
Is the name of the article.
column
Is the name of the column to be added or dropped. The default is NULL. If NULL, all columns are published.
@operation
Specifies the replication status; add (the default) marks the column for replication; drop unmarks the column.

Remarks

This stored procedure sets a bit in sysarticles. Only an unsubscribed article can be partitioned using sp_articlecolumn.

Example

This example modifies the column col5, marking it for replication.

sp_articlecolumn PUB_TEST, ART_ALLS, 'col5', 'add'

Permission

Execute permission defaults to the system administrator and database owner.

Tables Used

syscolumns, sysarticles, syspublications, sysdatabases

See Also

sp_addarticle | sp_droppublication
sp_addpublication | sp_enumfullsubscribers
sp_articleview | sp_helparticle
sp_changearticle | sp_helparticlecolumns
sp_changepublication | sp_helppublication
sp_droparticle |


sp_articlefilter Replication Stored Procedure

Creates a filter stored procedure used to horizontally partition data replicated from a published table.

Syntax

sp_articlefilter publication, article [, filter_name] [, filter_clause]

where

publication
Is the name of the publication that contains the article.
article
Is the name of the article.
filter_name
Is the name of the filter stored procedure to be created from the filter_clause.
filter_clause
Is a restriction (WHERE) clause that defines a horizontal partition. When entering the restriction clause, omit the word "WHERE."

Remarks

This stored procedure creates the filter and inserts the ID of the filter stored procedure in the filter column of the sysarticles table, and it inserts the text of the restriction clause in the filter_clause column.

Only unsubscribed articles can be modified by this stored procedure.

To create an article with a horizontal partition, execute sp_addarticle with no filter parameter. Execute sp_articlefilter, providing all parameters including filter_clause. Then execute sp_articleview, providing all parameters including the identical filter_clause. If the filter already exists and if the type in sysarticles is 1 (log-based article) or 3 (log-based article with manual filter), the filter will be dropped and re-created.

If filter_name and filter_clause are not provided, the previous filter is deleted and the filter ID is set to 0.

Example

This example creates the mypub filtered stored procedure.

sp_articlefilter, MyPub, MyArticle, MyFilter, 'state = "OR"'

Permission

Only the system administrator and the database owner can use this stored procedure.

Tables Used

sysobjects, syspublications, syssubscriptions, sysarticles

See Also

sp_addarticle | sp_articleview
sp_articlecolumn |


sp_articleview Replication Stored Procedure

Creates the synchronization object for an article when a table is filtered vertically and/or horizontally. This synchronization object is a view that is used as the filtered source of the schema and data for the destination tables.

Syntax

sp_articleview publication, article [, view_name] [, filter_clause]

where

publication
Is the name of the publication that contains the article.
article
Is the name of the article.
view_name
Is the name of the synchronization object.
filter_clause
Is a restriction (WHERE) clause that defines a horizontal partition. When entering the restriction clause, omit the word "WHERE."

Remarks

This stored procedure creates the view and inserts the ID of the synchronization object (the view) in the sync_objid column of the sysarticles table, and the text of the restriction clause in the filter_clause column. If all columns are replicated and there is no filter_clause, the sync_objid in the sysarticles table is set to the ID of the base table and the use of sp_articleview is not required.

Only unsubscribed articles can be modified by this stored procedure.

To publish a vertically partitioned table (that is, to filter columns) first run sp_addarticle with no sync_object parameter, run sp_articlecolumn once for each column to be replicated (defining the vertical partition), and then run sp_articleview to create the synchronization object.

To publish a horizontally partitioned table (that is, to filter rows), run sp_addarticle with no filter parameter. Run sp_articlefilter, providing all parameters including filter_clause. Then run sp_articleview, providing all parameters including the identical filter_clause.

To publish a vertically and horizontally partitioned table, run sp_addarticle with no sync_object or filter parameters, run sp_articlecolumn once for each column to be replicated, and then run sp_articlefilter and sp_articleview.

If the article already has a synchronization object (a view), sp_articleview will drop the existing view and create a new one if the type in sysarticles is 1 (log-based article) or 3 (log-based article with manual filter).

If you manually create a custom filter stored procedure and a synchronization object, do not run sp_articleview. Instead, provide them as the filter and sync_object parameters to sp_addarticle, along with the appropriate type value.

Example

This example creates the synchronization view MyView for MyPub and filters on the zip code 94609.

sp_articleview 'MyPub', 'MyArticle', 'MyView', 'zip = "94609"'

Permission

Only the system administrator or the database owner can use this stored procedure.

Tables Used

sysobjects, syscolumns, syspublications, syssubscriptions, sysarticles

See Also

sp_addarticle | sp_articlefilter
sp_articlecolumn |


sp_changearticle Replication Stored Procedure

Changes an article's properties.

Syntax

sp_changearticle publication, article [, property, value]

where

publication
Is the name of the publication that contains the article.
article
Is the name of the article whose property is to be changed.
property
States an article property to change. Can be:

name
description
sync_object
type
ins_cmd
del_cmd
upd_cmd
filter
dest_table
creation_script
pre_creation_cmd

value
Specifies the article value. Can be used with:
name
Is the new name for the article.
description
Is a descriptive entry for the publication job.
sync_object
Is the name of the table or view used to produce a synchronization output file. The default is NULL.
type
Is the article type:
1Log-based article (the default)
3Log-based article with manual filter
5Log-based article with manual view
7Log-based article with manual filter and manual view
ins_cmd
Is the INSERT statement to execute; otherwise, it will be constructed from the log.
del_cmd
Is the DELETE statement to execute; otherwise, it will be constructed from the log.
upd_cmd
Is the UPDATE statement to execute; otherwise, it will be constructed from the log.
filter
Specifies a stored procedure used to the filter the table (horizontal partition). The default is NULL.
dest_table
Is the destination table, if different from the source table (source_table).
creation_script
Is the path and name of an article schema script used to create target tables. The default is NULL.
pre_creation_cmd
Specifies a pre-creation command that can drop, delete, or truncate the destination table before synchronization is applied. Can be:

None
Drop
Delete
Truncate

Remarks

Within an existing publication, you can change a certain article (using sp_changearticle) without having to drop and re-create the entire publication. Only unsubscribed articles can be changed. Only the system administrator and the database owner can change an article.

Example

This example renames the ART_ALL article to ART_NEW.

sp_changearticle PUB1, ART_ALL, name, 'ART_NEW'

Permission

Execute permission defaults to the system administrator and the database owner.

Tables Used

sysobjects, sysarticles, syspublications, sysdatabases

See Also

sp_addarticle | sp_droppublication
sp_addpublication | sp_enumfullsubscribers
sp_articlecolumn | sp_helparticle
sp_changepublication | sp_helparticlecolumns
sp_droparticle | sp_helppublication


sp_changepublication Replication Stored Procedure

Changes a publication's properties.

Syntax

sp_changepublication publication [, property, 'value']

where

publication
Is the name of the publication.
property
Specifies the publication property to change. Can be name, description, taskid, sync_method, status, repl_freq, or restricted.
value
Specifies the publication value. Can be used with:
name
Is the new publication name.
description
Is an optional entry describing the publication.
taskid
Is a unique scheduler task ID created using the sp_addtask stored procedure.
sync_method
Specifies the synchronization method. Can be native (produces native-mode bulk copy output of all tables) or character (produces a character-mode bulk copy output of all tables).
status
Specifies the publication status. Can be inactive (publication data will not be available for subscribers when the publication is first created) or active (publication data is available immediately for subscribers).
repl_freq
Specifies the frequency of replication. Can be continuous (provides output of all log-based transactions) or snapshot (produces only scheduled synchronization events).
restricted
Specifies access to the publication. Can be false (the publication allows open enrollment and is visible to all) or true (the publication can be viewed only by authorized subscription servers).

Example

This example changes the name of the publication authors_publication to au_pub.

sp_changepublication authors_publication, name, 'au_pub'

Permission

Execute permission defaults to the system administrator and the database owner.

Tables Used

syspublications, sysdatabases

See Also

sp_addarticle | sp_droppublication
sp_addpublication | sp_enumfullsubscribers
sp_articlecolumn | sp_helparticle
sp_changearticle | sp_helparticlecolumns
sp_droparticle | sp_helppublication


sp_changesubscriber Replication Stored Procedure

For SQL Server 6.5 information, see sp_changesubscriber in What's New for SQL Server 6.5.

Changes the options for a subscription server. Any distribution task for the publisher's subscribers will be updated.

Syntax

sp_changesubscriber subscriber [, type] [, login] [, password]
[, commit_batch_size] [, status_batch_size] [, flush_frequency]
[, frequency_type] [, frequency_interval] [, frequency_relative_interval]
[, frequency_recurrence_factor] [, frequency_subday]
[, frequency_subday_interval] [, active_start_time_of_day]
[, active_end_time_of_day] [, active_start_date] [, active_end_date]

where

subscriber
Is the name of the subscription server that will have its options changed.
type
Specifies the subscription server type; 0 indicates a SQL Server 6.0 subscription server; 1 indicates a non-SQL Server 6.0 or other ODBC data source server. The default is 0.
login
Is reserved for future use.
password
Is reserved for future use.
commit_batch_size
Specifies the maximum number of transactions that will be sent to the subscription server as a single unit.
status_batch_size
Is reserved for future use.
flush_frequency
Specifies the frequency with which transactions will be removed from the distribution database tables after they have been successfully distributed to the subscriber's database.
frequency_type
Specifies the frequency with which to schedule the distribution task:
1One Time
2On Demand
4Daily
8Weekly
16Monthly
32Monthly Relative
64Autostart
128Recurring
frequency_interval
Specifies the interval for frequency_type.
frequency_relative_interval
Specifies the date of the distribution task. Used when frequency_type is set to 32 (monthly relative). The default is 1. The value can be:

1First (default)
2Second
4Third
8Fourth
16Last

frequency_recurrence_factor
Specifies how often the distribution task should re-occur during the defined frequency_type.
frequency_subday
Specifies how often to reschedule during the defined period:
1Once (default)
2Second
4Minute
8Hour
frequency_subday_interval
Specifies the interval for frequency_subday.
active_start_time_of_day
Specifies when the distribution task will first be scheduled. Formatted as HHMMSS. The default is 0.
active_end_time_of_day
Specifies when the distribution task will stop being scheduled. Formatted as HHMMSS. The default is 0.
active_start_date
Specifies the date when the distribution task will be scheduled initially. Formatted as YYYYMMDD. The default is 0.
active_end_date
Specifies the date when the distribution task will stop being scheduled. Formatted as YYYYMMDD. Default is 0.

Remarks

Only the system administrator can change a subscription server. This stored procedure writes to the MSsubscriber_info table in the distribution database.

Example

This example changes the BLOODHOUND subscriber's frequency from daily (the default) to weekly.

sp_changesubscriber BLOODHOUND, @frequency_type = 8

Permission

Execute permission defaults to the system administrator.

Table Used

sysservers

See Also

sp_addpublisher | sp_dropsubscriber
sp_addsubscriber | sp_helpdistributor
sp_dboption | sp_helpserver
sp_droppublisher | sp_helpsubscriberinfo


sp_changesubscription Replication Stored Procedure

Changes the subscription properties for an article or a publication. Is executed on a subscription server.

Syntax

sp_changesubscription publication, article, subscriber [, 'property', 'value']

where

publication
Is the name of the publication containing the article.
article
Is the name of the article.
subscriber
Is the name of the subscription server. If subscriber is not specified, defaults to @@REMSERVER (the server name contained within a remote server's login record).
property
Is the property to set. Can be sync_type or dest_db.
value
Is the value of property. For sync_type, can be none, manual, or automatic. For dest_db, is the name of a destination database.

Example

This example changes the subscription property of the myart3 article to a synchronization type of manual.

sp_changesubscription mypub1, myart3, sync_type, manual

Permission

Execute permission defaults to the system administrator and the database owner.

Tables Used

sysarticles, syspublications, syssubscriptions, sysservers

See Also

sp_addsubscription | sp_helpsubscription
sp_changesubstatus | sp_subscribe
sp_dropsubscription | sp_unsubscribe


sp_changesubstatus Replication Stored Procedure

Changes the status of an existing subscriber.

Syntax

sp_changesubstatus [publication [, article [, subscriber [, ]]]]
status [, previous_status]

where

publication
Is the name of the publication. If publication is not specified, all publications are affected.
article
Is the name of the article. It must be unique to the publication. If article is not specified, all articles are affected.
subscriber
Is the name of the subscription server that is to have its status changed. If no subscriber is specified, status is changed for all subscribers to the specified article.
status
Is the subscription status in the syssubscriptions table. Can be:
inactive | Subscriber entry exists without a subscription, which is used for restricted publications.
subscribed | Subscriber is requesting data but is not yet synchronized.
active | Subscriber is synchronized and receiving data.

previous_status
Allows you to change any subscriptions that currently have that status, thus allowing group functions on a specific set of subscriptions. (For example, setting all active subscriptions back to subscribed.) Normally, is NULL.

Remarks

This stored procedure changes the subscriber's status in the syssubscriptions table with the changed status. If required, it updates the article status in the sysarticles table to indicate active or inactive. If required, it sets the replication flag on or off in the sysobjects table for the replicated table.

Example

This example changes the status of the subscriber POODLE to inactive (entry exits without subscription).

sp_changesubstatus mypub1, myart3, POODLE, inactive

Permission

Execute permission defaults to the system administrator and the database owner.

Tables Used

sysobjects, sysarticles, syspublications, syssubscriptions, sysservers

See Also

sp_addsubscription | sp_helpsubscription
sp_changesubscription | sp_subscribe
sp_dropsubscription | sp_unsubscribe
sp_helpdistributor |


sp_distcounters Replication Stored Procedure

Displays the latest information for all subscription servers. Used by SQL Performance Monitor.

Syntax

sp_distcounters

Remarks

This stored procedure returns the subscription server name, the number of delivered jobs, the number of undelivered jobs, the delivery rate (number of jobs per second), and the delivery latency (in seconds).

A delivered job is one that is still in the distribution database but has already been executed against the destination database. An undelivered job is one that is currently in the distribution database but has not yet been executed against the destination database. The delivery rate is the number of jobs per second that were executed in the last batch sent to that subscription server. Latency refers to the amount of time that elapses from when a job is inserted into the distribution database to when it is executed against the subscriber.

This information can be viewed by using the appropriate counters in SQL Performance Monitor.

Example

This example displays the current status for the BLOODHOUND subscription server. Note "deliv" is short for delivered in this output.

sp_distcounters
go
subscriber  deliv_jobs  undeliv_jobs  delivery_rate  delivery_latency
----------  ----------  ------------  -------------  ---------------
BLOODHOUND  0               0             6              1

Permission

Execute permission defaults to the system administrator and is granted to public.

Table Used

None.

See Also

sp_replsync | sp_replica
sp_replcleanup |


sp_droparticle Replication Stored Procedure

Drops an article.

Syntax

sp_droparticle publication, article

where

publication
Is the name of the publication that contains the article to be dropped.
article
Is the name of the article to be dropped.

Remarks

An article cannot be removed if one or more subscriptions to it exist. Only the system administrator or the database owner can drop an article.

This stored procedure checks the article's type column in the sysarticles table to determine whether a view or filter should also be dropped. If a view or filter was autogenerated, it is dropped with the article. If it was manually created, it is not dropped.

Example

This example drops the article myarticle5 from the publication mypub.

sp_droparticle mypub, myarticle5

Permission

Execute permission defaults to the system administrator and the database owner.

Tables Used

sysobject, sysarticles, syspublications, syssubscriptions

See Also

sp_addarticle | sp_droppublication
sp_addpublication | sp_enumfullsubscribers
sp_articlecolumn | sp_helparticle
sp_changearticle | sp_helparticlecolumns
sp_changepublication | sp_helppublication


sp_droppublication Replication Stored Procedure

Drops a publication and its associated articles.

Syntax

sp_droppublication publication

where

publication
Is the name of the publication to be dropped. If all is specified, all publications are dropped from the publication database, except for those with subscriptions.

Remarks

This stored procedure recursively drops all articles associated with a publication and then drops the publication itself. A publication cannot be removed if it has one or more subscriptions to it. The associated sync task will also be dropped. Only the system administrator or the database owner can drop a publication.

Example

This example drops the mypub3 publication.

sp_droppublication mypub3

Permission

Execute permission defaults to the system administrator and the database owner.

Tables Used

sysarticles, syspublications, syssubscriptions

See Also

sp_addarticle | sp_droparticle
sp_addpublication | sp_enumfullsubscribers
sp_articlecolumn | sp_helparticle
sp_changearticle | sp_helparticlecolumns
sp_changepublication | sp_helppublication


sp_droppublisher Replication Stored Procedure

Drops a publication server.

Syntax

sp_droppublisher publisher [, dist]

where

publisher
Is the name of the publication server to be dropped.
dist
Drops the server as the distribution server. (Removes the server option dpub, and removes the remote login mapping of SA to SA with the trusted option.)

Remarks

Only the system administrator can drop a publication server. If dist is not provided, the publisher's subscriber (SQL Executive) Windows NT user account has its replication privilege revoked.

Example

The example drops the WOLFHOUND publication server entry.

sp_droppublisher WOLFHOUND

Permission

Execute permission defaults to the system administrator.

Table Used

sysservers

See Also

sp_addpublisher | sp_dropsubscriber
sp_addsubscriber | sp_helpdistributor
sp_changesubscriber | sp_helpserver
sp_dboption | sp_helpsubscriberinfo


sp_dropsubscriber Replication Stored Procedure

Drops a subscription server.

Syntax

sp_dropsubscriber subscriber

where

subscriber
Is the name of the subscription server to be dropped.

Remarks

This stored procedure removes the server sub option and removes the remote login mapping of SA to repl_subscriber. Only the system administrator can drop a subscription server.

Example

This example drops the subscription server BLOODHOUND.

sp_dropsubscriber BLOODHOUND

Permission

Execute permission defaults to the system administrator.

Tables Used

sysservers, sysremotelogins

See Also

sp_addpublisher | sp_droppublisher
sp_addsubscriber | sp_helpdistributor
sp_changesubscriber | sp_helpserver
sp_dboption | sp_helpsubscriberinfo


sp_dropsubscription Replication Stored Procedure

Drops subscriptions to a particular article, publication, or set of subscriptions on the publication server.

Syntax

sp_dropsubscription 'publication', 'article', 'subscriber'

where

publication
Is the name of the associated publication. Specifying all cancels all subscriptions for all publications for the specified subscriber.
article
Is the name of the article. Specifying all drops subscriptions to all articles for each specified publication and subscriber. If article is not supplied, subscriptions are dropped for all articles in the publication.
subscriber
Is the name of the subscription server that will have its subscriptions dropped. Specifying all drops all subscriptions for all subscribers.

Remarks

Only the system administrator, database owner, and a remote connection from the subscription server can drop a subscription to an existing publication or article.

Examples

This example drops all articles from all publications and drops all subscriptions for all subscribers.

sp_dropsubscription 'all', 'all', 'all'

Permission

Execute permission defaults to the system administrator and database owner.

Tables Used

sysarticles, syspublications, syssubscriptions, sysservers

See Also

sp_addsubscription | sp_helpsubscription
sp_changesubscription | sp_subscribe
sp_changesubstatus | sp_unsubscribe


sp_enumfullsubscribers Replication Stored Procedure

Returns a list of subscribers who have subscribed to all articles in a specified publication.

Syntax

sp_enumfullsubscribers publication

where

publication
Is the name of the publication.

Example

This example returns a list of all subscribers who have subscribed to all articles in the publication pub3.

sp_enumfullsubscribers pub3

Permission

Execute permission defaults to the system administrator and the database owner.

Tables Used

sysarticles, syspublications, syssubscriptions, sysservers

See Also

sp_addarticle | sp_droparticle
sp_addpublication | sp_droppublication
sp_articlecolumn | sp_helparticle
sp_changearticle | sp_helparticlecolumns
sp_changepublication | sp_helppublication


sp_helparticle Replication Stored Procedure

Displays information about an article.

Syntax

sp_helparticle publication[, article] [, returnfilter]

where

publication
Is the name of the publication.
article
Is the name of an article in the publication. If article is not supplied, information on all articles for the specified publication is returned.
returnfilter
Specifies if the filter clause should be returned. Is 1 if the filter clause should be returned, 0 if not. The default is 1.

Remarks

Displays the article name, base table name, destination table, synchronization object, type, status, filter, description, insert command, update command, delete command, creation script path, and (depending on the returnfilter parameter) filter clause.

Example

This example returns information about the types_table article in the pub_alltypes publication. The filter clause will be returned.

sp_helparticle pub_alltypes, types_table

Permission

Execute permission defaults to the public group.

Table Used

sysobjects, syscolumns, sysusers, sysarticles, syspublications, syssubscriptions, sysservers

See Also

sp_addarticle | sp_droparticle
sp_addpublication | sp_droppublication
sp_articlecolumn | sp_enumfullsubscribers
sp_changearticle | sp_helparticlecolumns
sp_changepublication | sp_helppublication


sp_helparticlecolumns Replication Stored Procedure

Displays all columns in the underlying table.

Syntax

sp_helparticlecolumns publication, article

where

publication
Is the name of the publication that contains the article.
article
Is the name of the article that will have its columns displayed.

Remarks

This stored procedure returns 1 for columns that are published and 0 for those that are not published. It is useful in checking a vertical partition.

Example

This example displays the columns of the authors article in the authors_publication publication.

sp_helparticlecolumns authors_publication, authors

Permission

Execute permission defaults to the public group.

Tables Used

syscolumns, sysarticles, syspublications, syssubscriptions, sysservers

See Also

sp_addarticle | sp_droparticle
sp_addpublication | sp_droppublication
sp_articlecolumn | sp_enumfullsubscribers
sp_changearticle | sp_helparticle
sp_changepublication | sp_helppublication


sp_helpdistributor Replication Stored Procedure

Lists information about the distribution server, distribution database, working directory, and SQL Executive user account.

Syntax

sp_helpdistributor

Remarks

This stored procedure returns the name of the server's distribution server, the distribution database, the path of the distribution working directory, and the name of the Windows NT user account that the distribution process runs under. If the distribution database is not installed, a null value is returned.

Example

This example displays distribution information.

sp_helpdistributor

Permission

Execute permission defaults to the public group.

Table Used

sysservers

See Also

sp_addpublisher | sp_droppublisher
sp_addsubscriber | sp_dropsubscriber
sp_changesubscriber | sp_helpserver
sp_changesubstatus | sp_helpsubscriberinfo
sp_dboption |


sp_helppublication Replication Stored Procedure

Displays information about a publication.

Syntax

sp_helppublication [publication]

where

publication
Is the name of the publication to be viewed.

Remarks

This stored procedure displays the publication ID, the name, whether the publication is unrestricted/restricted, the status, the SQL Executive task ID, the replication frequency, the synchronization method, and a description. If publication is not provided, information on all publications is returned.

Example

This example displays information about the mypub5 publication.

sp_helppublication mypub5

Permission

Execute permission defaults to the public group.

Tables Used

sysarticles, syspublications, syssubscriptions, sysservers

See Also

sp_addarticle | sp_droparticle
sp_addpublication | sp_droppublication
sp_articlecolumn | sp_enumfullsubscribers
sp_changearticle | sp_helparticle
sp_changepublication | sp_helparticlecolumns


sp_helppublicationsync Replication Stored Procedure

Provides information about a scheduled synchronization task for a publication.

Syntax

sp_helppublicationsync publication

where

publication
Is the publication name.

Remarks

Using this stored procedure is the equivalent to running the sp_helptask stored procedures in full mode against the publication task ID.

It returns the information as supplied when the synchronization task was defined. For more information, see the ,sp_addtask SQL Executive Stored Procedure.

Example

This example displays information about the scheduled synchronization task for the mypub publication.

sp_helppublicationsync mypub

Permission

Execute permission defaults to the public group.

See Also

sp_addtask


sp_helpreplicationdb Replication Stored Procedure

Returns information about a specified database or a list of all publication databases on the server.

Syntax

sp_helpreplicationdb [databasename [, {pub | sub}]]

where

databasename
Is the name of the database about which information will be returned. Wildcard characters can be used; % is the default.
pub | sub
Determines what information will be returned. When pub (the default) is specified, checks whether the specified database is a publication database. When sub is specified, checks whether the specified database is a subscription (destination) database.

Remarks

If run without options, this stored procedure returns a list of all published databases on the server. If run with options, it returns the databasename only if that database is set for publishing (when the pub option is supplied) or subscribing (when the sub option is supplied).

Example

This example returns information about the inventory database and indicates if it is a subscription database.

sp_helpreplicationdb inventory, sub

Permission

Execute permission defaults to the public group.

Table Used

sysdatabases

See Also

sp_helppublication


sp_helpsubscriberinfo Replication Stored Procedure

For SQL Server 6.5 information, see sp_helpsubscriberinfo in What's New for SQL Server 6.5.

Displays information about a subscription server.

Syntax

sp_helpsubscriberinfo subscriber

where

subscriber
Is the name of the subscription server.

Remarks

This stored procedure displays information about the parameters set by sp_addsubscriber.

Example

This example displays information about the subscription server WOLFHOUND.

sp_helpsubscriberinfo WOLFHOUND

Permission

Execute permission defaults to the system administrator.

Table Used

sysservers

See Also

sp_addpublisher | sp_droppublisher
sp_addsubscriber | sp_dropsubscriber
sp_changesubscriber | sp_helpdistributor
sp_dboption | sp_helpserver


sp_helpsubscription Replication Stored Procedure

Lists subscription information associated with a particular publication, article, subscriber, or set of subscriptions.

Syntax

sp_helpsubscription [publication [, article [, subscriber ]]]

where

publication
Is the name of the associated publication. If publication is not given, returns all subscription information for this server.
article
Is the name of the article. If article is not given, returns all subscription information for selected publications and subscribers.
subscriber
Specifies the subscription server that will view subscriptions. If subscriber is not provided, returns all subscription information for selected publications and articles.

Remarks

This stored procedure returns subscriber, publication, article, destination database, subscription status, and synchronization type.

Example

This example returns all subscription information about the publication authors_publication and the article authors.

sp_helpsubscription authors_publication, authors

Permission

Execute permission defaults to the public group.

Tables Used

sysarticles, syspublications, syssubscriptions, sysservers

See Also

sp_addsubscription | sp_dropsubscription
sp_changesubscription | sp_subscribe
sp_changesubstatus | sp_unsubscribe


sp_MSkill_job Replication Stored Procedure

Removes a single job from the distribution database while continuing to send all other data to the subscriber. Used on the distribution server.

Syntax

sp_MSkill_job job_id, publisher, publisher_db [, subscriber [, subscriber_db]]

where

job_id
Is the ID of the job being removed.
publisher
Is the name of the publication server where the job originated.
publisher_db
Is the name of the published database.
subscriber
Is the name of the subscription server.
subscriber_db
Is the name of the destination database.

Remarks

The sp_MSkill_job replication stored procedure is useful if all subscribers are failing on the distribution of a replicated transaction.

Important Use this procedure with caution. It is used on the distribution database.

Example

This example terminates job 90 that is waiting to be distributed.

sp_MSkill_job 90, WOLFHOUND, pubs

See Also

MSlast_job_info


sp_replcleanup Replication Stored Procedure

Removes transactions from the distribution database tables after they have been successfully distributed to the subscriber's database.

Syntax

sp_replcleanup publisher, subscriber, retention

where

publisher
Is the name of a publication server.
subscriber
Is the name of a subscription server.
retention
Is the number of hours to retain transactions after they have been successfully distributed to the subscription server.

Remarks

The sp_replcleanup stored procedure cleans up jobs for the specified publisher/subscriber pair. It is run on the distribution database and removes entries from these destination database tables: MSjob_commands, MSjobs, MSsubscriber_status, and MSsubscriber_jobs.

Important Each distribution database is automatically cleaned up once a day. There is a default subscriber cleanup task (which has a large overhead) that is scheduled by default to run daily at 1:05 A.M.

Example

This example "cleans up" (removes transactions from) the distribution database tables on the AIREDALE server after they have been successfully distributed to the server WOLFHOUND and retains transactions for at least 8 hours.

sp_replcleanup AIREDALE, WOLFHOUND, 8

Permission

Execute permission defaults to the system administrator.

Tables Used

MSjob_commands, MSjobs, MSsubscriber_status, MSsubscriber_jobs

See Also

sp_replsync | sp_replica
sp_distcounters |


sp_replcmds Replication Stored Procedure

For SQL Server 6.5 information, see sp_replcmds in What's New for SQL Server 6.5.

Returns the commands for transactions marked for replication.

Syntax

sp_replcmds [maxtrans]

where

maxtrans
Is an integer indicating the number of transactions to return information about. If maxtrans is not provided, defaults to 1 (the next transaction waiting for distribution).

Remarks

This replication stored procedure is used by the logreader process. It returns information about the publication database from which it is executed. It allows you to view transactions currently not distributed (those transactions remaining in the transaction log that have not been sent to the distribution server), with their commands and it returns article ID, partial_command (true or false), the command, page, row, and timestamp.

Example

This example returns the commands for two transactions marked for replication.

sp_replcmds 2

Permission

Execute permission defaults to the system administrator.

Table Used

None.

See Also

sp_repldone | sp_replstatus
sp_replflush | sp_repltrans


sp_replcounters Replication Stored Procedure

Returns replication statistics about latency, throughput, and transaction count for each published database. Used by SQL Performance Monitor.

Syntax

sp_replcounters

Remarks

This stored procedure returns a list of published databases, and for each published database, returns the number of replicated transactions in the log that have not yet been delivered to the distribution database. It also returns the number of transactions per second that have been read out of the log.

This information can be viewed by using the appropriate counters in SQL Performance Monitor.

Example

This example shows information about replicated transactions in the pubs database.

sp_replcounters
go
database  repl. trans  repl. rate trans/sec  repl. latency(sec)
--------  -----------  --------------------  ------------------
pubs      72           0.739645              174015000.0

Permission

Execute permission defaults to the system administrator and is granted to probe.

Table Used

None.

See Also

sp_replcmds | sp_replflush
sp_repldone | sp_replstatus


sp_repldone Replication Stored Procedure

Updates the record that identifies the server's last distributed transaction.

Syntax

sp_repldone page, row [, timestamp] [, numtrans] [, time] [, reset]

where

page
Specifies the page for the server's last distributed transaction.
row
Specifies the row for the server's last distributed transaction.
timestamp
Is the timestamp of the server's last distributed transaction.
numtrans
Is the number of transactions distributed.
time
Specifies the number of milliseconds, if provided, needed to distribute the last batch of transactions.
reset
Specifies the reset status. When set to 1, all replicated transactions in the log are marked as distributed. When set to 0, the transaction log is reset to the first replicated transaction and no replicated transactions are marked as distributed.

Valid only when page is 0 and row is 0.

Remarks

This replication stored procedure is used by the logreader process to keep track of which transactions have been distributed.

Caution If you execute this stored procedure manually, you can invalidate the order and consistency of delivered transactions.

With this stored procedure, you can manually tell the server that a transaction has been replicated (sent to the distribution server). It also allows you to change the transaction marked as the next one awaiting replication¾you can move forward or backward in the list of replicated transactions. (All transactions less than or equal to that transaction will be marked as distributed.)

The required parameters page and row can be obtained using the sp_repltrans or sp_replcmds replication stored procedures.

When page is 0, row is 0, and reset is 1, all replicated transactions in the log are marked as distributed. This is useful when there are replicated transactions in the transaction log that are no longer valid (for example, a published table has been dropped) and you want to truncate the log. For example:

sp_repldone 0, 0, NULL, 0, 0, 1

When page is 0, row is 0, and reset is 0, the transaction log is reset to the first replicated transaction and no replicated transactions are marked as distributed. This is useful if you want to scan the transaction log's replicated transactions. For example:

sp_repldone 0, 0, 0, NULL, 0, 0, 0

Or, because these are all default settings:

sp_repldone

Permission

Execute permission defaults to the system administrator.

Table Used

None.

See Also

sp_replcmds | sp_replstatus
sp_replflush | sp_repltrans


sp_replflush Replication Stored Procedure

Flushes the article cache.

Syntax

sp_replflush

Remarks

Article definitions are stored in cache for efficiency. This stored procedure is used by other "sp_repl" replication stored procedures whenever an article definition is modified or dropped.

You should not have to execute this procedure manually.

Permission

Only the system administrator can use this procedure.

See Also

sp_replcmds | sp_replstatus
sp_repldone | sp_repltrans


sp_replica Replication Stored Procedure

Remotely sets on a subscription server a sysobjects category bit that marks the table as a replica.

Syntax

sp_replica tabname, replicated

where

tabname
Is a unique table name (owner.table) within the current database.
replicated
Sets a category bit that indicates that this is a destination table, a copy and not the original (publication) table. If false, clears the category replica_bit; if true, sets the category replica_bit.

Example

This example marks the authors table as a replica.

sp_replica authors, true

Permission

Execute permission defaults to the system administrator.

Table Used

sysobjects

See Also

sp_distcounters | sp_replcleanup
sp_replsync |


sp_replstatus Replication Stored Procedure

Used to update the internal table structure for replication (the internal table structure indicates whether the table is being replicated).

Syntax

sp_replstatus objectID, status

where

objectID
Is the object ID of the table being replicated.
status
Specifies the status. Can be 0 (not replicated) or 1 (replicated).

Remarks

This replication stored procedure is used by the logreader process. It returns information about the publication database from which it is executed.

Executing sp_replstatus must be done in conjunction with an update of the category bit in the sysobjects table.

Example

This example indicates the sp_replstatus is being replicated.

sp_replstatus

Permission

Execute permission defaults to the system administrator and is granted to repl_subscriber.

Table Used

None.

See Also

sp_replcmds | sp_replflush
sp_repldone | sp_repltrans


sp_replsync Replication Stored Procedure

Used from a subscription server to acknowledge completion of a manual synchronization.

Syntax

sp_replsync publisher, publisher_db, publication [, article]

where

publisher
Is the name of the publisher.
publisher_db
Is the name of the database used.
publication
Is the name of the publication.
article
Is the name of the article.

Remarks

This stored procedure informs the distribution server that manual synchronization is complete. If all three of these fields are matched in the MSlast_job_info table, sp_replsync increments job_id by 1. (These fields are populated in MSlast_job_info when the distribution process encounters the job containing this specific manual synchronization event.) If no article is specified, all articles in the publication are marked as synchronized.

Example

This example, used from a subscription server, acknowledges the completion of manual synchronization for the WOLFHOUND server's mydb database, containing the mypub1 publication with the article myart3.

sp_replsync WOLFHOUND, mydb, mypub1, myart3

Permission

Execute permission defaults to the system administrator and the database owner.

Tables Used

sysobjects, MSlast_job_info

See Also

sp_distcounters | sp_replica
sp_replcleanup |


sp_repltrans Replication Stored Procedure

Returns a result set of all the transactions in the publication database transaction log that are marked for replication but have not been marked as distributed.

Syntax

sp_repltrans

Remarks

This replication stored procedure returns information about the publication database from which it is executed. It allows you to view transactions currently not distributed (those transactions remaining in the transaction log that have not been sent to the distribution server). It returns a results set displaying the row identifier (RID, containing the page and row) and the timestamp for each transaction. It is similar to the sp_replcmds stored procedure but does not return the commands for the transactions.

Example

This example returns all transactions in the publication database transaction log marked for publication but not yet distributed.

sp_repltrans
go
page        row    timestamp
----------- ------ ------------------
5131        0      0x00000001000011d6

(1 row(s) affected)

Permission

Execute permission defaults to the system administrator.

Table Used

None.

See Also

sp_replcmds | sp_replstatus
sp_repldone | sp_repltrans
sp_replflush |


sp_subscribe Replication Stored Procedure

Remotely adds a subscription to a particular article within a publication.

Syntax

sp_subscribe publication, [article [, destination_db
[, @sync_type = {'automatic' | 'manual' | 'none'}]]]

where

publication
Is the name of the publication.
article
Is the name of the article. The name must be unique within the publication. If article is not supplied or if set to all, a subscription is added to all articles in the publication.
destination_db
Is the name of the destination (subscription) database in which to place replicated data. The default is NULL (indicating the same database name as the publication database).
@sync_type
Specifies the synchronization type. If set to automatic (the default), the subscription synchronization job is passed to the distribution database. If set to manual, the synchronization holder is passed to the distribution database and must be manually reset by the subscriber.

If set to none, there is no synchronization. A synchronization file is not created, there is no synchronization job passed to the distribution database, and the subscriber's status is set to active instead of subscribed. All future transactions are sent to the subscriber.

Remarks

This stored procedure causes rows to be added to the syssubscriptions table only if those rows indicate that the publication was unrestricted. If the publication was restricted, a valid entry must already exist in syssubscriptions. Running sp_subscribe causes the status for this entry to be changed from inactive to subscribed.

Example

This example adds remote subscription to the types_table article in the pub_alltype publication for the mydb database (on the subscription server) and sets the synchronization type to manual.

sp_subscribe pub_alltypes, types_table, mydb, 'manual'

Permission

Execute permission defaults to the system administrator and database owner and is also granted to repl_subscriber.

Tables Used

sysarticles, syspublications, syssubscriptions, sysservers

See Also

sp_addsubscription | sp_dropsubscription
sp_changesubscription | sp_helpsubscription
sp_changesubstatus | sp_unsubscribe


sp_unsubscribe Replication Stored Procedure

Remotely cancels a subscription to a particular article within a publication, to a whole publication, or to all publications. It also removes all pending jobs from the distribution database.

Syntax

sp_unsubscribe 'publication', 'article'

where

publication
Is the name of the associated publication. Specifying all drops all subscriptions. An entry is required.
article
Is the name of the article. Specifying all drops subscriptions to all articles for each specified publication.

Remarks

If the publication is restricted, running sp_unsubscribe causes the status for this subscription to be changed to inactive.

Example

This example cancels a subscription to all articles and all publications.

sp_unsubscribe 'all', 'all'

Permission

Execute permission defaults to the system administrator and the database owner and is also granted to repl_subscriber.

Tables Used

sysarticles, syspublications, syssubscriptions, sysservers

See Also

sp_addsubscription | sp_dropsubscription
sp_changesubscription | sp_helpsubscription
sp_changesubstatus | sp_subscribe


Stored Procedures - SQL Executive Stored Procedures

Stored Procedures–SQL Executive Stored Procedures

SQL Executive stored procedures give system administrators the ability to create tasks for replication, event scheduling and alert management. The SQL Executive stored procedures are rarely executed directly, they are usually manipulated by SQL Enterprise Manager, which provides an easy, graphical way to manage the entire alerting and scheduling system. It is recommended that you use SQL Enterprise Manager to configure your alert and scheduling infrastructure.

This section describes the stored procedures used by SQL Executive to implement and initiate scheduled events and alerts. The stored procedures can be categorized by type: alert stored procedures and scheduling stored procedures.

Alert Stored Procedures

These are the stored procedures used by the SQL Executive to provide alerts:

sp_addalert | sp_helpalert
sp_addnotification | sp_helpnotification
sp_addoperator | sp_helpoperator
sp_dropalert | sp_updatealert
sp_dropnotification | sp_updatenotification
sp_dropoperator | sp_updateoperator

Scheduling Stored Procedures

These are the stored procedures used by the SQL Executive to provide scheduling:

sp_addtask | sp_helptask
sp_droptask | sp_purgehistory
sp_helphistory | sp_updatetask

All of the SQL Executive stored procedures are listed individually within this section.


sp_addalert SQL Executive Stored Procedure

Creates an alert.

Syntax

sp_addalert name, message_id, severity [, enabled] [, delay_between_responses] [, notification_message] [, include_event_description_in] [, database_name] [, event_description_keyword] [, task_name]

where

name
Is the name of the alert (for example, 605 Alert). This name will appear in the e-mail and/or page sent in response to the alert. It must be unique and be no more than 60 characters.
message_id
Is the message error number that defines the alert. (Normally corresponds to an error number in the sysmessages table.) If severity is used to define the alert, message_id must be zero or NULL. Note that only sysmessages errors written to the event log can cause an alert to be sent.
severity
Specifies the severity level (9 through 25, 110, 120, 130, or 140) that defines the alert. Any SQL Server message stored in the sysmessages table that is sent to the Windows NT event log with the indicated severity will cause the alert to be sent. If message_id is used to define the alert, severity must be zero or NULL.
enabled
Indicates whether the alert is currently enabled (1 if enabled, 0 if not). A non-enabled alert will not be sent. The default is enabled (1).
delay_between_responses
Specifies the wait period, in seconds, between responses to the alert. The response consists of :
  • One or more notifications sent via e-mail and/or pager

    and/or

  • A task to execute

    By setting this value it is possible to prevent, for example, an unwanted flood of e-mail messages from being sent when an alert repeatedly occurs in a short period of time. If a value is not supplied, the default is 0, which means there is no waiting between responses (each occurrence of the alert generates a response).

notification_message
Is an optional additional message that will be sent to the operator as part of the e-mail and/or pager notification. Specifying notification_message is useful for adding special notes such as remedial procedures. It can contain as many as 255 characters.
include_event_description_in
Specifies whether the description of the SQL Server error from the Windows NT event log should be included as part of the notification message. Must be NONE, EMAIL, PAGER or BOTH.
database_name
More restrictively defines the alert by specifying the database in which the error must occur in order for the alert to fire. If database_name is not supplied, the alert will fire regardless of in which database the error occurred.
event_description_keyword
More restrictively defines the alert by specifying that the description of the SQL Server error in the Windows NT event log must be like the supplied sequence of characters. Transact-SQL LIKE expression pattern-matching characters can be used. This parameter is useful for filtering object names (for example, %customer_table%). It can contain as many as 100 characters.
task_name
Specifies an On-Demand task to be executed in response to an alert. The task must be of type CmdExec or TSQL. For details, see the sp_addtask SQL Executive Stored Procedure.

Remarks

This stored procedure must be run from the msdb database.

The following summarizes the circumstances under which errors/messages generated by SQL Server and SQL Server applications are sent to the Windows NT event log and can therefore raise alerts:

  • Severity 19 or higher sysmessages errors
  • information/warnings/errors from the server (severities 110, 120, and 130)
  • Any RAISERROR statement invoked with WITH_LOG syntax
  • Any user-defined messages in the sysmessages table that were created with a WITH_LOG option of 'TRUE'
  • Any sysmessages error modified using the sp_altermessage SQL executive stored procedure (for example, sp_altermessage 123456, with_log, true)
  • Any event logged using the xp_logevent extended stored procedure

SQL Enterprise Manager provides an easy, graphical way to manage the entire alerting system. Using SQL Enterprise Manager is the recommended way to configure your alert infrastructure.

If an alert is not functioning properly, check the following:

  • The SQL Executive service is running
  • The event appeared in the Windows NT event log
  • The alert is enabled

Example

This example adds an alert ('Test Alert') that invokes the task 'Back up the Customer Database,' when fired.

EXEC sp_addalert @name = 'Test Alert', @message_id = 55001, @severity = NULL, @notification_message = 'Error 55001 has occurred. The database will be backed up...', @task_name = 'Back up the Customer Database'

Permission

Only the system administrator can use this procedure.

Tables Used

sysalerts, systasks

See Also

sp_addnotification | sp_helpalert
sp_addtask | sp_updatealert
sp_dropalert |


sp_addnotification SQL Executive Stored Procedure

Sets up a notification for an alert.

Syntax

sp_addnotification alert_name, operator_name, notification_method

where

alert_name
Specifies which alert this notification is for.
operator_name
Specifies the operator to be notified when the alert occurs.
notification_method
Indicates the method by which the operator will be notified. Can be EMAIL, PAGER, or BOTH.

Remarks

This stored procedure must be run from the msdb database.

To send a notification in response to an alert, you must first configure SQLServer to send mail. For details, see the Microsoft SQL Server Administrator's Companion.

You can add a notification for an operator who does not have the necessary address information to be notified by using the specified notification_method. If a failure occurs when sending an e-mail message or pager notification, the failure is reported in the Windows NT application event log.

SQL Enterprise Manager provides an easy, graphical way to manage the entire alerting system. Using SQL Enterprise Manager is the recommended way to configure your alert infrastructure.

Example

This example adds a notification for the specified alert ('Test Alert').

EXEC sp_addnotification 'Test Alert', 'John Doe', EMAIL

Permission

Only the system administrator can use this procedure.

Tables Used

sysalerts, sysnotifications, sysoperators

See Also

sp_dropnotification | sp_updatenotification
sp_helpnotification |


sp_addoperator SQL Executive Stored Procedure

Sets up an operator (notification recipient) for use with alerts.

Syntax

sp_addoperator name [, enabled] [, email_address] [, pager_number]
[, weekday_pager_start_time] [, weekday_pager_end_time] [, saturday_pager_start_time] [, saturday_pager_end_time] [, sunday_pager_start_time] [, sunday_pager_end_time] [, pager_days]

where

name
Is the name of the operator (notification recipient). This name must be unique and can be as many as 50 characters.
enabled
Indicates the operator's current status (1 if currently enabled, 0 if not). If an operator is not enabled, he or she will not receive notifications. The default is 1 (enabled).
email_address
Specifies the e-mail address of the operator. This string will be passed directly to the e-mail system. It can be as many as 100 characters.
pager_number
Specifies the pager address of the operator. This string will be passed directly to the e-mail system. It can be as many as 100 characters.
weekday_pager_start_time
Sets the start time after which to send pager notification to the specified operator Monday through Friday. It must be of the form HHMMSS. The default is 9:00 A.M.
weekday_pager_end_time
Sets the end time after which to cease pager notification to the specified operator Monday through Friday. It must be of the form HHMMSS. The default is 6:00 P.M.
saturday_pager_start_time
Sets the start time after which to send pager notification to the specified operator on Saturdays. It must be of the form HHMMSS. The default is 9:00 A.M. (if not supplied).
saturday_pager_end_time
Sets the end time after which to cease a pager notification to the specified operator on Saturdays. It must be of the form HHMMSS. The default is 6:00 P.M. (if not supplied).
sunday_pager_start_time
Sets the start time after which to send a pager notification to the specified operator on Sundays. It must be of the form HHMMSS. The default is 9:00 A.M. (if not supplied).
sunday_pager_end_time
Sets the end time after which to cease pager notification to the specified operator on Sundays. It must be of the form HHMMSS. The default is 6:00 P.M. (if not supplied).
pager_days
Specifies the days that the operator is available for pages (subject to the specified start/end times). Must be a value from 0 through 127. The value is calculated by adding together the individual values for the required days:

1Sunday
2Monday
4Tuesday
8Wednesday
16Thursday
32Friday
64Saturday

For example, Monday through Friday would be 2+4+8+16+32 = 62. If no value is supplied, the default is 0 (meaning that the operator is never available to receive a page).

Remarks

This stored procedure must be run from the msdb database.

Paging is supported via the e-mail system, which must have an e-mail-to-pager capability if you want to use paging.

SQL Enterprise Manager provides an easy, graphical way to manage the entire alerting system. Using SQL Enterprise Manager is the recommended way to configure your alert infrastructure.

Example

This example sets up the operator information for John Doe.

EXEC sp_addoperator @name = 'John Doe', @email_address = 'JohnD@company.com'

Permission

Only the system administrator can use this procedure.

Tables Used

sysoperators

See Also

sp_dropoperator | sp_updateoperator
sp_helpoperator |


sp_addtask SQL Executive Stored Procedure

For SQL Server 6.5 information, see sp_addtask in What's New for SQL Server 6.5.

Creates a scheduled task.

Syntax

sp_addtask name [, subsystem] [, server] [, username] [, databasename]
[, enabled] [, freqtype] [, freqinterval] [, freqsubtype] [, freqsubinterval]
[, freqrelativeinterval] [, freqrecurrencefactor] [, activestartdate]
[, activeenddate] [, activestarttimeofday] [, activeendtimeofday]
[, nextrundate] [, nextruntime] [, runpriority] [, emailoperatorname]
[, retryattempts] [, retrydelay] [, command] [, loghistcompletionlevel]
[, emailcompletionlevel] [, description] [, tagadditionalinfo] [, tagobjectid]
[, tagobjecttype] [, @newid OUTPUT]

where

name
Is the name of the task being scheduled.
subsystem
Specifies the subsystem to use. Can be Distribution, LogReader, Sync, TSQL, or CmdExec. These must be typed using the capitalization (case) shown.
server
Specifies the server on which to execute this task.
username
Specifies the database user to impersonate when executing this task. Only the system administrator or the database owner can specify this parameter.
databasename
Specifies the database to use when executing the task.
enabled
Specifies the status of scheduled tasks: 1 indicates enabled, the tasks will be scheduled and run; 0 indicates disabled, the tasks will not be scheduled and run.
freqtype
Specifies the frequency for this task:
1One Time
2On Demand (the default)
4Daily
8Weekly
16Monthly
32Monthly Relative
64Autostart
124Recurring
freqinterval
Specifies the interval for freqtype.
freqsubtype
Specifies how often to reschedule the task during the defined period:
1 Once (the default)
2 Second
4 Minute
8 Hour
freqsubinterval
Specifies the value for freqsubtype when the freqsubtype is set to second, minute, or hour.
freqrelativeinterval
Specifies the value used when freqtype is set to 32 (monthly relative). Indicates the first, second, third, fourth, or last day of the month:

1First (the default)
2Second
4Third
8Fourth
16Last

freqrecurrencefactor
Specifies how often the task should reoccur during the defined freqtype.
activestartdate
Specifies the date when this task will first be scheduled. Formatted as YYYYMMDD. The default is 0.
activeenddate
Specifies the date when this task will stop being scheduled. Formatted as YYYYMMDD. The default is 0.
activestarttimeofday
Specifies when this task will be scheduled initially. Formatted as HHMMSS. The default is 0.
activeendtimeofday
Specifies when this task will stop being scheduled. Formatted as HHMMSS. The default is 0.
nextrundate
Specifies the date the task will be scheduled. If the current date is greater than activestartdate, specifies the next date that the task will be scheduled; 0 indicates that the SQL Executive will calculate the next appropriate date. Formatted as YYYYMMDD. The default is 0.
nextruntime
Specifies the date the task will be scheduled if the current time is greater than the activestarttime. 0 indicates that the SQL Executive will calculate the next appropriate time. Formatted as HHMMSS. The default is 0.
runpriority
Specifies the thread priority level at which the subsystem event thread runs. The default is 0.
emailoperatorname
The e-mail name of the operator who will receive notifications. The default is NULL.
retryattempts
Specifies the number of times the SQL Executive retries before issuing an error. The default is 0.
retrydelay
Specifies the interval the SQL Executive waits before retrying the task. The default is 1.
command
Specifies a command string (based on the valid specified subsystem commands) to be passed to the subsystem. If the specified subsystem is TSQL, the command cannot consist of more than one batch. The batch separator GO is not supported. The default is NULL.
loghistcompletionlevel
Specifies the level of events to capture in the event log: 1 captures all successfully run events, 2 captures only failed events.
emailcompletionlevel
Specifies the level of events to capture via e-mail: 1 captures all successfully run events; 2 captures only failed events. The default is 2.
description
Is a description of the task.
tagadditionalinfo
Is user-defined information. This parameter is not required and is normally not used. Varchar (96).
tagobjectid
Is user-defined information. This parameter is not required and is normally not used. Integer.
tagobjecttype
Is user-defined information. This parameter is not required and is normally not used. Integer.
@newid OUTPUT
Is an output parameter that returns the system generated ID for the task.

Remarks

This stored procedure must be run from the msdb database.

Examples

A. Add a Sync Task

This example adds a task for "auth_table_sync" in subsystem "Sync" to run each hour from 9 A.M. to 11 P.M. If scheduled to run after September 26, 1995, the task starts at 4:00 P.M. the first day.

sp_addtask "auth_table_sync", "Sync", "server1", "sa",
    "pubs", 1, 4, 1, 8, 1, 0, 0, 19950926, 19991231,
    090000, 230000, 00000000, 160000, 0, "", 2, 1, "", 2, 2
B. Add a Distribution Task

This example adds a task for "dist_server2_pubs" in subsystem "Distribution" to run every 15 minutes and pass the command string "-Sserver2 -Usa -P -dpubs -pserver1".

sp_addtask "dist_server2_pubs", "Distribution", "server1",
    "sa", "pubs", 1, 4, 1, 4, 15, 0, 0, 19950926, 19991231, 000500,
    235500, 00000000, 000000, 0, "", 2, 1,
    "-server2 -Usa -P -dpubs -pserver1", 2, 2

Permission

Execute permission defaults to the public group.

Tables Used

systasks

See Also

sp_droptask | sp_purgehistory
sp_helphistory | sp_updatetask
sp_helptask |


sp_dropalert SQL Executive Stored Procedure

Drops an alert.

Syntax

sp_dropalert name

where

name
Specifies which alert to drop.

Remarks

This stored procedure must be run from the msdb database.

Dropping an alert also drops all the associated notifications for that alert.

SQL Enterprise Manager provides an easy, graphical way to manage the entire alerting system. Using SQL Enterprise Manager is the recommended way to configure your alert infrastructure.

Example

This example drops the 'Test Alert' alert.

sp_dropalert 'Test Alert'

Permission

Only the system administrator can use this procedure.

Tables Used

sysalerts, sysnotifications

See Also

sp_addalert | sp_updatealert
sp_helpalert |


sp_dropnotification SQL Executive Stored Procedure

Drops a notification for an alert.

Syntax

sp_dropnotification alert_name, operator_name

where

alert_name
Specifies the alert to drop the notification for.
operator_name
Is the name of the operator who is no longer to be notified when alert_name occurs.

Remarks

This stored procedure must be run from the msdb database.

SQL Enterprise Manager provides an easy, graphical way to manage the entire alerting system. Using SQL Enterprise Manager is the recommended way to configure your alert infrastructure.

Example

This example drops the notification information for the 'Test Alert' alert.

sp_dropnotification 'Test Alert', 'John Doe'

Permission

Only the system administrator can use this procedure.

Tables Used

sysalerts, sysnotifications, sysoperators

See Also

sp_addnotification | sp_updatenotification
sp_helpnotification |


sp_dropoperator SQL Executive Stored Procedure

Drops an operator.

Syntax

sp_dropoperator name

where

name
Is the name of the operator to drop.

Remarks

This stored procedure must be run from the msdb database.

Dropping an operator also drops all of the operator's notifications. If the specified operator is the "Fail-Safe Operator," the operator cannot be dropped.

The "Fail-Safe Operator" is the operator who is notified if none of the pager notifications can be sent. The "Fail-Safe Operator" is defined using SQL Enterprise Manager, and SQL Enterprise Manager provides an easy, graphical way to manage the entire alerting system. Using SQL Enterprise Manager is the recommended way to configure your alert infrastructure.

Example

This example removes all of the operator information for John Doe.

sp_dropoperator 'John Doe'

Permission

Only the system administrator can use this procedure.

Tables Used

sysnotifications, sysoperators

See Also

sp_addoperator | sp_updateoperator
sp_helpoperator |


sp_droptask SQL Executive Stored Procedure

Removes a scheduled task.

Syntax

sp_droptask {name | loginname | id}

where

name
Is the name of the task to be removed.
loginname
Is a login name. If specified, all tasks assigned to that login name are dropped. If not NULL, loginname takes precedence over name and id.
id
Is the task ID of the task to be removed. If not NULL, id takes precedence over name.

Remarks

This stored procedure must be run from the msdb database.

Example

This example removes the auth_table_sync task.

sp_droptask auth_table_sync

Permission

Execute permission defaults to the public group.

Tables Used

systasks, syshistory

See Also

sp_addtask | sp_purgehistory
sp_helptask | sp_updatetask


sp_helpalert SQL Executive Stored Procedure

Reports information about the alerts defined for the server.

Syntax

sp_helpalert [having_name_like]

where

having_name_like
Is the string used to search for similar alert_names. Wildcard characters are supported.

Remarks

This stored procedure must be run from the msdb database.

SQL Enterprise Manager provides an easy, graphical way to manage the entire alerting system. Using SQL Enterprise Manager is the recommended way to configure your alert infrastructure.

Example

This example reports information about all alerts with a name beginning with Test.

sp_helpalert 'Test%'

Permission

Only the system administrator can use this procedure.

Tables Used

sysalerts, systasks

See Also

sp_addalert | sp_updatealert
sp_dropalert | Wildcard characters


sp_helphistory SQL Executive Stored Procedure

For SQL Server 6.5 information, see sp_helphistory in What's New for SQL Server 6.5.

Reports the history of one or more scheduled events, alerts, or tasks.

Syntax

sp_helphistory [, taskname] [, taskid] [, eventid] [, messageid] [, severity] [, source] [, category] [, startdate] [, enddate] [, starttime] [, endtime] [, skipped] [, oldestfirst] [, mode]

where

taskname
Specifies the name of the task about which a history will be displayed.
taskid
Specifies the ID of the task about which a history will be displayed.
eventid
Specifies the ID of the event from the Windows NT application event log.
messageid
Specifies the ID of the message as stored in the sysmessages table.
severity
Specifies the severity of the message as stored in the sysmessages table or passed with the RAISERROR statement.
source
Specifies the source of the event. Currently, there is only one source, MSSQLServer.
category
Reserved for future use.
startdate
Specifies tasks beginning their scheduled run(s) on this date.
enddate
Specifies tasks ending their scheduled run(s) on this date.
starttime
Specifies tasks beginning their scheduled run(s) at this time.
endtime
Specifies tasks ending their scheduled run(s) at this time.
skipped
Specifies the number of times this task's run was skipped (usually because the server or SQL Executive were not running).
oldestfirst
Display the oldest task history first.
mode
Specifies the return mode. Can be full (returns all information) or quick (returns only the most useful information). The default is quick.

Remarks

The outcome of the sp_helphistory SQL Executive stored procedure is determined by a match on all specified parameters.

Example

This example displays history of the sysmessages message 55001.

sp_helphistory @messageid = 55001

Permission

Execute permission defaults to the public group.

Tables Used

syshistory, sysoperators, systasks

See Also

sp_addtask | sp_purgehistory


sp_helpnotification SQL Executive Stored Procedure

Reports a list of notifications.

Syntax

sp_helpnotification object_type, name, enum_type, notification_method [, target_name]

where

object_type
Indicates the type of information to be returned. Can be ALERTS for a list of alerts assigned to the supplied operator name, or OPERATORS for a list of operators responsible for the supplied alert name.
name
Is either an operator name or an alert name.
enum_type
Controls what object_type information is returned. Specify ACTUAL (to see only the object_types associated with name), ALL (to see all the object_types including those that are not associated with name), or TARGET (to see only the object_type matching the supplied target_name, irrespective of association with name). This parameter will be ACTUAL in most cases.
notification_method
Specifies the notification method: EMAIL, PAGER or BOTH. When enum_type is ALL or TARGET, affects only the column headings appearing in the output. When enum_type is ACTUAL, affects both the column headings and the returned rows.
target_name
Specifies an alert name to search for (if object_type is ALERTS) or an operator name to search for (if object_type is OPERATORS). Needed only if enum_type is TARGET.

Remarks

This stored procedure must be run from the msdb database.

SQL Enterprise Manager provides an easy, graphical way to manage the entire alerting system. Using SQL Enterprise Manager is the recommended way to configure your alert infrastructure.

Examples

A. Alerts for a Specific Operator

This example returns all alerts for which the operator John Doe receives any kind of notification.

sp_helpnotification 'ALERTS', 'John Doe', 'ACTUAL', 'BOTH'
B. Operators for a Specific Alert

This example returns all operators who receive any kind of notification for the 'Test Alert' alert.

sp_helpnotification 'OPERATORS', 'Test Alert', 'ACTUAL', 'BOTH'

Permission

Only the system administrator can use this procedure.

Tables Used

sysalerts, sysnotifications, sysoperators

See Also

sp_addnotification | sp_updatenotification
sp_dropnotification |


sp_helpoperator SQL Executive Stored Procedure

Reports information about the operators defined for the server.

Syntax

sp_helpoperator [having_name_like]

where

having_name_like
Is the string used to search for similar operator names. Wildcard characters are supported.

Remarks

This stored procedure must be run from the msdb database.

SQL Enterprise Manager provides an easy, graphical way to manage the entire alerting system. Using SQL Enterprise Manager is the recommended way to configure your alert infrastructure.

Example

This example reports information about all operators with two names, beginning with John.

sp_helpoperator 'John%'

Permission

Only the system administrator can use this procedure.

Tables Used

sysoperators

See Also

sp_addoperator | Wildcard characters
sp_updateoperator |


sp_helptask SQL Executive Stored Procedure

For SQL Server 6.5 information, see sp_helptask in What's New for SQL Server 6.5.

Provides information about one or more tasks.

Syntax

sp_helptask taskname [, taskid] [, loginname] [, operatorname] [, subsystem]
[, mode]

where

taskname
Returns information about all tasks with names like taskname.
taskid
Is the ID of the task.
loginname
Is the owner of the tasks whose information is to be returned.
operatorname
Is the name of the operator who might be paged or sent e-mail when the tasks are completed (depending on the e-mail completion level).
subsystem
Is the subsystem the tasks will run against. For replication, can be Distribution, LogReader, or Sync.
mode
Specifies the amount of information to return. Can be full (returns all information) or quick (returns only the most useful information). The default is quick.

Remarks

The quick mode returns the taskname, taskid, subsystem, server (the server on which to execute the task), username (the username used for login to execute the task), dbname (the database to be used when executing the task), and enabled status (1 indicates tasks will be scheduled and run, 0 indicates disabled).

The full mode adds information as supplied when the task was defined. For details, see the options in the sp_addtask SQL Executive Stored Procedure.

Example

This example returns all information about the auth_table_sync task.

sp_helptask auth_table_sync, @mode = 'full'

Permission

Execute permission defaults to the public group.

Tables Used

sysoperators, systasks

See Also

sp_addtask | sp_purgehistory
sp_droptask | sp_updatetask


sp_purgehistory SQL Executive Stored Procedure

Removes information from the history log.

Syntax

sp_purgehistory [taskname] [, taskid] [, eventid] [, messageid] [, severity] [, source] [, category] [, startdate] [, enddate] [, starttime] [, endtime] [, skipped]

where

taskname
Specifies the name of the task about which a history will be displayed. You must be the task owner, unless you are the system administrator.
taskid
Specifies the ID of the task about which a history will be displayed. You must be the task owner, unless you are the system administrator.
eventid
Reserved.
messageid
Specifies the ID of the message as stored in the sysmessages table.
severity
Specifies the severity of the message as stored in the sysmessages table or passed with the RAISERROR statement.
source
Reserved.
category
Reserved for future use.
startdate
Specifies tasks beginning their scheduled run(s) on this date.
enddate
Specifies tasks ending their scheduled run(s) on this date.
starttime
Specifies tasks beginning their scheduled run(s) at this time.
endtime
Specifies tasks ending their scheduled run(s) at this time.
skipped
Specifies the number of times this task's run was skipped (usually because the server or SQL Executive was not running).

Remarks

The sp_purgehistory SQL Executive stored procedure clears all records found by matching all specified parameters.

Example

This example clears the history for taskid 12.

sp_purgehistory @taskid = 12

Permission

Execute permission defaults to the public group.

Tables Used

syshistory, systasks

See Also

sp_addtask | sp_helphistory


sp_updatealert SQL Executive Stored Procedure

Updates information for an existing alert.

Syntax

sp_updatealert name [, new_name] [, enabled] [, message_id] [, severity] [, delay_between_responses] [, notification_message] [, include_event_description_in] [, database_name] [, event_description_keyword] [, task_name] [, occurrence_count] [, count_reset_date] [, count_reset_time] [, last_occurrence_date] [, last_occurrence_time] [, last_response_date] [, last_response _time]

where

name
Is the original name of the alert.
new_name
Is the new name for the alert. It must be unique and be no more than 60 characters.
enabled
Indicates whether the alert is currently enabled (1 if enabled, 0 if not). An alert must be enabled to run. The default is 1 (enabled).
message_id
Is the message/error number that defines the alert. Normally corresponds to an error number in the sysmessages table. If severity is used to define the alert, must be zero or NULL.

Note Only sysmessages written to the Windows NT application event log can activate an alert.

severity
Specifies the severity level (9 through 25, 120, 130, or 140) that defines the alert. Any SQL Server message sent to the Windows NT event log with the indicated severity will activate the alert. If message_id is used to define the alert, must be zero or NULL.
delay_between_responses
Specifies the wait period, in seconds, between responses to the alert. The response consists of :
  • One or more notifications sent via e-mail and/or pager

    and/or

  • A task to execute

By setting this value it is possible to prevent, for example, an unwanted flood of e-mail messages from being sent when an alert repeatedly occurs in a short period of time. If not supplied, the default is 0, which means there is no waiting between responses (each occurrence of the alert generates a response).

notification_message
Is an optional additional message that will be sent to the operator as part of the e-mail and/or pager notification. Specifying notification_message is useful for adding special notes such as remedial procedures. It can contain as many as 255 characters.
include_event_description_in
Specifies whether the description of the SQL Server error from the Windows NT event log should be included as part of the notification message. Must be NONE, EMAIL, PAGER, or BOTH.
database_name
More restrictively defines the alert by specifying the database in which the error must occur in order for the alert to fire. If database_name is not supplied, the alert will fire regardless of the database in which the error occurs.
event_description_keyword
More restrictively defines the alert by specifying that the description of the SQL Server error in the Windows NT event log must be like the supplied sequence of characters. Transact-SQL LIKE expression pattern-matching characters may be used. This parameter is useful for filtering object names (for example, %customer_table%). It can contain as many as 100 characters.
task_name
Specifies the On-Demand task that will execute in response to an alert. The task must be of type 'CmdExec' or 'TSQL'. For details, see the sp_addtask SQL executive stored procedure.
occurrence_count
Indicates the number of times the alert has occurred. This parameter is used for reset purposes only.
count_reset_date
Indicates the date the occurrence count was last reset. This parameter is used for reset purposes only.
count_reset_time
Indicates the time the occurrence count was last reset. This parameter is used for reset purposes only.
last_occurrence_date
Indicates the date the alert last occurred. This parameter is used for reset purposes only.
last_occurrence_time
Indicates the time the alert last occurred. This parameter is used for reset purposes only.
last_response_date
Indicates the date the alert was last responded to by the SQL Executive service. This parameter is used for reset purposes only.
last_response_time
The time the alert was last responded to by the SQL Executive service. This parameter is used for reset purposes only.

Remarks

This stored procedure must be run from the msdb database.

SQL Enterprise Manager provides an easy, graphical way to manage the entire alerting system. Using SQL Enterprise Manager is the recommended way to configure your alert infrastructure.

Example

This example updates the alert 'Test Alert' to an enabled status of 0.

sp_updatealert @name = 'Test Alert', @enabled = 0

Permission

Only the system administrator can use this procedure.

Tables Used

sysalerts, systasks

See Also

sp_addalert | sp_helpalert
sp_dropalert |


sp_updatenotification SQL Executive Stored Procedure

Updates the notification method of an alert notification.

Syntax

sp_updatenotification alert_name, operator_name, notification_method

where

alert_name
Is the name of the alert associated with this notification.
operator_name
Specifies which operator will be notified when the alert occurs.
notification_method
Indicates the method by which the operator will be notified. Can be: EMAIL, PAGER, or BOTH.

Remarks

This stored procedure must be run from the msdb database.

You can update a notification for an operator who does not have the necessary address information to be notified using the specified notification_method. If a failure occurs when sending an e-mail message or pager notification, the failure is reported in the Windows NT application event log.

SQL Enterprise Manager provides an easy, graphical way to manage the entire alerting system. Using SQL Enterprise Manager is the recommended way to configure your alert infrastructure.

Example

This example sets the notification status to EMAIL.

sp_updatenotification 'Test Alert', 'John Doe', EMAIL

Permission

Only the system administrator can use this procedure.

Tables Used

sysalerts, sysnotifications, sysoperators

See Also

sp_addnotification | sp_helpnotification
sp_dropnotification |


sp_updateoperator SQL Executive Stored Procedure

Updates information about an operator.

Syntax

sp_updateoperator name [, new_name] [, enabled] [, email_address] [, pager_number] [, weekday_pager_start_time] [, weekday_pager_end_time] [, saturday_pager_start_time] [, saturday_pager_end_time] [, sunday_pager_start_time] [, sunday_pager_end_time] [, pager_days]

where

name
Is the original name of the operator.
new_name
Is the new name for the operator. This name must be unique and can be as many as 50 characters.
enabled
Indicates the operator's current status (1 if currently enabled, 0 if not). If an operator is not enabled, he or she will not receive notifications. The default is 1 (enabled).
email_address
Specifies the e-mail address of the operator. This string will be passed directly to the e-mail system. It can be as many as 100 characters.
pager_number
Specifies the pager address of the operator. This string will be passed directly to the e-mail system. It can be as many as 100 characters.
weekday_pager_start_time
Sets the starting time after which to send a pager notification to this operator Monday through Friday. It must be of the form HHMMSS. The default is 9:00 A.M.
weekday_pager_end_time
Sets the end time after which to cease a pager notification to the specified operator Monday through Friday. It must be of the form HHMMSS. The default is 6:00 P.M.
saturday_pager_start_time
Sets the start time after which to send a pager notification to the specified operator on Saturdays. It must be of the form HHMMSS. The default is 9:00 A.M.
saturday_pager_end_time
Sets the end time after which to send a pager notification to the specified operator on Saturdays. It must be of the form HHMMSS. The default is 6:00 P.M.
sunday_pager_start_time
Sets the start time after which to send a pager notification to the specified operator on Sundays. It must be of the form HHMMSS. The default is 9:00 A.M.
sunday_pager_end_time
Specifies the end time after which to cease pager notification to the specified operator on Sundays. It must be of the form HHMMSS. The default is 6:00 P.M.
pager_days
Specifies the days that the operator is available for pages (subject to the specified start/end times). Must be a value from 0 through 127. The value is calculated by adding together the individual values for the required days:

1Sunday
2Monday
4Tuesday
8Wednesday
16Thursday
32Friday
64Saturday

For example, Monday through Friday would be 2+4+8+16+32 = 62. If no value is supplied, the default is 0 (meaning that the operator is never available to receive a page, regardless of the pager schedule for that operator).

Remarks

This stored procedure must be run from the msdb database.

SQL Enterprise Manager provides an easy, graphical way to manage the entire alerting system. Using SQL Enterprise Manager is the recommended way to configure your alert infrastructure.

Example

This example updates the operator status to enabled.

sp_updateoperator @name = 'John Doe', @enabled = 1

Permission

Only the system administrator can use this procedure.

Tables Used

sysoperators

See Also

sp_addoperator


sp_updatetask SQL Executive Stored Procedure

Updates information about a task.

Syntax

sp_updatetask {currentname | id} [, name] [, subsystem] [, server] [, username] [, databasename] [, enabled] [, freqtype] [, freqinterval] [, freqsubtype] [, freqsubinterval] [, freqrelativeinterval] [, freqrecurrencefactor] [, activestartdate] [, activeenddate] [, activestarttimeofday] [, activeendtimeofday] [, nextrundate] [, nextruntime] [, runpriority] [, emailoperatorname] [, retryattempts] [, retrydelay] [, command] [, loghistcompletionlevel] [, emailcompletionlevel] [, description] [, tagadditionalinfo] [, tagobjectid] [, tagobjecttype]

where

currentname | id
Specifies which task to update.
name
Specifies a new name for the task.
subsystem
For replication, specifies which subsystem to use. Can be Distribution, LogReader, or Sync. These must be typed using the capitalization (case) shown.
server
Specifies the name of server on which to execute this task.
username
Specifies the database user to impersonate when creating this task. Only the system administrator or the database owner can specify this parameter.
databasename
Specifies the database to use when executing the task.
enabled
Specifies the status of scheduled tasks: 1 indicates enabled (tasks will be scheduled and run), 0 indicates disabled.
freqtype
Specifies the frequency with which to schedule this task:
1One Time
2On Demand (the default)
4Daily
8Weekly
16Monthly
32Monthly Relative
64Autostart
124Recurring
freqinterval
Specifies the interval for freqtype.
freqsubtype
Specifies how often to reschedule during the defined period:
1 Once (the default)
2 Second
4 Minute
8 Hour
freqsubinterval
Specifies the value for freqsubtype when the subtype is set to second, minute, or hour.
freqrelativeinterval
Is the value used when freqtype is set to 32 (monthly relative). Indicates the first, second, third, fourth, or last day of the month.

1First (the default)
2Second
4Third
8Fourth
16Last

freqrecurrencefactor
Specifies how often the task should re-occur during the defined freqtype.
activestartdate
Specifies the date when this task will be scheduled initially. Formatted as YYYYMMDD. The default is 0.
activeenddate
Specifies the date when this task will stop being scheduled. Formatted as YYYYMMDD. The default is 0.
activestarttimeofday
Specifies the time this task will be scheduled initially. Formatted as HHMMSS. The default is 0.
activeendtimeofday
Specifies when this task will stop being scheduled. Formatted as HHMMSS. The default is 0.
nextrundate
Specifies the date the task will be scheduled. If the current date is greater than activestartdate, specifies the next date that the task will be scheduled: 0 indicates that the SQL Executive will calculate the next appropriate date. Formatted as YYYYMMDD. The default is 0.
nextruntime
Specifies the time the task will be scheduled. If the current time is greater than the activestarttime, specifies the next time that the task will be scheduled: 0 indicates that the SQL Executive will calculate the next appropriate time. Formatted as HHMMSS. The default is 0.
runpriority
Specifies the thread priority level at which the subsystem event thread runs. The default is 0.
emailoperatorname
Specifies the e-mail name of the operator who will receive notifications.
retryattempts
Specifies the number of times the SQL Executive retries before issuing an error. The default is 0.
retrydelay
Specifies the SQL Executive the SQL Executive waits before retrying the task. The default is 1.
command
Specifies a command string (based on the valid specified subsystem commands) to be passed to the subsystem. If the specified subsystem is TSQL, the command cannot consist of more than one batch. The batch separator GO is not supported. The default is NULL.
loghistcompletionlevel
Specifies the level of events to capture in the event log, 1 captures all successfully run events, 2 captures only failed events.
emailcompletionlevel
Specifies the level of events to capture via e-mail, 1 captures all successfully run events, 2 captures only failed events. The default is 2.
description
Is text describing the task.
tagadditionalinfo
Reserved for future use.
tagobjectid
Reserved for future use.
tagobjecttype
Reserved for future use.

Remarks

All specified (non-NULL) parameters are updated. To clear a string, use ' '.

Examples

This example renames the auth_table_sync task to authors_sync.

sp_updatetask 'auth_table_sync', @name = 'authors_sync'

Permission

Only the system administrator can use this procedure.

Table Used

systasks

See Also

sp_droptask | sp_addtask


Stored Procedures - System Stored Procedures

Stored Procedures–System Stored Procedures

SQL Server system stored procedures are provided for your convenience. They make it easy to retrieve information from the system tables, administer databases, and perform other tasks that involve updating system tables.

System stored procedures are created in the master database during installation and are owned by the system administrator. The names of all system stored procedures begin with sp_. All stored procedures for which documentation is provided are for regular system use. Additional stored procedures exist in the master database for internal use only. Although these procedures can be viewed and used as examples for writing your own procedures, they are not guaranteed to be included in future releases.

You can run system stored procedures from any database. If a system stored procedure is executed from a database other than master, any non-qualified references to system tables are mapped to the database from which the procedure is being run. For example, if the database owner of the pubs database runs sp_adduser from pubs, the new user is added to pubs..sysusers.

When the parameter for a system stored procedure is a reserved word or an object name and the object name is qualified by a database name or owner name, the entire name must be enclosed in single quotation marks.

Because system stored procedures are located in the master database, their permissions are also set there. Some system stored procedures can be run only by database owners. These procedures make sure that the user executing the procedure is the owner of the database from which the procedures are being executed.

Other system stored procedures can be executed by any user who has been granted EXECUTE permission on them. The EXECUTE permission must be granted in the master database.

  • A user can have permission to execute a system stored procedure either in all databases or in none of them.
  • The owner of a user database cannot directly control permissions on the system stored procedures within his or her own database.

The following sections detail the system stored procedures intended for regular use by the system administrator, the database owner, or all users.


sp_addalias System Stored Procedure

Maps one user to another in a database.

Syntax

sp_addalias login_id, username

where

login_id
Is the master.dbo.syslogins login ID of the user who wants an alternate identity in the current database. An alias allows a SQL Server user to be known in a database as another user. If the user with this login_id exists in the database's sysusers table, SQL Server won't find the user's alias identity, since it checks sysusers before checking sysalternates.
username
Specifies the database user with whom the first user will be linked. This name must exist in both master.dbo.syslogins and in the sysusers table of the current database.

Remarks

Executing sp_addalias maps one user (login_id) to another (login_id) in the current database. The mapping is shown in sysalternates, where the two users' suids are connected.

A report on any users mapped to a specified user can be generated with the sp_helpuser system stored procedure if you give the specified login ID as a parameter.

When a user tries to use a database, SQL Server checks sysusers to see if the login ID is listed there. If the login ID is not there, it then checks sysalternates. If an entry (the user's suid) is found there. and it is mapped to a database user's suid (altsuid in sysalternates table), the first user is treated as the second user while using the database.

There are three ways that a user can be authorized to use a database (assuming the user is listed in master.dbo.syslogins).

  • The user can be listed in the sysusers table of that database. (New database users are added by the database owner with the sp_adduser system stored procedure.)
  • The user can have an alias in the database, which has been added by the database owner with the sp_addalias system stored procedure.
  • The user can use the database as guest if there is a guest entry in the database's sysusers table.

Example

In this example, there is a user named Albert in the current database's sysusers table and a login ID for a user ID Victoria in master.dbo.syslogins. The sp_addalias system stored procedure allows Victoria to use the current database and to be known as Albert in that database.

sp_addalias Victoria, Albert

Permission

Execute permission defaults to the database owner.

Tables Used

master.dbo.syslogins, sysalternates, sysusers

See Also

sp_addlogin | sp_helpuser
sp_adduser | USE
sp_dropalias |


sp_addextendedproc System Stored Procedure

Registers the name of a new extended stored procedure to SQL Server.

Syntax

sp_addextendedproc function_name, dll_name

where

function_name
Is the name of the function to call within the DLL.
dll_name
Is the name of the DLL containing the function.

Remarks

Programmers using Microsoft Open Data Services can create extended stored procedures. Once an extended stored procedure is created, it must be added to SQL Server by using sp_addextendedproc. For more information about creating extended stored procedures, see Microsoft SQL Server Programming Open Data Services.

You should only add an extended stored procedure to the master database. To execute an extended stored procedure from a database other than master, you must qualify the name of the extended stored procedure with master.

The sp_addextendedproc procedure adds entries to the sysobjects table, registering the name of the new extended stored procedure with SQL Server. It also adds an entry in the syscomments table.

Example

This example adds the xp_diskfree extended stored procedure.

sp_addextendedproc xp_diskfree

Permission

Only the system administrator can use this procedure.

Table Used

syscomments, sysobjects

See Also

EXECUTE | sp_dropextendedproc
GRANT | sp_helpextendedproc
REVOKE |


sp_addgroup System Stored Procedure

Creates a group in the current database.

Syntax

sp_addgroup grpname

where

grpname
Is the name of the group to add. Group names must follow the rules for identifiers.

Remarks

Groups are used as collective names for granting and revoking permissions.

The sp_addgroup system stored procedure adds an entry for the new group to a database's sysusers table. Each group's uid is a number greater than or equal to 16,384 (except the uid of the public group, which is always 0).

Once a group has been created, you can use the group name as an optional parameter with the sp_adduser system stored procedure, which adds the new user to a group at the same time as it is created. To add an already existing user to a group, use the sp_changegroup system stored procedure.

There is a built-in group, public, in every database. Each user automatically belongs to public and can be added to only other group. You cannot remove a user from the public group.

Example

This example creates an accounting group.

sp_addgroup accounting

Permission

Execute permission defaults to the database owner.

Table Used

sysusers

See Also

GRANT | sp_changegroup
REVOKE | sp_dropgroup
sp_adduser | sp_helpgroup


sp_addlogin System Stored Procedure

For SQL Server 6.5 information, see sp_addlogin in What's New for SQL Server 6.5.

Creates a new SQL Server user by adding an entry to master.dbo.syslogins.

Syntax

sp_addlogin login_id [, passwd [, defdb [, deflanguage]]]

where

login_id
Is the login ID of the user. Login IDs must follow the rules for identifiers.
passwd
Is the user's password. If no password is specified, the default password is NULL (no password needs to be explicitly entered). After sp_addlogin has been executed, the password is encrypted and stored in the syslogins table.
defdb
Specifies the user's default database (the database the user is connected to after logging in). If no defdb is specified, the default is master.
deflanguage
Is the default language assigned when a user logs in to SQL Server. If no deflanguage is specified, the server's default language, defined by the configuration variable default language, is used.

Remarks

After sp_addlogin is executed, the user can log in to SQL Server.

When you are using integrated security, the presence or absence of a login ID determines if a user is uniquely known within SQL Server or is instead mapped to a default account, if one exists. If no default account and no login ID exists for a specific user, that user cannot log in.

The user can change his or her own password at any time by using the sp_password system stored procedure. The system administrator can change any user's password by using sp_password with NULL as the old password.

If the name of a default database is supplied (defdb), the user is connected to the specified database without the USE statement and without passing through master. However, the user cannot use the default database until given access to that database by its database owner (by using the sp_adduser or sp_addalias system stored procedure).

The user can change his or her own default database at any time by using the sp_defaultdb system stored procedure. The system administrator can change any user's default database by using sp_defaultdb.

The user can change his or her own default language at any by using the sp_defaultlanguage system stored procedure. The system administrator can change any user's default language by using sp_defaultlanguage.

Examples

A. Create a Login ID

This example creates a SQL Server login for the login ID Victoria. Since the passwd and defdb parameters are not included, Victoria's password is NULL and her default database is master.

sp_addlogin Victoria
B. Create a Login ID and Default Database

This example creates a SQL Server login identification number for the user Albert. His password is food and his default database is corporate.

sp_addlogin Albert, food, corporate
C. Create a Login ID with a Different Default Language

This example creates a SQL Server login for Claire. Her password is caniche, her default database is public_db, and her default language is French.

sp_addlogin Claire, caniche, public_db, french

Permission

Only the system administrator can use this stored procedure.

Tables Used

master.dbo.sysdatabases, master.dbo.syslogins, master.dbo.syslanguages

See Also

sp_addalias | sp_helpuser
sp_adduser | sp_password
sp_defaultdb | xp_grantlogin
sp_defaultlanguage | xp_logininfo
sp_droplogin | xp_revokelogin


sp_addmessage System Stored Procedure

Adds a new error message to the sysmessages table.

Syntax

sp_addmessage msg_id, severity, 'text of message'
[, language [, {true | false} [, REPLACE]]]

where

msg_id
Is the ID of the message. It must be an integer. Acceptable values for user-defined error messages start with 50001. The msg_id must be unique; an error will be returned if that ID already exists. By default, any message added will have the language ID (@@langid) of the connection adding the message. To add a message for a different language, first use the SET LANGUAGE statement.
severity
Represents the severity level of the error. Valid levels are 1 through 25. Only the system administrator can add a message with a severity level of 19 through 25. For details on severity levels and use, see the Microsoft SQL Server Administrator's Companion.
text of message
Is the text of the error message. The string can have as many as 255 characters and must be surrounded by single quotation marks.
language
Specifies the language for this message. Because multiple languages can be installed on the same server, language specifies in which language each message is written. When not specified, U.S. English is the default language.
true | false
Specifies whether the sysmessages is to be written to the Windows NT event log when it occurs. If true, the error will be automatically written to the Windows NT event log. If false, the error will not be automatically written to the Windows NT event log but may be written, depending on how the error was raised.

Note If a message is written to the Windows NT event log, it is also written to the SQL Server error log file.

REPLACE
Is optionally used to overwrite an existing error message with new message text and severity level. This option must be specified if the msg_id already exists.

Remarks

If no parameters are supplied, a syntax diagram will be displayed.

Example

This example adds an informational message to sysmessages.

sp_addmessage 50001, 16, 'Percentage expects a value between 20 and 100. Please re-execute with a more appropriate value.'

Permission

Execute permission defaults to the system administrator, who can grant execute permission to other users.

Tables Used

sysmessages

See Also

CREATE TABLE | sp_altermessage
RAISERROR | sp_dropmessage


sp_addremotelogin System Stored Procedure

Adds a new remote login ID to master.dbo.sysremotelogins.

Syntax

sp_addremotelogin remoteserver [, login_ID [, remotename]]

where

remoteserver
Is the name of the remote server to which the remote login applies. The server must be known to the local server by an entry in the master.dbo.sysservers table.
login_ID
Is the login ID of the user on the local SQL Server. The user named by login_ID must already exist in the master.dbo.syslogins table. Use the sp_addserver system stored procedure to add a remote server.
remotename
Is the ID used by the remote server when logging in to the local server. All remote logins not explicitly matched to a local ID are automatically mapped to a local ID.

Remarks

When a server receives a remote login, the local server tries three ways to map the remote user to a local user. First, the local server looks for an entry in the sysremotelogins table that matches the remote server name and the remote login ID. If one is found, then the local server's user ID (suid) for that row logs in the remote user. If no entry is found, the local server searches for an entry with a value of NULL in the remoteusername column and a local server's user ID that is not -1. In this case, the remote user is mapped to the local server's user ID. Finally, if the previous attempts failed, the local server checks the sysremotelogins table for an entry with a remote name of NULL and a local server's user ID of -1. In this case, the remote login ID supplied by the remote server looks for a local server's user ID in the syslogins table.

The login ID of the local user may be different on the remote server.

Every remote login entry has a status. The default status is not trusted. This means that when a remote login with not trusted status is received, SQL Server checks the password. If you don't want the password to be checked, change the status to trusted by using the sp_remoteoption system stored procedure.

Examples

A. Map One to One

This example shows a simple way to map remote names to local names when the local and remote servers have the same users. It creates an entry in the sysremotelogins table so that the remote server ACCOUNTS can validate logins. When no login parameters are given, a null value is entered in the remoteusername column of sysremotelogins.

sp_addremotelogin ACCOUNTS
B. Map Many to One

This example creates an entry that maps all users from the remote server ACCOUNTS to a local login ID Albert.

sp_addremotelogin ACCOUNTS, Albert
C. Explicit One-to-One Mapping

This example causes a remote login from the remote user Chris on the remote server ACCOUNTS to be mapped to the local user salesmgr.

sp_addremotelogin ACCOUNTS, salesmgr, Chris

Permission

Only the system administrator can execute this procedure.

See Also

sp_addlogin | sp_helpremotelogin
sp_addserver | sp_helpserver
sp_dropremotelogin | sp_remoteoption


sp_addsegment System Stored Procedure

Defines a segment on a database device in the current database.

Syntax

sp_addsegment segname, logical_name

where

segname
Is the name of the new segment, which is added to the syssegments table of the current database. Segment names must be unique in each database.
logical_name
Specifies the database device where segname will be located. A database device can have more than one segment associated with it.

Remarks

The sp_addsegment system stored procedure defines segment names for database devices that have been assigned to a specific database with the ALTER DATABASE or CREATE DATABASE statement. The maximum number of segments for any database is 32. Segments are named subsets of a database defined per device. Before you can use segment procedures in a database, make the database the current one by issuing the USE database statement.

Once a segment has been defined, it can be used with the CREATE TABLE statement, the CREATE INDEX statement, and in the sp_placeobject system stored procedure, which puts data for a table or index on the segment. When a table or index is created on a particular segment, all subsequent data for the table or index is put on that segment.

To extend the range of a segment to another database device used by the same database, use the sp_extendsegment system stored procedure.

If a database is extended with the ALTER DATABASE statement on a device used by that database, the segments mapped to that device are also extended.

The SYSTEM and DEFAULT segments are mapped to each database device included in a CREATE DATABASE or ALTER DATABASE statement. The LOGSEGMENT is also mapped to each device, unless it is put on a separate device by using the LOG ON extension to the CREATE DATABASE statement or by using the sp_logdevice system stored procedure. To unmap these segments, use the sp_dropsegment system stored procedure. For more information, see the Microsoft SQL Server Administrator's Companion.

Example

This example creates a segment named INDEXES on the database device named DEV1.

sp_addsegment indexes, dev1

Permission

Execute permission defaults to the system administrator and the database owner.

Tables Used

syssegments, master.dbo.sysusages, master.dbo.sysdevices

See Also

ALTER DATABASE | sp_extendsegment
CREATE INDEX | sp_helpdb
CREATE TABLE | sp_helpdevice
DISK INIT | sp_placeobject
sp_dropsegment |


sp_addserver System Stored Procedure

Defines a remote server or the name of the local server.

Syntax

sp_addserver server_name [, LOCAL]

where

server_name
Is the name of the new server, which is added to the master.dbo.sysservers table. Server names must be unique and must conform to the rules for identifiers.
LOCAL
Is an optional parameter that identifies the server being added as the local server. This parameter sets the value of the global variable @@SERVERNAME. (The setup program sets this variable to the computer name during installation. It is recommended that you do not change the name to something other than the computer name because the computer name is how users connect to SQL Server by default without the need for additional configuration). The local definition takes effect only after the server is shut down and restarted.

Remarks

To execute a stored procedure on a remote server, the remote server must be added to the sysservers table.

To set or clean server options, use the sp_serveroption system stored procedure .

Example

This example creates an entry for a remote server named ACCOUNTS in the local master.dbo.sysservers table.

sp_addserver ACCOUNTS

Permission

Execute permission defaults to the system administrator and the database owner.

Table Used

master.dbo.sysservers

See Also

sp_addremotelogin | sp_helpremotelogin
sp_dropremotelogin | sp_helpserver
sp_dropserver | sp_serveroption


sp_addtype System Stored Procedure

Creates a user-defined datatype. Executing sp_addtype creates a user-defined datatype and adds it to the systypes system table. Once a user datatype is created, you can use it in the CREATE TABLE and ALTER TABLE statements, as well as bind defaults and rules to it.

Syntax

sp_addtype typename, phystype [, nulltype]

where

typename
Names the user datatype. Datatype names must follow the rules for identifiers and must be unique in each database.
phystype
Is the physical, or SQL Server - supplied, type (char, int, and so on) on which the user datatype is based. For details on available datatypes, see the Datatypes topic. (Quotation marks are required around all parameters that have embedded blank spaces or punctuation marks. For example, 'char(10)'.)
nulltype
Indicates how the user-defined datatype handles null value entries. Can be NULL or NOT NULL. The default nullability, if not explicitly defined by sp_addtype, will be set to the current default nullability. Use the GETANSINULL system function to determine the current default nullability, which can be adjusted by using the SET command or sp_dboption.. Nullability should be explicitly defined.

Note Remember that datatype nullability only defines the default nullability for this datatype. If nullability is explicitly defined when the user-defined datatype is used during table creation, it will take precedence over the defined nullability. For details, see the ALTER TABLE and CREATE TABLE statements.

Remarks

Define each user datatype in terms of one of the physical (SQL Server - supplied) datatypes, preferably specifying NULL (allow null entries) or NOT NULL (disallow them). A user-defined datatype name must be unique in the database, but user-defined datatypes with different names can have the same definition.

Examples

A. Datatype That Does Not Allow Null Values

This example creates a user-defined datatype named ssn to be used for columns that hold social security numbers.

Notice that varchar(11) is enclosed in single quotation marks because it contains punctuation (parentheses).

sp_addtype ssn, 'VARCHAR(11)', 'NOT NULL'
B. Datatype That Allows Null Values

This example creates a user-defined datatype (based on datetime) named birthday that allows null values.

sp_addtype birthday, datetime, NULL

Permission

Execute permission defaults to the public group.

Table Used

See Also

CREATE DEFAULT | sp_droptype
CREATE RULE | sp_rename
CREATE TABLE | sp_unbindefault
sp_bindefault | sp_unbindrule
sp_bindrule |


sp_addumpdevice System Stored Procedure

Adds a dump device to SQL Server.

Syntax

sp_addumpdevice {'disk' | 'diskette' | 'tape'}, 'logical_name',
'physical_name' [, {{cntrltype [, noskip | skip [, media_capacity]]} |
{@devstatus = {noskip | skip}}}]

where

disk | diskette | tape
Specifies the type of dump device. Use disk to add a hard disk file as a dump device. Use diskette to add a 5.25-inch or 3.5-inch diskette drive file as a dump device. Use tape for any tape devices supported by Windows NT. Enclose these options in single quotation marks.
logical_name
Is the logical name of the dump device used in the LOAD and DUMP statements. This name must follow the rules for identifiers.
physical_name
Is the physical name of the dump device. Physical names must follow the rules for operating-system filenames or universal naming conventions for network devices and must include a full path.

When creating a dump device on a remote network location, be sure that the name under which the SQL Server was started has appropriate write capabilities on the remote computer.

If you are adding a tape device, this parameter must be the physical name assigned to the local tape device by Windows NT, for example \\.\TAPE0 for the first tape device on the computer. The tape device must be attached to the server computer; it cannot be used remotely. Enclose names containing non-alphanumeric characters in quotation marks.

cntrltype
Is not required when creating dump devices. However, if used in scripts, it is still acceptable to supply this parameter, but SQL Server ignores it.

Note As of SQL Server version 4.2, sp_addumpdevice no longer uses the cntrltype or media_capacity parameters because SQL Server automatically detects the control type and media capacity information. In this release of SQL Server, the syntax is still supported; however, both parameters will be removed in a future release.

skip | noskip
Indicates whether ANSI tape labels are read (noskip) or ignored (skip). For example, when skip is specified and the ANSI label of a tape warns that it has expired or that you don't have permission to write to it, SQL Server ignores the warning. Or, if the tape you are writing to is new (and therefore has no ANSI label), SQL Server writes a new label on the first try. The skip option prevents unnecessary retries as SQL Server tries to find a label.

Specifying noskip tells SQL Server to read existing ANSI tape labels on the tape to which you are writing. Use noskip for diskette dump devices.

The sp_addumpdevice system stored procedure lets you choose between the security of paying attention to ANSI labels or the convenience of ignoring them. In either case, SQL Server still reads/writes the labels.

media_capacity
Is not required when creating dump devices. However, if used in scripts, it is still acceptable to supply this parameter, but SQL Server ignores it. For more information, see contrltype, above.
@devstatus = skip | noskip
Explicitly defines whether ANSI tape labels are read (noskip) or ignored (skip). Use this local variable when you do not explicitly use the ctrltype or media_capacity parameters.

Remarks

The sp_addumpdevice system stored procedure adds a dump device to the master.dbo.sysdevices table. It can then be referred to logically in the DUMP, DUMP TRANSACTION, and LOAD statements.

Ownership and permission problems can interfere with the use of disk or file dump devices. Make sure that appropriate file permissions are given to the account under which SQL Server was started.

SQL Server supports tape backups to tape devices that are supported by Windows NT. For information about Windows NT - supported tape devices, see the hardware compatibility list for Windows NT. To view the tape devices available on the computer, use SQL Enterprise Manager.

Use only the recommended tapes for the specific tape drive (as suggested by the drive manufacturer). If you are using DAT drives, use computer-grade DAT tapes (Digital Data Storage-DDS). If you are using a non-computer-grade tape, SQL Server backups are restricted to a single tape (a database dump that spans multiple tapes is not allowed).

Examples

A. Disk Dump Device

This example adds a disk device named MYDISKDUMP, with the physical name C:\DUMP\DUMP1.DAT.

sp_addumpdevice 'disk', 'mydiskdump', 'c:\dump\dump1.dat'
B. Network Disk Dump Device

This example shows a remote disk device dump. The name under which SQL Server was started must have permissions to that remote file.

sp_addumpdevice 'disk', 'networkdevice',
    '\\servername\sharename\path\filename.ext'
C. Tape Dump Device

This example adds the TAPEDUMP1 device with the physical name \\.\TAPE0.

sp_addumpdevice 'tape', 'tapedump1',
    '\\.\tape0'

Permission

Execute permission defaults to the system administrator.

Table Used

master.dbo.sysdevices

See Also

DISK INIT | sp_dropdevice
DUMP | sp_helpdevice
LOAD |


sp_adduser System Stored Procedure

Adds a new user to the current database.

Syntax

sp_adduser login_id [, username [, grpname]]

where

login_id
Is the user's login ID as found in the name column of master.dbo.syslogins.
username
Specifies a name for this user in the current database. Omitting this parameter causes the username to default to the user's login ID.
grpname
Identifies an existing group in the database. If you don't specify a group, the user becomes a member of the default group public. If you want to add a user to a group, you must supply a value for the username parameter. (The username can be the same as login_id.)

A user can be a member of only one group, in addition to public. Every user is a member of the default group, public. The group must already exist in the database.

Remarks

The sp_adduser system stored procedure treats the combination of a guest login ID and user guest as a special case. In earlier releases, a non-special guest user could be created within a user-defined database. SQL Server 6.0 prevents this from happening, in the following way:

  • If a login name of guest is specified with the sp_adduser system stored procedure and a guest login exists and the username is not specified as guest, a user with the suid of the login name guest will be added.
    sp_adduser guest, dbuser1
  • If the username guest is specified and the login name specified is not guest, an error message is returned, stating the guest user cannot be mapped to a login.
    sp_adduser loginid1, guest
  • If a login name of guest is specified and the username specified is guest or not supplied, then the user created within the database will be the special guest user. If the guest user already exists, an error message will be returned.
    sp_adduser guest, guest

The database owner executes the sp_adduser system stored procedure to add a login ID to the sysusers table of the current database, enabling the user to access the current database under his or her own name.

Specifying a username parameter gives the new user a name in the database different from his or her login ID on SQL Server. The ability to assign a different name to a user on SQL Server and in a database is provided as a convenience. This is not an alias as provided by the sp_addalias system stored procedure¾ the user is simply given a different name, not mapped to the identity and permissions of another user as with sp_addalias.

To access a database, a user must be listed in sysusers (by using sp_adduser) or mapped to another user in sysalternates (by using sp_addalias), or there must be a guest entry in sysusers.

Examples

A. Add a User

The SQL Server login ID Victoria has already been added to SQL Server with sp_addlogin. This example adds Victoria to the database. Victoria will be known in the current database by the username Victoria and belong to the group fort_mudge (previously created with sp_addgroup).

sp_adduser Victoria, Victoria, fort_mudge
B. Add a Username with the Same Login ID

This example adds Margaret to the database. Her database username is the same as her SQL Server login ID, and she belongs to the default group public.

sp_adduser Margaret
C. Add a User Who Uses a Different Username

This example adds Haroldq to the database. When Haroldq uses the current database, his name is Harold. He belongs to the fort_mudge group.

sp_adduser Haroldq, Harold, fort_mudge

Permission

Execute permission defaults to the database owner.

Tables Used

master.dbo.syslogins, sysalternates, sysusers

See Also

GRANT | sp_dropgroup
REVOKE | sp_helpuser
sp_addalias | USE
sp_addgroup | xp_grantlogin
sp_changegroup | xp_logininfo
sp_dropalias | xp_revokelogin


sp_altermessage System Stored Procedure

Alters the state of a sysmessages error.

Syntax

sp_altermessage message_id, WITH_LOG, {true | false}

where

message_id
Specifies which sysmessages error or message to alter.
WITH_LOG
Specifies that the sysmessages is to be written to the Windows NT event log when it occurs.

Note If a message is written to the Windows NT event log, it is also written to the SQL Server error log file.

true | false
Specifies whether the error will be written to the Windows NT event log. If true, the error will be automatically written to the Windows NT event log. If false, the error will not be automatically written to the Windows NT event log but may be written, depending on how the error was raised.

Remarks

The effect of the sp_altermessage system stored procedure with the WITH_LOG option is similar to that of the RAISERROR WITH LOG parameter, except that sp_altermessage changes the logging behavior of an existing message. If a message has been altered to be WITH_LOG, then no matter how a user invokes the error it will always be written to the Windows NT event log. Even if RAISERROR is executed without the WITH LOG option, the error will be written to the Windows NT event log.

System messages (such as 605), as well as user messages added by sp_addmessage, can be modified by using sp_altermessage.

Example

This example causes existing message 55001 to be logged to the Windows NT event log.

sp_altermessage 55001, WITH_LOG, TRUE

Permission

Execute permission defaults to the system administrator and can be transferred to other users.

Table Used

sysmessages

See Also

sp_addmessage sp_dropmessage


sp_bindefault System Stored Procedure

Binds a default to a column or to a user-defined datatype.

Syntax

sp_bindefault defname, objname [, futureonly]

where

defname
Is the name of the default created by the CREATE DEFAULT statement.
objname
Specifies the table and column or the user-defined datatype to which the default is to be bound. If objname is not of the form 'table.column', it is assumed to be a user-defined datatype. (Quotation marks are required around all system stored procedure parameters that have embedded blanks or punctuation.) By default, existing columns of the user-defined datatype inherit the default defname unless a default has been bound directly to the column. A default cannot be bound to a column of type timestamp or a column with the IDENTITY property.
futureonly
Used only when binding a default to a user-defined datatype, this option prevents existing columns of that datatype from inheriting the new default. It is never used when binding a default to a column. If futureonly is specified, any existing default bound to that datatype will be explicitly bound to any existing columns of that datatype that do not already have a default bound to them.

Remarks

First use the CREATE DEFAULT statement to create a default. Then execute the sp_bindefault system stored procedure to bind the default to a column or to a user-defined datatype in the current database. You can bind a new default to a column or to a user-defined datatype with sp_bindefault without unbinding an existing default. The old default is overridden. You cannot bind a default to a SQL Server - supplied datatype.

Existing columns of the user-defined datatype inherit the new default unless they have a default bound directly to them or unless the futureonly option is used. New columns of the user-defined datatype always inherit the default.

The default must be compatible with the datatype of the column. For example, you cannot use "N/A" as a default for a numeric column. If the default is not compatible with the column to which you've bound it, SQL Server returns an error message when it tries to insert the default value (not when you bind it). You cannot bind a default to a column that already has a DEFAULT constraint.

When you bind a default to a column, information is added to the syscolumns table. When you bind a default to a user-defined datatype, information is added to the systypes table.

Examples

A. Bind a Default to a Column

Assuming that a default named today has been defined in the current database by the CREATE DEFAULT statement, this example binds the default to the startdate column of the employees table. Whenever a row is added to the employees table and data for the startdate column is not supplied, the column gets the value of the default today.

sp_bindefault today, 'employees.startdate'
B. Bind a Default to a User-defined Datatype

Assuming that a default named def_ssn and a user-defined datatype named ssn exist, this example binds the default def_ssn to the ssn user-defined datatype. The default is inherited by all columns that are assigned the user-defined datatype ssn when a table is created. Existing columns of type ssn also inherit the default def_ssn unless you specify futureonly (which prevents existing columns of that user-defined datatype from inheriting the default), or unless the column has a default bound directly to it. Defaults bound to columns always take precedence over those bound to datatypes.

sp_bindefault def_ssn, ssn
C. FUTUREONLY

This example binds the default def_ssn to the user-defined datatype ssn. Because futureonly is specified, no existing columns of type ssn are affected.

sp_bindefault def_ssn, ssn, FUTUREONLY

Permission

Execute permission defaults to the object owner.

Tables Used

syscolumns, sysobjects, systypes

See Also

CREATE DEFAULT | sp_unbindefault
DROP DEFAULT |


sp_bindrule System Stored Procedure

Binds a rule to a column or to a user-defined datatype.

Syntax

sp_bindrule rulename, objname [, futureonly]

where

rulename
Is the name of a rule created by the CREATE RULE statement.
objname
Specifies the table and column or the user-defined datatype to which the rule is to be bound. If objname is not of the form 'table.column', it is assumed to be a user-defined datatype. (Quotation marks are required around all system stored procedure parameters that have embedded blanks or punctuation.) By default, existing columns of the user-defined datatype inherit the rule rulename unless a rule has been bound directly to the column.
futureonly
Used only when binding a rule to a user-defined datatype, this option prevents existing columns of a user-defined datatype from inheriting the new rule. If futureonly is specified, any existing rule bound to that datatype will be explicitly bound to any existing columns of that datatype that do not already have a rule bound to them.

Remarks

First use the CREATE RULE statement to create a rule. Then execute the sp_bindrule system stored procedure to bind it to a column or to a user-defined datatype in the current database. You can bind a new rule to a column (although using a CHECK constraint is preferred) or to a user-defined datatype with sp_bindrule without unbinding an existing rule. The old rule is overridden. If a rule is bound to a column with an existing CHECK constraint, all restrictions are evaluated. You cannot bind a rule to a SQL Server - supplied datatype.

The rule is enforced when an INSERT is attempted, not at binding. You can bind a character rule to a column of numeric datatype, even though such an INSERT is illegal.

Existing columns of the user-defined datatype inherit the new rule unless they have a rule bound directly to them or the futureonly option is used. New columns of the user-defined datatype always inherit the rule.

When you bind a rule to a column, information is added to the syscolumns table. When you bind a rule to a user-defined datatype, information is added to the systypes table.

Examples

A. Bind a Rule to a Column

Assuming that a rule named today has been created in the current database by the CREATE RULE statement, this example binds the rule to the startdate column of the employees table. When a row is added to employees, the data for the startdate column is checked against the today rule.

sp_bindrule today, 'employees.startdate'
B. Bind a Rule to a User-defined Datatype

Assuming the existence of a rule named rule_ssn and a user-defined datatype named ssn, this example binds rule_ssn to ssn. In a CREATE TABLE statement, columns of type ssn inherit the rule_ssn rule. Existing columns of type ssn also inherit the rule_ssn rule unless you specify the futureonly option (which prevents existing columns of type ssn from inheriting the rule) or ssn has a rule bound directly to it. Rules bound to columns always take precedence over those bound to datatypes.

sp_bindrule rule_ssn, ssn
C. FUTUREONLY

This example binds the rule_ssn rule to the user-defined datatype ssn. Because futureonly is specified, no existing columns of type ssn are affected.

sp_bindrule rule_ssn, ssn, FUTUREONLY

Permission

Execute permission defaults to the object owner.

Tables Used

syscolumns, sysobjects, systypes

See Also

CREATE RULE | sp_unbindrule
DROP RULE |


sp_certify_removable System Stored Procedure

For SQL Server 6.5 information, see sp_certify_removable in What's New for SQL Server 6.5.

Verifies that a database is configured properly for distribution on removable media.

Syntax

sp_certify_removable dbname[, AUTO]

where

dbname
Specifies the database to be verified.
AUTO
As necessary, gives ownership of the database and all database objects to the system administrator, and drops any user-created database users and any non-default permissions.

Remarks

If the database is configured properly, the sp_certify_removable system stored procedure sets the database offline and returns information that will be required when the database is later installed using sp_dbinstall. It truncates the transaction log, moves it to the system device, and drops the log device. It returns the physical and logical names and the size, in megabytes, of the system device and the data device(s). Make a note of this information and provide it¾along with the distribution disk¾to users who will be installing the distributed database.

The system administrator must be owner of the database and all database objects because the system administrator is a known user that exists on all SQL Servers and can be counted on to exist when the database is later distributed and installed.

If you run sp_certify_removable without the AUTO option and it returns information indicating that the system administrator is not the database owner, that user-created users exist, that the system administrator does not own all objects in the database, or that non-default permissions have been granted, you have two ways to correct those conditions:

  • You can use SQL Server tools and procedures, and then run sp_certify_removable again.
  • You can simply run sp_certify_removable with the AUTO option.

Note that this stored procedure only checks for users and user permissions. It is permissible to add groups to the database and to grant permissions to those groups. For information, see the GRANT statement.

Example

This example certifies that the inventory database is ready to be removed.

sp_certify_removable inventory, AUTO

Permission

Only the system administrator can use this stored procedure.

See also

sp_create_removable | sp_dboption
sp_dbinstall | sp_dbremove.


sp_changedbowner System Stored Procedure

Changes the owner of a database.

Syntax

sp_changedbowner login_id [, true]

where

login_id
Is the login ID of the new owner of the current database. The new owner must not already be known as a user or an alias (that is, the new owner must not already be listed in sysusers or sysalternates). Executing sp_changedbowner with the single parameter login_id changes the database ownership to the login_id and drops the aliases of users who could act as the old database owner.
true
Transfers aliases and their permissions to the new database owner.

Remarks

The sp_changedbowner system stored procedure makes login_id the owner of the current database.

The new database owner must already have a login ID on SQL Server but must not have a database name or alias name in the current database. To assign database ownership to such a user, drop the user's database name and alias entries before executing sp_changedbowner.

After the sp_changedbowner system stored procedure is executed, the new owner is known as the database owner inside the database.

To grant permissions to a user who is the new owner, the system administrator must grant the permissions to the database owner, because the user is known inside the database only by that other name.

Example

This example makes the user Albert the owner of the current database.

sp_changedbowner Albert

Permission

Only the system administrator can execute this procedure.

Tables Used

master.dbo.sysdatabases, master.dbo.syslogins, sysalternates, sysusers

See Also

CREATE DATABASE | sp_dropuser
sp_addlogin | sp_helpdb
sp_dropalias |


sp_changegroup System Stored Procedure

Changes a user's group.

Syntax

sp_changegroup grpname, username

where

grpname
Is the name of a group that already exists in the current database.
username
Specifies which user to add to the group. The user must already exist in the current database.

Remarks

Groups provide a collective name that is used when granting and revoking permissions. A user can be a member of only one group, in addition to public.

The sp_changegroup system stored procedure adds the specified user to the specified group. The user is dropped from the group he or she belongs to and is added to the one specified by grpname. If you use public as the grpname parameter, it must be enclosed in quotation marks because PUBLIC is an SQL keyword.

New database users can be added to groups at the same time as they are given access to the database by sp_adduser.

Every user is a member of the default group public, if not explicitly added to some other group by sp_adduser or sp_changegroup.

Example

This example makes Albert a member of the developers group. It doesn't matter which group Albert belonged to before.

sp_changegroup developers, Albert

Permission

Execute permission defaults to the database owner.

Table Used

sysusers

See Also

GRANT | sp_adduser
REVOKE | sp_dropgroup
sp_addgroup | sp_helpgroup


sp_configure System Stored Procedure

For SQL Server 6.5 information, see sp_configure in What's New for SQL Server 6.5.

Displays or changes configuration options.

Syntax

sp_configure [config_name [, config_value]]

where

config_name
Specifies a configuration option. SQL Server understands any unique string that is part of the configuration name. This parameter must be enclosed in quotation marks if it contains embedded blanks or is a keyword.
config_value
Is the value for the configuration option.

Remarks

All users can execute the sp_configure system stored procedure with no parameters (SQL Server displays a list of all configuration options and their current values) or with config_name (SQL Server displays the current value for the specified configuration option).

Only the system administrator can execute sp_configure with both parameters and change the configuration option value. After using sp_configure, the system administrator must execute the RECONFIGURE statement to install the changed value. Dynamic options take effect immediately after the RECONFIGURE statement has been run. For all non-dynamic options, SQL Server must be stopped and restarted before the options can take effect. For details, see the RECONFIGURE statement.

The information returned by sp_configure, when executed with no parameters, shows a config_value column and a run_value column. The config_value column contains the value to which the configuration option was set with sp_configure (the value in sysconfigures.value). The run_value column contains the value for that option (the value in syscurconfigs.value) for SQL Server. These values do not necessarily have to be equivalent. For example, the system administrator may have changed an option with sp_configure but has not executed the RECONFIGURE statement (for dynamic options) or restarted SQL Server (for non-dynamic options).

The run_value column contains the value that SQL Server is using. This value changes for dynamic configuration options (listed in the Configuration Option Overview and marked with an asterisk) after the system administrator runs the RECONFIGURE statement. This value specifies changes for static configuration options after you shut down and restart SQL Server. This is the value in syscurconfigs.value.

Configuration Option Overview

Many configuration options are often considered advanced and should be changed only under very special and often rare circumstances. In the following table, advanced options are shown in bold type; dynamic options are marked with an asterisk (*).

config_name | Minimum | Maximum | config_value | run_value
allow updates* | 0 | 1 | 0 | 0
backup buffer size* | 1 | 10 | 1 | 1
backup threads | 0 | 32 | 5 | 5
cursor threshold* | -1 | 2147483647 | 100 | 100
database size | 1 | 10000 | 2 | 2
default language | 0 | 9999 | 0 | 0
default sortorder id | 0 | 255 | 52 | 52
fill factor | 0 | 100 | 0 | 0
free buffers* | 20 | 524288 | 204 | 204
hash buckets | 4999 | 265003 | 7993 | 7993
language in cache | 3 | 100 | 3 | 3
LE threshold maximum* | 2 | 500000 | 200 | 200
LE threshold minimum* | 2 | 500000 | 20 | 20
LE threshold percent* | 1 | 100 | 0 | 0
locks | 5000 | 2147483647 | 5000 | 5000
logwrite sleep (ms)* | -1 | 500 | 0 | 0
max async IO | 1 | 255 | 8 | 8
max lazywrite IO* | 1 | 255 | 8 | 8
max worker threads* | 10 | 1024 | 255 | 255
media retention | 0 | 365 | 0 | 0
memory | 1000 | 1048576 | 4096 | 4096
nested triggers* | 0 | 1 | 1 | 1
network packet size* | 512 | 32767 | 4096 | 4096
open databases | 5 | 32767 | 20 | 20
open objects | 100 | 2147483647 | 500 | 500
priority boost | 0 | 1 | 0 | 0
procedure cache | 1 | 99 | 30 | 30
RA cache hit limit* | 1 | 255 | 4 | 4
RA cache miss limit* | 1 | 255 | 3 | 3
RA delay* | 0 | 500 | 15 | 15
RA pre-fetches* | 1 | 1000 | 3 | 3
RA slots per thread | 1 | 255 | 5 | 5
RA worker threads | 0 | 255 | 3 | 3
recovery flags | 0 | 1 | 0 | 0
recovery interval* | 1 | 32767 | 5 | 5
remote access | 0 | 1 | 1 | 1
remote login timeout* | 0 | 2147483647 | 5 | 5
remote query timeout* | 0 | 2147483647 | 0 | 0
resource timeout* | -1 | 2147483647 | 100 | 100
set working set size | 0 | 1 | 0 | 0
show advanced option* | 0 | 1 | 1 | 1
SMP concurrency | -1 | 64 | 0 | 1
sort pages* | 64 | 511 | 64 | 64
spin counter* | 1 | 2147483647 | 10000 | 10
tempdb in ram (MB) | 0 | 2044 | 0 | 0
user connections | 5 | 32767 | 20 | 20

Advanced options are displayed only when "show advanced option" is set to 1 (the default is 0).

Configuration Option Details

Many configuration options can be grouped and are often changed together.

In the following listings, advanced configuration options are noted in bold type and dynamic options are marked with an asterisk (*).

allow updates*
Specifies whether or not direct updates are allowed against system tables. Can be on (1) or off (0). By default, this option is off (0); system tables can be updated only through system procedures, not through ad hoc updates.

When allow updates is on (1), any user who has appropriate permissions can update the system tables directly with ad hoc updates and can create stored procedures that update the system tables.

Important Allowing direct updates to the system tables is risky. Updating certain fields in the system tables can prevent SQL Server from running. Stored procedures created while allow updates is on (1) will always be able to update the system tables, even after the option has been turned off.

Because the system tables are critical, it is best to turn on this option only in tightly controlled situations. To guarantee that no other users can access SQL Server while the system tables can be directly updated, restart SQL Server from the Win32 command prompt with the /m option. For more information, see the sqlservr Command-line Executable.

This command starts SQL Server in a single-user mode, which allows only one system administrator to log in and turns on the allow updates configuration option.

The allow updates option is a dynamic option, which means that a new value takes effect as soon as you use the RECONFIGURE WITH OVERRIDE statement. As an added protection, the WITH OVERRIDE clause is always required for this configuration option.

backup buffer size*
Specifies the size of the dump and load buffer (used to increase backup speed). This value determines the size, in 32-page increments, of the backup buffer. For example, a backup buffer size of 5 means that a buffer of 160 pages (5 * 32 pages) will be created. This option, when reconfigured, takes effect immediately.
backup threads
Specifies the number of threads to be reserved for striped dump and load operations. A value of 0 turns off striped dumps. This option does not take effect until the server is stopped and restarted.
cursor threshold*
Specifies the value where keyset generation occurs asynchronously. When cursors generate a keyset for a results set, the optimizer estimates the number of rows that will be returned by that results set. If the optimizer estimates that the number of returned rows is greater than this threshold, the cursor is generated asynchronously. Otherwise, the cursor is generated synchronously. When set to -1, all keysets are generated synchronously. If the cursor threshold is set to 0, all keysets will be generated asynchronously. Normally you would not want to set this value too low, as small results sets are faster to build synchronously.

The accuracy of the optimizer to determine an estimate for the number of rows in a keyset depends on the currency of the statistics for each of the tables in the cursor. For more information on updating table statistics, see the DBCC and the UPDATE STATISTICS statements.

database size
Sets the default number of megabytes allocated to each new user database. The default is 2 MB; however, the minimum allowable database size is 1 MB, which allows databases to exist on removable media such as floppy disks. A database size specified in a CREATE DATABASE statement takes precedence over the value set by this configuration option.

If most of the new databases on your SQL Server require more than 2 MB, you might want to increase this value. You also must increase it if your model database grows larger than 2 MB, because the CREATE DATABASE statement causes SQL Server to copy model when creating a new user database.

Note The model database is 1 MB by default.

default language
Specifies the ID of the language that is used by the server to display system messages, unless a user has chosen another language from those available on the server. The language us_english always has an ID of 0. Additional languages are assigned unique numbers when they are added.
default sortorder id
Specifies the number of the sort order currently installed as the default on the server.

Note Do not use the sp_configure system stored procedure to change sort orders. For more information about changing sort orders, see the Microsoft SQL Server Administrators Companion.

fill factor
Determines how full SQL Server makes each page when it is creating a new index on existing data (unless the user specifies some other value using the CREATE INDEX statement). The fill factor percentage affects performance because SQL Server must take time to split pages when they fill up.

The fill factor percentage is used only at the time the index is created and becomes less important as changes to the data are made. The pages are not maintained at any particular level of fullness.

The default for this configuration option is 0; legal values range from 0 through 100. A fill factor of 0 does not mean that pages are 0 percent full. It is treated similarly to a fill factor of 100 in that SQL Server creates clustered indexes with full data pages and nonclustered indexes with full leaf pages. It is different from 100 in that SQL Server leaves a space within the index B-tree. There is seldom a reason to change the default fill factor, especially since you can override it with the CREATE INDEX statement.

If fill factor is set to 100, SQL Server creates both clustered and nonclustered indexes with each page 100 percent full. A fill factor of 100 makes sense only for read-only tables ¾ tables to which no additional data will ever be added.

Smaller fill factor values cause SQL Server to create new indexes with pages that are not full. For example, a fill factor of 10 is a reasonable choice if you are creating an index on a table that you know contains only a small portion of the data that it will eventually hold. Smaller fill factor values cause each index to take more storage space.

free buffers*
Determines the threshold of free buffers available to the system. The minimum value is 20 and the maximum value is equal to one-half the number of buffers available when the server is started. The lazy writer process ensures that the number of free buffers available to the system does not fall below this threshold.

This option is automatically changed by the system whenever the memory option is changed; free buffers will be equal to 5 percent of the available memory. After the memory option is changed, a message will be displayed describing the change to free buffers. After this change, free buffers can be manually reconfigured to any legal value.

hash buckets
Sets the number of buckets used for hashing pages to buffers in memory. If the value specified is not a prime number, the closest prime number is used. For example, specifying 8000 creates 7993 hash buckets (the default). On systems with a large amount of memory, this value can be increased to allow faster access to data residing in data cache. For systems with 160 MB or less, 7993 is an appropriate value. This option does not take effect until the server is stopped and restarted.
language in cache
Indicates the maximum number of languages that can be simultaneously held in the language cache. The default is 3.

Lock Escalation Options

Many configuration options can be grouped and are often changed together.

When queries request a large number of rows from a particular table or tables, SQL Server generates page-level locks. If a query requests a large percentage of the rows from the table (see LE threshold percent), then lock escalation will occur. This makes table scans and operations against a large results set more efficient. The lock escalation options apply per statement, and not per transaction. The lock escalation options are:

  • LE threshold maximum*
  • LE threshold minimum*
  • LE threshold percent*
LE threshold maximum*
Determines the maximum number of page locks to hold before escalating to a table lock. If the number of page locks is greater than the escalation maximum, a table lock will occur regardless of whether or not the LE threshold percent has been exceeded. The default is 200.
LE threshold minimum*
Determines the minimum number of page locks required before escalating to a table lock. A table lock will occur only if this minimum is reached when the LE threshold percent is exceeded. LE threshold minimum prevents the server from escalating to a table lock for small tables where the LE threshold percentage is reached quickly. The default is 20.
LE threshold percent*
Specifies the percentage of page locks needed on a table before a table lock is requested. The default (0) causes a table lock to occur only when the LE threshold maximum has been reached.

Note To override these values for a given request, see the optimizer_hints option with the SELECT statement. The HOLDLOCK table lock options include UPDLOCK, TABLOCK, TABLOCKX, and PAGLOCK.

locks
Sets the number of available locks. Locks are not shared the way open databases and database objects are shared. The default is 5000.

Increase this value if SQL Server displays a message saying that you have exceeded the number of available locks. Since each lock consumes memory (32 bytes per lock), increasing this value can make it necessary to increase the amount of memory dedicated to the server.

logwrite sleep (ms)*
Specifies the number of milliseconds that a write to the log will be delayed if the buffer is not full. This increases the chance that more data will be added to the log buffer by other users, so that fewer physical log writes will be needed. Acceptable values for this option are -1 through 500. The special value of -1 means that the log write will not be delayed. The default is 0, which causes the server to wait only if other users are ready to execute.
max async IO
Configures the number of asynchronous I/Os that can be issued. The default is 8. This value should be changed only on systems with databases defined on multiple physical database devices that reside on separate physical disks, or on systems taking advantage of disk striping.
max lazywrite IO*
Tunes the priority of batched asynchronous I/Os performed by the lazy writer. This is comparable to max async IO, which controls batch I/O such as bulk copy and checkpoints, but max lazywrite IO is specific to the lazy writer. This option should be configured only on systems that have multiple hard disks. It is dynamically configurable up to the value specified by max async IO. Do not change this option unless your primary support provider instructs you to do so.
max worker threads*
Configures the number of worker threads that are available to SQL Server processes. SQL Server makes use of the native thread services of the operating system. Instead of one worker thread, there are many. Each network that SQL Server simultaneously supports is supported by one or more threads, another thread handles database checkpoints, and a pool of threads handles all users.

The max worker threads option allows you to control the number of threads allocated to the user pool. When the number of user connections is less than max worker threads, one thread handles each connection. However, if the number of connections exceeds max worker threads, thread pooling occurs. Additionally, if the configured value for worker threads is exceeded, the request is handled by the next worker thread that completes its current task. The default is 255.

media retention
Sets the number of days that you expect to retain each backup medium after it has been used for a database or transaction log dump. The default is 0. Unless you change this value, no warning is issued. A typical value might be 7 (days).

If you try to use the backup medium before the set number of days have passed, SQL Server issues a warning message.

memory
Sets the size of available memory, in 2K units. The default run value is determined by the setup program based on the amount of memory in your computer.

To optimize this number for your system, subtract the memory required for Windows NT (and other system uses, if the computer is not wholly dedicated to SQL Server) from the total physical memory.

Ideally, you want to allocate as much memory as possible to SQL Server without causing the system to page. You can use the Windows NT Performance Monitor to help determine what the threshold is for your system ¾ the Page Faults/sec counter of the Memory Object indicates whether you are generating any page faults. If so, SQL Server is running with too much memory. The threshold varies depending on your system. For example, on a 32-MB system, 16 MB might be appropriate for SQL Server; on a 64-MB system, 48 MB might be appropriate.

The amount of memory specified must be sufficient for the SQL Server static memory needs (kernel overhead, user stack space, and so on), as well as for the procedure cache and the data cache (also called buffer cache).

The memory left over after the SQL Server memory needs are met is divided between the procedure cache and the data cache. The percentage allocated to the procedure cache is set with the procedure cache configuration option.

You can use DBCC MEMUSAGE and statistics from the Windows NT Performance Monitor to help you adjust this value. Change this value only when you add or remove memory, or when you change how you use your system.

When the memory option is reconfigured, it will automatically cause a possible change to the configured free buffers configuration option. The free buffers configuration value will be set to 5 percent of the new memory size.

The maximum value for the memory option is 2 GB. Note, however, that the memory option does not include memory needs for tempdb if you have placed tempdb in RAM using the tempdb in ram (MB) option.

nested triggers*
Controls the use of nested triggers. When this option is 0, triggers will not cascade. Set it to 1 to enable nested (or cascading) triggers. The default is 1.
network packet size*
Sets the server-wide value for the default network packet size. The client application can override this value. On systems using differing network protocols, this option should be set to the size of the most common protocol used. This option can improve network performance when network protocols support larger packets. If reconfigured, the change takes effect immediately. The default is 4096.
open databases
Sets the maximum number of databases that can be open at one time on SQL Server. The default is 20.
open objects
Sets the maximum number of database objects that can be open at one time on SQL Server. The default is 500.

Increase this value if SQL Server displays a message saying that you have exceeded the number of open objects. Because open objects consume memory, increasing this value can make it necessary to increase the amount of memory dedicated to the server.

priority boost
Determines whether or not SQL Server should run at a higher priority than other processes on the same computer. If this option is set to 1, SQL Server will run at a higher priority in the Windows NT scheduler. The default is 0 and should be changed only on Windows NT systems dedicated to SQL Server.
procedure cache
Specifies the percentage of memory allocated to the procedure cache after the SQL Server memory needs are met. The SQL Server memory needs are the sum of memory necessary for locks, user connections, the code itself, and so on. The remaining memory is divided between the procedure cache and the data cache according to the percentage set by this configuration option.

The procedure cache is the area of memory where the most recently used procedures are stored. The procedure cache is also used when a procedure is being created and when a query is being compiled. If SQL Server finds a procedure or a compilation already in the cache, SQL Server does not need to read it from the disk.

The data cache is the area of memory where the most recently used data pages and index pages are stored. If SQL Server finds a data page or index page that has already been called by a user in the cache, SQL Server does not need to read it from the disk.

Information in both caches is stored in least recently used, most recently used (LRU-MRU) fashion.

The default for the procedure cache configuration option is 30, which gives the procedure cache 30 percent of the remaining memory after the SQL Server requirements are met. By default, the data cache gets the other 70 percent.

Since the optimum value for this configuration option is different from application to application, resetting it can improve SQL Server performance. For example, if you run many different procedures or ad hoc queries, your application will use the procedure cache more, so you might want to increase this value. Many applications fall into this category while they are being developed. You might want to set this option to 50 during your development cycle and then reset it to 30 when your application has stabilized.

You can use DBCC MEMUSAGE to help you adjust this value.

Read Ahead Configuration Options

Many configuration options can be grouped and are often changed together.

Read ahead configuration options control "parallel data scan" capabilities, which enable asynchronous read ahead of data when SQL Server determines that pages are being retrieved in sequential order. With read ahead (RA), separate background threads will be used to pre-fetch pages for a given results set. Read ahead is used by queries, DBCC CHECKTABLE, DBCC CHECKDB, DBCC CHECKALLOC, UPDATE STATISTICS, CREATE INDEX, exporting with bulk copy, and the retrieval of text and image data. Read ahead pre-fetches are configured based on extents. The Read Ahead configuration options are:

  • RA cache hit limit*
  • RA cache miss limit*
  • RA delay*
  • RA pre-fetches*
  • RA slots per thread
  • RA worker threads
RA cache hit limit*
Is the number of cache hits that a read-ahead request can have before it is canceled. This is used for detecting situations in which the Read Ahead manager finds everything in cache and is of little help to the query. The default value '4' should suffice for most systems. Do not change this option unless your primary support provider instructs you to do so.
RA cache miss limit*
Is the number of cache misses that occur during a horizontal traversal before read ahead starts for that command. Avoid setting this value lower than 3. Setting the RA cache miss limit to 1 causes a read-ahead request to be made whenever a data page is accessed from disk, and it can lead to thrashing and poor performance. Do not change this option unless your primary support provider instructs you to do so.
RA delay*
Specifies the delay of read ahead, in milliseconds. This is required to account for the latency to "prime" the RA Manager before it starts servicing an initial RA request. The default value '15' should suffice for most systems. For SMP machines, this value should be set to 15.
RA pre-fetches*
Determines how far ahead the read-ahead (RA) manager will read (on an extent basis) before the pre-fetch manager idles. A value of 3 means that for each request posted, the RA manager keeps three extents ahead of the current scan position.
RA slots per thread
Is the number of simultaneous requests each read-ahead (RA) service thread will manage. The number of threads multiplied by the number of slots is equivalent to the total number of concurrent RA scans that the system will support. The default value should be sufficient for most systems. If your system has an efficient IO subsystem, you may be able to increase the number of scans that a single thread can handle.
RA worker threads
Specifies the number of threads used to service read-ahead requests. Each thread will manage a configurable number of structures (see the RA slots per thread option), where each of these structures (slots) represents an individual range scan. This option should be set to the maximum number of concurrent users on the system. A warning will be logged in the error log if the number of threads requesting RA scans exceeds the number of configured RA slots.
recovery flags
Determines what information SQL Server displays in the error log during recovery. Can be 0 or 1. The default is 0, which means that SQL Server writes only the database name and a message stating that recovery is in progress. 1 means that SQL Server displays information about each individual transaction, including whether it was canceled or committed.
recovery interval*
Sets the maximum number of minutes per database that SQL Server needs to complete its recovery procedures in case of a system failure. The default is 5 minutes per database.

SQL Server uses this number and the amount of activity on each database to decide when to do a checkpoint on each database. When SQL Server does a checkpoint, it writes all dirty pages (data pages that have been changed by data modification statements) to the disk. The checkpoint also performs a few other housekeeping tasks, including truncating the transaction log if this option has been set using the sp_dboption system stored procedure. A typical checkpoint takes about 1 second.

You might want to change the recovery interval as your application and its use change. For example, to guarantee that changes are frequently written to the disk, you can shorten the recovery interval when there is a lot of update activity. Shortening the recovery interval causes more frequent checkpoints, which slows the system slightly. On the other hand, setting the recovery interval too high might cause the recovery time to be unacceptably long.

remote access
Controls logins from remote SQL Servers. Can be 0 or 1. The default is 1. Set remote access to 0 to discontinue allowing remote access to or from a server.
remote login timeout*
Specifies the number of seconds to wait before returning from a remote login attempt. A value of 0 will allow an infinite wait.
remote query timeout*
Specifies the number of seconds to wait before returning from processing a remote query. A value of 0 will allow an infinite wait.
resource timeout*
Specifies the number of seconds to wait for a resource to be released. The default is 10. Increase this value if the SQL Server error log shows a lot of "logwrite" or "bufwait" timeout warnings.
set working set size
Directs Windows NT to reserve physical memory space for SQL Server equal to the sum of the memory setting and the size of tempdb if it is in RAM.
show advanced option*
Determines whether or not the advanced options should be displayed by the sp_configure system stored procedure. When set to 1, the advanced options are displayed. The default is 0.
SMP concurrency
Controls the number of threads that SQL Server will release to Windows NT for execution which, in effect, limits the number of CPUs used by SQL Server. On a uniprocessor computer, the optimal value is 1. On a symmetric multiprocessor (SMP) computer, the limit depends on whether or not the server is a dedicated SQL Server. If the server is not dedicated, reconfiguring this value can cause poor response time to other applications running on the same machine. If response time for other applications is not an issue, set SMP concurrency to -1, "Dedicated SMP Support," which means that there is no limit.

When SQL Server is installed, SMP concurrency will be set to 0, which means auto configure. In auto configure mode, the limit is set to N-1, where N is the number of processors detected at SQL Server startup. On a uni-processor machine this value will be set to 1. If "Dedicated SMP Support" is chosen, then SMP concurrency will be set to -1.

sort pages*
Specifies the maximum number of pages that will be allocated to sorting per user. On systems that perform large sorts, increasing this number can improve performance. Since additional sort pages will consume memory, increasing this value can make it necessary to increase the amount of memory dedicated to the server.
spin counter*
Specifies the maximum number of attempts a process will perform to obtain a resource. By default, SQL Server will attempt to set this value to 10000. This is the default for multiprocessor machines. On uniprocessor machines, the run value will default to 10.
tempdb in ram (MB)
Accepts a value for the size of the tempdb database, in megabytes. Zero causes tempdb to reside on a disk device; the default is the MASTER device. A non-zero value is the size of the tempdb in RAM. Regardless of whether it exists on disk or in RAM, tempdb is altered in the same way as any other database; however, when tempdb resides in RAM, it can be altered only 10 times without requiring the server to be shut down and restarted.

Altering tempdb while it is in RAM causes each alteration of the database to allocate a new "chunk" of contiguous memory to tempdb. This chunk of memory, although it is contiguous, is not necessarily located next to the existing portion(s) of tempdb in RAM. In order to obtain maximum performance, the server should be stopped and restarted after tempdb is altered.

Important If tempdb is in RAM at the time of an upgrade, it will subsequently be moved out of RAM. The default disk device(s) must have the minimum amount free (2 MB) to create tempdb. If not, SQL Server startup will fail. To temporarily force a 2-MB tempdb in RAM, use the -f flag on the command line with SQLSERVR.EXE. This will allow the server to start. Once it has started, you must perform one of the following options immediately:

  • Increase the size of a default device
  • Free space on a default device
  • Add a default device
time slice
Sets the number of times that a user process is allowed to pass through a yield point without voluntarily yielding. If the time slice is set too low, SQL Server can spend too much time switching processes. If it is set too high, users can experience long response time.

The default is 100. There is seldom reason to change it.

user connections
Sets the maximum number of simultaneous connections to SQL Server allowed. The actual number of possible connections might be less than this value, depending on your database environment.

The number of user connections allowed depends on your version. For SQL Workstation, the number is 15, and for SQL Server the number is 32,767. However, the actual number is based on practical limits that vary depending on your application and hardware.

Use this statement to get a report on the maximum number of user connections that your system can use:

select @@max_connections

The memory overhead per connection is about 40K.

There is no formula for determining how many connections to allow for each user. Rather, you must estimate this number based on system and user requirements. Users executing DB-Library applications need one connection for each process started with a call to dbopen. On a system with many users, there is more likelihood that connections needed only occasionally can be shared among users.

Permission

Execute permission on sp_configure with no parameters or with only the first parameter defaults to all users. Execute permission for sp_configure with both parameters, used to change a configuration option, defaults to the system administrator. RECONFIGURE permission defaults to the system administrator and is not transferable.

Tables Used

master.dbo, master.dbo.syslanguages, sysconfigures, syscurconfigs, spt_values

Examples

A. List the Advanced Configuration Options

This example shows how to set and list all configuration options. Advanced configuration options are displayed by first setting the show advanced option to 1. After this has been changed, executing sp_configure with no parameters will display all configuration options.

sp_configure 'show advanced option', 1
go
    Configuration option changed. Run the RECONFIGURE command to install.
RECONFIGURE
go
sp_configure
B. Change a Configuration Option

This example sets the system recovery interval to 3 minutes.

sp_configure 'recovery interval', 3

See Also

RECONFIGURE | sp_defaultlanguage
sp_dboption | sp_droplanguage


sp_create_removable System Stored Procedure

Creates a removable media database. Creates three or more devices (one for the system catalog tables, one the transaction log, and one or more for the data tables) and places the database on those devices. Use this stored procedure to create the database prior to performing database development.

Syntax

sp_create_removable dbname, syslogical, 'sysphysical', syssize,
loglogical, 'logphysical', logsize, datalogical1, 'dataphysical1', datasize1
[... , datalogical16, 'dataphysical16', datasize16]

where

dbname
Is the name of the database that will be created for use on removable media.
syslogical
Is the logical name of the device that will contain the system catalog tables and the transaction log.
sysphysical
Is the physical name, including a fully qualified path, of the device that will hold the system catalog tables and the transaction log.
syssize
Is the size, in megabytes, of the device that will hold the system catalog tables and the transaction log. The minimum syssize is 1.
loglogical
Is the logical name of the device that will contain the transaction log.
logphysical
Is the physical name, including a fully qualified path, of the device that will contain the transaction log.
logsize
Is the size, in megabytes, of the device that will contain the transaction log. The minimum logsize is 1.
datalogical
Is the logical name of a device that will contain the data tables.

There must be from 1 through 16 data devices. In general, you will create more than one data device when the database is expected to be large and will need to be distributed on multiple disks.

dataphysical
Is the physical name, including a fully qualified path, of a device that will contain data tables.
datasize
Is the size, in megabytes, of a device that will contain data tables. The minimum datasize is 1.

Remarks

Only removable media databases should be placed on these devices.

The device created for the transaction log is used only during database development. (When database development is complete you will run the sp_certify_removable system stored procedure. Among other actions, sp_certify_removable will truncate the transaction log, move it to the system device, and drop the log device.)

Example

This example creates the database inventory as a removable database.

sp_create_removable inventory, invsys, 'c:\sql60\data\invsys.dat, 2',
   invlog,'c:\sql60\data\invlog.dat',4
   invdata,'c:\sql60\data\invdata.dat',10,

Permission

Only the system administrator can use this stored procedure.

See also

sp_certify_removable | sp_dboption
sp_dbinstall | sp_dbremove


sp_dbinstall System Stored Procedures

sp_dbinstall System Stored Procedure

Installs a database and its devices. It must be run once for each device of the database being installed. This system stored procedure copies the system device to the hard disk (placing the system catalog tables and the transaction log on read/write media). You can leave the data device on the distribution media (usually a CD), or you can copy it to the hard disk (but it remains read-only).

Syntax

sp_dbinstall database, logical_dev_name, 'physical_dev_name', size,
'devtype' [,'location']

where

database
Is the name of the removable media database being installed. Any valid database name conforming to the SQL Server rules for identifiers can be used. You are not required to enter the database name that was originally used for this database during development.
logical_dev_name
Is the logical name of the device being installed.
physical_dev_name
Is the physical name, including the fully qualified path, of the device being installed. The path entered here is the path to the device on the distribution media.
size
Is the size, in 1-MB blocks, of the device being installed.
devtype
Indicates the type of device being installed:
SYSTEM
Indicates that the device being installed contains the system catalog tables and the transaction log. The system device must be installed before the data device.
DATA
Indicates that the device being installed contains data tables. The data device must be installed after the system device. Note that even if a data device will be left on the distribution media, it must be installed using this system stored procedure.

If the database contains more than one data device, you must run this system stored procedure once for each device.

location
Indicates the destination location to which the device will be copied from the distribution media. This is usually a destination on the computer's local hard disk. The location is a fully qualified filename, including the drive, directory, and filename of the device. The referenced directories must already exist (sp_dbinstall will not create them).

A location is required for the system device. It is optional for a data device (since a data device can be left on the distribution media).

Remarks

Important When using sp_dbinstall, all of a database's devices must be installed.

The information required by the sp_dbinstall parameters is provided when the database is verified using sp_certify_removable.

When a database is installed using sp_dbinstall, it is set to offline. Before it can be used it must be placed online by using sp_dboption. After the database has been installed using sp_dbinstall and brought online using sp_dboption, it can be configured to suit local requirements. Users can be added, permissions can be granted, and stored procedures and views can be created. However, after the database is installed, do not attempt to perform inserts, updates, or deletes against the read-only data in the data tables.

Before the database can be used (that is, set online by using sp_dboption) all of its devices must be available. This means that if a database¾because of size¾has been distributed on several CDs with a different data device on each CD, and if the computer is equipped with only one CD drive, then as each device is installed sp_dbinstall must be provided a location parameter for all but one of the devices, so that all but one of the data devices are copied off the distribution CDs onto the computer's local hard disk. If this is done, only one CD will need to be in the CD drive when the database is used. To eliminate all need for a CD when using the database, all the data devices can be copied.

As an advanced option, if the data device has been moved to read/write media, it can be made read/write by running sp_addsegment against the device and using sp_devoption to set the readonly setting to false for that device.

You can also use this system stored procedure to install databases and devices from non-removable media.

Example

This example installs the removable media database inventory from the distribution CD, which is located in the computer's CD-ROM drive, drive E. The system device containing the system catalog tables and the transaction log is copied to the computer's hard disk and the data device is left on the distribution media.

sp_dbinstall inventory,invsys,'e:\invsys.dat',2,'SYSTEM',
   'c:\sql60\data\invsys.dat'
EXEC sp_dbinstall inventory,invdata,'e:\invdata.dat',10,'DATA'

Permission

Only the system administrator can use this stored procedure.

Tables Used

sysdatabases, sysdevices, sysusages

See also

sp_certify_removable | sp_dboption
sp_create_removable | sp_dbremove


sp_dboption System Stored Procedure

For SQL Server 6.5 information, see sp_dboption in What's New for SQL Server 6.5.

Displays or changes database options.

Syntax

sp_dboption [dbname, optname, {true | false}]

where

dbname
Specifies the database in which you want to set the option.
optname
Is the name of the option you want to set or turn off. SQL Server understands any unique string that is part of the option name. Enclose the option name with quotation marks if it includes embedded blanks or is a keyword. The available options are:
ANSI null default
Allows the user to control the database default nullability. When not explicitly defined, a user-defined datatype or a column definition will use the default setting for nullability. Nullability is determined by session settings and database settings. SQL Server defaults to NOT NULL. However, the ANSI-standard is NULL. For ANSI compatibility, setting ANSI null default to TRUE changes the database default nullability to NULL.

With this option set to true, all user-defined datatypes or columns not explicitly defined as NOT NULL during a CREATE TABLE or ALTER TABLE statement will default to allowing NULLs. Columns defined with constraints will follow constraint rules regardless of this setting (for example, PRIMARY KEY columns, IDENTITY columns, and columns of type bit cannot be NULL).

Session settings override the default database setting for ANSI null default. For more information, see the SET statement.

dbo use only
Sets a database for use only by the database owner. Active users of the database can continue to access the database, but no new users are allowed. When active users disconnect or change database context (with the USE statement), they will not be allowed access to this database unless this option has been set to false.
no chkpt on recovery
Defines whether or not a checkpoint record is added to the database after it is recovered during a SQL Server startup. If this option is off (false, the default), a checkpoint record is added.

The no chkpt on recovery option is useful when an up-to-date copy of a database is kept. In these situations, there is a "primary" and a "secondary" database. Initially, the primary database is dumped and loaded into the secondary database. Then, at intervals, the transaction log of the primary database is dumped and loaded into the secondary database. If this option is on (true) in the secondary database, no checkpoint record is added to a database after it is recovered, so subsequent transaction log dumps from the primary database can be loaded into it.

offline
Allows a database to be placed online (when set to false, the database is ready to be used) or offline (when set to true, the database is unavailable and cannot be used). This option is primarily used on databases with removable media devices but it can be used on any database.

When a database is placed online, all devices belonging to the specified database are opened (if they are not already open) and marked as non-deferred, and the database is recovered and becomes available for use.

When a database is placed offline, all devices belonging to that database are closed and marked as deferred, except those that contain space belonging to other online databases. Databases placed offline are not recovered automatically at server startup.

Note A database cannot be placed offline if it has an active user.

published
Allows the database to be published for replication. This option does not publish a database. Instead, it permits the tables of a database to be published.

When set to true, this option enables publishing and adds the user repl_subscriber to the database.

When set to false , it disables publishing, drops all publications, unmarks all transactions that were marked for replication in the transaction log, and removes the database user repl_subscriber.

read only
Defines a database as read only. This option means that users can retrieve data from the database but cannot modify anything. Because a read-only database does not allow data modifications, automatic recovery is skipped at system startup.
select into/bulkcopy
Allows a database to accept non-logged operations. Non-logged operations include: using the UPDATETEXT or WRITETEXT statement, using SELECT INTO into a permanent table, using fast bulk copy (bcp), or performing a table load. This option need not be set to run bcp on a table that has indexes, because tables with indexes are always copied with the slower version of bcp and are logged.

After performing non-logged operations, using the DUMP TRANSACTION statement is prohibited. Issuing DUMP TRANSACTION after making unlogged changes to the database with SELECT INTO or bulk copy produces an error message telling you to use DUMP DATABASE instead. Once all non-logged operations are completed, turn off select into/bulkcopy and issue the DUMP DATABASE statement.

By default, the select into/bulkcopy option is turned off in newly created databases. To change the default situation, set this option in the model database.

Note Because SELECT is a keyword, you must enclose select into/
bulkcopy in quotation marks to avoid a syntax error.

single user
Restricts database access to a single user. Any user accessing the database when single user is set to true can continue to use the database. A new user will be allowed into this database only if all other users have disconnected or changed to another database. When this option is set, the trunc. log on chkpt. option is not supported. Truncate the log after single user operations are completed.
subscribed
Allows the database to be subscribed for replication. Setting subscribed to true aliases the login ID of repl_publisher to DBO. This allows the distribution process to replicate to this database. Setting subscribed to false removes the alias.

This stored procedure does not subscribe to a database. It permits a database to subscribe to a published database.

trunc. log on chkpt.
Causes the transaction log to be truncated (committed transactions are removed) every time the CHECKPOINT process occurs (usually once per minute). When the database owner runs CHECKPOINT manually, however, the log is not truncated. It may be useful to turn this option on while doing development work, to prevent the log from growing. While the trunc. log on chkpt. option is set, backups of the transaction log are not allowed since dumps from the truncated transaction log dumps cannot be used to recover from media failure. Issuing the DUMP TRANSACTION statement produces an error message instructing you to use the DUMP DATABASE statement instead.
true | false
Specifies how to set the option. Use true if you want to set the option and false if you want to turn off the option.

Remarks

To display the list of available database options, execute sp_dboption with no parameters. To list all of the configured options for a particular database, execute the sp_helpdb system stored procedure. The only option you can set for the master database is trunc. log on chkpt. The database owner or system administrator can set or turn off particular database options for all new databases by executing sp_dboption on the model database.

After sp_dboption has been executed, a checkpoint will be executed in the database for which the option was changed. This will cause the change to take effect immediately.

For additional details on database options, see the Microsoft SQL Server Administrator's Companion.

Permission

Execute permission to display the list of options only (using sp_dboption with no parameters) defaults to all users. Execute permission to change an option (using sp_dboption with parameters) defaults to the system administrator and the database owner of the database for which the option is to be changed.

Examples

A. sp_dboption with No Parameters

This example displays a list of the database options.

sp_dboption
go

    Settable database options:
    --------------------------
    ANSI null default
    dbo use only
    no chkpt on recovery
    offline
    published
    read only
    select into/bulkcopy
    single user
    subscribed
    trunc. log on chkpt.
B. Set a Database to Read Only

This example makes the pubs database read only.

sp_dboption pubs, 'read', TRUE
go

    CHECKPOINTing database that was changed.
C. Turn Off an Option

This example makes the pubs database writable again.

sp_dboption pubs, 'read', FALSE
go

    CHECKPOINTing database that was changed.
D. Take a Database Offline

This example takes the sales database offline if there are no users accessing the sales database.

USE master
go
sp_dboption sales, offline, TRUE
go

    CHECKPOINTing database that was changed.

Tables Used

master.dbo.spt_values, master.dbo.sysdatabases

See Also

CHECKPOINT | sp_droppublisher
SELECT | sp_dropsubscriber
sp_addpublisher | sp_helpdb
sp_addsubscriber | sp_helpdistributor
sp_changesubscriber | sp_helpserver
sp_configure | sp_helpsubscriberinfo


sp_dbremove System Stored Procedure

Used to remove a database, and optionally, any devices to which it has exclusive use. This system stored procedure is useful primarily with databases created on removable media; however, it can be used on all databases including damaged databases.

Syntax

sp_dbremove database[, dropdev]

where

database
Is the name of the database to be removed.
dropdev
Removes from sysdevices all devices of which that database has exclusive use. It does not delete the .DAT files.

Remarks

This stored procedure removes the entries in sysdatabases and sysusages for the specified database. If the dropdev keyword is included, it also removes from sysdevices all devices of which that database has exclusive use. It does not delete the .DAT files.

If no value is provided, the usage syntax is displayed.

Permission

Execute permission defaults to the system administrator and database owner of the database for which the drop will be performed.

Example

This example removes the sales database and removes from sysdevices all devices used exclusively by sales.

sp_dbremove sales, dropdev

Tables Used

master.dbo.sysalternates, master.dbo.spt_values, master.dbo.sysdatabases, master.dbo.sysprocesses

See Also

ALTER DATABASE | DBCC
CREATE DATABASE |


sp_defaultdb System Stored Procedure

Changes a user's default database.

Syntax

sp_defaultdb login_id, defdb

where

login_id
Is the user's login ID.
defdb
Specifies the user's default (home) database (the database to which the user is connected when logging in).

Remarks

A default database can be set by using either sp_defaultdb or sp_addlogin when the user's login ID is initially added to SQL Server.

If no default database has been specified, users are connected to the master database.

After sp_defaultdb is executed, the user is connected to the new defdb the next time he or she logs in. However, this system stored procedure does not automatically give the user access to that database. The database owner must give database access to the user through sp_adduser or sp_addalias, or there must be a guest user specified in the database's sysusers table. A user who does not have access to the database by any of these means will be connected to the master database and an error message will be displayed.

If a user's default database is dropped, the user is connected to master on the next login and an error message is displayed.

The system administrator can change anyone's default database by using sp_defaultdb. Users can change only their own default database.

Example

This example sets pubs as the default database for Victoria.

sp_defaultdb Victoria, pubs

Permission

Execute permission defaults to public for a user's login ID only. Execute permission defaults to the system administrator for any login ID.

Tables Used

master.dbo.sysdatabases, master.dbo.syslogins

See Also

sp_addlogin | sp_password
sp_droplogin | USE


sp_defaultlanguage System Stored Procedure

Changes a user's default language.

Syntax

sp_defaultlanguage login_id [, language]

where

login_id
Is the user's login ID.
language
Specifies the user's default language.

Remarks

A default language can be set by using either sp_defaultlanguage or sp_addlogin when the user's login ID is initially added to SQL Server. If a language is not specified, the user's default language is set to the server's default language.

If a user's default language is dropped from the server, the server's default language is used as the initial language setting and a message is displayed.

The system administrator can change anyone's default language by using sp_defaultlanguage. Users can change only their own default language.

Example

This example sets the default language for Claire to French.

sp_defaultlanguage Claire, french

Permission

Execute permission defaults to public for the user's own login only. Execute permission defaults to the system administrator for any login ID.

Tables Used

master.dbo.syslanguages, master.dbo.syslogins

See Also

SET | sp_droplogin
sp_addlogin | sp_helplanguage


sp_depends System Stored Procedure

Displays information about database object dependencies ¾ the views and procedures that depend on the specified table or view, and the tables and views that are depended on by the specified view or procedure.

Syntax

sp_depends objname

where

objname
Specifies which database object to examine for dependencies. The object can be a table, view, stored procedure, or trigger.

Remarks

Executing sp_depends lists all objects, if any, that depend on objname and all objects, if any, on which objname depends (for example, views depend on one or more tables and can have procedures or other views that depend on them). An object that references another object is considered dependent on that object.

This system stored procedure determines the dependencies by looking at the sysdepends table.

The updated and selected columns in the report from sp_depends are meaningful if the object being reported on is a stored procedure or trigger. The values in these columns indicate whether the stored procedure or trigger updates or selects from that object.

References to objects outside the current database are not reported.

Example

This example lists the database objects that depend on the titles table.

sp_depends titles

Permission

Execute permission defaults to the public group.

Tables Used

master.dbo.sp_values, master.dbo.sysdatabases, sysdepends, sysobjects

See Also

CREATE PROCEDURE | EXECUTE
CREATE TABLE | sp_help
CREATE VIEW |


sp_devoption System Stored Procedure

Displays or sets device status. Although primarily used on removable media devices, this procedure can be used for all devices.

This stored procedure is used internally (by other system stored procedures) and is not typically used by users.

Syntax

sp_devoption [devicename [, optname {, true | false} [, override]]]

where

devicename
Is a device name.
optname
Is the name of the option you want to turn on or off. Can be:
deferred
When set to true, indicates that the device is not to be automatically opened at server startup time. Setting deferred to true can be useful when you create a new device and will not immediately place a database on it.
'read only'
When set to true, indicates that the device is read only.
true | false
Specifies how to set the optname option.
override
When supplied, allows you to set a device that contains read/write databases to read only. Can only be used when optname is 'read only'. If this option is not supplied, read only devices can only contain read only databases.

Remarks

If no parameters are specified, a list of the settable options is displayed.

Permission

Execute permission defaults to the system administrator.

Tables Used

master.dbo.sysdatabases, master.dbo.sysusages, master.dbo.spt_values, master.dbo.sysdevices

Examples

A. Set Device to Not Open at Startup

This example sets the device DEV1 so that it will not be opened automatically at server startup.

sp_devoption DEV1,deferred,true
B. Set Device to Be Read Only

This example sets the device DEV1 to be read only.

sp_devoption DEV1, readonly, true

See Also

DISK INIT sp_dropdevice


sp_diskdefault System Stored Procedure

Sets a database device's status to indicate whether the device can be used for database storage when the user does not specify a database device or specifies DEFAULT with the CREATE DATABASE or ALTER DATABASE statements.

Syntax

sp_diskdefault database_device, {defaulton | defaultoff}

where

database_device
Is the logical name of the database device (not a dump device).
defaulton | defaultoff
Indicates whether the specified database device is the default. Use defaulton if the database device can be a default database device. Use defaultoff if the database device cannot be a default database device. The defaulton option will most frequently be used after a database device has been added to the system by the DISK INIT statement. The defaultoff option will most frequently be used to change the default status of the MASTER database device (which is the designated default when SQL Server is initially installed).

Remarks

You can have multiple default devices. They are used in alphabetic order, the order in which they appear in the sysdevices table.

When SQL Server is initially installed, the MASTER database device is the only default database device.

To find out which database devices are default database devices, execute the sp_helpdevice system stored procedure.

Example

In this example, the MASTER database device will no longer be used by the CREATE DATABASE or ALTER DATABASE statements for the default storage of a database.

sp_diskdefault master, defaultoff

Permission

Only the system administrator can use this procedure.

Table Used

master.dbo.sysdevices

See Also

ALTER DATABASE | DISK INIT
CREATE DATABASE | sp_helpdevice


sp_dropalias System Stored Procedure

Removes the alias login ID identity that was established by sp_addalias.

Syntax

sp_dropalias login_id

where

login_id
Is the name (in master.dbo.syslogins) of the user who has an alias.

Remarks

Executing the sp_dropalias system stored procedure deletes an alternate suid mapping for a user from the sysalternates table. When a user's alias is dropped, the user no longer can access the database for which the alias was created.

Example

Assuming that Victoria has an alias (for example, as the database owner) in the current database, this procedure drops her alias from the database.

sp_dropalias Victoria

Permission

Only the database owner can use this procedure.

Table Used

sysalternates

See Also

sp_addalias | sp_dropuser
sp_adduser | sp_helpuser
sp_changedbowner | USE
sp_droplogin |


sp_dropdevice System Stored Procedure

Removes a SQL Server database device or dump device.

Syntax

sp_dropdevice logical_name [, DELFILE]

where

logical_name
Is the logical name of the database device or the dump device as listed in master.dbo.sysdevices.name.
DELFILE
Specifies that the physical file should be deleted.

Remarks

The sp_dropdevice system stored procedure drops a database device or dump device from SQL Server, deleting the entry from master.dbo.sysdevices. It frees the file handle and the device number when a database device is dropped. This means that the physical file can be deleted without shutting down SQL Server. To delete the physical file, use the DELFILE option or delete the file from the command line.

Note You can also immediately use the DISK INIT statement to create a new device with that same device number, logical name, and physical name (if you've deleted the file).

Permission

Execute permission defaults to the system administrator and cannot be transferred.

Tables Used

master.dbo.sysdatabases, master.dbo.sysdevices, master.dbo.sysusages

Example

This example drops the TAPEDUMP1 tape dump device from SQL Server.

sp_dropdevice TAPEDUMP1

See Also

DROP DATABASE | sp_helpdb
sp_addumpdevice | sp_helpdevice


sp_dropextendedproc System Stored Procedure

Drops an extended stored procedure.

Syntax

sp_dropextendedproc function_name

where

function_name
Specifies which extended stored procedure to drop.

Remarks

Executing sp_dropextendedproc drops the extended stored procedure name from the sysobjects table and removes the entry from the syscomments table.

Example

This example drops xp_diskfree.

sp_dropextendedproc xp_diskfree

Permission

Only the system administrator can use this procedure.

Tables Used

syscomments, sysobjects

See Also

sp_addextendedproc sp_helpextendedproc


sp_dropgroup System Stored Procedure

Removes a group from a database.

Syntax

sp_dropgroup grpname

where

grpname
Specifies which group to drop from the current database.

Remarks

Executing sp_dropgroup drops a group name from a database's sysusers table.

You cannot drop a group that has members. Before you can drop the group, you must execute sp_changegroup for each member.

Example

In this example, the purchasing group has merged with the accounting group. Members of the purchasing group, Martha (username Martha) and George (username George), are moved. Martha is moved to the accounting group, George is moved to the public group. Then the purchasing group is dropped. The group name public is enclosed in single quotation marks because public is a reserved word.

sp_changegroup accounting, Martha
EXEC sp_changegroup 'public', George
EXEC sp_dropgroup purchasing

Permission

Only the database owner can use this procedure.

Tables Used

sysobjects, sysprotects, sysusers

See Also

GRANT | sp_changegroup
REVOKE | sp_dropuser
sp_addgroup | sp_helpgroup
sp_adduser | USE


sp_droplanguage System Stored Procedure

Drops an alternate language from the server and removes its row from master.dbo.syslogins.

Syntax

sp_droplanguage language [, dropmessages]

where

language
Is the language to be dropped.
dropmessages
Drops all SQL Server system messages in language when the language is dropped. A language with associated system messages cannot be dropped without also dropping its messages.

Remarks

Executing the sp_droplanguage system stored procedure also drops a language from the list of available alternate languages by deleting its entry from the master.dbo.syslanguages table.

Examples

A. Drop a Language

If there are no associated messages, this example drops French from the set of available alternate languages.

sp_droplanguage french
B. Drop a Language with Messages

If there are associated messages, this example drops French from the set of available alternate languages.

sp_droplanguage french, dropmessages

Permission

Only the system administrator can use this procedure.

Tables Used

master.dbo.syslanguages, master.dbo.sysmessages

See Also

sp_helplanguage


sp_droplogin System Stored Procedure

Removes a SQL Server login ID by deleting the user's entry in master.dbo.syslogins.

Syntax

sp_droplogin login_id

where

login_id
Is the name of the user as listed in master.dbo.syslogins.

Remarks

The sp_droplogin procedure checks only the current database to see if the login ID to be dropped is a user there. You cannot drop a user's login ID if the user is an object owner or user in any database(s).

Example

This example drops the login ID Victoria from SQL Server.

sp_droplogin Victoria

Permission

Only the system administrator can use this procedure.

Tables Used

master.dbo.syslogins, sysusers

See Also

sp_addlogin | sp_dropuser
sp_changedbowner | sp_helpuser
sp_dropalias |


sp_dropmessage System Stored Procedure

Drops a specified error message from the sysmessages system table.

Syntax

sp_dropmessage [msg_id [, language | 'all']]

where

msg_id
Specifies the message to drop. This parameter must be a user-defined message with a msg_id greater than or equal to 50000.
language
Specifies the language of the message to drop.
'all'
Drops all language versions of msg_id.

Remarks

If no parameters are supplied, a syntax diagram will be displayed.

Example

This example drops the message (number 50001) from sysmessages.

sp_dropmessage 50001
go
    Message dropped.

Permission

Execute permission defaults to the system administrator, who can transfer it to other users.

Table Used

sysmessages

See Also

CREATE TABLE | sp_addmessage
RAISERROR | sp_altermessage


sp_dropremotelogin System Stored Procedure

Removes a remote user login.

Syntax

sp_dropremotelogin remoteserver [, loginame [, remotename]]

where

remoteserver
Specifies which server has the remote login to be dropped.
loginame
Is the local server's username that is associated with the remote server in the sysremotelogins table.
remotename
Is the remote username that gets mapped to loginame when logging in from the remote server.

Remarks

Executing sp_dropremotelogin drops a user login ID from a remote server, deleting the user's entry from master.dbo.sysremotelogins.

To add local server users, use the sp_addlogin system stored procedure. To drop local server users, use the sp_droplogin system stored procedure.

Examples

A. Drop a Remote Server

This example drops the entry for the remote server ACCOUNTS.

sp_dropremotelogin ACCOUNTS
B. Drop a Login Mapping

This example drops the entry for mapping remote logins from the remote server ACCOUNTS to the local user named Albert.

sp_dropremotelogin ACCOUNTS, Albert
C. Drop a Remote User

This example drops the login for the remote user Chris on the remote server ACCOUNTS that was mapped to the local user salesmgr.

sp_dropremotelogin ACCOUNTS, salesmgr, Chris

Permission

Execute permission defaults to the system administrator and cannot be transferred.

Tables Used

master.dbo.sysremotelogins, master.dbo.sysservers

See Also

sp_addlogin | sp_droplogin
sp_addremotelogin | sp_helpremotelogin
sp_addserver | sp_helpserver


sp_dropsegment System Stored Procedure

Drops a segment from a database or unmaps a segment from a database device.

Syntax

sp_dropsegment segname [, logical_name]

where

segname
Is the segment to be dropped.
logical_name
Specifies the database device that you want the segment segname to no longer use. This parameter is optional, except when dropping the SYSTEM, DEFAULT, and LOGSEGMENT system segments from a database device.

Remarks

You cannot drop a segment if it is being referenced by any table or index in the current database.

If you do not supply a logical_name, the segment is dropped from the current database. If you supply a logical_name, the segment is dropped only from the named database device; it remains mapped to any previously specified devices and the segment remains in the database.

Using the sp_placeobject system stored procedure to change future space allocations for a table or an index from one segment to another removes the reference to the original segment. You can drop the original segment name with sp_dropsegment.

For the SYSTEM, DEFAULT, and LOGSEGMENT system segments, specify the device name from which you want the segments dropped.

Examples

A. Drop a Segment

This example drops the segment INDEXES from the current database.

sp_dropsegment INDEXES
B. Unmap a Segment

This example unmaps the segment INDEXES from the database device DEV1.

sp_dropsegment INDEXES, DEV1

Permission

Execute permission defaults to the database owner.

Tables Used

sysindexes, syssegments, master.dbo.sysdevices, master.dbo.sysusages

See Also

sp_addsegment | sp_placeobject
sp_helpsegment |


sp_dropserver System Stored Procedure

Drops a server from the list of known servers, deleting the entry from the master.dbo.sysservers table.

Syntax

sp_dropserver server_name [, droplogins]

where

server_name
Is the server to be dropped.
droplogins
Indicates that any remote logins for server_name should also be dropped.

Remarks

Running sp_dropserver on a server that has associated entries in the master.dbo.sysremotelogins table results in an error message, stating that you need to drop the remote users before you can drop the server. To drop all remote logins for a server when dropping the server, use the droplogins option.

Example

This example drops the remote server ACCOUNTS.

sp_dropserver ACCOUNTS

Permission

Execute permission defaults to the system administrator and cannot be transferred.

Tables Used

master.dbo.sysremotelogins, master.dbo.sysservers

See Also

sp_addserver | sp_helpremotelogin
sp_dropremotelogin | sp_helpserver


sp_droptype System Stored Procedure

Deletes a user-defined datatype from systypes.

Syntax

sp_droptype typename

where

typename
Is the name of a user-defined datatype that you own.

Remarks

The typename user-defined datatype cannot be dropped if tables or other database objects reference it.

Example

This example drops the user-defined datatype named birthday.

sp_droptype birthday

Permission

Execute permission defaults to the database owner and the datatype owner.

Tables Used

syscolumns, sysobjects, systypes, sysusers

See Also

sp_addtype sp_rename


sp_dropuser System Stored Procedure

Removes a user from the current database by deleting the entry from the current database's sysusers table.

Syntax

sp_dropuser username

where

username
Is the user to drop.

Remarks

The owner of a database cannot be dropped. If other users are aliased to the user being dropped, their aliases are dropped and they can no longer access the database.

Example

This example drops the user Albert from the current database. He will no longer be able to use the database.

sp_dropuser Albert

Permission

Execute permission defaults to the database owner.

Tables Used

sysalternates, sysobjects, sysprotects, systypes, sysusers

See Also

GRANT | sp_adduser
REVOKE | sp_droplogin
sp_addalias | USE


sp_extendsegment System Stored Procedure

Extends the range of a segment to another database device.

Syntax

sp_extendsegment segname, logical_name

where

segname
Is the name of the existing segment (previously defined by the sp_addsegment system stored procedure).
logical_name
Specifies the database device to be added to the current database device range for segname.

Remarks

Once a segment has been defined, you can put a table or index on it by using the CREATE TABLE and CREATE INDEX statements. If a table or index is created on a particular segment, all subsequent data for that table or index will be located on that segment.

To associate a segment with a database device, the database must have been created or altered with a reference to that device. A database device can have more than one segment associated with it, and a segment can be extended over several database devices.

Extending the log segment to a new device unmaps any existing segments from that device.

Because sp_addsegment and sp_extendsegment do not accept a size parameter, when a segment is created it is mapped to the entire amount of space allocated for the specified database on the specified device. When the database is expanded with ALTER DATABASE, any segments mapped to that device for the database are expanded to all allocated space.

Example

This example extends the range of the segment INDEXES to the database device DEV2.

sp_extendsegment INDEXES, DEV2

Permission

Execute permission defaults to the database owner.

Tables Used

syssegments, master.dbo.sysdevices, master.dbo.sysusages

See Also

ALTER DATABASE | sp_helpdb
CREATE INDEX | sp_helpdevice
CREATE TABLE | sp_helpsegment
sp_addsegment | sp_placeobject
sp_dropsegment |


sp_help System Stored Procedure

Reports information about a database object (any object listed in the sysobjects table) or about a SQL Server - supplied or user-defined datatype.

Syntax

sp_help [objname]

where

objname
Is the name of any object in sysobjects or any user-defined datatype in the systypes table. Database names are not acceptable.

Remarks

The sp_help system stored procedure looks for an object in the current database only.

When no objname parameter is specified, sp_help lists object names, owners, and object types for all objects in the current database.

System procedures do not work on temporary tables because a procedure cannot access a temporary object unless the procedure created the object itself during the current session.

Examples

A. Help on All Objects

This example lists information about each object in sysobjects.

sp_help
B. Help on a Single Object

This example displays information about the publishers table.

sp_help publishers

Permission

Execute permission defaults to the public group.

Tables Used

master.dbo.spt_values, syscolumns, sysindexes, sysobjects, systypes

See Also

sp_helpgroup | sp_helpsql
sp_helpindex | sp_helpuser
sp_helprotect |


sp_helpconstraint System Stored Procedure

Returns a list of all constraint types, their user-defined or system-supplied name, the columns on which they have been defined, and the expression that defines the constraint (for DEFAULT and CHECK constraints only).

Syntax

sp_helpconstraint table_name

where

table_name
Specifies the table about which you want constraint information.

Remarks

Executing sp_help table_name reports all information about the specified table. To see only the constraint information, use sp_helpconstraint.

Permission

Execute permission defaults to the public group.

Tables Used

syscolumns, syscomments, sysconstraints, sysindexes, sysobjects, sysreferences

Example

This example shows all constraints for the employee table.

sp_helpconstraint employee

See Also

ALTER TABLE | sp_help
CREATE TABLE |


sp_helpdb System Stored Procedure

Reports information about a specified database or all databases.

Syntax

sp_helpdb [dbname]

where

dbname
Specifies the database about which you want information.

Remarks

When dbname is specified, sp_helpdb reports on that database. When no parameter is supplied, sp_helpdb reports on all databases in master.dbo.sysdatabases.

Examples

A. Help on a Single Database

This example displays the following information about the pubs database:

sp_helpdb pubs
B. Help on All Databases

This example displays information about all databases on the SQL Server but does not include the device_fragments, size, and usage columns.

sp_helpdb

Permission

Execute permission defaults to the public group.

Tables Used

master.dbo.spt_values, master.dbo.sysdatabases, master.dbo.sysdevices, master.dbo.syslogins, master.dbo.sysusages

See Also

ALTER DATABASE | sp_dboption
CREATE DATABASE | sp_renamedb
sp_configure |


sp_helpdevice System Stored Procedure

Reports information about SQL Server database devices and dump devices.

Syntax

sp_helpdevice [logical_name]

where

logical_name
Is the logical name of the database device or dump device that you want information about.

Remarks

When logical_name is specified, sp_helpdevice displays information about the specified database device or dump device. When no parameter is specified, sp_helpdevice displays information about all database devices and dump devices in master.dbo.sysdevices.

The sysdevices table contains database devices and dump devices. Database devices can be designated as default database devices, which means that they can be used for database storage when a user executes the CREATE DATABASE or ALTER DATABASE statement with no specifier database device name or with the keyword DEFAULT. To make a database device a default database device, execute the sp_diskdefault system procedure.

Database devices are added to the system with the DISK INIT statement. Dump devices are added to the system by the sp_addumpdevice system procedure.

The status column in the sp_helpdevice report contains a number that corresponds to the status description in the description column.

The cntrltype column specifies the controller number of the device. For hard-disk dump devices, the controller number is 2; for diskette dump devices, the controller number is 3 or 4; and for tape devices, the controller number is 5. For database devices, it is 0.

The device_number column is 0 for dump devices, 0 for the MASTER database device, and a value from 1 through 255 for other database devices.

The low and high columns represent virtual page numbers for database devices and disk dump devices.

The high and low columns represent media capacity for diskette dump devices (high - low = number of 2K blocks).

Examples

A. Help on All Devices

This example reports information about all database devices and dump devices on SQL Server.

sp_helpdevice
B. Help on a Single Device

This example reports information about the TAPEDUMP device.

sp_helpdevice TAPEDUMP

Permission

Execute permission defaults to the public group.

Tables Used

master.dbo.spt_values, master.dbo.sysdevices

See Also

DISK INIT | sp_diskdefault
DUMP | sp_dropdevice
LOAD | sp_helpdb
sp_addumpdevice | sp_logdevice
sp_configure | sp_who


sp_helpextendedproc System Stored Procedure

Displays the currently defined extended stored procedures and the name of the dynamic-link library to which the function belongs.

Syntax

sp_helpextendedproc [function_name]

where

function_name
Specifies which extended stored procedure to display information about.

Remarks

When function_name is specified, sp_helpextendedproc reports on the specified extended stored procedure. When no parameter is supplied, sp_helpextendedproc reports on all extended stored procedures.

Examples

A. Help on All Extended Stored Procedures

This example reports on all extended stored procedures.

sp_helpextendedproc
B. Help on a Single Extended Stored Procedure

This example reports on the xp_cmdshell extended stored procedure.

sp_helpextendedproc xp_cmdshell

Permission

Execute permission defaults to the system administrator and can be transferred.

Table Used

syscomments, sysobjects

See Also

sp_addextendedproc | sp_dropextendedproc


sp_helpgroup System Stored Procedure

Reports information about a group or all groups in the current database.

Syntax

sp_helpgroup [grpname]

where

grpname
Is the name of a group created by sp_addgroup in the current database.

Remarks

When grpname is specified, sp_helpgroup reports on the specified group. If no parameter is supplied, sp_helpgroup reports on all groups in the database.

To get a report on the default group public, enclose the name public in quotation marks because it is a reserved word.

Examples

A. Help on a Single Group

This example displays information about the hackers group.

sp_helpgroup hackers
B. Help on All Groups

This example displays information about all groups in the current database.

sp_helpgroup

Permission

Execute permission defaults to the public group.

Table Used

sysusers

See Also

GRANT | sp_dropgroup
REVOKE | sp_helprotect
sp_addgroup | sp_helpuser
sp_changegroup |


sp_helpindex System Stored Procedure

Reports information about the indexes on a table.

Syntax

sp_helpindex tabname

where

tabname
Specifies a table in the current database.

Remarks

Executing sp_helpindex lists up to eight indexes on a table.

Example

This example reports on the types of indexes on the sysobjects table.

sp_helpindex sysobjects

index_name

index_description

index_keys

---------------------

--------------------

---------------

sysobjects

clustered, unique

id

ncsysobjects

nonclustered, unique

name, uid

Permission

Execute permission defaults to the public group.

Tables Used

master.dbo.spt_values, sysindexes, syssegments

See Also

CREATE INDEX | sp_statistics
DROP INDEX | UPDATE STATISTICS
sp_help |


sp_helplanguage System Stored Procedure

Reports information about a particular alternate language or about all languages.

Syntax

sp_helplanguage [language]

where

language
Specifies the alternate language about which information is to be displayed.

Remarks

When language is supplied, sp_helplanguage reports on the specified language. When no parameter is supplied, sp_helplanguage reports on all languages in master.dbo.syslanguages.

Examples

A. Help on a Single Language

This example displays information about the alternate language French.

sp_helplanguage french
B. Help on All Languages

This example displays information about all installed alternate languages.

sp_helplanguage

Permission

Execute permission defaults to the public group.

Table Used

master.dbo.syslanguages

See Also

sp_droplanguage | sp_setlangalias


sp_helplog System Stored Procedure

Reports the name of the device that contains the first page of the log in the current database.

Syntax

sp_helplog

Permission

Execute permission defaults to the public group.

Tables Used

sysindexes, master.dbo.sysdevices

See Also

ALTER DATABASE | sp_helpdevice
CREATE DATABASE | sp_logdevice


sp_helpremotelogin System Stored Procedure

Reports information about a particular remote server's logins or about all remote servers' logins.

Syntax

sp_helpremotelogin [remoteserver [, remotename]]

where

remoteserver
Specifies the server about which remote login information is to be displayed.
remotename
Specifies a particular remote user on the remote server.

Examples

A. Help on a Single Server

This example displays information about all remote users of the remote server ACCOUNTS.

sp_helpremotelogin ACCOUNTS
B. Help on All Remote Users

This example displays information about all remote users of all remote servers known to the local server.

sp_helpremotelogin

Permission

Execute permission defaults to the public group.

Tables Used

master.dbo.sysremotelogins, master.dbo.sysservers

See Also

sp_addremotelogin | sp_helpserver
sp_dropremotelogin |


sp_helprotect System Stored Procedure

For SQL Server 6.5 information, see sp_helprotect in What's New for SQL Server 6.5.

Reports permissions by database object and, optionally, by user for that object.

Syntax

sp_helprotect name [, username]

where

name
Is the name of a table, view, stored procedure, user, or group in the current database.
username
Is a username in the current database.

Remarks

Executing sp_helprotect reports permissions on a database object. If the username parameter is supplied, only that user's permissions on the database object are reported. If name is a user or group and username is also supplied, the permissions for the user or group are listed.

The procedure looks for objects and users in the current database only.

Examples

A. Permissions for a Table

This example reports the permissions for the titles table.

sp_helprotect titles
B. Permissions for a User

This example lists all permissions that Judy has in the database.

sp_helprotect Judy

Permission

Execute permission defaults to the public group.

Tables Used

master.dbo.spt_values, syscolumns, sysobjects, sysprotects, sysusers

See Also

GRANT statement | sp_help
REVOKE statement |


sp_helpsegment System Stored Procedure

Reports information about a particular segment or about all segments in the current database.

Syntax

sp_helpsegment [segname]

where

segname
Specifies the segment about which you want information. If you omit this parameter, information about all segments in the current database is displayed. If the segname is DEFAULT, you must enclose it in quotation marks because the word DEFAULT is a reserved word.

Remarks

Segments are added to the syssegments table in the current database by using the sp_addsegment system procedure.

Example

This example reports information about the SEGMENT3 segment, including which database tables and indexes use that segment.

sp_helpsegment segment3

Permission

Execute permission defaults to the public group.

Tables Used

master.dbo.sysdevices, master.dbo.sysusages, sysindexes, syssegments

See Also

sp_addsegment | sp_helpdb
sp_dropsegment | sp_helpdevice
sp_extendsegment |


sp_helpserver System Stored Procedure

For SQL Server 6.5 information, see sp_helpserver in What's New for SQL Server 6.5.

Reports information about a particular remote or replication server or about all servers of both types.

Syntax

sp_helpserver [server_name]

where

server_name
Specifies the server about which information is to be displayed. When no server_name is supplied, reports about all servers in master.dbo.sysservers.

Remarks

This system stored procedure returns the server's name, network name, status, and ID. Status can be:

dist | Distribution server
dpub | Combination publisher/subscriber
pub | Publication server
rpc | Remote server
sub | Subscription server

A server can have more than one status.

Permission

Execute permissions defaults to the public group.

Tables Used

master.dbo.sp_values, master.dbo.sysservers

Examples

A. Information About All Servers

This example displays information about all servers (sp_helpserver with no parameters).

sp_helpserver
B. Information About a Specific Server

This example displays all information about the sales server.

sp_helpserver sales

See Also

sp_addpublisher | sp_dropserver
sp_addserver | sp_dropsubscriber
sp_addsubscriber | sp_helpdistributor
sp_changesubscriber | sp_helpremotelogin
sp_dboption | sp_helpsubscriberinfo
sp_droppublisher | sp_serveroption


sp_helpsort System Stored Procedure

Displays the SQL Server default sort order and character set.

Syntax

sp_helpsort

Remarks

Binary sort order is the default.

For the output of sp_helpsort to appear correctly on a client computer, the client must be running the same character set and code page as the SQL Server. For more information about sort orders, see Microsoft SQL Server Setup.

Example

This example displays the name of the server's default sort order, its character set, and a table of its primary sort values.

sp_helpsort
go

Sort Order Description
----------------------------------------------------------------
Character Set = 2, cp850
    Code Page 850 (Multilingual) character set.
Sort Order = 40, bin_cp850
    Binary Sort Order for the CodePage 850 Character Set

Characters, in Order
----------------------------------------------------------------

Permission

Execute permission defaults to the public group.

Table Used

master.dbo.syscharsets


sp_helpsql System Stored Procedure

Provides syntax for Transact-SQL statements, system procedures, and other special topics.

Syntax

sp_helpsql ['topic']

where

topic
Specifies the topic on which you want help. Help information is available for all Transact-SQL statements, all system procedures, and the following special topics: datatypes, expressions, functions, wildcard characters, mathematical functions, and text functions. You must include quotation marks around topic.

Remarks

Online Help is also available through the SQL Help icon in the SQL Server program group.

You can enter just the first few letters of a topic. If these letters are enough to identify the topic, then Help on the topic is displayed. For example, to get Help on the CREATE TABLE statement, execute the following:

sp_helpsql 'CREATE TAB'

To get help on all topics starting with "CREATE," execute the following:

sp_helpsql 'CREATE'

Examples

A. Help on a Single Command

This example displays a brief definition of the DISK INIT statement along with its syntax.

sp_helpsql 'disk init'
B. Help on Functions

This example displays information about SQL Server functions.

sp_helpsql functions

Permission

Execute permission defaults to the public group.


sp_helpstartup System Stored Procedure

Reports a listing of all auto-start stored procedures.

Syntax

sp_helpstartup

Remarks

Executing sp_helprotect reports a list of all stored procedures marked for auto execution (to be run when the server is started).

Example

This example reports information about all auto execution stored procedures.

sp_helpstartup

Permission

Execute permission defaults to the public group. However, only a system administrator can make an auto execution stored procedure.

Table Used

master.dbo.sysobjects

See Also

CREATE PROCEDURE | sp_unmakestartup
sp_makestartup |


sp_helptext System Stored Procedure

Prints the text of a rule, a default, or an unencrypted stored procedure, trigger, or view.

Syntax

sp_helptext objname

where

objname
Specifies the object about which the definition is to be displayed. The object must be in the current database.

Remarks

Executing sp_helptext prints out the text that was used to create the object. It looks for the text in the syscomments table of the current database only.

If an object (stored procedure, trigger or view) was created with the ENCRYPTION option, then sp_helptext will display garbled text.

With SQL Server 6.0, sp_helptext no longer displays the count of rows to be returned before it returns those rows.

Example

This example displays the text of the employee_insupd trigger. Since this trigger is in the pubs database, this example must be executed from pubs.

Permission

Execute permission defaults to the public group.

Table Used

syscomments

See Also

CREATE DEFAULT statement | CREATE TRIGGER statement
CREATE PROCEDURE statement | CREATE VIEW statement
CREATE RULE statement | sp_help


sp_helpuser System Stored Procedure

Reports information about the users of a database.

Syntax

sp_helpuser [username]

where

username
Is a user in the current database. If you don't specify a name, the system procedure reports on all users of the current database.

Remarks

If the specified user is not listed in the current database's sysusers table, the procedure checks to see if the user has an alias to another user or is a group name.

Examples

A. List All Users

This example displays information about all users in the current database.

sp_helpuser
go

Users_name

ID_in_db

Group_name

Login_id

Default_db

-----------

--------

------------

----------

------------

ann

4

hackers

ann

master

dbo

1

public

sa

master

guest

2

public

NULL

NULL

judy

3

hackers

judy

master

B.    List Information for a Single User

This example displays information about the database owner.

sp_helpuser dbo

Permission

Execute permission defaults to the public group.

Tables Used

master.dbo.syslogins, sysalternates, sysusers

See Also

GRANT statement | sp_help
REVOKE statement | sp_helpgroup
sp_adduser | USE statement
sp_dropuser |


sp_lock System Stored Procedure

Reports information about locks.

Syntax

sp_lock [spid1 [, spid2]]

where

spid1
Is the SQL Server process ID number from master.dbo.sysprocesses. Execute sp_who to get the spid of the lock. If this parameter is not supplied, information about all locks is displayed.
spid2
Identifies another SQL Server process ID number to check for locks.

Remarks

Users can control locking by adding an optimizer hint to the FROM clause of a SELECT statement or by setting the TRANSACTION ISOLATION LEVEL with the SET statement. For syntax and restrictions, see the SELECT and SET statements.

In general, read operations acquire shared locks, and write operations acquire exclusive locks. Update locks are created at the page level and are acquired during the initial portion of an update operation when the pages are being read. Update locks are compatible with shared locks. Later, if the pages are changed, the update locks are promoted to exclusive locks.

An intent lock indicates the intention to acquire a shared or exclusive page level lock. An intent lock prevents another transaction from acquiring a table lock for that table.

An extent lock is held on a group of eight database pages while they are being allocated or freed. Extent locks are set while a CREATE or DROP statement is running or while an INSERT or UPDATE statement that requires new data or index pages is running.

The locktype column indicates whether the lock is a shared lock (Sh), an exclusive lock (Ex), or an update lock. This column also indicates whether the lock is held on a table (table or intent), a page, or an extent, and whether it is blocking (blk) another process. The blk suffix in the locktype indicates that this process is blocking another process that needs to acquire a lock. As soon as this process finishes, the other process(es) move forward.

When reading sp_lock information, use the OBJECT_NAME( ) function to get a table's name from its ID number. For example:

SELECT object_name(16003088)

Other information can also be displayed based on the spid returned from sp_lock. For information about using the Windows NT Performance Monitor to view information about a specific spid, see the DBCC statement.

Examples

A. List All Locks

This example displays information about all locks currently held in SQL Server.

sp_lock
B. List a Single Lock

This example displays information about locks currently held on spid 1.

sp_lock 1

Permission

Execute permission defaults to the public group.

Tables Used

master.dbo.spt_values, master.dbo.syslocks, master.dbo.sysprocesses

See Also

DBCC | SELECT statement
Functions | sp_who
KILL statement |


sp_logdevice System Stored Procedure

Puts the syslogs system table, which contains the transaction log, on a separate database device.

Syntax

sp_logdevice dbname, database_device

where

dbname
Specifies which database has the syslogs table to put on a specific database device.
database_device
Is the name of the database device on which to put the syslogs table. This database device must have been referenced in a CREATE DATABASE or ALTER DATABASE statement for dbname. Run sp_helpdevice for a report on existing database devices.

Note Because sp_logdevice affects only future allocations of space for syslogs, the first pages of your log remain on the same device as your data, leaving them temporarily vulnerable. However, using the LOG ON extension to CREATE DATABASE immediately puts the entire transaction log on a separate device.

Remarks

For better recovery and performance, put most databases and their transaction logs on separate database devices. You can keep small and non-critical databases on the same device as their log. In that case, however, use only the DUMP DATABASE statement (never DUMP TRANSACTION) for backups.

DBCC CHECKALLOC and sp_helplog show some pages for syslogs still allocated on the database device until after the next DUMP TRANSACTION statement. After that, transfer the transaction log to the device named when you executed sp_logdevice.

The size of the database device required for a transaction log varies according to the amount of update activity and the frequency of transaction log dumps. As a rule, allocate to the log device 10-25 percent of the space you allocate to the database itself. It is best to start small, since space allocated to a transaction log device cannot be reclaimed.

To increase the amount of allocated storage space on the transaction log database device, give the logical name of the log database device in the ON clause when you execute the ALTER DATABASE statement. Then execute sp_logdevice to make the newly allocated space available to the log.

The device or segment on which you put syslogs is used only for the syslogs table. If you want to increase the amount of storage space allocated to the rest of the database, specify any database device other than the log database device when you execute the ALTER DATABASE statement.

Use the DISK INIT statement to format a new physical database device on which to store databases and transaction logs.

For further details, see the Microsoft SQL Server Administrator's Companion.

Example

This example shows how sp_logdevice is used after altering a database. In this example the products database is altered by 2 MB and the log is then moved to that 2-MB segment.

ALTER DATABASE products ON logdevice = 2
go

sp_logdevice products, logdevice

Permission

Execute permission defaults to the database owner of the named database.

Tables Used

master.dbo.sysdatabases, master.dbo.sysdevices, master.dbo.sysusages

See Also

ALTER DATABASE | DUMP
CREATE DATABASE | sp_extendsegment
DBCC | sp_helpdevice
DISK INIT |


sp_makestartup System Stored Procedure

Sets a stored procedure for auto execution. Auto execution stored procedures are executed every time the server is started.

Syntax

sp_makestartup procedure_name

where

procedure_name
Specifies the name of the procedure to start automatically when the server is started.

Remarks

There is no limit to the number of startup procedures you can have, but be aware that each auto execution procedure consumes one connection. If you need to execute multiple procedures at startup but don't need to execute them in parallel, you can make one procedure the startup procedure and have that procedure call the other procedures. For more information, see the CREATE PROCEDURE statement.

Example

This example makes the update_all_stats procedure an auto execution procedure.

sp_makestartup update_all_stats

Permission

Only the system administrator can use this procedure.

Tables Used

master.dbo.sysobjects, master.dbo.syscolumns

See Also

CREATE PROCEDURE | sp_unmakestartup
sp_helpstartup |


sp_monitor System Stored Procedure

Displays statistics about SQL Server.

Syntax

sp_monitor

Remarks

SQL Server keeps track in a series of global variables of how much work it has done. Executing sp_monitor displays the current values of these global variables and shows how much they have changed since the last time the procedure was run.

For each column, the statistic is printed in the form number(number)-number% or number(number). The first number refers to the number of seconds (for cpu_busy, io_busy, and idle) or the total number (for the other variables) since SQL Server was restarted. The number in parentheses refers to the number of seconds or total number since the last time sp_monitor was run. The percentage is the percentage of time since sp_monitor was last run. For example, if the report shows cpu_busy as 4250(215)-68%, the CPU has been busy 4250 seconds since SQL Server was last started up, 215 seconds since sp_monitor was last run, and 68 percent of the total time since sp_monitor was last run.

These are the columns in the sp_monitor report:

Column | Description
last_run | The time sp_monitor was last run.
current_run | The time sp_monitor is being run.
seconds | The number of elapsed seconds since sp_monitor was run.
cpu_busy | The number of seconds that the server computer's CPU has been doing SQL Server work.
io_busy | The number of seconds that SQL Server has spent doing input and output operations.
idle | The number of seconds that SQL Server has been idle.
packets_received | The number of input packets read by SQL Server.
packets_sent | The number of output packets written by SQL Server.
packet_errors | The number of errors encountered by SQL Server while reading and writing packets.
total_read | The number of reads by SQL Server.
total_write | The number of writes by SQL Server.
total_errors | The number of errors encountered by SQL Server while reading and writing.
connections | The number of logins or attempted logins to SQL Server.

Example

This example reports information about how busy SQL Server has been.

sp_monitor
go

last_run

current_run

seconds

------------------

--------------------

-------------

Mar 29 1993 11:55AM

Apr 4 1993 2:22 PM

561

cpu_busy

io_busy

idle

-----------------

---------------

-------------

190(0)-0%

187(0)-0%

148(556)-99%

packets_received

packets_sent

packet_errors

-----------------

-----------------

-------------

16(1)

20(2)

0(0)

total_read

total_write

total_errors

connections

-----------------

-----------------

-------------

------------

141(0)

54920(127)

0(0)

4(0)

Permission

Execute permission defaults to the system administrator, who can transfer it to other users.

Table Used

master.dbo.spt_monitor

See Also

sp_who
Variables


sp_password System Stored Procedure

Adds or changes a password for a SQL Server login ID.

Syntax

sp_password old, new [, login_id]

where

old
Is the user's old password, which is encrypted in master.dbo.syslogins. The default password for all users is NULL. The system administrator can specify NULL for this parameter no matter what the user's old password was. However, if the system administrator gives any value besides NULL, SQL Server checks the value against master.dbo.syslogins and rejects it if it is wrong.
new
Is the user's new password.
login_id
Is an option that only the system administrator can use to change any user's password.

Remarks

Any user can use sp_password to change his or her own password. Only the system administrator can change someone else's password (using the login_id parameter).

The old parameter is checked against the existing password for the user login_id (unless the user executing the procedure is the system administrator and the old parameter is NULL) and must match for the password to be changed. Passwords are encrypted in master.dbo.syslogins.password.

If front-end programs require the same password on remote servers as on the local server, a user must change his or her password on all the remote servers before changing the local password. The sp_password procedure should be executed as a call to a remote stored procedure on each remote server.

Permission

Execute permission defaults to the public group. Each member of public has permission to change only his or her own password. The system administrator can change any user's password.

Table Used

master.dbo.syslogins

Examples

A. SA Can Change Password Without Knowing the Former Password

In this example, the system administrator has changed Victoria's password to ok. Notice that NULL is not enclosed in quotation marks.

sp_password NULL, ok, Victoria
B. A User Changes Her Password

In this example, the user Victoria changes her password from ok to coffee.

sp_password ok, coffee

See Also

sp_addlogin | xp_grantlogin
sp_adduser | xp_logininfo
sp_defaultdb | xp_revokelogin


sp_placeobject System Stored Procedure

Puts future space allocations for a table or index on a particular segment.

Syntax

sp_placeobject segname, objname

where

segname
Specifies the segment where the table or index is to be located.
objname
Specifies the table or index whose subsequent space allocation is to be put on the segment segname.

Remarks

You cannot change the location of future space allocations for system tables.

Putting a table or index on a particular segment does not affect the location of any existing table or index data. It affects only future space allocation. By changing the segment used by a table or index, the data can be spread across multiple segments.

If a table or index is created with the CREATE TABLE or CREATE INDEX statement, you can specify a segment. If no segment is specified, the data will go on the DEFAULT segment.

When sp_placeobject is used to split a table or index across more than one disk fragment, the diagnostic DBCC statement reports on the data located on the fragments in use for storage before sp_placeobject was executed. These messages can be ignored.

A table with text or image columns has an additional entry in the sysindexes table for the text chain, with the name column set to the name of the table preceded by the letter t and an indid of 255. You can use sp_placeobject to store the text chain on a separate device, giving both the table name and the name of the text chain from sysindexes.

Example

This example causes all subsequent space allocation for the index named employee_nc on the table employee to be placed on the segment named INDEXES.

sp_placeobject indexes, 'employee.employee_nc'
EXEC sp_placeobject textseg, 'mytab.tmytab'

Permission

Execute permission defaults to the table owner, database owner, and system administrator.

Tables Used

sysindexes, sysobjects, syssegments

See Also

DBCC | sp_help
sp_addsegment | sp_helpindex
sp_dropsegment | sp_helpsegment
sp_extendsegment |


sp_processmail System Stored Procedure

Uses extended stored procedures (xp_findnextmsg, xp_readmail, and xp_deletemail) to process incoming mail messages (expected to be only a single query) from the inbox for SQL Server. It uses the xp_sendmail extended stored procedure to return the results set back to the message sender.

Syntax

sp_processmail [@subject = subject] [[,] @filetype = filetype]
[[,] @separator = separator] [[,] @set_user = user] [[,] @dbuse = dbname]

where

@subject = subject
Specifies the subject line of mail messages to interpret as queries for SQL Server. When specified, sp_processmail will process only messages that have this subject. By default, SQL Server processes all mail messages as though they were queries.
@filetype = filetype
Specifies the file extension to be used when sending the results set file back to the message sender. The default is .TXT.
@separator = separator
Specifies the column separator (field terminator) for each column of the results set (this information is passed to the xp_sendmail extended stored procedure to return the results set back to the message sender). The default is 'TAB', which is a special case for the tab character to be used between columns.
@set_user = user
Specifies the security context in which the query should be run. The default is 'guest' (the guest user).
@dbuse = dbname
Specifies the database context in which the query should be run. The default is the master database.

Remarks

Incoming e-mail is expected to have a single valid SQL Server query as the message text. The results of the query are returned to the message sender and copied to any e-mail users on the CC: list of the original message. After messages are processed, they are deleted from the inbox. If e-mail is often sent to the server, sp_processmail should be run frequently. To set up regular e-mail processing, you can use the SQL Executive to schedule an sp_processmail task. This will process mail at the specified frequency and record an informational message with the number of queries processed in the task history.

Results are sent as an attached file. The complete filename sent consists of "SQL" followed by a random string of numbers and then the specified extension (@filetype), for example, SQL356.TXT.

Important To get an appropriate icon attached to the mail message, make sure that the file type is associated properly. Create a file association by using the Windows NT File Manager. To associate the appropriate application with the file from the File Manager File menu, choose Associate. For example, to return .CSV files to a client as Excel files, associate the .CSV extension with the Microsoft Excel program. Any existing associations (for example, .TXT files are associated with NOTEPAD.EXE) will be handled correctly. If the mail recipient has the same association, he or she can double-click on the icon (in the returned mail message) and automatically load the application.

Errors received when the query is processed will be returned to the message sender through the message text. When the results set is returned to the client, xp_sendmail is called with the @echo_error parameter set to 'true'. The messages sent also include a row count (number of rows affected) by the query.

If desired, different sp_processmail tasks can be set up for queries in different databases. For example, you could adopt the convention that queries to the pubs database must have a subject of "SQL:pubs". Then you could run sp_processmail with @subject = 'SQL:pubs' and @dbuse = 'pubs'. Different database queries and groupings could have other formatting structures. For example, distribution tasks could have @subject = 'SQL:distribution' and @dbuse = 'distribution'. Any of these can be scheduled tasks with the SQL Executive. For more information on scheduling events, see the Microsoft SQL Server Administrator's Companion.

The sp_processmail system stored procedure can also be customized in many ways by retrieving the text of the procedure with the sp_helptext system stored procedure and then modifying the Transact-SQL code. Possible changes include:

  • Process only certain custom message types using the @type parameter with the xp_readmail extended stored procedure.
  • Mark the message as 'read' but don't delete the message after processing, (issue the xp_readmail a second time with @peek set to 'false').
  • Send the query results in the body of the e-mail message by calling the xp_sendmail extended stored procedure with @attach_results set to 'false'.
  • Set the security context to run the query in a user context based on the message sender. If the e-mail usernames are the same as your SQL Server usernames, this is as simple as changing the call to xp_sendmail to use @set_user = @originator. If your mail usernames are not valid SQL Server usernames (if, for example, they contain embedded blanks), you could do a table lookup or character substitution to get the appropriate SQL Server username to pass to xp_sendmail.

Example

This example processes all messages in the pubs database with results sets returned to the client in CSV (comma separated values) format.

sp_processmail @filetype = 'CSV', @separator = ',', @dbuse = 'pubs'

Permission

Permission to use this procedure defaults to the system administrator.

See Also

sp_addtask | xp_readmail
xp_deletemail | xp_sendmail
xp_findnextmsg |


sp_recompile System Stored Procedure

Causes each stored procedure and trigger that uses the specified table to be recompiled the next time the stored procedure and triggers are run.

Syntax

sp_recompile tabname

where

tabname
Specifies a table in the current database.

Remarks

The queries used by stored procedures and triggers are optimized only once, when they are compiled. As you add indexes or make other changes to your database that affect its statistics, your compiled stored procedures and triggers may lose efficiency. By recompiling the stored procedures and triggers that act on a table, you can reoptimize the queries for greatest efficiency.

The sp_recompile system procedure looks for a table in the current database only. It cannot be used on system tables.

Example

This example causes each trigger and stored procedure that uses the titles table to be recompiled the next time it is run.

sp_recompile titles

Permission

Execute permission defaults to the public group.

Table Used

sysobjects


sp_remoteoption System Stored Procedure

Displays or changes remote login options.

Syntax

sp_remoteoption [remoteserver, loginame, remotename, optname, {true | false}]

where

remoteserver
Specifies the remote server that has the remote login to which the option should apply.
loginame
Is the login name that identifies the remote login for the remoteserver, loginame, remotename combination.
remotename
Is the remote username that identifies the remote login for the remoteserver, loginame, remotename combination.
optname
Is the option you want to set or turn off. Currently, there is only one option, trusted, which means that the local server accepts remote logins from other servers without verifying user access for the particular remote login. The default is untrusted (trusted set to false), which results in password verification. SQL Server understands any unique string that is part of the option name. Use quotation marks around the option name if it includes embedded blanks.
true | false
Specifies whether to set the option. Choose true if you want to set the option, false if you want to turn it off.

Remarks

To display a list of the remote login options, execute sp_remoteoption with no parameters.

Only the system administrator can set or turn off particular server options. For details on remote login options, see the Microsoft SQL Server Administrator's Companion.

Examples

A. List Options

This example lists the remote login options:

sp_remoteoption
go
Settable remotelogin options.
remotelogin_option
--------------------------------------------
trusted
B. Trusted Logins

This example defines the remote login from the remote server ACCOUNTS to be trusted (the password will not be checked).

sp_remoteoption ACCOUNTS, salesmgr, chris, trusted, TRUE
C. Untrusted Logins

This example defines the remote login from the remote server ACCOUNTS to be untrusted (the password will be checked).

sp_remoteoption ACCOUNTS, salesmgr, chris, trusted, FALSE

Permission

Execute permission without parameters (display options only) defaults to the public group. Only the system administrator can use sp_remoteoption with parameters (to change an option).

Tables Used

master.dbo.sp_values, master.dbo.sysremotelogins, master.dbo.syssrvers

See Also

sp_helpremotelogin


sp_rename System Stored Procedure

Changes the name of a user-created object in the current database.

Syntax

sp_rename objname, newname [, COLUMN | INDEX ]

where

objname
Is the original name of the user object (table, view, column, stored procedure, trigger, default, or rule) or datatype. If the object to be renamed is a column in a table, objname must be in the form 'table.column'. If the object to be renamed is an index, objname must be in the form 'table.index'. The table name is not included in newname. You can rename an object in the current database only, and only if you own it. This rule holds for all users, including the system administrator and database owner. Users can change the names only of those objects they own. The database owner or system administrator can change the name of any user's objects by using SETUSER. For details, see the SETUSER statement.
newname
Is the new name of the object or datatype. Names of objects and datatypes must follow the rules for identifiers. When the table name is required in objname, it is excluded from newname.
COLUMN | INDEX
Specifies whether the object being renamed is a column or an index. Specifying this parameter resolves any possible conflict that can occur when column names and index names are identical.

Remarks

You can change the name of an object or datatype in the current database only. The names of most system datatypes and system objects cannot be changed.

When you rename a view, information about the view is updated in the sysobjects table.

When you rename a stored procedure, information about the procedure is changed in the sysobjects table.

Examples

A. Rename a Table

This example renames the titles table books.

sp_rename titles, books
B. Rename a Column

This example renames the title column in the books table name.

sp_rename 'books.title', name, COLUMN

Permission

Execute permission defaults to the object owner.

Tables Used

syscolumns, sysindexes, sysobjects, systypes

See Also

ALTER TABLE | CREATE VIEW
CREATE DEFAULT | Datatypes
CREATE PROCEDURE | sp_addtype
CREATE RULE | sp_depends
CREATE TABLE | sp_renamedb
CREATE TRIGGER |


sp_renamedb System Stored Procedure

Changes the name of a database.

Syntax

sp_renamedb oldname, newname

where

oldname
Is the original name of the database.
newname
Is the new name of the database. Names of objects and datatypes must follow the rules for identifiers.

Remarks

Only the system administrator can change the name of a database. The system administrator must put a database in single-user mode by using sp_dboption before renaming it, and must restore it to multi-user mode afterward.

Example

This example changes the name of the accounting database to financial.

sp_renamedb accounting, financial

Permission

Execute permission defaults to the system administrator.

Table Used

master.dbo.sysdatabases

See Also

CREATE DATABASE | sp_depends
sp_changedbowner | sp_helpdb
sp_dboption | sp_rename


sp_serveroption System Stored Procedure

For SQL Server 6.5 information, see sp_serveroption in What's New for SQL Server 6.5.

Sets server options.

Syntax

sp_serveroption [server_name, optname, {true | false}]

where

server_name
Specifies the server for which you want to set the option.
optname
Is the type of server. Can be:
dist | Distribution server
dpub | Combination publisher/subscriber
pub | Publication server
rpc | Remote server
sub | Subscription server

The default is rpc.

true | false
Specifies whether to set the option. Choose true if you want to set the option, false if you want to turn it off.

Remarks

To display a list of the server options, execute sp_serveroption with no parameters.

Examples

A. List Options

This example lists the server options.

sp_serveroption
go

Settable server options.
server_option
--------------------------------
dist
dpub
pub
rpc
sub
B. Set an Option

This example sets the server as a combination publisher/subscriber server.

sp_serveroption ACCOUNTS, dpub, TRUE

Permission

Only the system administrator can use sp_serveroption to set server options.

Tables Used

master.dbo.sp_values, master.dbo.sysserver

See Also

sp_addpublisher | sp_helpserver
sp_droppublisher. |


sp_setlangalias System Stored Procedure

Assigns or changes the alias for an alternate language.

Syntax

sp_setlangalias language, alias

where

language
Is the name of the language.
alias
Is the new local alias for the alternate language.

Remarks

The alias replaces the current value of the syslanguages.alias for the original language.

The new alias can be used in place of the original language by the SET LANGUAGE statement.

Example

This example assigns the alias name français to the original language name French.

sp_setlangalias français, french

Permission

Execute permission defaults to the system administrator.

Table Used

master.dbo.syslanguages

See Also

SET | sp_helplanguage
sp_droplanguage |


sp_spaceused System Stored Procedure

Displays the number of rows, the disk space reserved, and the disk space used by a table in a database, or displaces the disk space reserved and used by an entire database.

Syntax

sp_spaceused [objname] [[,] @updateusage = {true | false}]

where

objname
Specifies the name of the table for which space usage information (reserved and allocated space) is requested.
@updateusage
Specifies whether or not DBCC UPDATEUSAGE should be run within the database (when no objname is specified) or on a specific object (when objname is specified). Setting this option to true could take a significant amount of time. If preferred, DBCC UPDATEUSAGE can be run separately. See the remarks for more information.

Remarks

Executing sp_spaceused computes the amount of disk space used for data and indexes, and the disk space used by a table in the current database. If no table (objname) is given, sp_spaceused reports on the space used by the entire current database.

After you drop an index, sp_spaceused reports inaccurate information. This is a known limitation. However, sp_spaceused provides a quick, rough estimate. If you notice incorrect values when you execute sp_spaceused, run DBCC UPDATEUSAGE to correct the inaccuracies. Because this statement takes some time to run on large tables or databases use it only when you suspect incorrect values being returned or when other users are not active.

Examples

A. Space Information About a Table

This example reports on the amount of space allocated (reserved) for the titles table, the amount used for data, the amount used for index(es), and the unused space reserved by database objects.

sp_spaceused titles
go

name    rows  reserved  data   index_size   unused
------- ----- --------- ------ ------------ -------------
titles  18    48 KB     6 KB   8 KB         34 KB
B. Updated Space Information About a Complete Database

This example shows a summary of space used in the current database with the optional @updateusage.

sp_spaceused @updateusage = 'TRUE'
go

DBCC UPDATEUSAGE: messages are printed...
DBCC execution completed. If DBCC printed error messages, see your System Administrator.

database_name               database_size   unallocated space
--------------------------- --------------- ------------------
pubs                        3.00 MB         1.69 MB

reserved       data          index_size     unused
-------------- ------------- -------------- ---------------
1344 KB        300 KB        116 KB         928 KB

Permission

Execute permission defaults to the public group.

Tables Used

master..sysusages, sysindexes, sysobjects

See Also

CREATE INDEX | DROP TABLE
CREATE TABLE | sp_help
DROP INDEX | sp_helpindex


sp_unbindefault System Stored Procedure

Unbinds (removes) a default from a column or from a user-defined datatype in the current database.

Syntax

sp_unbindefault objname [, futureonly]

where

objname
Specifies the table and column or the user-defined datatype from which the default is to be unbound. If the parameter is not of the form 'table.column', then objname is recognized as a user-defined datatype. When unbinding a default from a user-defined datatype, any columns of that datatype that have the same default as the user datatype are also unbound. Columns of that datatype with defaults bound directly to them are unaffected.
futureonly
Used only when unbinding a default from a user-defined datatype, this option prevents existing columns of that datatype from losing this default. It is never used when unbinding a default from a column.

Remarks

Columns of the user-defined datatype lose their current default unless their default has previously been changed or the futureonly option is used.

To display the text of a default, execute sp_helptext with the default name as the parameter.

When you unbind a default, the information about the binding is removed from the syscolumns table if the default was bound to a column, and from the systypes table if the default was bound to a user-defined datatype.

Examples

A. Unbind a Default from a Column

This example unbinds the default from the startdate column of the employees table.

sp_unbindefault 'employees.startdate'
B. Unbind a Default from a User-defined Datatype

This example unbinds the default from the user-defined datatype ssn and all columns of that type. It unbinds existing and future columns of that type.

sp_unbindefault ssn
C. Use futureonly

This example unbinds future uses of the user datatype ssn, but existing columns of type ssn are unaffected.

sp_unbindefault ssn, FUTUREONLY

Permission

Execute permission defaults to the specified object owner.

Tables Used

syscolumns, sysobjects, systypes

See Also

CREATE DEFAULT | sp_bindefault
DROP DEFAULT | sp_helptext


sp_unbindrule System Stored Procedure

Unbinds a rule from a column or a user-defined datatype in the current database.

Syntax

sp_unbindrule objname [, futureonly]

where

objname
Specifies the table and column or the user-defined datatype from which the rule is to be unbound. If the parameter is not of the form 'table.column', objname is recognized as a user-defined datatype. When unbinding a rule from a user-defined datatype, any columns of that datatype that have the same rule as the user datatype are also unbound. Columns of that datatype with rules bound directly to them are unaffected.
futureonly
Used only when unbinding a rule from a user-defined datatype, this option prevents existing columns of that datatype from losing this rule. It is never used when unbinding a rule from a column.

Remarks

The rule is unbound from all existing columns of the user-defined datatype unless their default has previously been changed or the futureonly option is used.

To display the text of a rule, execute sp_helptext with the rule name as the parameter.

When you unbind a rule, the information about the binding is removed from the syscolumns table if the rule was bound to a column, and from the systypes table if the rule was bound to a user-defined datatype.

Examples

A. Unbind a Rule from a Column

This example unbinds the rule from the startdate column of the employees table.

sp_unbindrule 'employees.startdate'
B. Unbind a Rule from a User-defined Datatype

This example unbinds the rule from the user-defined datatype ssn. It unbinds the rule from existing and future columns of that type.

sp_unbindrule ssn
C. Use futureonly

This example unbinds the rule from the user-defined datatype ssn without affecting existing ssn columns.

sp_unbindrule ssn, FUTUREONLY

Permission

Execute permission defaults to the object owner.

Tables Used

syscolumns, sysobjects, systypes

See Also

CREATE RULE | sp_bindrule
DROP RULE | sp_helptext


sp_unmakestartup System Stored Procedure

Discontinues auto execution of the stored procedure.

Syntax

sp_unmakestartup procedure_name

where

procedure_name
Specifies the name of the procedure that should no longer automatically execute when the server is started.

Example

This example unmarks the update_all_stats procedure from being an auto execution procedure.

sp_unmakestartup update_all_stats

Permission

Only the system administrator can use this procedure.

Tables Used

master.dbo.sysobjects

See Also

CREATE PROCEDURE | sp_makestartup
sp_helpstartup |


sp_who System Stored Procedure

For SQL Server 6.5 information, see sp_who in What's New for SQL Server 6.5.

Reports information about current SQL Server users and processes.

Syntax

sp_who [login_id | 'spid']

where

login_id
Is the user's login ID on SQL Server. If no name is specified, the procedure reports on all active users of SQL Server.
spid
Specifies a specific process. You can supply a process number as a parameter if you enclose it in quotation marks (SQL Server expects a char type).

Remarks

This system stored procedure reports information about a specified user, a specified SQL Server process, or all users currently running a process on SQL Server. Executing sp_who without parameters reports which users are running what processes in all databases.

Examples

A. List All Current Processes

This example shows how to view all current processes by executing sp_who without parameters. The blk column contains the system process ID of a blocking process; this value references the spid column of this table (self-referencing). A blocking process (which may have an exclusive lock) is one that is holding resources that another process needs. In this example, process 11 (a SELECT on a table) is blocked by process 10 (an uncommitted transaction).

sp_who
go
spid   status     loginame hostname  blk   dbname     cmd
------ ---------- -------- --------- ----- ---------- ----------------
1      sleeping   sa                 0     master     MIRROR HANDLER
2      sleeping   sa                 0     master     LAZY WRITER
3      sleeping   sa                 0     master     CHECKPOINT SLEEP
4      sleeping   sa                 0     master     RA MANAGER
10     sleeping   Mary     WKSTA1    0     pubs       AWAITING COMMAND
11     runnable   Joe      WKSTA5    10    pubs       SELECT
B. List a Specific User's Process

This example shows how to view information about a single current user by loginame or spid.

sp_who Mary

Or

sp_who '10'

Permission

Execute permission defaults to the public group.

Table Used

master.dbo.sysprocesses

See Also

KILL sp_lock


Subqueries

You can nest a SELECT statement inside a SELECT, INSERT, UPDATE, or DELETE statement, another subquery, or anywhere an expression is allowed. However, the expression that includes the subquery must return true or false. Usually a subquery is nested inside the WHERE or HAVING clause of an outer SELECT, INSERT, UPDATE, DELETE, or another subquery. Many SQL statements that include subqueries can also be formulated as joins.

Syntax

A subquery can be used in these contexts:

expression comparison_operator [ANY | ALL | SOME] (subquery)

expression [NOT] IN (subquery)

[NOT] EXISTS (subquery)

A subquery has the following restricted SELECT syntax:

(SELECT [ALL | DISTINCT] subquery_select_list
[FROM {table_name | view_name}[optimizer_hints]
[[, {table_name2 | view_name2}[optimizer_hints]
[..., {table_name16 | view_name16}[optimizer_hints]]]
[WHERE clause]
[GROUP BY clause]
[HAVING clause])

where

expression
Is a standard expression. For details, see the Expressions and Search Conditions topics.
comparison_operator
Is a standard comparison operator. For details, see the Operators topic.
ANY | SOME
Are synonymous. When used, the expression evaluates to true if the comparison is true for at least one row of subquery. The expression evaluates to false if the comparison returns no rows or if the comparison is false for all rows in the subquery. Otherwise, the expression is unknown.
ALL
When used the expression evaluates to true if the comparison returns no rows or if the comparison is true for all rows in the subquery. The expression evaluates to false if the comparison is false for at least one of the rows in the subquery. Otherwise, the expression is unknown.
DISTINCT
Includes only unique rows in the results. Cannot be used with subqueries that include a GROUP BY clause.
subquery_select_list
Is a restricted select list for use with subqueries introduced with IN or a comparison operator. It consists of one expression. If a column name is used in the WHERE clause of the outer statement, a column name in the subquery select list must be join-compatible with it.

The select list must consist of only one column name except for the EXISTS subquery, in which case an asterisk (*) is usually used in place of the single column name. Do not specify more than one column name or a column of text and image datatype; these are not allowed in subqueries.

Examples

A. Simple Subqueries

Note that the syntax for EXISTS is somewhat different from the syntax for the other keywords; it does not take an expression between WHERE and itself. In the following examples, the queries, which are semantically equivalent, illustrate the difference.

SELECT DISTINCT pub_name
FROM publishers
WHERE EXISTS
    (SELECT *
    FROM titles
    WHERE pub_id = publishers.pub_id
    AND type = 'business')

Or

SELECT distinct pub_name
FROM publishers
WHERE pub_id IN
    (SELECT pub_id
    FROM titles
    WHERE type = 'business')
B. Correlated Subquery

A correlated (or repeating) subquery depends on the outer query for its values. It is executed repeatedly, once for each row that might be selected by the outer query. Here is an example:

SELECT DISTINCT au_lname, au_fname
FROM authors
WHERE 100 IN
    (SELECT royaltyper
    FROM titleauthor
    WHERE titleauthor.au_id = authors.au_id)

The subquery in this statement cannot be evaluated independently of the outer query. It needs a value for authors.au_id, but this value changes as SQL Server examines different rows in authors.

C. Correlated Subquery with GROUP BY and HAVING Greater Than ALL

A correlated subquery can also be used in the HAVING clause of an outer query. This example finds the types of books for which the maximum advance is more than twice the average for the group.

SELECT t1.type
FROM titles t1
GROUP BY t1.type
HAVING MAX(t1.advance) >= ALL
    (SELECT 2 * AVG(t2.advance)
    FROM titles t2
    WHERE t1.type = t2.type)
D. Multiple Correlated Subqueries

This example finds the names of authors who have participated in writing at least one popular computing book.

SELECT au_lname, au_fname
FROM authors
WHERE au_id IN
    (SELECT au_id
    FROM titleauthor
    WHERE title_id IN
        (SELECT title_id
        FROM titles
        WHERE type = 'popular_comp'))

See Also

DELETE | INSERT
EXECUTE | SELECT
Expressions | UPDATE
Functions |


System Tables

System tables are tables used to store information about the system (the system catalog) or an individual database (the database catalog). The system catalog consists of system tables found only in the master database. The database catalog consists of system tables found in every database.

In SQL Server 6.0, the addition of replication and the SQL Executive has added new system tables based on the type of database used in replication and scheduling of events.

The system tables have been categorized by the types of related information:

  • Database Catalog
  • System Catalog
  • Replication Tables
  • SQL Executive


System Tables-Database Catalog

System Tables–Database Catalog

The following system tables are found within every user-defined or system database, including the master database:

Table | Description
sysalternates | Contains one row for each SQL Server user mapped to a user of the current database.
sysarticles | Contains a row for each of the articles posted by the publication server.
syscolumns | Contains one row for every column in every table and view, and a row for each parameter in a stored procedure.
syscomments | Contains entries for each view, rule, default, trigger, and stored procedure.
sysconstraints | Contains one row for each PRIMARY KEY, FOREIGN KEY, CHECK, DEFAULT, and UNIQUE constraint.
sysdepends | Contains one row for each procedure, view, or table that is referenced by a procedure, view, or trigger.
sysindexes | Contains one row for each clustered index and one row for each nonclustered index. These indexes are the result of a CREATE INDEX statement or the CREATE TABLE statement with a PRIMARY KEY or UNIQUE constraint. Additionally, sysindexes contains one row for each table that has no clustered index and one row for each table that contains text or image columns.
syslogs | Contains the transaction log and is used by SQL Server for recovery and roll forward ¾ it is for internal use only.
sysobjects | Contains one row for each database object and (in tempdb only) temporary object.
sysprocedures | Contains entries for each view, default, rule, trigger, and stored procedure.
sysprotects | Contains user permissions information ¾ entries for each GRANT and REVOKE statement that has been executed.
syspublications | Contains a row for each of the publications posted by the publication server.
sysreferences | Contains one row for each FOREIGN KEY constraint.
syssegments | Contains one row for each segment (named collection of disk pieces).
syssubscriptions | Associates the IDs of each publication event with the IDs of all subscription servers expecting to receive the data.
systypes | Contains one row for each system-supplied and each user-defined datatype.
sysusers | Contains one row for each user allowed to use the database and one row for each group.

The section that follows these tables lists all tables in alphabetical order and provides detailed information.


sysalternates (all databases)

Contains one row for each SQL Server user mapped to a user (or with an alias) of the current database. When a user tries to access a database, SQL Server looks for a valid uid entry in sysusers. If one is not found, it looks in sysalternates.suid. If the user's suid is found there, the user is treated as the database user whose suid is listed in sysalternates.altsuid.

Column | Datatype | Description
suid | smallint | Server user ID of the user being mapped.
altsuid | smallint | Server user ID of the user to whom another user is mapped.

Index

sysalternates clustered, unique on suid

Referenced by Stored Procedures

sp_addalias | sp_dropalias | sp_dropuser
sp_adduser | sp_droplogin | sp_helpuser
sp_changedbowner |  |


sysarticles (all databases)

Has a row for each of the articles posted by the publishing server.

Column | Datatype | Description
artid | int | An identity column providing a unique ID number for the article.
columns | varbinary(32) | The columns in the tables that are being published.
creation_script | varchar(127) | The schema script for the article.
del_cmd | varchar(255) | Command to execute upon delete, else construct from the log.
description | varchar(255) | Descriptive entry for the article.
dest_table | varchar(30) | Name of the destination table.
filter | int | The stored procedure ID, used for horizontal partitioning.
filter_clause | text | The WHERE clause of the article, used for horizontal filtering.
ins_cmd | varchar(255) | Command to execute upon insert, else construct from the log.
name | varchar(30) | Name associated with the article. Unique within the publication.
objid | int | Published table object ID.
pubid | int | ID of the publication to which the article belongs.
pre_creation_cmd | tinyint | A pre-creation command for drop table, delete table, or truncate: 0 None 1 Drop 2 Delete 3 Truncate
status | tinyint | Bitmap used to describe a property of the column or the parameter: 0x08 The column allows null values. 0x40 The parameter is an OUTPUT parameter. 0x80 The column is an identity column.
sync_objid | int | The ID of the table or view that represents the article definition.
type | tinyint | The type of article: 1 Log-based article 3 Log-based article with manual filter 5 Log-based article with manual view 7 Log-based article with manual filter and manual view
upd_cmd | varchar(255) | Command to execute upon update, or else construct from the log.

Index

unc1sysarticles nonclustered, unique on artid, pubid

Referenced by Stored Procedures

sp_addarticle | sp_droparticle | sp_helparticlecolumns
sp_addsubscription | sp_droppublication | sp_helppublication
sp_articlecolumn | sp_dropsubscription | sp_helpsubscription
sp_changearticle | sp_enumfullsubscribers | sp_subscribe
sp_changesubscription | sp_helparticle | sp_unsubscribe
sp_changesubstatus |  |


syscolumns (all databases)

For SQL Server 6.5 information, see syscolumns System Table in What's New for SQL Server 6.5.

Contains one row for every column in every table and view, and a row for each parameter in a stored procedure.

Column | Datatype | Description
id | int | ID of the table to which this column belongs or of the stored procedure with which this parameter is associated.
number | smallint | Subprocedure number when the procedure is grouped (0 for nonprocedure entries).
colid | tinyint | Column ID.
status | tinyint | Bitmap used to describe a property of the column or the parameter: 0x08 The column allows null values. 0x40 The parameter is an OUTPUT parameter. 0x80 The column is an identity column.
type | tinyint | Physical storage type; copied from systypes.
length | tinyint | Physical length of data; copied from systypes or supplied by the user.
offset | smallint | Offset into the row where this column appears; if negative, variable-length column.
usertype | smallint | User type ID; copied from systypes.
cdefault | int | ID of the stored procedure that generates the default value for this column.
domain | int | ID of the stored procedure that contains the rule for this column.
name | varchar(30) | Column name.
printfmt | varchar(255) | Reserved.
prec | tinyint | Level of precision for this column.
scale | tinyint | Scale for this column.

Index

syscolumns clustered, unique on id, number, colid

Referenced by Stored Procedures

sp_articlecolumn | sp_help | sp_special_columns
sp_bindefault | sp_helparticle | sp_sproc_columns
sp_bindrule | sp_helparticlecolumns | sp_statistics
sp_column_privileges | sp_helprotect | sp_tables
sp_columns | sp_pkeys | sp_unbindefault
sp_droptype | sp_rename | sp_unbindrule
sp_fkeys |  |


syscomments (all databases)

Contains entries for each view, rule, default, trigger, CHECK constraint, DEFAULT constraint, and stored procedure. The text field contains the original SQL definition statements. Since text is often longer than 255 characters, entries often span rows. Each object can occupy as many as 255 rows.

Column | Datatype | Description
id | int | Object ID to which this text applies.
number | smallint | Number within procedure grouping, if grouped. 0 for nonprocedure entries.
colid | tinyint | Row sequence number for object definitions longer than 255 characters.
texttype | smallint | 0 User-supplied comment (users can add entries that describe an object or column) 1 System-supplied comment (for views, rules, defaults, triggers, and stored procedures) 4 Encrypted comments (applies to procedures, triggers and views)
language | smallint | Reserved.
text | varchar(255) | Actual text of the SQL definition statement.

Index

syscomments clustered, unique on id, number, colid, texttype

Referenced by Stored Procedures

sp_helpconstraint | sp_helpextendedproc | sp_helptext


sysconstraints (all databases)

Contains mappings of constraints to the objects that own the constraints.

Column | Datatype | Description
constid | int | Constraint ID.
id | int | ID of the table that owns the constraint.
colid | tinyint | ID of the column on which the constraint is defined. 0 if a table constraint.
spare1 | tinyint | Reserved.
status | int | 1 PRIMARY KEY constraint 2 UNIQUE KEY constraint 3 FOREIGN KEY constraint 4 CHECK constraint 5 DEFAULT constraint 16 Column-level constraint 32 Table-level constraint
actions | int | Reserved.
error | int | Reserved.

Index

csysconstraints clustered located on id, colid

unc1sysconstraints nonclustered, unique on constid


sysdepends (all databases)

Contains one row for each procedure, view, or table that is referenced by a procedure, view, or trigger.

Column | Datatype | Description
id | int | Object ID.
number | smallint | Procedure number.
depid | int | Dependent object ID.
depnumber | smallint | Dependent procedure number.
depdbid | smallint | Reserved.
depsiteid | smallint | Reserved.
status | smallint | Internal status information.
selall | bit | On if the object is used in a SELECT * statement.
resultobj | bit | On if the object is being updated.
readobj | bit | On if the object is being read.

Index

sysdepends clustered, ignore duplicate key, unique on id, number, depid, depnumber, depdbid, depsiteid

Referenced by Stored Procedures

sp_depends | sp_rename


sysindexes (all databases)

For SQL Server 6.5 information, see sysindexes System Table in What's New for SQL Server 6.5.

Contains one row for each clustered index and one row for each nonclustered index. These indexes are the result of a CREATE INDEX statement or the CREATE TABLE statement with a PRIMARY KEY or UNIQUE constraint. Additionally, sysindexes contains one row for each table that has no clustered index and one row for each table that contains text or image columns.

Column | Datatype | Description
name | varchar(30) | Name of table (for indid = 0 or 255). Otherwise, name of index.
id | int | ID of table (for indid = 0 or 255). Otherwise, ID of table to which the index belongs.
indid | smallint | ID of index: 0 Table 1 Clustered index >1 Nonclustered 255 Entry for tables that have text or image data
dpages | int | For indid = 0 or indid = 1, dpages is the count of used data-only pages. For indid = 255, rows is set to 0. Otherwise, dpages is the count of leaf-level index pages.
reserved | int | For indid = 0 or indid = 1, reserved is the total of pages allocated for all indexes on the table and the data pages. For indid = 255, reserved is the total pages allocated for text or image data. Otherwise, reserved is the total count of pages allocated only for this index.
used | int | For indid = 0 or indid = 1, used is the total count of pages used for all indexes on the table and the data pages. For indid = 255, used is the total pages used for text or image data. Otherwise, used is the total count of pages used only for this index.
rows | int | The data-level row count based on indid = 0 or indid = 1. This value is repeated for indid > 1. For indid = 255, rows is set to 0.
first | int | Pointer to first data or leaf page.
root | int | For indid >= 1 and < 255, root is the pointer to the root page. For indid = 0 or indid = 255, root is the pointer to the last page.
distribution | int | Pointer to distribution page (if entry is an index).
OrigFillFactor | tinyint | The original fillfactor value used when the index was created. This value is not maintained; however, it can be helpful if you need to re-create an index and do not remember what fillfactor was used.
segment | smallint | Number of segment in which this object resides.
status | smallint | Internal system-status information: 1 Cancel command if attempt to insert duplicate key 2 Unique index 4 Cancel command if attempt to insert duplicate row 16 Clustered index 64 Index allows duplicate rows 2048 Index used to enforce PRIMARY KEY constraint 4096 Index used to enforce UNIQUE constraint
rowpage | smallint | Maximum count of rows per page.
minlen | smallint | Minimum size of a row.
maxlen | smallint | Maximum size of a row.
maxirow | smallint | Maximum size of a nonleaf index row.
keycnt | smallint | Number of keys.
keys1 | varbinary(255) | Description of key columns (if entry is an index).
keys2 | varbinary(255) | Description of key columns (if entry is an index).
soid | tinyint | Sort order ID that the index was created with. 0 if there is no character data in the keys.
csid | tinyint | Character set ID that the index was created with. 0 if there is no character data in the keys.

Index

sysindexes clustered, unique on id, indid

Referenced by Stored Procedures

sp_dropsegment | sp_helplog | sp_rename
sp_fkeys | sp_helpsegment | sp_spaceused
sp_helpconstraint | sp_pkeys | sp_special_columns
sp_helpindex | sp_placeobject | sp_statistics


syslogs (all databases)

Contains the transaction log. It is used by SQL Server for recovery and roll forward. It is for internal use only.

You cannot delete from, insert into, or update syslogs.

Column | Datatype | Description
xactid | binary(6) | Transaction ID
op | tinyint | Update-operation number

Index

This table does not have any indexes.


sysobjects (all databases)

Contains one row for each object (constraint, default, log, rule, stored procedure, and so on) created within a database. In tempdb only, this table includes a row for each temporary object.

Column | Datatype | Description
name | varchar(30) | Object name.
id | int | Object ID.
uid | smallint | User ID of owner object.
type | char(2) | One of the following object types: C CHECK constraint D Default or DEFAULT constraint F FOREIGN KEY constraint K PRIMARY KEY or UNIQUE constraint L Log P Stored procedure R Rule RF Stored procedure for replication S System table TR Trigger U User table V View X Extended stored procedure
userstat | smallint | Application-dependent type information.
sysstat | smallint | Internal-status information.
indexdel | smallint | Index delete count (incremented if an index is deleted).
schema | smallint | Count of changes in schema of a given object (incremented if a rule or default is added).
refdate | datetime | Reserved for future use.
crdate | datetime | Indicates the date that the object was created.
version | datetime | Reserved for future use.
deltrig | int | Stored-procedure ID of a delete trigger.
instrig | int | Stored-procedure ID of an insert trigger.
updtrig | int | Stored-procedure ID of an update trigger.
seltrig | int | Reserved.
category | int | Used for publication, constraints, and identity.
cache | smallint | Reserved.

Index

sysobjects clustered, unique on id

ncsysobjects nonclustered, unique on name, uid

Referenced by Stored Procedures

sp_addarticle | sp_droptype | sp_rename
sp_bindefault | sp_dropuser | sp_replica
sp_bindrule | sp_fkeys | sp_spaceused
sp_changearticle | sp_help | sp_sproc_columns
sp_changesubstatus | sp_helparticle | sp_statistics
sp_column_privileges | sp_helpconstraint | sp_stored_procedures
sp_columns | sp_helpextendedproc | sp_table_privileges
sp_depends | sp_helprotect | sp_tables
sp_droparticle | sp_pkeys | sp_unbindefault
sp_dropgroup | sp_placeobject | sp_unbindrule


sysprocedures (all databases)

Contains entries for each view, default, rule, trigger, CHECK constraint, DEFAULT constraint, and stored procedure. The plan or sequence tree for each object is stored in binary form. If the sequence tree doesn't fit in one entry, it is put into more than one row. The sequence field identifies the sub-rows.

Column | Datatype | Description
type | smallint | Object type: 1 Entry describes a plan (reserved) 2 Entry describes a tree
id | int | Object ID.
sequence | smallint | Sequence number if more than one row is used to describe this object.
status | smallint | Internal system status.
number | smallint | Subprocedure number when the procedure is grouped (0 for nonprocedure entries).

Index

sysprocedures clustered, unique on id, number, type, sequence

Referenced by Stored Procedures

sp_sproc_columns | sp_stored_procedures


sysprotects (all databases)

For SQL Server 6.5 information, see sysprotects System Table in What's New for SQL Server 6.5.

Contains user permissions information ¾ entries for each GRANT and REVOKE statement that has been executed.

Column | Datatype | Description
id | int | ID of object to which this permission applies.
uid | smallint | ID of user or group to which this permission applies.
action | tinyint | One of the following permissions: 26 REFERENCES 193 SELECT 195 INSERT 196 DELETE 197 UPDATE 198 CREATE TABLE 203 CREATE DATABASE 207 CREATE VIEW 222 CREATE PROCEDURE 224 EXECUTE 228 DUMP DATABASE 233 CREATE DEFAULT 235 DUMP TRANSACTION 236 CREATE RULE
protecttype | tinyint | Either 205 (grant) or 206 (revoke).
columns | varbinary(32) | Bitmap of columns to which this SELECT or UPDATE permission applies. Bit 0 indicates all columns; bit 1 means permission applies to that column; NULL means no information.

Index

sysprotects clustered on id, uid, action

Referenced by Stored Procedures

sp_column_privileges | sp_helprotect | sp_table_privileges
sp_dropgroup | sp_stored_procedures | sp_tables
sp_dropuser |  |


syspublications (all databases)

Contains a row for each of the publications posted by the publishing server.

Column | Datatype | Description
description | varchar(255) | Descriptive entry for the publication.
name | varchar(30) | Unique name associated with the publication.
pubid | int | An identity column providing a unique ID number for the publication.
repl_freq | tinyint | 0 indicates transaction based; 1 indicates scheduled table refresh.
restricted | bit | Sets the security option for the publication. 1 indicates restricted; 0 indicates unrestricted. 0 is the default.
status | tinyint | 0 indicates log-based; 1 indicates not log-based; default is log-based, 0 is the default.
sync_method | tinyint | 0 indicates native bcp; 1 indicates char bcp.
taskid | int | Scheduled task ID.

Index

unc1syspublications nonclustered, unique on pubid

unc2syspublications nonclustered, unique on name

Referenced by Stored Procedures

sp_addarticle | sp_changesubstatus | sp_helparticle
sp_addpublication | sp_dboption | sp_helparticlecolumns
sp_addsubscription | sp_droparticle | sp_helppublication
sp_articlecolumn | sp_droppublication | sp_helpsubscription
sp_changearticle | sp_dropsubscription | sp_subscribe
sp_changepublication | sp_enumfullsubscribers | sp_unsubscribe
sp_changesubscription |  |


sysreferences (all databases)

Contains mappings of FOREIGN KEY constraint definitions.

Column | Datatype | Description
constid | int | Constraint ID
fkeyid | int | ID of referencing table
fkeydbid | smallint | Reserved
rkeyid | int | ID of referenced table
rkeydbid | smallint | Reserved
rkeyindid | smallint | Reserved
keycnt | smallint | Number of columns in key
fkey1 | tinyint | Column ID of referencing column
fkey2 | tinyint | Column ID of referencing column
fkey3 | tinyint | Column ID of referencing column
fkey4 | tinyint | Column ID of referencing column
fkey5 | tinyint | Column ID of referencing column
fkey6 | tinyint | Column ID of referencing column
fkey7 | tinyint | Column ID of referencing column
fkey8 | tinyint | Column ID of referencing column
fkey9 | tinyint | Column ID of referencing column
fkey10 | tinyint | Column ID of referencing column
fkey11 | tinyint | Column ID of referencing column
fkey12 | tinyint | Column ID of referencing column
fkey13 | tinyint | Column ID of referencing column
fkey14 | tinyint | Column ID of referencing column
fkey15 | tinyint | Column ID of referencing column
fkey16 | tinyint | Column ID of referencing column
rkey1 | tinyint | Column ID of referenced column
rkey2 | tinyint | Column ID of referenced column
rkey3 | tinyint | Column ID of referenced column
rkey4 | tinyint | Column ID of referenced column
rkey5 | tinyint | Column ID of referenced column
rkey6 | tinyint | Column ID of referenced column
rkey7 | tinyint | Column ID of referenced column
rkey8 | tinyint | Column ID of referenced column
rkey9 | tinyint | Column ID of referenced column
rkey10 | tinyint | Column ID of referenced column
rkey11 | tinyint | Column ID of referenced column
rkey12 | tinyint | Column ID of referenced column
rkey13 | tinyint | Column ID of referenced column
rkey14 | tinyint | Column ID of referenced column
rkey15 | tinyint | Column ID of referenced column
rkey16 | tinyint | Column ID of referenced column

Index

ucsysreferences clustered unique on constid

nc1sysreferences nonclustered fkeyid

nc2sysreferences nonclustered rkeyid

Referenced by Stored Procedures

sp_fkeys | sp_helpconstraint


syssegments (all databases)

Contains one row for each segment (named collection of disk fragments). When SQL Server is installed, this table contains three entries: segment 0 (system) for system tables, segment 1 (default) for other objects, and 2 (log segment) for the transaction log (the syslogs table). All entries in sysusages contain both of these segments and their maps.

Column | Datatype | Description
segment | smallint | Segment number
name | varchar(30) | Segment name, used internally
status | smallint | Default segment

Index

This table does not have any indexes.

Referenced by Stored Procedures

sp_addsegment | sp_helpdb | sp_helpsegment
sp_dropsegment | sp_helpindex | sp_placeobject
sp_extendsegment |  |


syssubscriptions (all databases)

Associates the IDs of published articles with the IDs of all subscription servers expecting to receive the data.

Column | Datatype | Description
artid | int | Unique ID of an article
srvid | smallint | Server ID of the subscription server
dest_db | varchar(30) | Name of the destination database
status | tinyint | Status: 0 Inactive 1 Subscribed 2 Active
sync_type | tinyint | Type 8 synchronization: 0 Manual 1 Automatic 2 None
timestamp | timestamp | Initial time of subscription

Index

unc1syssubscriptions nonclustered, unique on artid, srvid

Referenced by Stored Procedures

sp_addsubscription | sp_droppublication | sp_helppublication
sp_changesubscription | sp_dropsubscription | sp_helpsubscription
sp_changesubstatus | sp_enumfullsubscribers | sp_subscribe
sp_droparticle | sp_helparticle | sp_unsubscribe


systypes (all databases)

Contains one row for each system-supplied and each user-defined datatype. Domains (defined by rules) and defaults are given if they exist. The rows that describe system-supplied datatypes cannot be altered. The system-supplied datatypes and their ID numbers (the contents of the name and type fields, respectively) are as follows:

Column | Datatype | Description
uid | smallint | User ID of datatype creator.
usertype | smallint | User type ID.
variable | bit | Variable-length datatype is 1, otherwise, 0.
allownulls | bit | Indicates the default nullability for this datatype. If nullability is specified with the CREATE or ALTER TABLE statement then that value will override the default nullability for this datatype.
type | tinyint | Physical storage datatype.
length | tinyint | Physical length of datatype.
tdefault | int | ID of stored procedure that generates default for this datatype.
domain | int | ID of stored procedure that contains integrity checks for this datatype.
name | varchar(30) | Datatype name.
printfmt | varchar(255) | Reserved.
prec | tinyint | Level of precision for this datatype.
scale | tinyint | Scale for this datatype. Scale is based on precision.

Index

systypes clustered, unique on name

ncsystypes nonclustered, unique on usertype

Referenced by Stored Procedures

sp_addtype | sp_droptype | sp_special_columns
sp_bindefault | sp_dropuser | sp_sproc_columns
sp_bindrule | sp_help | sp_unbindefault
sp_columns | sp_rename | sp_unbindrule
sp_datatype_info |  |


sysusers (all databases)

Contains one row for each user allowed to use the database and one row for each group.

When SQL Server is initially installed, master..sysusers contains three entries: dbo, with an suid of 1 and a uid of 1; guest, with a suid of -1 and uid of 2; and public, with an suid of -2 and a uid of 0. The sysusers table in the model database (and thus in all user databases) initially contains two entries: dbo and public.

The guest user provides access to the database to users not explicitly listed in sysusers, with a restricted set of permissions. The guest entry in master means that any user with an account on SQL Server (that is, with an entry in syslogins) can access master.

The public user refers to all users. The keyword PUBLIC is used with the GRANT and REVOKE statements to signify that permission is granted to or taken away from all users.

Column | Datatype | Description
suid | smallint | Server user ID, copied from syslogins. A suid of 1 is the system administrator, -1 is a guest account.
uid | smallint | User ID, unique in this database. A uid 1 is the database owner.
gid | smallint | Group ID to which this user belongs. If uid = gid, this entry defines a group. The public group has a suid equal to -2. All other groups have a suid equal to -gid.
name | varchar(30) | Username or group name, unique in this database.
environ | varchar(255) | Reserved.

Index

sysusers clustered, unique on suid

ncsysusers1 nonclustered, unique on name

ncsysusers2 nonclustered, unique on uid

Referenced by Stored Procedures

sp_addalias | sp_depends | sp_helpgroup
sp_addgroup | sp_dropgroup | sp_helprotect
sp_adduser | sp_droplogin | sp_helpuser
sp_changedbowner | sp_droptype | sp_stored_procedures
sp_changegroup | sp_dropuser | sp_table_privileges
sp_column_privileges | sp_helparticle | sp_tables
sp_dboption |  |


System Tables - System Catalog

System Tables–System Catalog

These system tables are found only within the master database:

Table | Description
syscharsets | Contains one row for each character set and sort order defined for use by SQL Server.
sysconfigures | Contains one row for each user-settable configuration option.
syscurconfigs | Contains an entry for each of the configuration options, as in sysconfigures, but contains the current values and four entries that describe the configuration structure.
sysdatabases | Contains one row for each database on SQL Server.
sysdevices | Contains one row for each disk dump device, diskette dump device, tape dump device, and database device.
syslanguages | Contains one row for each language known to SQL Server. Although U.S. English is omitted, it is always available to SQL Server.
syslocks | Contains information about active locks.
syslogins | Contains one row for each valid SQL Server user account.
sysmessages | Contains one row for each system error or warning that can be returned by SQL Server.
sysprocesses | Contains information about SQL Server processes.
sysremotelogins | Contains one row for each remote user who is allowed to call remote stored procedures on this SQL Server.
sysservers | Contains one row for each remote SQL Server on which this SQL Server can call remote stored procedures.
sysusages | Contains one row for each disk-allocation piece assigned to a database.


syscharsets (master database only)

Contains one row for each character set and sort order defined for use by SQL Server. One of the sort orders is marked in sysconfigures as the default sort order, which is the only one actually in use.

Column | Datatype | Description
type | smallint | Type of entity this row represents. 1001 is a character set, 2001 is a sort order.
id | tinyint | Unique ID for the character set or sort order. Note that sort orders and character sets cannot share the same ID number. ID numbers 0 through 200 are reserved.
csid | tinyint | If the row represents a character set, this field is unused. If the row represents a sort order, this field is the ID of the character set that sort order is built on. It is assumed that a character set row with this ID exists in this table.
status | smallint | Internal system status information bits.
name | varchar(30) | Unique name for the character set or sort order. This field must contain only the letters A-Z or a-z, digits 0 - 9, and underscores(_). It must begin with a letter.
description | varchar(255) | Optional description of the features of the character set or sort order.
definition | image | Internal definition of the character set or sort order. The structure of the data in this field depends on the type.

Index

csyscharsets clustered, unique on id

ncsyscharsets nonclustered, unique located on name

Referenced by Stored Procedures

sp_helpsort


sysconfigures (master database only)

Contains one row for each configuration option that can be set by a user. The sysconfigures table contains the configuration options that were defined before the latest SQL Server startup, plus any dynamic configuration options that were set since the latest SQL Server startup.

Column | Datatype | Description
config | smallint | Configuration variable number
value | int | User-modifiable value for the variable (being used by SQL Server only if RECONFIGURE has been executed)
comment | varchar(255) | Explanation of the configuration option
status | smallint | Bitmap indicating the status for the option: 1 Dynamic (The variable takes effect when the RECONFIGURE statement is executed.) 2 Advanced (The variable is displayed only when the 'show advanced option' is set.)

Index

sysconfigures clustered, unique on config

Referenced by Stored Procedures

sp_configure


syscurconfigs (master database only)

This table contains an entry for each of the configuration options, as does sysconfigures, but syscurconfigs contains the current values. In addition, it contains four entries that describe the configuration structure. The syscurconfigs table is built dynamically when queried by a user. For details, see the sysconfigures topic.

Referenced by Stored Procedures

sp_configure | sp_helpsort


sysdatabases (master database only)

Contains one row for each database on SQL Server. When SQL Server is initially installed, sysdatabases contains entries for the master database, the model database, and the tempdb database. The status column values are additive when more than one option is set or database condition applies.

Column | Datatype | Description
name | varchar(30) | Name of the database.
dbid | smallint | Database ID.
suid | smallint | Server user ID of database creator.
mode | smallint | Used internally for locking a database while it is being created.
status | smallint | Status bits, some of which can be set by the user with the sp_dboption system stored procedure (READ ONLY, DBO USE ONLY, SINGLE USER, and so on): 2 Database is in transition 4 select into/bulkcopy; set with sp_dboption 8 trunc. log on chkpt; set with sp_dboption 16 no chkpt on recovery; set with sp_dboption 32 Crashed while the database was being loaded; instructs recovery not to proceed 64 Database not recovered yet 128 Database is in recovery 256 Database is suspect; cannot be opened or used in its present state 1024 read only; set with sp_dboption 2048 dbo use only; set with sp_dboption 4096 single user; set with sp_dboption 8192 Database being checkpointed 16384 ANSI null default; set with sp_dboption 32768 Emergency mode
version | smallint | Internal version number of the SQL Server code with which the database was created.
logptr | int | Pointer to the transaction log.
crdate | datetime | Creation date.
dumptrdate | datetime | Date of the last DUMP TRANSACTION.
category | int | Used for publication and subscription databases.

Index

sysdatabases clustered, unique on name

ncsysdatabases nonclustered, unique on dbid

Referenced by Stored Procedures

sp_addlogin | sp_dboption | sp_helpdb
sp_addpublication | sp_defaultdb | sp_logdevice
sp_changearticle | sp_devoption | sp_renamedb
sp_changedbowner | sp_dropdevice | sp_spaceused
sp_changepublication | sp_droplogin | sp_tables
sp_databases |  |


sysdevices (master database only)

Contains one row for each disk dump device, diskette dump device, tape dump device, and database device. When SQL Server is installed initially, sysdevices has four entries: one for the MASTER database device (for databases), one for a disk dump device, and two for diskette dump devices.

Column | Datatype | Description
low | int | First virtual page number on a database device (not used for dump devices).
high | int | Last virtual page number on a database device (not used for dump devices).
status | smallint | Bitmap indicating the type of device: 1 Default disk 2 Physical disk 4 Logical disk 8 Skip header 16 Dump device 32 Serial writes 64 Device mirrored 128 Reads mirrored (reserved) 256 Half-mirror only (reserved) 512 Mirror enabled 4096 Read Only 8192 Deferred
cntrltype | smallint | Controller type: 0 Non CD-ROM database device 2 Disk dump device 3 - 4 Diskette dump device 5 Tape dump device 6 Named pipe device
name | varchar(30) | Logical name of the dump device or database device.
phyname | varchar(127) | Name of the physical device.
mirrorname | varchar(127) | Name of the mirror device.
stripeset | varchar(30) | Reserved for future use.

Index

sysdevices clustered, unique on name

Referenced by Stored Procedures

sp_addsegment | sp_devoption | sp_helpdb
sp_addumpdevice | sp_diskdefault | sp_helpdevice
sp_configure | sp_dropdevice | sp_helplog
sp_dbinstall | sp_dropsegment | sp_helpsegment
sp_dbremove | sp_extendsegment | sp_logdevice


syslanguages (master database only)

Contains one row for each language known to SQL Server. Although U.S. English is not in syslanguages, it is always available to SQL Server.

Column | Datatype | Description
langid | smallint | Unique language ID
dateformat | char(3) | Date order (for example, dmy)
datefirst | tinyint | First day of the week ¾ 1 for Monday, 2 for Tuesday, and so on through 7 for Sunday
upgrade | int | SQL Server version of last upgrade for this language
name | varchar(30) | Official language name (for example, français)
alias | varchar(30) | Alternate language name (for example, french)
months | varchar(251) | Comma-separated list of full-length month names, in order from January through December, with each name containing as many as 20 characters
shortmonths | varchar(119) | Comma-separated list of short-month names, in order from January through December, with each name containing as many as 9 characters
days | varchar(216) | Comma-separated list of day names, in order from Monday through Sunday, with each name containing as many as 30 characters

Index

csyslanguages clustered, unique on langid

nc1syslanguages nonclustered, unique on name

nc2syslanguages nonclustered, unique on alias

Referenced by Stored Procedures

sp_configure | sp_helplanguage | sp_setlangalias
sp_droplanguage |  |


syslocks (master database only)

Contains information about active locks. The syslocks system table is not a standard table. Rather, it is built dynamically when queried by a user. Updates to syslocks are not allowed. The type values are additive when more than one lock is in effect.

Column | Datatype | Description
id | int | Table ID
dbid | smallint | Database ID
page | int | Page number
type | smallint | Type of lock: 1 Exclusive table lock 2 Shared table lock 3 Exclusive intent lock (will do page locking on indicated pages) 4 Shared intent lock 5 Exclusive page lock 6 Shared page lock 7 Update page lock (changes to exclusive lock if page is actually modified) 8 Exclusive extent lock 9 Update extent lock 11 Next extent lock 12 Previous extent lock Any of the above lock types can appear with 256 (0x100) added to them, indicating that the lock is blocking another user. 257 Blocking exclusive table lock 265 Blocking update extent lock
spid | smallint | ID of process that holds the lock

Index

This table does not have any indexes.

Referenced by Stored Procedures

sp_lock


syslogins (master database only)

Contains one row for each valid SQL Server user account. When SQL Server is installed initially, syslogins contains one entry, in which the name is sa, the suid is 1, and the password is NULL. It also contains an entry named probe with a NULL password. The login probe and the user probe exist for the two-phase commit process.

Column | Datatype | Description
suid | smallint | Server user ID
status | smallint | Reserved
accdate | datetime | Reserved
totcpu | int | Reserved
totio | int | Reserved
spacelimit | int | Reserved
timelimit | int | Reserved
resultlimit | int | Reserved
dbname | varchar(30) | Name of user's default database when connection is established
name | varchar(30) | Login ID of user
password | varchar(30) | Encrypted password of user (may be NULL)
language | varchar(30) | User's default language (NULL for us_english)

Index

syslogins clustered, unique on suid

ncsyslogins nonclustered, unique on name

Referenced by Stored Procedures

sp_addalias | sp_changedbowner | sp_helpdb
sp_addlogin | sp_defaultdb | sp_helpuser
sp_addremotelogin | sp_defaultlanguage | sp_password
sp_adduser | sp_droplogin |


sysmessages (master database only)

Contains one row for each system error or warning that can be returned by SQL Server. SQL Server displays the error description on the user's screen.

Column | Datatype | Description
error | int | Unique error number
severity | smallint | Severity level of the error
dlevel | smallint | Reserved. For internal use only.
description | varchar(255) | Explanation of the error with placeholders for parameters
langid | smallint | Language

Index

sysmessages clustered on error, dlevel

ncsysmessages nonclustered, unique on error, dlevel, langid

Referenced by Stored Procedures

sp_addmessage | sp_droplanguage | sp_dropmessage


sysprocesses (master database only)

For SQL Server 6.5 information, see sysprocesses System Table in What's New for SQL Server 6.5.

Contains information about SQL Server processes. The sysprocesses system table is not a standard table. Rather, it is built dynamically when queried by a user. Updates to sysprocesses are not allowed. Use the KILL statement to cancel a process.

Column | Datatype | Description
spid | smallint | Process ID
kpid | smallint | Windows NT thread ID
status | char(10) | Process ID status (for example, runnable, sleeping, and so on)
suid | smallint | Server user ID of user who executed command
hostname | char(10) | Name of workstation
program_name | char(16) | Name of application program
hostprocess | char(8) | Workstation process ID number
cmd | char(16) | Command currently being executed
cpu | int | Cumulative CPU time for process
physical_io | int | Cumulative disk reads and writes for process
memusage | int | Number of 2K pages of the procedure cache that are currently allocated to the process
blocked | smallint | Process ID of blocking process, if any
waittype | binary | Reserved
dbid | smallint | Database ID
uid | smallint | ID of user who executed command
gid | smallint | Group ID of user who executed command

Index

This table does not have any indexes.

Referenced by Stored Procedures

sp_dboption | sp_who


sysremotelogins (master database only)

Contains one row for each remote user who is allowed to call remote stored procedures on this SQL Server.

Column | Datatype | Description
remoteserverid | smallint | Remote server identification
remoteusername | varchar(30) | User's login name on a remote server
suid | smallint | Local server user ID
status | smallint | Bitmap of options

Index

csysremotelogins clustered, unique on remoteserverid, remoteusername

Referenced by Stored Procedures

sp_addremotelogin | sp_dropremotelogin | sp_dropsubscriber
sp_addsubscriber | sp_dropserver | sp_remoteoption


sysservers (master database only)

Contains one row for each remote SQL Server on which this SQL Server can call remote stored procedures.

Column | Datatype | Description
srvid | smallint | ID number (for local use only) of the remote server
srvstatus | smallint | Bitmap of options
srvname | varchar(30) | Name of the server
srvnetname | varchar(32) | Reserved (currently the same as srvname)
topologyx | int | Used by the SQL Enterprise Manager server topology diagram
topologyy | int | Used by the SQL Enterprise Manager server topology diagram

Index

csysservers clustered, unique on srvid

ncsysservers nonclustered, unique on srvname

Referenced by Stored Procedures

sp_addpublisher | sp_dropremotelogin | sp_helpremotelogin
sp_addremotelogin | sp_dropserver | sp_helpserver
sp_addserver | sp_dropsubscriber | sp_helpsubscriberinfo
sp_addsubscriber | sp_dropsubscription | sp_helpsubscription
sp_addsubscription | sp_enumfullsubscribers | sp_remoteoption
sp_changesubscriber | sp_helparticle | sp_serveroption
sp_changesubscription | sp_helpdistributor | sp_subscribe
sp_changesubstatus | sp_helppublication | sp_unsubscribe
sp_droppublisher |  |


sysusages (master database only)

Contains one row for each disk-allocation piece assigned to a database. Each database contains a specified number of database (logical) page numbers. Each disk piece includes segments 0 and 1.

When the CREATE DATABASE statement is executed, SQL Server scans the disk(s) to find available disk-allocation pieces. One or more contiguous disk-allocation pieces are assigned to the database, and the mapping is recorded in sysusages.

Column | Datatype | Description
dbid | smallint | Database ID
segmap | int | Bitmap of possible segment assignments
lstart | int | First database (logical) page number
size | int | Number of contiguous database (logical) pages
vstart | int | Starting virtual page number

Index

sysusages clustered, unique on dbid, lstart

ncsysusages nonclustered, unique on vstart

Referenced by Stored Procedures

sp_addsegment | sp_dropsegment | sp_helpsegment
sp_databases | sp_extendsegment | sp_logdevice
sp_dbinstall | sp_helpdb | sp_remove
sp_devoption | sp_helplog | sp_spaceused
sp_dropdevice |  |


System Tables - Replication Tables

System Tables–Replication Tables

Publication databases use the following tables (part of the database catalog) for replication purposes:

Table | Description
sysarticles | Has a row for each of the articles posted by the publication server.
sysobjects | Has a category field set by replication for each object marked for replication. This is set when an article is created and when an article is initially subscribed to.
syspublications | Has a row for each of the publications posted by the publication server.
syssubscriptions | Associates the IDs of published articles with the IDs of all subscription servers expecting to receive the data.

Destination databases maintain replication information in the MSlast_job_info table:

Table | Description
MSlast_job_info | Contains the job ID of the last job (from a batch) that was successfully applied. (A job is a complete transaction from the transaction log of the publication database.) Also, if present, contains information about an article that has paused distribution while waiting for manual synchronization.

Distribution databases contain the following tables dedicated to replication:

Table | Description
MSjob_commands | Contains one entry for each command associated with a transaction in the MSjobs table. One transaction can contain many commands.
MSjob_subscriptions | Associates a subscriber with a particular article. (This is actually subscriber-side information that is maintained in the distribution database.)
MSjobs | Contains the actual transactions. There is one entry for every transaction stored in the distribution database.
MSsubscriber_info | Contains information used by SQL Executive for passing jobs.
MSsubscriber_jobs | Associates each subscriber with the command that subscriber needs to receive.
MSsubscriber_status | Contains status information for the individual batches of transactions sent to subscribers.

All servers participating in replication keep some replication-related data in the system catalog found in the master database:

Table | Description
sysservers | Used by both the publication and subscription servers. The srvstatus column has status bits set for RPC, PUBLISH, SUBSCRIBE, and DISTRIBUTE. A publication server uses all four options to register the subscribing servers that can receive its publications. A subscription server uses only the RPC option to register the publication servers that it authorizes to send it publications. The options can be reviewed by running sp_helpserver and viewing the status column.
sysdatabases | Used by the publication server. When set up for replication, the category column defines whether a database is permitted to publish.

For more information about the tables used by replication, see the specific table, listed separately.


MSjob_commands (distribution database only)

Distribution database table. Contains one entry for each command associated with a transaction in the MSjobs table. One transaction can contain many commands.

Column | Datatype | Description
publisher_id | smallint | The local server ID of the publishing server.
publisher_db | varchar(30) | The name of the published database.
job_id | int | The job ID.
command_id | int | The command ID.
art_id | int | The article ID.
incomplete | bit | Indicates whether this is the full command, or if the command is broken into separate entries.
command | varchar(255) | The actual command or command fragment.

Index

ucMSjob_commands clustered, unique on publisher_db, publisher_id, job_id, command_id

Referenced by Stored Procedures

sp_replcleanup


MSjob_subscriptions (distribution database only)

Distribution database table. Associates a subscriber with a particular article. (This is actually subscriber-side information maintained in the distribution database.)

Column | Datatype | Description
publisher | varchar(30) | The name of the publishing server.
publisher_id | smallint | The local server ID of the publishing server.
publisher_db | varchar(30) | The name of the published database.
subscriber | varchar(30) | The name of the subscriber.
subscriber_id | smallint | The local server ID of the subscribing server.
art_id | int | The article ID.
subscriber_db | varchar(30) | The name of the database on the subscribing server.
status | tinyint | Status: 0 Inactive 1 Subscribed 2 Active
ts | binary(8) | The timestamp of the published subscription.
status | tinyint | Reserved.

Index

ucMSsubscriptions clustered, unique on publisher_db, publisher_id, art_id, subscriber_id


MSjobs (distribution database only)

Distribution database table. Contains the actual transactions. There is one entry for every transaction that is stored in the distribution database.

Column | Datatype | Description
publisher_id | smallint | The local server ID of the publishing server.
publisher_db | varchar(30) | The name of the published database.
job_id | int | The job ID.
type | tinyint | The transaction type: 0 SQL command 1 Noop command 2 SQL script 3 Native bcp command 4 Character bcp command 5 Manual sync
xactid_page | int | If the event is log based, the page of the transaction.
xactid_row | smallint | If the event is log based, the row of the transaction.
xactid_ts | binary(8) | The timestamp of the transaction.
entry_time | datetime | The time the row was added to the table.

Index

ucMSjobs clustered, unique on publisher_db, publisher_id, job_id

Referenced by Stored Procedures

sp_replcleanup


MSlast_job_info (destination database only)

Destination database table. Contains the job ID of the last job (from a batch) that was successfully applied. (A job is a complete transaction from the transaction log of the publishing database.) Also, if present, contains the name of a job that has paused distribution while waiting for manual synchronization.

Column | Datatype | Description
publisher | varchar(30) | The name of the publishing server associated with the job ID.
publisher_db | varchar(30) | The name of the published database.
job_id | int | The job ID of the last job (from a batch) that was successfully applied.
publication | varchar(30) | The source publication.
article | varchar(30) | The source article.
description | varchar(100) | A description provided by the distribution process.

Index

This table does not have any indexes.

Referenced by Stored Procedures

sp_replsync


MSsubscriber_info (distribution database only)

For SQL Server 6.5 information, see MSsubscriber_info Table in What's New for SQL Server 6.5.

Distribution database table. Contains information used by SQL Executive for passing jobs.

Column | Datatype | Description
publisher | varchar(30) | The name of the publisher.
subscriber | varchar(30) | The name of the subscriber.
type | tinyint | The subscriber type. 0 indicates SQL Server 6.0 subscriber. 1 indicates an ODBC data source.
login | varchar(30) | Allows NULL.
password | varchar(30) | Allows NULL.
commit_batch_size | int | The number of transactions executed on the subscriber before a commit is issued.
status_batch_size | int | The number of transactions before the status state is updated.
flush_frequency | int | The minimum time, in hours, that transactions will be retained within the distribution database after they have been distributed.
frequency_type | int | The primary frequency of this task. One time, On demand, Daily, and so on.
frequency_interval | int | The interval of frequency_type.
frequency_relative_interval | int | The relative interval for day of the month when the freqtype is monthly (32).
frequency_recurrence_factor | int | The recurrence factor based on the frequency_type.
frequency_subday | int | The reschedule occurrence based on frequency_interval. Once, every second, every minute, every hour.
frequency_subday_interval | int | The amount of time per frequency_subday when it is a unit of time.
active_start_time_of_day | int | The time of day when this task is active.
active_end_time_of_day | int | The time of day this task is no longer active.
active_start_date | int | The date and time after which this task may be scheduled.
active_end_date | int | The date and time after which this task may no longer be scheduled.
retryattempts | int | The number of retry attempts when a task execution fails.
retrydelay | int | The delay, in minutes, between retry attempts.

Index

ucMSsubscriber_info clustered, unique on publisher, subscriber


MSsubscriber_jobs (distribution database only)

Distribution database table. Associates each subscriber with the command that subscriber needs to receive.

Column | Datatype | Description
job_id | int | The job ID.
publisher_id | smallint | The local server ID of the publishing server.
publisher_db | varchar(30) | The name of the published database.
subscriber_id | smallint | The subscriber ID.
subscriber_db | varchar(30) | The name of the database on the subscribing server.
command_id | int | The ID of the command.

Index

ucMSsubscriber_jobs clustered, unique on publisher_db, publisher_id, subscriber_db, subscriber_id, job_id, command_id

Referenced by Stored Procedures

sp_replcleanup | sp_MSkill_job


MSsubscriber_status (distribution database only)

Distribution database table. Contains status information for the individual batches of transactions sent to subscribers.

Column | Datatype | Description
publisher_id | smallint | The local server ID of the publishing server.
publisher_db | varchar(30) | The name of the published database.
job_id | int | The job ID.
subscriber_db | varchar(30) | The name of the database on the subscribing server.
subscriber_id | smallint | The local server ID of the subscribing server.
completion_time | datetime | The time the row was inserted.
status | int | The completion status.
delivery_latency | int | In seconds, the time between a job being inserted in the distribution database and being executed against the subscriber.
delivered_jobs | int | The number of jobs still in the distribution database that have already been executed against the destination database.
delivery_rate | int | The number of jobs per second that were executed in the last batch sent to that subscription server.

Index

ucMSsubscriber_status clustered, unique on publisher_db, publisher_id, subscriber_db, subscriber_id, job_id

Referenced by Stored Procedures

sp_MSsubscriber_status | sp_replcleanup


System Tables-SQL Executive Tables

System Tables–SQL Executive Tables

SQL Executive handles event scheduling and alert management for any SQL Server process, such as replication. All scheduling information is stored within the msdb database.

The msdb database uses the following tables for scheduling purposes:

Table | Description
sysalerts | Contains one row for each alert.
syshistory | Contains one row for each task that has occurred.
sysnotifications | Contains one row for each notification.
sysoperators | Contains one row for each operator.
systasks | Contains one row for every scheduled task.


sysalerts

Contains one row for each alert. An alert is a message sent in response to some event that has occurred; an alert can "forward" messages outside of the SQL Server environment. An alert can be EMAIL and/or PAGER, and it can also generate a task.

Column | Datatype | Description
id | int | The alert ID.
name | varchar(60) | The alert name.
event_source | varchar(30) | The source of the event: SQL Server.
event_categoryname | varchar(30) | Reserved for future use.
event_id | varchar(20) | The ID of the event (from the event log) that triggers this alert.
message_id | int | User-defined message ID or reference to sysmessages message that triggers this alert.
severity | int | The severity that triggers this alert.
enabled | tinyint | The status of the alert: 0 Disabled 1 Enabled
delay_between_notifications | int | The wait period, in seconds, between notifications for this alert.
last_occurrence_date | int | The last occurrence (date) of the alert.
last_occurrence_time | int | The last occurrence (time of day) of the alert.
last_response_date | int | The last notification (date) of the alert.
last_response_time | int | The last notification (time of day) of the alert.
notification_message | varchar(255) | Additional information sent with the alert.
include_event_description | tinyint | Bitmask representing whether the event description is sent by either or both: 1 EMAIL 2 PAGER
database_name | varchar(30) | The database in which this alert must occur to trigger this alert.
event_description_keyword | varchar(100) | The pattern the error must match in order for the alert to trigger.
occurrence_count | int | The number of occurrences for this alert.
count_reset_date | int | The day (date) that this count will be reset to 0.
count_reset_time | int | The time of day that this count will be reset to 0.
task_id | int | The ID of the task that is executed when this alert occurs.
has_email_notification | int | The number of operators who receive e-mail notification when this alert occurs.
has_pager_notification | int | The number of operators who receive pager notification when this alert occurs.

Index

ByName clustered, unique on name
ByID nonclustered, unique on id

Referenced by Stored Procedures

sp_addalert | sp_dropnotification | sp_updatealert
sp_addnotification | sp_helpnotification | sp_updatenotification
sp_dropalert |  |


syshistory

Contains one row for each scheduled event, alert, or task that has occurred.

Column | Datatype | Description
id | int | The ID of the history entry.
eventid | int | Reserved for future use.
messageid | int | The ID of the message sent.
severity | int | The severity of the message sent.
taskid | int | The ID of the task executed.
source | varchar(30) | The source of the event.
category | varchar(30) | The category of event.
runstatus | int | The completion type: Success, Failure, Aborted, or Skipped.
rundate | int | The date the event was completed.
runtime | int | The time of day the event was completed.
runduration | int | The amount of time needed to complete the task.
reviewstatus | varchar(32) | Reserved for future use.
emailoperatorid | int | The ID of the operator to whom e-mail was sent.
retries | int | The number of retry attempts for a task.
comments | varchar(255) | The description of the outcome of the task, if any. This is usually error information.
timesskipped | int | The number of times the task was skipped because of a server or SQL Executive problem.

Index

ucsyshistory clustered, unique on id

Referenced by Stored Procedures

sp_droptask | sp_helphistory | sp_purgehistory


sysnotifications

Has a row for each notification.

Column | Datatype | Description
alert_id | int | The ID of the alert.
operator_id | int | The operator ID to whom this notification should be sent.
notification_method | tinyint | The method of notification (EMAIL, PAGER, BOTH).

Index

ByAlertIDAndOperator clustered, unique on alert_id, operator_id

Referenced by Stored Procedures

sp_addnotification | sp_dropnotification | sp_updatenotification
sp_dropalert | sp_dropoperator |


sysoperators

Contains one row for each operator.

Column | Datatype | Description
id | int | The ID of the operator.
name | varchar(50) | The name of the operator.
enabled | tinyint | The status of alert notifications (Boolean). If 1, this operator can receive notifications when an alert occurs.
email_address | varchar(100) | The e-mail address for this operator.
last_email_date | int | The date this operator last received an e-mail alert notification.
last_email_time | int | The time of day this operator last received an e-mail alert notification.
pager_address | varchar(100) | The pager address for this operator.
last_pager_date | int | The date this operator last received a pager alert notification.
last_pager_time | int | The time of day this operator last received a pager alert notification.
weekday_pager_start_time | int | The time of day on a weekday (Monday through Friday) after which this operator is available to receive a pager alert notification.
weekday_pager_end_time | int | The time of day on a weekday (Monday through Friday) after which this operator is not available to receive a pager alert notification.
saturday_pager_start_time | int | The time of day on Saturday after which this operator is available to receive a pager alert notification.
saturday_pager_end_time | int | The time of day on Saturday after which this operator is not available to receive a pager alert notification.
sunday_pager_start_time | int | The time of day on Sunday after which this operator is available to receive a pager alert notification.
sunday_pager_end_time | int | The time of day on Sunday after which this operator is not available to receive a pager alert notification.
pager_days | tinyint | Bitmask. The days of the week during which this operator is available to receive a pager alert notification.

Index

ByName clustered, unique on name
ByID nonclustered, unique on id

Referenced by Stored Procedures

sp_addnotification | sp_helphistory | sp_schedulerrefresh
sp_addoperator | sp_helpnotification | sp_updatenotification
sp_dropnotification | sp_helpoperator | sp_updateoperator
sp_dropoperator | sp_helptask | sp_verifytask


systasks

Contains one row for every scheduled task. Each task may be generated or executed in response to an alert. Tasks execute in the specified subsystem: replication (Distribution, LogReader, Sync), Transact-SQL (TSQL), or command-line executables (CmdExec).

Column | Datatype | Description
id | int | The ID of the task.
name | varchar(100) | The name of the task.
subsystem | varchar(30) | The subsystem used for a task: Distribution, LogReader, Sync, TSQL, or CmdExec.
server | varchar(30) | The server on which this task is executed.
username | varchar(30) | The username under which this task should be executed.
ownerloginid | smallint(2) | The login ID of the task creator.
databasename | varchar(30) | The database in which this task should be executed.
enabled | tinyint | The status of this task. (Boolean.)
freqtype | int | The primary frequency of this task. One time, On demand, Daily, and so on.
freqinterval | int | The interval of freqtype.
freqsubtype | int | The reschedule occurrence based on freqinterval. Once, every second, every minute, every hour.
freqsubinterval | int | The amount of time per freqsubtype when it's a unit of time.
freqrelativeinterval | int | The relative interval for day of month when the freqtype is monthly (32).
freqrecurrencefactor | int | The recurrence factor based on the freqtype.
activestartdate | int | The date and time after which this task may be scheduled.
activeenddate | int | The date and time after which this task may no longer be scheduled.
activestarttimeofday | int | The time of day when this task is active.
activeendtimeofday | int | The time of day this task is active.
lastrundate | int | The date this task was last executed.
lastruntime | int | The time of day this task was last executed.
nextrundate | int | The date this task is scheduled to be executed next.
nextruntime | int | The time of day this task is scheduled to be executed next.
runpriority | int | The Windows NT thread priority to use when executing this task.
emailoperatorid | int | The ID of the operator to whom e-mail is sent.
retryattempts | int | The number of retry attempts when a task execution fails.
retrydelay | int | The delay, in minutes, between retry attempts.
datecreated | datetime | The date and time this task was created.
datemodified | datetime | This date and time this task was last modified.
command | varchar(255) | Command to execute based on the subsystem.
lastruncompletionlevel | int | The task completion status of the last execution of this task.
lastrunduration | int | The duration of the last execution of this task.
lastrunretries | int | The number of retry attempts during the previous execution of this task.
loghistcompletionlevel | int | The task completion status which causes task history information to be logged.
emailcompletionlevel | int | The task completion status which causes notification of the operator by e-mail.
description | varchar(255) | Description of the task.
tagadditionalinfo | varchar(96) | Temporary storage space contained in this object. Used by replication.
tagobjectid | int | The ID of the object using temporary storage space. Used by replication.
tagobjecttype | int | The type of object using temporary storage space. Used by replication.

Index

ucsystasks clustered, unique on name
uncsystasks nonclustered, unique on id

Referenced by Stored Procedures

sp_addalert | sp_helphistory | sp_updatealert
sp_addtask | sp_helptask | sp_updatetask
sp_droptask | sp_purgehistory |


Text and Image Manipulation

Text and image data consists of character or binary data stored and managed as a linked list of 2K data pages that appear as if they were stored in a table row. A text or image datatype contains a pointer (assigned at initialization) to the first data page or value fragment for that entry, and thus to the entire text or image value.

In SQL Server, this type of storage (variable number of 2K pages stored in a linked list) is fundamentally different from other datatypes. Because of this, text and image data is also manipulated differently. To assist in manipulating text and image data, SQL Server provides a variety of functions and statements. For more information on the text and image datatypes, see the Datatypes topic.

These are the text and image functions:

  • TEXTPTR
  • TEXTVALID

For details about these functions, see the Functions topic.

These are the text and image statements:

  • READTEXT
  • UPDATETEXT
  • WRITETEXT

The following functions and statement are also useful with text and image data:

  • PATINDEX
  • DATALENGTH
  • SET TEXTSIZE

For information about PATINDEX and DATALENGTH, see the Functions topic. For information about the TEXTSIZE session setting, see the SET statement.

The following sections detail each of the text and image manipulation statements.


READTEXT Statement

Reads text and image values, starting from a specified offset and reading a specified number of bytes.

Syntax

READTEXT [[database.]owner.]table_name.column_name
text_ptr offset size [HOLDLOCK]

where

[database.]owner.]table_name.column_name
Specifies a table and column. Both names must be included, but the database name and owner name are optional.
text_ptr
Is a valid text pointer.
offset
Specifies the number of bytes to skip before starting to read the text or image data.
size
Specifies the number of bytes of data to read. If size is 0, 4K bytes of data are read.
HOLDLOCK
Causes the text value to be locked for reads until the end of the transaction. Other users can read the value, but they cannot modify it.

Remarks

READTEXT is used with a text_ptr. The value of text_ptr can be obtained using the TEXTPTR function. The TEXTPTR function returns a pointer to the text or image column in the specified row or to the text or image column in the last row returned by the query if more than one row is returned. Since the TEXTPTR function returns a 16-byte binary string, it is best to declare a local variable to hold the text pointer and then use the variable with READTEXT.

The value in the global variable @@TEXTSIZE, which is the limit on the number of bytes of data to be returned, supersedes the size specified for READTEXT if it is less than the specified size for READTEXT. For details on how to set the session setting for TEXTSIZE, see the SET statement.

Permission

Users must have SELECT permission on the table to use READTEXT. READTEXT permission is transferred when SELECT permission is transferred.


UPDATETEXT Statement

Updates an existing text or image field. WRITETEXT updates and replaces an entire text or image field. UPDATETEXT is more flexible because it changes only a portion of a text or image value in place.

Syntax

UPDATETEXT
[[database.]owner.]table_name.dest_column_name dest_text_ptr
{NULL | insert_offset} {NULL | delete_length} [WITH LOG]
[inserted_data |
[{[database.]owner.]table_name.src_column_name src_text_ptr}]

where

table_name.dest_column_name
Specifies the table and text or image column to be updated. The database name and owner name are optional.
dest_text_ptr
Is a text pointer value (returned by the TEXTPTR function) that points to the text or image data to be updated.
insert_offset
Is the zero-based starting position, specified as the number of bytes (from the start of the existing text or image value) to skip before inserting the new data. The existing text or image data beginning at this zero-based starting position will be shifted to the right to make room for the new data. A value of 0 means that the new data will be inserted at the beginning of the existing data value. A value of NULL means that the new data will be appended to the existing data value.
delete_length
Is the number of bytes to delete from the existing text or image value, starting at the insert_offset position. A value of 0 means that no data will be deleted. A value of NULL means that all data from the insert_offset position to the end of the existing text or image value will be deleted.
WITH LOG
Specifies that the inserted text or image data will be logged. This option allows recovery, but it can quickly increase the size of the transaction log.

Note If the WITH LOG option is not specified, the database must have the select into/bulkcopy database option turned on. For details, see the sp_dboption system stored procedure.

inserted_data
Is the data to be inserted into the existing text or image value at the insert_offset location. This is a single char, varchar, binary, varbinary, text, or image constant.
table_name.src_column_name
Specifies the table and text or image column that can be used as the source of the inserted data.
src_text_ptr
Is a text pointer value (returned by the TEXTPTR function) that points to a text or image value that can be used as the source of the inserted data.

Remarks

The UPDATETEXT statement can be used to replace existing data, delete existing data, or insert new data. Newly inserted data can be a single inserted_data constant, or a table name, column name, or text pointer.

To replace data, specify a non-null insert_offset value, a non-zero delete_length value, and the new data to be inserted.

To delete existing data, specify a non-null insert_offset value and a non-zero delete_length. Do not specify any new data to be inserted.

To insert new data, specify the desired insert_offset value, a delete_length of 0, and the new data to be inserted.


WRITETEXT Statement

Permits nonlogged, interactive updating of an existing text or image field. This statement completely overwrites any existing data in the column it affects. By default, WRITETEXT statements are not logged so that the transaction log won't fill up with the large amounts of data that often make up these datatypes.

Syntax

WRITETEXT [[database.]owner.]table_name.column_name text_ptr
[WITH LOG] data

where

table_name.column_name
Specifies the text column and table to be updated. The database name and owner name are optional.
text_ptr
Is a value that stores the pointer to the text or image data.
WITH LOG
Logs the inserted text or image data, which aids media recovery. Because text data quickly increases the size of the transaction log, be sure that the transaction log resides on a separate database device.

Remarks

The WRITETEXT statement completely overwrites any existing data in the column it affects. Use WRITETEXT to replace text data and UPDATETEXT to modify text data. UPDATETEXT is more flexible because it changes only a portion of a text of image value rather than the entire value.

By default, WRITETEXT is a nonlogged operation. This means that text or image data is not logged when it is written into the database. To use WRITETEXT in its default, nonlogged state, the system administrator must use the sp_dboption system stored procedure to set select into/bulkcopy, which allows nonlogged data to be inserted.

For WRITETEXT to work, the column must already contain a valid text pointer. There are two ways to create a text pointer:

  • Insert actual data into the text or image column
  • Update the column with data or a NULL

Because an initialized text column uses 2K of storage, even to store a couple of words, SQL Server saves space by not initializing text columns when explicit or implicit null values are placed in text columns with INSERT.

The maximum length of text that can be inserted interactively with WRITETEXT is approximately 120K for text and image data.

You cannot use WRITETEXT on text and image columns in views.

The DB-Library functions dbwritetext and dbmoretext and the ODBC function SQLPutData are faster and use less dynamic memory than WRITETEXT. These functions can insert up to 2 gigabytes of text data.

Caution After using the WRITETEXT statement, you must execute DUMP DATABASE. After nonlogged operations occur within a database, the DUMP TRANSACTION statement cannot be performed. For details, see the DUMP statement.

Text and Image
Examples

A. READTEXT Statement

This example selects the second through twenty-sixth characters of the pr_info column in the pub_info table.

DECLARE @ptrval varbinary(16)
SELECT @ptrval = TEXTPTR(pr_info)
    FROM pub_info pr, publishers p
        WHERE p.pub_id = pr.pub_id
        AND p.pub_name = 'New Moon Books'
READTEXT pub_info.pr_info @ptrval 1 25
B. Use WRITETEXT to Change Text Data

This example puts the text pointer into the local variable @ptrval, and then WRITETEXT places the new text string into the row pointed to by @ptrval.

DECLARE @ptrval varbinary(16)
SELECT @ptrval = TEXTPTR(pr_info)
    FROM pub_info pr, publishers p
        WHERE p.pub_id = pr.pub_id
        AND p.pub_name = 'New Moon Books'
WRITETEXT pub_info.pr_info @ptrval 'New Moon Books (NMB) has just released another top ten publication. With the latest puglication this makes NMB the hottest new publisher of the year!'

Note that publication is spelled incorrectly (puglication) in this example. In example C, this value is corrected with UPDATETEXT.

C. Use UPDATETEXT to Modify Text Data

This example puts the text pointer into the local variable @ptrval, and then uses UPDATETEXT to update the spelling error in example B.

DECLARE @ptrval varbinary(16)
SELECT @ptrval = TEXTPTR(pr_info)
    FROM pub_info pr, publishers p
        WHERE p.pub_id = pr.pub_id
        AND p.pub_name = 'New Moon Books'
UPDATETEXT pub_info.pr_info @ptrval 88 1 'b'
go

See Also

Datatypes | SELECT
DECLARE | SET
DELETE | UPDATE
INSERT |


Trace Flags

For SQL Server 6.5 information, see Trace Flags in What's New for SQL Server 6.5.

Trace Flags are used to temporarily set a specific server characteristic. Trace flags can be activated through two methods: by using the DBCC statement and with the -T option with the sqlservr command-line executable. When set, trace flags are in effect only until reset (for options set with the DBCC statement) or until the server is stopped and restarted. For details, see the Utilities topic and the DBCC statement. For details on troubleshooting and setting and using trace flags, see the Microsoft SQL Server Administrator's Companion.

The following table summarizes the trace flags available in SQL Server 6.0. These trace flags are provided primarily for backward compatibility. In general, trace flags should be used to temporarily work around a problem until a permanent solution is put in place. Trace flags are not a part of the supported feature set, and future compatibility or continued use is not assured.

These are the trace flags available in SQL Server 6.0:

Trace flag | Description
- 1 | Sets trace flags for all client connections, rather than for a single client connection. Because trace flags set using the -T command-line option (with sqlservr) automatically apply to all connections, this trace flag is used only when setting trace flags using DBCC TRACEON and DBCC TRACEOFF. For details, see the sqlservr command-line executable and DBCC statement.
106 | Disables line number information for syntax errors.
107 | Interprets numbers with a decimal point as float instead of decimal. For details, see the Datatypes topic.
204 | Generally, allows non-ANSI-standard behavior for various features: · Allows queries that contain aggregates or a GROUP BY clause to have items in the select list that are not in the GROUP BY clause and are not aggregate functions. ANSI-standard SQL does not allow this. · Ignores trailing blanks in the LIKE pattern. For details, see the Search Conditions and Wildcard Characters topics.
206 | Provides backward compatibility for the SETUSER statement. For details, see the SETUSER statement.
243 | Provides backward compatibility for nullability behavior. When set, SQL Server has the same nullability violation behavior as that of a 4.2 server: · Processing of the entire batch will be terminated if the nullability error (inserting NULL into a NOT NULL field) can be detected at compile time · Processing of the offending row will be skipped but the command will continue if the nullability violation is detected at run time The behavior of SQL Server 6.0 is now more consistent ¾ all nullability checks are made at run time and a nullability violation results in the command terminating but the batch/transaction continuing to process.
244 | Disables checking for allowed interim constraint violations. By default, SQL Server checks for and allows interim constraint violations. An interim constraint violation is caused by a change that initially violates a constraint, followed by another change that removes the violation such that the constraint is met, all within a single statement and transaction. SQL Server checks for interim constraint violations for self-referencing DELETE statements, INSERT statements based on a SELECT, and multi-row UPDATE statements. This checking requires more work tables. With this trace flag you can disallow interim constraint violations, thus requiring fewer work tables.
302 | Prints information about whether the statistics page is used, the actual selectivity (if available), and what SQL Server estimated the physical and logical I/O would be for the indexes. Index selection information is also available in a more readable format using SET SHOWPLAN ON, as described with the SET statement. Trace flag 302 should be used with trace flag 310 to show the actual join ordering.
310 | Prints information about join order.
325 | Prints information about the cost of using a nonclustered index or a sort to process an ORDER BY clause.
326 | Prints information about the estimated and actual cost of sorts.
652 | Disables read ahead for the server.
653 | Disables read ahead for the current connection.
1200 | Prints lock information (the process ID and type of lock requested).
1204 | Returns the type of locks participating in the deadlock and the current command affected.
1205 | Returns more detailed information on the command being executed at the time of a deadlock.
1609 | Turns on the unpacking and checking of RPC information with the execution of the sp_sqlexec extended stored procedure in Open Data Services. Use this flag only when applications depend on the old behavior. The application should be changed to use EXECUTE sql_string rather than sp_sqlexec. For details, see the EXECUTE statement.
1704 | Prints information when a temporary table is created or dropped.
3502 | Prints a message to the log at the start and end of each checkpoint.
3205 | By default, if a tape drive supports hardware compression, the DUMP statement will use it. With this trace flag, you can disable hardware compression for tape drives. This might be useful when you want to exchange tapes with other sites or tape drives that do not support compression.
3503 | Indicates whether the checkpoint at the end of automatic recovery was skipped for a database (this applies only to READ ONLY databases). For details, see the sp_dboption system stored procedure.
3604 | Sends trace output to the client. ( ) This trace flag is used only when setting trace flags with DBCC TRACEON and DBCC TRACEOFF.
3605 | Sends trace output to the error log. (If you start SQL Server from the command line, the output will also appear on the screen.)
3607 | Skips automatic recovery for all databases.
3608 | Skips automatic recovery for all databases except the master database.
3609 | Skips the creation of the tempdb database. Use this trace flag if the device or devices on which tempdb resides are problematic or problems exist in the model database.
3640 | Eliminates the sending of DONE_IN_PROC messages to the client for each statement in a stored procedure. This is similar to the session setting NOCOUNT, but when set as a trace flag every client session is handled this way. For details, see the SET statement.
4022 | Skips the execution of all startup stored procedures. For more information, see the CREATE PROCEDURE statement and the sp_makestartup system stored procedure.
4030 | Prints both a byte and ASCII representation of the receive buffer. This trace flag is usually used when you need to see what queries a client is sending to SQL Server. You might use this trace flag if you experience a protection violation and need to determine which statement caused it. Typically, you would set this flag globally or use SQL Enterprise Manager. You can also use DBCC INPUTBUFFER. For details, see the DBCC statement.
4031 | Prints both a byte and ASCII representation of the send buffers (what SQL Server sends back to the client). You can also use DBCC OUTPUTBUFFER. For details, see the DBCC statement.
4032 | Prints only an ASCII representation of the receive buffer. Usually used in place of trace flag 4030 (if trace output speed is important) when you need to see what queries a client is sending to SQL Server.

See also

Datatypes | SET
DBCC | sqlservr Command-line Executable


Transactions

A transaction is a single unit of work. Any single SQL statement is considered to be a single unit of work whether it affects only a single row or multiple rows within a table. In SQL Server, a transaction is implicit (due to the nature of the statements executed) or explicit (as defined by the user). An explicit transaction is a grouping of SQL statements surrounded by the transaction delimiters: BEGIN TRANSACTION, COMMIT TRANSACTION, and optionally, one of the following statements. In creating explicitly defined transactions, the following statements are used:

  • BEGIN TRANSACTION
  • COMMIT TRANSACTION
  • ROLLBACK TRANSACTION
  • SAVE TRANSACTION

All transactions must be enclosed within BEGIN TRANSACTION...COMMIT TRANSACTION statements. The outermost pair actually creates and commits the transaction; the inner pairs track the nesting level. When a nested transaction is encountered, the global variable @@TRANCOUNT is incremented.

Naming nested transactions with a transaction_name has little effect on the outermost transaction. Only the first (outermost) transaction name is registered with the system, and a rollback to any other name (other than a valid savepoint name) generates an error. None of the statements executed before the rollback are rolled back when this error occurs. No portion of the transaction is committed until the outermost COMMIT TRANSACTION is issued. Normally, this apparent transaction nesting occurs as stored procedures or triggers with BEGIN...COMMIT pairs call each other.

Although transactions can be nested, they have little effect on the behavior of ROLLBACK TRANSACTION statements, except for generating errors if not handled properly. The syntax allows stored procedures and triggers to be called from within transactions if they contain BEGIN TRANSACTION and COMMIT TRANSACTION statements.

Grouping a large number of Transact-SQL statements into one long-running transaction can negatively affect recovery time and cause concurrency problems. If SQL Server fails during such a transaction, recovery time can increase because SQL Server must first undo the transaction. Wherever possible, it is wise to break transactions into smaller transactions. Make sure each transaction is well-defined within a single batch. To minimize possible concurrency conflicts, transactions should not span multiple batches nor wait for user input.

In stored procedures and triggers, the number of BEGIN TRANSACTION statements must match the number of COMMIT TRANSACTION statements. A procedure or trigger that contains unpaired BEGIN TRANSACTION and COMMIT TRANSACTION statements produces an error message when it is executed.

Transaction Rules

To define a transaction, place Transact-SQL statements and/or stored procedures between the statements BEGIN TRANSACTION and COMMIT TRANSACTION. Within a user-defined (or explicit) transaction, there are some important rules to follow:

  • Do not use the following statements inside a user-defined transaction:
ALTER DATABASE | DISK INIT | LOAD TRANSACTION
CREATE DATABASE | DROP <objname> | RECONFIGURE
CREATE INDEX | DUMP TRANSACTION | SELECT INTO
CREATE PROCEDURE | GRANT or REVOKE | TRUNCATE TABLE
CREATE TABLE | LOAD DATABASE | UPDATE STATISTICS
CREATE VIEW |  |

  • If they create a temporary table, you cannot use a system stored procedure inside a user-defined transaction.

    Note Additionally, you cannot use the sp_dboption system stored procedure to set database options or use any system procedures that change the master database inside user-defined transactions.

  • To cancel all or part of a transaction (to a previously defined savepoint), use the statement ROLLBACK TRANSACTION transaction_name. The transaction's statements or procedures that have changed the database are undone. The ROLLBACK TRANSACTION statement must appear within a transaction. You cannot roll back a transaction after COMMIT TRANSACTION has been entered.
  • Calls to remote stored procedures are executed independently of any transaction in which they're included.

    Important Statements executed with calls to remote stored procedures are not rolled back with ROLLBACK TRANSACTION, and they do not depend on COMMIT TRANSACTION to be executed. In other words, statements executed on a remote server through remote stored procedures happen outside the scope of the local user-defined transaction.

No explicit permission is necessary to define a transaction. By default, all users can define a transaction. All statements used within a transaction follow their specific permission rules.


BEGIN TRANSACTION Statement

Marks the starting point of a user-specified transaction.

Syntax

BEGIN TRANsaction [transaction_name]

where

transaction_name
Is the name assigned to the transaction. The transaction_name must conform to the rules for identifiers. Use transaction names only on the outermost pair of nested BEGIN... COMMIT or BEGIN...ROLLBACK statements.

Remarks

Naming multiple transactions with a transaction_name has little effect on the transaction. Only the first (outermost) transaction name is registered with the system. A rollback to any other name (other than a valid savepoint_name) generates an error. None of the statements executed before the rollback are in fact rolled back when this error occurs.


COMMIT TRANSACTION Statement

Marks the end of a user-defined transaction.

Syntax

COMMIT TRANsaction [transaction_name]

where

transaction_name
Is the name assigned to the transaction. The transaction_name must conform to the rules for identifiers. Use transaction names only on the outermost pair of nested BEGIN... COMMIT or BEGIN...ROLLBACK statements.

Remarks

The ROLLBACK TRANSACTION statement must appear within a transaction. You cannot roll back a transaction after a COMMIT TRANSACTION statement is executed.


ROLLBACK TRANSACTION Statement

Rolls back a user-specified transaction to the last savepoint inside a transaction or to the beginning of a transaction.

Syntax

ROLLBACK TRANsaction [transaction_name | savepoint_name]

where

transaction_name
Is the name assigned to the transaction. The transaction_name must conform to the rules for identifiers. Use transaction names only on the outermost pair of nested BEGIN... COMMIT or BEGIN...ROLLBACK statements.
savepoint_name
Is the name assigned to the savepoint. The savepoint_name must conform to the rules for identifiers. Use savepoint names only when a conditional rollback should affect only part of the transaction.

Remarks

ROLLBACK TRANSACTION, without a savepoint_name or transaction_name, will roll back to the beginning of the transaction. When nesting transactions, a ROLLBACK TRANSACTION statement, without a transaction_name or savepoint_name, always rolls back statements to the outermost BEGIN TRANSACTION statement and cancels the transaction. All the transaction's statements or procedures are undone. A transaction cannot be rolled back after a COMMIT TRANSACTION statement is executed.

Within a transaction, duplicate savepoint_names are allowed, but when used with ROLLBACK TRANSACTION, only the first instance of a savepoint_name is used.

In triggers or stored procedures, ROLLBACK TRANSACTION statements, without a savepoint_name or transaction_name, roll back all statements to the first BEGIN TRANSACTION in the batch that called the procedure or fired the trigger. A ROLLBACK TRANSACTION statement in a stored procedure or trigger that rolls back past more than one BEGIN TRANSACTION statement produces an error message indicating the number of nesting levels affected. This message (level 16) does not affect subsequent processing.

The rollback also affects all data modification statements issued from within the trigger. The statements executed as a result of the trigger firing and the transaction that attempted the data modification against the table are treated as an atomic unit by the rollback. Remember that the entire transaction is terminated if the rollback is issued from within a trigger. Also note that upon entering the trigger, the global variable @@TRANCOUNT is incremented, in spite of the lack of a BEGIN TRANSACTION statement. (The system treats a trigger as an implied transaction.)

ROLLBACK TRANSACTION statements in stored procedures do not affect subsequent statements in the batch that called the procedure; subsequent statements in the batch are executed. ROLLBACK TRANSACTION statements in triggers "undo" the modification attempted (that fired the trigger), and subsequent statements in the batch are not executed.

A ROLLBACK TRANSACTION statement does not produce any messages to the user. If warnings are needed in stored procedures, use the RAISERROR statement or the PRINT statement. The RAISERROR statement is the preferred method for sending errors.


SAVE TRANSACTION Statement

Sets a savepoint within a transaction.

Syntax

SAVE TRANsaction savepoint_name

where

savepoint_name
Specifies the name assigned to the savepoint. Savepoint names must conform to the rules for identifiers.

Remarks

A user can set a savepoint, or marker, within a transaction. It defines a location to which a transaction can return if part of the transaction might be conditionally canceled. If a transaction is rolled back to a savepoint, it must proceed to completion (with more SQL statements if needed and a COMMIT TRANSACTION statement), or it must be canceled altogether (by rolling it back to its beginning). To cancel an entire transaction, use the form ROLLBACK TRANSACTION transaction_name. All the transaction's statements or procedures are undone.

Important When a transaction begins, resources used during the transaction are held until the completion of the transaction (namely locks). When part of a transaction is rolled back to a savepoint, resources continue to be held until the completion of the transaction (or a rollback of the complete transaction).


TRUNCATE TABLE Statement

Removes all rows from a table without logging the individual row deletes. This allows TRUNCATE TABLE to be efficient and quick, but unrecoverable.

Syntax

TRUNCATE TABLE [[database.]owner.]table_name

Remarks

TRUNCATE TABLE removes all rows from a table, but the table structure and all indexes (although empty of data) continue to exist until you issue a DROP TABLE statement. Defined constraints, rules and defaults bound to the columns, and triggers remain in effect. Additionally, an identity column will be reset to the original seed. If you do not want to reset the identity value for a column, use the DELETE statement without a WHERE clause instead of the TRUNCATE TABLE statement.

The TRUNCATE TABLE works similarly to the DELETE statement but is faster than DELETE. The DELETE statement removes rows one at a time and logs each deleted row as a transaction. TRUNCATE TABLE deallocates whole pages of data and makes fewer log entries. TRUNCATE TABLE guarantees that all rows are removed from the table and cannot be rolled back. DELETE can be rolled back. Both the DELETE and TRUNCATE TABLE statements reclaim the space occupied by the data and its associated indexes.

You cannot use TRUNCATE TABLE on a table referenced by a FOREIGN KEY constraint; instead, use the DELETE statement without a WHERE clause. Because TRUNCATE TABLE is not logged, it cannot activate a trigger.

Note Because TRUNCATE TABLE deallocates the distribution pages for all indexes, run UPDATE STATISTICS after adding new rows to the table.

Example

This example removes all data from the authors table.

TRUNCATE TABLE authors

Permission

TRUNCATE TABLE permission defaults to the table owner and is not transferable.

See Also

DELETE | DROP TABLE


UNION Operator

In SQL Server 6.5, new behavior is introduced for the UNION Operator due to ANSI-NULL handling.For SQL Server 6.5 information, see ANSI-standard Null Handling in What's New for SQL Server 6.5.

Combines the results of two or more queries into a single results set consisting of all the rows belonging to all queries in the union.

Syntax

SELECT select_list [INTO clause]
[FROM clause]
[WHERE clause]
[GROUP BY clause]
[HAVING clause]
[UNION [ALL]
SELECT select_list
[FROM clause]
[WHERE clause]
[GROUP BY clause]
[HAVING clause]...]
[ORDER BY clause]
[COMPUTE clause]

where

INTO
Creates a new table based on the columns specified in the select list and the rows chosen in the WHERE clause. The first query in the Transact-SQL statement is the only one that can contain an INTO clause.
UNION
Is a set operation that requires two operands.
ALL
Incorporates all rows into the results, including duplicates.

Remarks

Because UNION is a binary operation, you must add parentheses to an expression involving more than two queries to specify evaluation order. The default evaluation order of a Transact-SQL statement containing UNION operators is left to right. By default duplicate rows are eliminated; however, using UNION with the ALL keyword returns all rows, including duplicates.

The first query in the UNION statement can contain an INTO clause that creates a table to hold the final results set. The INTO statement must be in the first query or an error message will be returned.

GROUP BY and HAVING clauses can be used only within individual queries and cannot be used to affect the final results set. ORDER BY and COMPUTE clauses are allowed only at the end of the UNION statement to define the order of the final results or to compute summary values.

The UNION operator cannot appear within a CREATE VIEW statement or within a subquery. You cannot specify the FOR BROWSE option in queries with the UNION operator.

The UNION operator can appear within an INSERT-SELECT statement. For example:

INSERT INTO salesall
    SELECT * FROM sales
    UNION
    SELECT * FROM saleseast

All select lists in a Transact-SQL statement must have the same number of expressions (such as column names, arithmetic expressions, and aggregate functions). For example, the following statement is invalid because the first select list is longer than the second:

SELECT au_id, title_id, au_ord FROM titleauthor
UNION
SELECT stor_id, date FROM sales

Corresponding columns in the individual queries of a UNION statement must occur in the same order, because UNION compares the columns one to one in the order given in the individual queries.

The descriptions of the columns that are part of a UNION operation do not have to be identical. The following table shows the rules for comparing the datatypes and options of corresponding (ith) columns.

Datatype of ith column | Datatype of ith column of results table
Not datatype-compatible (data conversion not handled implicitly by SQL Server). | Error returned by SQL Server.
Both fixed-length char with lengths L1 and L2. | Fixed-length char with length equal to the greater of L1 and L2.
Both fixed-length binary with lengths L1 and L2. | Fixed-length binary with length equal to the greater of L1 and L2.
Either or both variable-length char. | Variable-length char with length equal to the maximum of the lengths specified for the ith columns.
Either or both variable-length binary. | Variable-length binary with length equal to the maximum of the lengths specified for the ith columns.
Both numeric datatypes (for example, smallint, int, float, money). | Datatype equal to the maximum precision of the two columns. For example, if the ith column of table A is of type int and the ith column of table B is of type float, then the datatype of the ith column of the results table is float, because float is more precise than int.
Both columns' descriptions specify NOT NULL. | Specifies NOT NULL.

Examples

A. Simple UNION

The results set in this example includes the contents of the stor_id and stor_name columns of both the stores and storeseast tables.

SELECT stor_id, stor_name FROM stores
UNION
SELECT stor_id, stor_name FROM storeseast
B. Selecting INTO with UNION

In this example, the INTO clause in the first query specifies that the table called results hold the final results set of the union of the designated columns of the publishers, stores, and storeseast tables.

SELECT pub_id, pub_name, city INTO results FROM publishers
UNION
SELECT stor_id, stor_name, city FROM stores
UNION
SELECT stor_id, stor_name, city FROM storeseast
C. UNION of Two SELECT Statements with ORDER BY

The order of certain parameters used with the UNION clause is important. This example illustrates the incorrect and correct usage of UNION in two SELECT statements in which a column is to be renamed in the output.

/* INCORRECT */
SELECT city FROM storeseast
    ORDER BY cities
UNION
SELECT cities = city FROM stores

/* CORRECT */
SELECT cities = city FROM storeseast
UNION
SELECT city FROM stores
ORDER BY cities

See Also

Select


UPDATE Statement

For SQL Server 6.5 information, see UPDATE Statement in What's New for SQL Server 6.5.

Changes data in existing rows, either by adding new data or by modifying existing data.

Syntax

UPDATE {table_name | view_name}
SET [{table_name | view_name}]
{column_list
| variable_list
| variable_and_column_list}
[, {column_list2
| variable_list2
| variable_and_column_list2}
... [, {column_listN
| variable_listN
| variable_and_column_listN}]]
[WHERE clause]

where

table_name | view_name =
[[database_name.]owner.]{table_name | view_name}

Specifies the name of the table or view used in the UPDATE statement. If the table or view is not in the current database, use a fully qualified table_name or view_name (database_name.owner.object_name).

SET
Is a required keyword used to introduce the list of column or variable clauses to be updated. When more than one column name and value pair are listed, separate the names with commas.
column_list =
column_name = {expression | DEFAULT | NULL}
variable_list =
variable_name = {expression | NULL}
column_name
Specifies a column from the table (table_name) or view (view_name).
expression
Is a column_name, constant, function (aggregate functions are not allowed), or any combination of column_names, constants, and functions connected by an operator(s), or a subquery. For details, see the Expressions topic.
DEFAULT
Inserts the default value for that column. For a column defined with the timestamp datatype, the next value will be inserted. If a default does not exist for the column and the column allows NULLs, NULL will be inserted.

DEFAULT is not valid for an identity column; columns with the IDENTITY property should not be explicitly updated. For more information, see the CREATE TABLE statement.

variable_and_column_list =
variable_name = column_name = {expression | NULL}

Sets local variables as well as columns. This syntax provides the same functionality as an UPDATE statement followed by a SELECT statement in an explicitly defined transaction. Because the combination of selecting and updating is performed during a single UPDATE statement, the transaction is implicit and locks are held for a shorter period of time. For sample syntax, see "Setting Variables and Columns," later in this topic.

WHERE clause =
WHERE {search_conditions | CURRENT OF cursor_name}

Is used to perform a searched update (using search_conditions) or a positioned update (using CURRENT OF cursor_name). When no WHERE clause is given in the UPDATE statement, all rows in the table are modified.

search_conditions
Specifies the criteria for a searched update. A search_condition can include an expression, a subquery, a constant, and so on. For details on valid search_conditions, see the Search Conditions topic.

The IDENTITYCOL keyword can be used in the place of a column_name that has the IDENTITY property. For more information, see the CREATE TABLE statement.

CURRENT OF cursor_name
Specifies the criteria for a positioned update against the current row within the specified cursor_name. Cursor operations affect only the single row on which the cursor is positioned. For details about cursors, see the Cursors topic.

Remarks

Use the UPDATE statement to change single rows, groups of rows, or all rows in a table. UPDATE specifies which row(s) to change and provides the new data. When updating rows, these rules apply:

  • Updating a column with an empty string (' ') into a varchar or text column inserts a single space. All char columns are right-padded to the defined length.

    All trailing spaces are removed from data inserted into varchar columns, except in strings that contain only spaces. These strings are truncated to a single space.

  • If a column being updated violates a constraint or rule, or if it is the wrong datatype, the update does not take place and an error message is returned.

    Constraints are defined with the CREATE TABLE or ALTER TABLE statement. Rules are created with the CREATE RULE statement and bound with the sp_bindrule system stored procedure.

  • Modifying a text column with UPDATE initializes it, assigns a valid text pointer to it, and allocates at least one 2K data page (even if updating the column with NULL). For details about updating text or image fields, see the Text and Image Manipulation topic.

    Note The UPDATE statement is logged; if you are replacing or modifying large blocks of text or image data, use the WRITETEXT or UPDATETEXT statement instead of the UPDATE statement. The WRITETEXT and UPDATETEXT statements (by default) are not logged. For details, see the Text and Image Manipulation topic.

  • An UPDATE statement must follow the rules for a batch. For details, see the Batches topic.
Rules for an Update-In-Place

In SQL Server 6.0, various techniques are used to determine whether or not an UPDATE can be performed "in-place." When an "update-in-place" occurs, the overall performance of the UPDATE statement is improved because the update is direct (only the row modifications to the page are logged). The decision as to whether or not an update-in-place can occur is based on the following requirements. If these requirements are not true, a deferred update will take place. A deferred update is a delete followed by an insert.

  • The UPDATE cannot affect the column(s) that participates in a clustered index.
  • The table cannot have an UPDATE trigger.
  • The table cannot be marked for replication.
  • For single-row updates:
    • The updated column(s) can be variable length, but the new total row size must fit on the same page as the old row.
    • The updated column(s) can participate in a nonunique nonclustered index only if the index key is a fixed-width column.
    • The updated column(s) can participate in a unique nonclustered index only if the index key is fixed-width and the WHERE clause criteria must have an exact match (based on an unique index match¾the index could be the same as the updated column).
    • The new row cannot include differing bytes by more than 50 percent of the original row size, and the total number of discontiguous differing bytes is not more than 24.
  • For multirow updates:
    • The updated column must be fixed length.
    • The updated column cannot participate in a unique nonclustered index.
    • The updated column can participate in a nonunique nonclustered index only if the column is a fixed-width column (the index used to find rows cannot be the same as the updated column).
    • The table cannot include a column with the timestamp datatype.

To see the update strategy used (DIRECT or DEFERRED), set the SHOWPLAN session setting. For details, see the SET statement.

Transact-SQL Extension for the UPDATE Statement

In addition to the syntax shown earlier, Transact-SQL includes a feature that allows you to select data from a table or tables and update corresponding data in the first named table. The functionality provided is similar to that of using a correlated subquery as a search_condition in the WHERE clause of a standard UPDATE.

Transact-SQL extension syntax:

UPDATE {table_name | view_name}
SET [{table_name | view_name}]
{column_list
| variable_list
| variable_and_column_list}
[, {column_list2
| variable_list2
| variable_and_column_list2}
... [, {column_listN
| variable_listN
| variable_and_column_listN}]]
[FROM {table_name | view_name}
[, {table_name | view_name}]...]
[..., {table_name16 | view_name16}]]
[WHERE clause]

where

FROM
Lets you name more than one table or view to use with a WHERE clause to specify which rows to update. The additional FROM clause allows you to update rows from one table based on data stored in other tables, giving you similar functionality to a correlated subquery (SELECT statement in the WHERE clause).

For an example of the differences between correlated subqueries and this Transact-SQL extension, see the examples later in this section.

Setting Variables and Columns

In earlier releases of SQL Server, it was impossible to verify both the new and old values of a modified column. Values returned from the SELECT statement could not be guaranteed at the time of the UPDATE unless an explicitly defined transaction using HOLDLOCK was defined.

In earlier releases:

BEGIN TRANSACTION
SELECT variable_name = column_name1
FROM table_name
WHERE column_name2 = expression
HOLDLOCK
UPDATE table_name
SET column_name1 = expression
 WHERE column_name2 = expression
COMMIT TRANSACTION

In SQL Server 6.0:

UPDATE table_name
SET column_name1 = expression, variable_name = column_name1
WHERE column_name2 = expression

In this single update (an implicit transaction), the locks are held only until the update completes (no need to hold them for both an UPDATE and a SELECT).

Permission

UPDATE permission defaults to the table owner, who can transfer it to other users.

Examples

A. UPDATE Statement with Only the SET Clause

These examples show how all rows can be affected if a WHERE clause is eliminated from an UPDATE statement.

In this example, if all the publishing houses in the publishers table move their head offices to Atlanta, Georgia, this is how the publishers table could be updated:

UPDATE publishers
SET city = 'Atlanta', state = 'GA'

This example changes the names of all the publishers to NULL:

UPDATE publishers
SET pub_name = NULL

You can also use computed column values in an update. This example doubles all prices in the titles table:

UPDATE titles
SET price = price * 2
B. UPDATE Statement with a WHERE Clause

The WHERE clause specifies which rows are to be updated. For example, in the unlikely event that northern California is renamed Pacifica (abbreviated PC) and the people of Oakland vote to change the name of their city to Bay City, here is how to update the authors table for all former Oakland residents whose addresses are now out of date:

UPDATE authors
    SET state = 'PC', city = 'Bay City'
        WHERE state = 'CA' AND city = 'Oakland'

You must write another statement to change the name of the state for residents of other northern California cities.

C. UPDATE Statement with a Nested SELECT Statement

To modify the ytd_sales column to reflect the most recent sales recorded in the sales table, this example assumes that only one set of sales is recorded for a given title on a given date and that updates are current.

UPDATE titles
    SET ytd_sales = ytd_sales  qty
        FROM titles, sales
            WHERE titles.title_id = sales.title_id
            AND sales.date = (SELECT MAX(sales.date) FROM sales)

This example assumes that only one set of sales is recorded for a given title on a given date and that updates are current. If this is not the case (if more than one sale for a given title can be recorded on the same day), then the example shown here does not work correctly. It executes without error, but each title is updated with only one sale, regardless of how many sales actually occurred on that day. This is because a single UPDATE statement never updates the same row twice.

In the situation where more than one sale for a given title can occur on the same day, all the sales for each title must be aggregated together within the UPDATE statement, as shown in this example:

UPDATE titles
    SET ytd_sales =
        (select sum(qty)
            FROM sales
                WHERE sales.title_id = titles.title_id
                    AND sales.date IN (SELECT MAX(date) FROM sales))
    FROM titles, sales

See Also

CREATE INDEX | DELETE
CREATE TABLE | INSERT
CREATE TRIGGER | Text and Image Manipulation
Cursors | UPDATE


UPDATE STATISTICS Statement

Updates information about the distribution of key values in specified indexes.

Syntax

UPDATE STATISTICS [[database.]owner.]table_name [index_name]

where

table_name
Specifies the table with which the index is associated. The table_name parameter is required because Transact-SQL does not require index names to be unique in a database.
index_name
Specifies the index to be updated. If an index name is not specified, the distribution statistics for all indexes in the specified table are updated. To see a list of index names and descriptions, execute the sp_helpindex system stored procedure with the table name.

Remarks

SQL Server keeps statistics about the distribution of the key values in each index and uses these statistics in decisions about which index(es) to use in query processing. The optimization of your queries depends on the accuracy of the distribution steps. If there is significant change in the key values in your index, rerun UPDATE STATISTICS on that index. If a great deal of data in an indexed column has been added, changed, or removed (that is, if you suspect that the distribution of key values has changed) or the table has been truncated using the TRUNCATE TABLE statement and then repopulated, use the UPDATE STATISTICS statement.

UPDATE STATISTICS is run automatically when you create or re-create an index on a table that already contains data. However, to see when the statistics were last updated, use the STATS_DATE system function or the DBCC SHOW_STATISTICS option. For syntax and usage, see the Functions topic and the DBCC statement.

Permission

UPDATE STATISTICS permission defaults to the table owner and is not transferable.

Examples

A. Update All Statistics for a Single Table

This single command will update the distribution statistics for all indexes on the authors table.

UPDATE STATISTICS authors
B. Update Only the Statistics for a Single Index

To update only the distribution information for one index on a table, specify the index after the table name.

UPDATE STATISTICS authors au_id_ind
C. Use Cursors to Run UPDATE STATISTICS on All Tables

In this example, the update_all_stats procedure will first create a cursor, tnames_cursor, and then populate the cursor with all rows from sysobjects of type 'U' = User-defined table. After retrieving all table names, this procedure will run UPDATE STATISTICS against each of the tables.

CREATE PROCEDURE update_all_stats
AS
/*
    This procedure will run UPDATE STATISTICS against
    all user-defined tables within this database.
*/
DECLARE @tablename varchar(30)
DECLARE @tablename_header varchar(75)
DECLARE tnames_cursor CURSOR FOR SELECT name FROM sysobjects
    WHERE type = 'U'
OPEN tnames_cursor
FETCH NEXT FROM tnames_cursor INTO @tablename
WHILE (@@fetch_status <> -1)
BEGIN
    IF (@@fetch_status <> -2)
    BEGIN
        SELECT @tablename_header = "Updating "
            RTRIM(UPPER(@tablename))
        PRINT @tablename_header
        EXEC ("UPDATE STATISTICS "  @tablename )
    END
    FETCH NEXT FROM tnames_cursor INTO @tablename
END
PRINT " "
PRINT " "
SELECT @tablename_header = "*************  NO MORE TABLES"
             "  *************"
PRINT @tablename_header
PRINT " "
PRINT "Statistics have been updated for all tables."
DEALLOCATE tnames_cursor
go
update_all_stats
go
Updating AUTHORS
Updating DISCOUNTS
Updating EMPLOYEE
Updating JOBS
Updating PUB_INFO
Updating PUBLISHERS
Updating ROYSCHED
Updating SALES
Updating STORES
Updating TITLEAUTHOR
Updating TITLES

*************  NO MORE TABLES  *************

Statistics have been updated for all tables.

See Also

CREATE INDEX | EXECUTE
Cursors | sp_helpindex
DBCC | System Functions


USE Statement

In SQL Server 6.5, when the USE statement is used in a batch, dynamic execution of the USE statement retrieves a different database name than if the USE statement was not in a batch in What's New for SQL Server 6.5.

Changes the database context.

Syntax

USE database_name

where

database_name
Specifies the database to which the user context will be switched.

Remarks

The execution of a USE statement takes effect immediately. This statement is executed both at compile and execution time, so statements that appear after the USE statement in a batch will be executed in the specified database.

It is likely that you will be connected automatically to the master database when you log in to SQL Server. Unless a default database has been set up for your login ID, you must execute the USE statement to change from master to another database.

You must be a known user in the database to which you're changing. If you are not known in the database, SQL Server displays a message. The owner of the database must give you access by executing the sp_adduser system stored procedure.

Users not recognized by name within the destination database can still be allowed access if a guest user exists in that database. A database owner can add the special guest user to any user database by using the sp_adduser system stored procedure. By default, the guest user is added to the master database during installation.

Permission

Permission is assigned when the database owner assigns permission by executing the sp_adduser system stored procedure.

See Also

CREATE DATABASE | sp_addalias
DROP DATABASE | sp_adduser
EXECUTE | sp_defaultdb


Utilities and Executables

SQL Server 6.0 provides a number of utilities that enhance the capabilities of the server and ease usability. The utilities included offer either a command-line or graphical user interface and usually have a specific function. The utilities can be categorized by how they are used.

Command-line Utilities and Executables

These are the utilities executed from the command-line:

Utility program | Executable | Description
bcp* | BCP.EXE | Used for command-line transfers either to or from SQL Server and an operating-system file.
Check Upgrade | CHKUPG.EXE | Used by SQL Setup during an upgrade to check the compatibility of existing user-defined databases. This program can be run standalone to provide information about database keywords and possible upgrade issues. For details, see Microsoft SQL Server Setup.
console* | CONSOLE.EXE | Used with the Transact-SQL DUMP statement to back up databases to diskette dump devices.
isql* | ISQL.EXE | Allows you to enter Transact-SQL statements and system procedures from an interactive command-line prompt. It is also used to run Transact-SQL scripts.
Language Installation | LANGINST.EXE | Used by SQL Setup to install additional language information, such as localized messages and country information.
makepipe* and readpipe* | MAKEPIPE.EXE and READPIPE.EXE | Determine the validity and integrity of the network named-pipe services. Always used together.
Sort Order Installation | CHARSET.EXE | Used by SQL Setup to install character set and order information.
SQL Alerter | SQLALRTR.EXE | Used to integrate the alert engine with the Windows NT Performance Monitor alerter. For details on alert management, see the Microsoft SQL Server Administrator's Companion.
SQL Executive | SQLEXEC.EXE | The local administrative agent responsible for scheduling tasks (including replication), handling alerts, and monitoring SQL Server. For details, see the Microsoft SQL Server Administrator's Companion.
sqlservr* | SQLSERVR.EXE | The SQL Server executable itself. This program can be started from the command line with special options used for troubleshooting and/or temporarily changing SQL Server behavior.
* The utilities marked with an asterisk (*) may need to be run standalone. They are detailed in the following sections.

Graphical Utilities

These graphical utilities are provided for ease of use. Each of these utilities provides online Help. For details, start these utilities from the icon in the Microsoft SQL Server 6.0 program group in Program Manager and use the online Help system.

Utility program | Executable | Description
ISQL/w | ISQLW.EXE | A graphical query tool that provides a way to analyze the plan of a query, view statistics information, and manage multiple queries in different windows simultaneously.
SQL Client Configuration Utility | WINDBVER.EXE | Used for managing the client configuration for DB-Library, various Net-Libraries and/or custom named pipes.
SQL Enterprise Manager | SQLEW.EXE | Used for complete SQL Server enterprise management, including: managing servers, databases, objects, alerts, scheduled tasks, replication and queries.
SQL Security Manager | SQSECMGR.EXE | Used for managing SQL Server integrated login security.
SQL Service Manager | SQLMGR.EXE | Used for starting, stopping, and pausing/continuing SQL Server activity.
SQL Setup | SETUP.EXE | Used initially for installation. Also used for upgrades, installing additional components, changing selected configuration options, and removing an installation.
SQL Transfer Manager | SQLXFR.EXE | Used for managing data or object transfers between Microsoft SQL Server and other SQL Server platforms to SQL Server 6.0.


bcp Command-line Utility

Copies a database table to or from an operating-system file in a user-specified format.

Syntax

bcp [[database_name.]owner.]table_name {in | out} datafile
[/m maxerrors] [/f formatfile] [/e errfile]
[/F firstrow] [/L lastrow] [/b batchsize]
[/n] [/c] [/E]
[/t field_term] [/r row_term]
[/i inputfile] [/o outputfile]
/U login_id [/P password] [/S servername] [/v] [/a packet_size]

where

database_name
Specifies the database. If the table being copied is in your default database, this parameter is optional.
owner
Is the owner's name. This name is optional if you own the table being copied. This parameter is optional. If no owner is specified and you do not own a table of that name, the program will not execute.
table_name
Specifies which database table to copy.
in | out
Specifies the direction of the copy. The in option copies from a file into the database table; the out option copies to a file from the database table.
datafile
Is the full path of an operating-system file when copying a table to or from a hard-disk file or a single diskette. The path can have from 1 through 255 characters. When copying a table to or from multiple diskettes, datafile is a drive specifier only (such as A:).
/m maxerrors
Is the maximum number of errors that can occur before the copy is canceled. Each row that cannot be rebuilt by bcp is ignored and counted as one error. If this option is not included, the default is 10.
/f formatfile
Is the full path of a file with stored responses from a previous use of bcp on the same table; creation of the format file is optional. Use this option when you have already created a format file that you want to use when copying in or out. After you answer format questions, bcp asks whether you want to save your answers in a format file. The default filename is BCP.FMT. The bcp utility can refer to a format file when copying data so that you do not have to duplicate your previous format responses interactively. If this option is not used, bcp queries you for format information.
/e errfile
Is the full path of an error file where bcp stores any rows that it was unable to transfer from the file to the database. Error messages from the bcp utility go to the user's workstation. If this option is not used, no error file is created.
/F firstrow
Specifies the number of the first row to copy (the default is the first row).
/L lastrow
Specifies the number of the last row to copy (the default is the last row).
/b batchsize
Specifies the number of rows per batch of data copied (the default copies all the rows in one batch).
/n
Performs the copy operation using the data's native (database) datatypes as the default. This option does not prompt for each field; it uses the default values.
/c
Performs the copy operation with a character datatype as the default. This option does not prompt for each field; it uses char as the default storage type, no prefixes, \t (tab) as the default field separator, and \n (new line) as the default row terminator.
/E
Is used when identity values are present within the table to be imported.

When importing data, an identity column is temporarily assigned an identity value of 0. As the rows are inserted into the table, SQL Server assigns unique values based on the seed and increment values specified during table creation. Use the /E flag when identity values already exist in the file. If SQL Server-generated identity values are preferred, place only non-identity columns in the file.

/t field_term
Is the default field terminator.
/r row_term
Is the default row terminator.
/i inputfile
Is the name of a file that redirects input to bcp.
/o outputfile
Is the name of a file that receives output redirected from bcp.
/U login_id
Is a login ID.
/P password
Is a user-specified password. If this option is not used, bcp prompts for a password. If this option is used at the end of the command line without any password, bcp uses the default password (NULL).
/S servername
Specifies which SQL Server to connect to. The servername is the name of the server computer on the network. This option is required when you are executing bcp from a remote computer on the network.
/v
Reports the current DB-Library version number.
/a packet_size
Is the number of bytes, per network packet, sent to and from the server. A server configuration option can be set using SQL Enterprise Manager (or the sp_configure system stored procedure). However, this option can be overridden on an individual basis with the bcp /a option. The valid values for packet_size are 512 through 65535. The server default is 4096; the default value for the Windows NT - based version of bcp is 4096. The default value for MS-DOS is 512, although larger sizes can be requested.

Increased packet size may enhance performance on bulk copy operations. Microsoft testing indicates that 4096 to 8192 is typically the fastest setting for bulk copy operations. If a larger packet is requested but cannot be granted, the client will default to 512. The performance statistics generated at the end of a bcp run will show the actual packet size used.


console Command-line Utility

Displays backup and restore messages when dumping or loading to or from diskette dump devices. The console command-line utility is used by the person responsible for dumping and loading a database.

Syntax

console [/S servername] [/P pipename]

where

/S servername
Specifies which SQL Server to connect to. The servername is the name of the server computer on the network. This option is required when you are executing console from a remote computer on the network.
/P pipename
Specifies the pipe that the server was started with.

Remarks

The console program must be running before a DUMP or LOAD statement can proceed for diskette dump devices.

The console program prompts the operator for information related to mounting and unmounting diskettes. Since the console workstation (which can be any screen group) displays prompts and messages for the operator, run it in a window on the same Windows NT - based workstation that is running SQL Server. Most console messages are self-explanatory. To stop a dump or load to a diskette, press N in response to any prompt to mount a new diskette.

If two diskettes (that is, two dumps/loads) are being used at once, only one console is needed. The program prints messages one at a time, waiting for a response before displaying the next prompt. For this reason, the messages include the name of the physical drive to which they pertain.

Make sure that the diskette you are using is formatted and not write-protected.

The console utility uses named pipes. If you want to use console on an alternate pipe, you must set up the connection using the SQL Client Configuration Utility.

For details, see the Microsoft SQL Server Administrator's Companion.

Note If the console utility has been started and appears to be unusable, wait for 1 minute and try to use it again. (SQL Server may be in the process of fixing a broken console connection).


isql Command-line Utility

For SQL Server 6.5 information, see ISQLPASSWORD in What's New for SQL Server 6.5.

Allows you to enter SQL statements and system procedures.

Syntax

isql /U login_id [/e] [/E] [/p] [/n] [/d dbname] [/q "query"] [/Q "query"]
[/c cmdend] [/h headers] [/w columnwidth] [/s colseparator]
[/t timeout] [/m errorlevel] [/L] [/?] [/r {0 | 1}]
[/H wksta_name] [/P password]
[/S servername] [/i inputfile] [/o outputfile] [/a packet_size]

where

/U login_id
Is the user login ID. Login IDs are case-sensitive.
/e
Echoes input.
/E
Uses a trusted connection instead of requesting a password.
/p
Prints performance statistics.
/n
Removes numbering and the prompt symbol (>) from input lines.
/d dbname
Issues a USE dbname statement when isql is started.
/q "query"
Executes a query when isql starts. (Note, the query statement should not include GO). If you issue a query from a batch file, you can use %variables. Environment %variables% also work. For example:

SET table = sysobjects
isql /q "Select * from %table%"

Use double quotation marks around the query and single quotation marks around anything embedded in the query.

/Q "query"
Executes a query and immediately exits isql. Use double quotation marks around the query and single quotation marks around anything embedded in the query.
/c cmdend
Specifies the command terminator. By default, commands are terminated and sent to SQL Server by entering GO on a line by itself. When you reset the command terminator, do not use SQL reserved words or characters that have special meaning to the operating system, whether preceded by a backslash or not.
/h headers
Specifies the number of rows to print between column headings. The default is to print headings only once for each set of query results. Use -1 to specify that no headers will be printed. If using -1, there must be no space between the parameter and the setting (/h-1, not /h -1).
/w columnwidth
Allows the user to set the screen width for output. The default is 80 characters. When an output line has reached its maximum screen width, it is broken into multiple lines.
/s colseparator
Specifies the column-separator character, which is blank by default. To use characters that have special meaning to the operating system (for example, | ; & < >), precede the character with a backslash (\).
/t timeout
Specifies the number of seconds before a command times out. If no timeout is specified, a command runs indefinitely; the default timeout for logging in to isql is 8 seconds.
/m errorlevel
Customizes the display of error messages. The message number, state, and error level are displayed for errors of the specified severity level or higher. Nothing is displayed for errors of levels lower than the specified level. Use -1 to specify that all headers are returned with messages, even informational messages. If using -1, there must be no space between the parameter and the setting (/m-1, not /m -1).
/L
Lists the locally configured servers and the names of the servers broadcasting on the network.
/?
Displays the syntax summary of isql switches.
/r {0 | 1}
Redirects message output to stderr. If you don't specify a parameter, or if you specify 0, only error-level message severity (severity 17 or higher) is redirected. If you specify 1, all message output (including "print") is redirected.
/H wksta_name
Is a workstation name, changing the value in the dynamic system table sysprocesses, if the user logs in from a computer different from the usual login computer. If no workstation name is specified, the current computer name is assumed.
/P password
Is a user-specified password. If the /P option is not used, isql prompts for a password. If the /P option is used at the end of the command line without any password, isql uses the default password NULL. Passwords are case-sensitive.
/S servername
Specifies which SQL Server to connect to. The servername is the name of the server computer on the network. This option is required if you are executing isql from a remote computer on the network.
/i inputfile
Identifies the file that contains a batch of SQL statements or stored procedures. The less-than symbol (<) can be used in place of /i.
/o outputfile
Identifies the file that receives output from isql. The greater-than symbol (>) can be used in place of /o.
/a packet_size
Allows you to request a different size packet. The valid values for packet_size are 512 through 65535. The default value for the Windows NT - based version of isql is 8192; otherwise, the default value is 512 for MS-DOS, although larger sizes can be requested with that version as well. Increased packet size can enhance performance on larger script execution where the amount of SQL statements between GO statements is substantial. Microsoft testing indicates that 8192 is typically the fastest setting for bulk copy operations. A larger packet size can be requested, but will default to 512 if the request cannot be granted.

Remarks

The isql utility is started directly from the operating system with the case-sensitive options listed here. Once started, isql accepts SQL commands and sends them to SQL Server interactively. The results are formatted and printed on the standard output device (the screen). Use QUIT or EXIT to exit from isql.

If you do not specify a username when you start isql, SQL Server checks for the environment variables ¾ for example, isqluser=(user) or isqlserver=(server), and uses those. If no environment variables are set, the workstation username is used. If you do not specify a server, the name of the workstation is used.

If neither the /U or /P options are used, SQL Server uses the currently logged in user account and will not prompt for a password. This is useful when using integrated or mixed security. For details about security, see the Microsoft SQL Server Administrator's Companion.

In addition to using Transact-SQL statements within isql, use the following commands:

Command | Description
GO | Executes a command.
RESET | Clears any statements you have entered.
ED | Calls the editor.
!! command | Executes an operating-system command.
QUIT or EXIT( ) | Exits from isql.
ctrl+c | Terminates a query without exiting from isql.

The command terminators, GO (by default), RESET, ED, !!, EXIT, QUIT, and CTRL+C, are recognized only if they appear at the beginning of a line, immediately following the isql prompt. Anything entered on the same line after these keywords is disregarded by isql.

Terminate a command by typing a line beginning with a command terminator. You can follow the command terminator with an integer to specify how many times the command should be run. For example, to execute this command 100 times, type:

SELECT x = 1
go 100

The results are printed once, at the end of execution.

With isql, there is a limit of 1000 characters per line. Large statements should be spread across multiple lines.

The user can call an editor on the current query buffer by typing ED as the first word on a line. Operating-system commands can also be executed by starting a line with two exclamation points (!!) followed by the command. The editor is defined in the EDITOR environment variable. The default editor is "edit" for MS-DOS and Windows NT. You can specify a different editor by setting the EDITOR environment variable. For example, to make the default editor Notepad, at the operating-system prompt, type:

SET EDITOR=notepad

The command recall facilities of DOSKEY can be used to recall and modify previously entered isql statements on a Windows NT - based computer. The existing query buffer can be cleared by typing RESET on a line by itself. It causes any pending input to be discarded.

When running stored procedures, isql prints a blank line between each set of results in a batch. In addition, the "0 rows affected" message does not appear when it doesn't apply to the statement executed.

To use isql interactively, type the isql command (and any of the options) at the operating-system prompt.

You can read in a file containing a query (such as STORES.QRY) for execution by isql by typing a command similar to this:

isql /U alma /P /i stores.qry

The file must include a command terminator(s). The results are displayed on the user's workstation.

You can read in a file containing a query (such as TITLES.QRY) and direct the results to another file by typing a command similar to this:

isql /U alma /P /i titles.qry /o titles.res

When using isql interactively, you can read an operating-system file into the command buffer with :r filename. Do not include a command terminator in the file; enter the terminator interactively once you have finished editing.

You can include comments in a Transact-SQL statement submitted to SQL Server by isql. Two types of commenting styles are allowed. For more information, see the Comments topic.

For example:

SELECT au_lname, au_fname
 -- Retrieve authors' last and first names.
    FROM authors a, titles t, titleauthor ta
        WHERE a.au_id = ta.au_id
        AND t.title_id = ta.title_id
/* This is a three-way join that links authors
** to the books they have written. */

Note Do not include a GO command within a comment. A GO command within a comment produces an error message.

You can return the result of an integer SELECT as the return value from isql. The first column of the first result row is converted to a 4-byte integer (long). MS-DOS passes the low byte to the parent process or operating-system error level. Windows NT passes the entire 4-byte integer. The syntax is:

EXIT(query)

For example:

EXIT(SELECT @@rowcount)

EXIT(SELECT 5)

You can also include the exit parameter as part of a batch file. For example:

isql /Q "EXIT(SELECT COUNT(*) FROM '%1')"

The isql utility passes everything between the parentheses ( ) to the server exactly as entered. The EXIT( ) statement can span lines. If a stored system procedure selects a set and returns a value, only the selection is returned. The EXIT( ) statement with nothing between the parentheses executes everything preceding it in the batch and then exits with no return value.

There are four exit formats:

  • EXIT

    Does not execute the batch; quits immediately and returns no value.

  • EXIT( )

    Executes the batch, and then quits and returns no value.

  • EXIT(query)

    Executes the batch, including the query, and then quits, returning the results of the query.

  • Using the RAISERROR statement with a severity of 127. If RAISERROR is used within an isql script and a severity of 127 is raised, isql will terminate and return the message ID back to the client. For example,
    RAISERROR(50001, 10, 127)

    This error will cause the isql script to terminate and the message ID 50001 will be returned to the to the client.

The return values - 1 to - 99 are reserved by SQL Server; isql defines the following values:

- 100: Error encountered prior to selecting return value.

- 101: No rows found when selecting return value.

- 102: Conversion error when selecting return value.


makepipe Command-line Utility

Tests the integrity of the network named pipe services, in conjunction with readpipe.

Syntax

makepipe [/h] [/w] [/p pipename]

where

/h
Displays usage.
/w
Specifies the wait time, in seconds, between read and write. The default is 0.
/p pipename
Is the name of the pipe. The default pipename is abc.

Remarks

This diagnostic utility checks to see if the named pipes are working. Use it (along with readpipe) if you cannot connect to SQL Server.

See Also

readpipe Command-line Utility


readpipe Command-line Utility

Tests the integrity of the network named pipe services, in conjunction with makepipe.

Syntax

readpipe /S servername /D string [/n] [/q] [/w] [/t] [/p pipename] [/h]

where

/S servername
Is the name of the SQL Server on which you just ran makepipe. Note that there are no spaces between /S and servername.
/D string
Is a test character string. Note that there are no spaces between /D and string.
/n
Specifies the number of iterations.
/q
Queries for incoming data (polling). Without /q, readpipe reads the pipe and waits for data.
/w
Specifies the wait time, in seconds, to pause while polling. The default is 0.
/t
Asks for Transact-SQL named pipes. This option overrides polling.
/p pipename
Is the name of the pipe. The default pipename is abc.
/h
Displays usage.

Remarks

This diagnostic utility checks to see if the named pipes are working. Use it (along with makepipe) if you cannot connect to SQL Server.

Because applications for Windows, Windows NT, and MS-DOS all run on Windows NT, you must be careful about which version of makepipe and readpipe you are running. You must use the version specific to the operating system on which you are testing the integrity of the named pipe.

After makepipe is started, the server waits for a client to connect. The readpipe command-line utility can then be run from other workstations. When all testing is complete, go to the screen where the makepipe program is still running and press CTRL+BREAK or CTRL+C to stop execution.

See Also

makepipe command-line utility


sqlservr Command-line Executable

Is the SQL Server executable program.

Syntax

sqlservr [/c] [/d master_device_path] [/f] [/e error_log_path] [/m] [/n]
[/p precision_level] [/r master_mirror] [/s registry_key] [/T trace#] [/x]

where

/c
Indicates to start SQL Server independent of the Windows NT Service Control Manager. This option is used when starting SQL Server from the command line to shorten the amount of time it takes for SQL Server to start. (Note that when you use this option, you cannot stop SQL Server using the SQL Service Manager or the net stop command. And if you log off from the Windows NT system, the SQL Server will be stopped.)
/d master_device_path
Indicates the fully qualified path for the MASTER database device (typically, C:\SQL60\DATA\MASTER.DAT). Note that there is no space between /d and master_device_path.
/f
Starts the server in minimally configured mode. The system administrator can then reconfigure configuration options (with the sp_configure system stored procedure) and avoid using the bldmastr command-line utility.
/e error_log_path
Indicates the fully qualified path for the error log file (typically, C:\SQL60\LOG\ERRORLOG). If you do not specify this option, an error log is not written. Note that there is no space between /e and error_log_path.
/m
Indicates to start SQL Server in single-user mode. When you start SQL Server in single-user mode, only a single user can connect, and the CHECKPOINT mechanism, which guarantees that completed transactions are regularly written from the disk cache to the database device, is not started. (Typically, this option is used if you experience problems with system databases that need to be repaired.)
/n
Indicates that you do not want to use the Windows NT event log to log SQL Server events. If you start SQL Server with the /n option, it is advisable to use the /e option too, or SQL Server events will not be logged.
/p precision_level
Specifies the maximum level of precision to be supported by decimal and numeric datatypes. By default, SQL Server has a maximum precision of 28. The acceptable values for precision_level are from 1 through 38; however, if no precision_level is supplied with the /p parameter, a maximum precision of 38 will be allowed for decimal and numeric datatypes.
/r master_mirror
Indicates the fully qualified path for the device used to mirror the MASTER database device. Use this option when starting SQL Server if the MASTER database device is damaged. (SQL Server always attempts to use the primary device specified by the /d option before it uses the mirror device specified by the /r option.)
/s registry_key
Indicates that you want to start SQL Server using an alternate set of startup parameters stored in the Windows NT Registry under the key registry_key. This option, which can be run only from the command line, lets you select from multiple previously defined startup configurations. You could, for example, create an alternate Registry key to start SQL Server in single-user mode.
/T trace#
Indicates that SQL Server should be started with a specified trace flag (trace#) in effect. Trace flags are used to start the server with non-standard behavior. For a list of available trace flags (trace#), see the Trace Flags topic.

Important When specifying a trace flag, use /T to pass the trace flag number. A lower case t (/t) is accepted by SQL Server; however, /t sets other internal trace flags that are needed only by SQL Server support engineers.

/x
Disables maintaining CPU statistics.


Variables

Variables are user-defined entities that are assigned values. A local variable is defined with a DECLARE statement, assigned an initial value with a SELECT statement, and used within the statement batch or procedure in which it was declared. Global variables are predefined and maintained by the system.

The following sections describe the declaration of local variables as well as the use of local and global variables.

Local Variables

Local variables are declared in the body of a batch or procedure with the DECLARE statement and given values with a SELECT statement. Local variables are often used in a batch or procedure as counters for WHILE loops or for IF...ELSE blocks.

Syntax

Variable declaration:

DECLARE @variable_name datatype
[, @variable_name datatype...]

Variable assignment:

SELECT @variable = {expression | select_statement}
[, @variable = {expression | select_statement}...]
[FROM table_list]
[WHERE search_conditions]
[GROUP BY clause]
[HAVING clause]
[ORDER BY clause]

where

@variable_name
Is the name of a variable. Variable names must be preceded by the "at" symbol (@). The single @ preceding the alphanumeric name signifies a local variable name. The variable name must conform to the rules for identifiers except that it can contain only 29 characters. Variables can be used only in place of constants. In standard SQL statements, variables cannot be used in place of the names of tables, columns, other database objects, or keywords. In SQL Server 6.0, strings can be resolved at execution time (rather than at compile time) by using the EXECUTE statement. For more information, see the EXECUTE statement.
datatype
Is a system or user-defined datatype. A variable cannot be of the image datatype. For more information on system datatypes, see the Datatypes topic. For more information about user-defined datatypes, see the sp_addtype system stored procedure.

Remarks

Local variables are often used in batches, stored procedures, and control-of-flow statement blocks. Local variables can be used only within the batch or procedure in which they are declared. When used in stored procedures, local variables are declared for automatic, non-interactive use by the procedure when it executes.

The SELECT statement that assigns a value to the local variable usually returns a single value. If the SELECT variable assignment statement returns more than one value, the variable is assigned the last value returned. If the SELECT variable assignment statement returns no rows, the variable retains its present value unless the variable assignment is made with a subquery. Only if the subquery returns no rows is the variable set to NULL. The SELECT statement that assigns values to variables cannot retrieve data in the same statement.

Global Variables

Predefined global variables can be used without being declared. Global variables are distinguished from local variables by having two "at" symbols (@@) preceding their names. Many of the global variables report on system activity since the last time SQL Server was started; others report information about a connection. In the listing that follows, connection-specific variables are noted with an asterisk (*). For information on the contents of a connection-specific variable, execute SELECT @@variablename. For the contents of many of these global variables, execute the sp_monitor system stored procedure.

@@CONNECTIONS
Specifies the number of logins or attempted logins since SQL Server was last started.
@@CPU_BUSY
Specifies the amount of time, in ticks (one three-hundredth second, or 3.33 milliseconds), that the CPU has spent doing SQL Server work since the last time SQL Server was started.
@@CURSOR_ROWS*
Specifies the number of qualifying rows in the last-opened cursor. @@CURSOR_ROWS returns:
-m | If the cursor is being populated asynchronously. The value returned (-m) refers to the number of rows currently in the keyset.
n | If the cursor is fully populated. The value returned (n) refers to the number of rows.
0 | If no cursors have been opened or the last opened cursor has been closed or deallocated.

@@DATEFIRST
Returns the current value of the SET DATEFIRST parameter. Indicates the first day of each week: 1 for Monday, 2 for Tuesday, and so on through for Sunday.
@@DBTS
Specifies the value of the current timestamp datatype for the database. This timestamp is guaranteed to be unique for the database.
@@ERROR*
Specifies the last error number generated by the system for the user connection. The @@ERROR global variable is commonly used to check the error status (succeed or fail) of the most recently executed statement. It contains 0 if the last statement succeeded. Using @@ERROR with control-of-flow statements is advantageous for handling errors. The statement IF @@ERROR < > 0 RETURN exits if an error is returned.
@@FETCH_STATUS*
Contains the status of a cursor FETCH command. It is set to 0 if the fetch is successful, to - 1 if the fetch failed or the row was beyond results set, - 2 if the row fetched is missing.
@@IDENTITY*
Saves the last-inserted IDENTITY value. The @@IDENTITY variable is updated specifically for each user when an INSERT or SELECT INTO statement or bulk copy inserting into a table occurs. If a statement changes the table without an identity column, @@IDENTITY is set to NULL. The @@IDENTITY value does not revert to a previous setting if the INSERT or SELECT INTO statement or bulk copy fails or if the transaction is rolled back. For more information, see the IDENTITY property.
@@IDLE
Specifies the amount of time, in ticks (one three-hundredth second, or 3.33 milliseconds), that SQL Server has been idle since it was last started.
@@IO_BUSY
Specifies the amount of time, in ticks (one three-hundredth second, or 3.33 milliseconds), that SQL Server has spent doing input and output operations since it was last started.
@@LANGID*
Specifies the local language ID of the language currently in use (specified in syslanguages.langid).
@@LANGUAGE*
Specifies the language currently in use (specified in syslanguages.name).
@@MAX_CONNECTIONS
Specifies the maximum number of simultaneous connections that can be made with SQL Server in the current computer environment. The user can configure SQL Server for fewer connections by using the sp_configure system stored procedure. @@MAX_CONNECTIONS is not necessarily the number configured currently.
@@MAX_PRECISION
Returns the level of precision used by decimal and numeric datatypes as currently set in the server. By default, the maximum precision is 28; however, a larger precision can be set when SQL Server starts by using the /p parameter with sqlservr. For more information, see the Utilities and Executables topic.
@@MICROSOFTVERSION
Is a version used internally to track the current version of the server. If version checking is necessary, use @@VERSION.
@@NESTLEVEL*
Specifies the nesting level of the current execution (initially 0). Each time a stored procedure calls another stored procedure, the nesting level is incremented. If the maximum of 16 is exceeded, the transaction is terminated.
@@PACK_RECEIVED
Specifies the number of input packets read by SQL Server since it was last started.
@@PACK_SENT
Specifies the number of output packets written by SQL Server since it was last started.
@@PACKET_ERRORS
Specifies the number of errors that have occurred while SQL Server was sending and receiving packets since the last time SQL Server was started.
@@PROCID*
Specifies the stored procedure ID of the currently executing procedure.
@@REMSERVER*
Returns the server name contained within a remote server's login record.
@@ROWCOUNT*
Specifies the number of rows affected by the last statement. This variable is set to 0 by any statement that does not return rows, such as an IF statement.
@@SERVERNAME
Specifies the name of the local SQL Server. You must define this name with the sp_addserver system stored procedure, and then restart SQL Server. The setup program sets this variable to the computer name during installation. Although you can change @@SERVERNAME by using the sp_addserver system stored procedure and restarting SQL Server, this method is not usually required.
@@SERVICENAME
Specifies the name of a running service. Currently, @@SERVICENAME defaults to @@SERVERNAME.
@@SPID*
Specifies the server process ID number of the current process (the spid column of the sysprocesses system table).
@@TEXTSIZE*
Specifies the current value of the TEXTSIZE option of the SET statement, which specifies the maximum length, in bytes, of text or image data that a SELECT statement returns. The default limit is 4K.
@@TIMETICKS
Specifies the number of microseconds per tick. The amount of time per tick is computer-dependent. Each tick on the operating system is 31.25 milliseconds (1/32 second).
@@TOTAL_ERRORS
Specifies the number of errors that have occurred while SQL Server was reading or writing since the last time SQL Server was started.
@@TOTAL_READ
Specifies the number of disk reads by SQL Server since it was last started (disk reads only, not cache reads).
@@TOTAL_WRITE
Specifies the number of disk writes by SQL Server since it was last started.
@@TRANCOUNT*
Specifies the number of currently active transactions for the current user.
@@VERSION
Specifies the date, version number, and processor type for the current version of SQL Server.

See Also

Datatypes | RAISERROR
PRINT | sp_monitor


Wildcard Characters

Wildcard characters are used with the LIKE keyword to represent any character in a string when searching for a char, varchar, or datetime value.

Syntax

expression [NOT] LIKE 'string'

The string can include these wildcard characters:

Wildcard | Meaning
% | Any string of zero or more characters
_ (underscore) | Any single character
[ ] | Any single character within the specified range ([a-f]) or set ([abcdef])
[^] | Any single character not within the specified range ([^a-f]) or set ([^abcdef])

Remarks

You can use the LIKE keyword and wildcard characters with datetime data as well as with char and varchar data. When you use LIKE with datetime values, SQL Server converts the dates to the standard datetime format and then to varchar. Since the standard storage format doesn't include seconds or milliseconds, you cannot search for seconds or milliseconds with LIKE and a pattern. It is a good idea to use LIKE when you search for datetime values, since datetime entries can contain a variety of date parts. For example, if you insert the value 9:20 into a column named arrival_time, the clause WHERE arrival_time = '9:20' does not find the value because SQL Server converts the entry into 'Jan 1, 1900 9:20 AM'. However, the clause WHERE arrival_time LIKE '%9:20%' does find the value.

To use %, _, [ ], or [^] as literal characters in a LIKE string rather than as wildcards, use square brackets around the percent sign, the underscore, and the open bracket. Use the close bracket by itself. Use the dash as the first character inside a set of square brackets, as shown here:

Symbol | Meaning
LIKE '5%' | 5 followed by any string of 0 or more characters
LIKE '5[%]' | 5%
LIKE '_n' | an, in, on, and so on
LIKE '[_]n' | _n
LIKE '[a-cdf]' | a, b, c, d, or f
LIKE '[-acdf]' | -, a, c, d, or f
LIKE '[ [ ]' | [
LIKE ']' | ]

You can't always duplicate NOT LIKE patterns with LIKE and the negative wildcard [^] because NOT LIKE finds the items that do not match the entire LIKE pattern; LIKE with negative wildcards is evaluated one character at a time.

For example, this query shows all system tables in a database, because they all begin with the letters sys:

SELECT name
FROM sysobjects
WHERE name LIKE 'sys%'

To see all objects that are not system tables, use NOT LIKE 'sys%'. If you have a total of 32 objects and LIKE finds 13 names that match the pattern, NOT LIKE finds the 19 objects that do not match the LIKE pattern.

You won't always find the same names with a pattern such as LIKE '[^s][^y][^s]%'. Instead of 19 names, you might get only 14, with all the names that begin with "s" or have "y" as the second letter or have "s" as the third letter eliminated from the results as well as the system table names. This result occurs because match strings with negative wildcards are evaluated in steps, one wildcard at a time. If the match fails at any point in the evaluation, it is eliminated.

Pattern Matching with Blanks

When performing string comparisons with LIKE, all characters in the pattern string are significant, including every leading and/or trailing blank (space). If a comparison to return all rows with a string LIKE 'abc ' (abc followed by a single space) is requested, a row where the value of that column is 'abc' (abc without a space) will not be returned. The reverse, however, is not true. Trailing blanks in the expression to which the pattern is matched are ignored. If a comparison to return all rows with a string LIKE 'abc' (abc without a space) is requested, all rows that start with 'abc' and have zero or more trailing blanks would be returned.

A string comparison using a pattern char and varchar data may not pass a LIKE comparison because of how the data is stored. It is important to understand the storage for each datatype and where a LIKE comparison may fail. In the following example, a local char variable is passed to a stored procedure and then pattern matching is used to find all of the books by a certain author. In this procedure, the author's last name is passed as a variable.

CREATE PROCEDURE find_books @au_lname char(20)
AS
SELECT @au_lname = RTRIM(@au_lname)  '%'
SELECT t.title_id, t.title
    FROM authors a, titleauthor ta, titles t
        WHERE a.au_id = ta.au_id AND ta.title_id = t.title_id
        AND a.au_lname LIKE @au_lname

In the find_books procedure, no rows will be returned because the char variable (@au_lname) will contain trailing blanks whenever the name contains fewer than 20 characters. Because the au_lname column is varchar, there are no trailing blanks. This procedure will fail because the trailing blanks are significant.

This example succeeds because trailing blanks are not added to a varchar variable:

CREATE PROCEDURE find_books2 @au_lname varchar(20)
AS
SELECT t.title_id, t.title
    FROM authors a, titleauthor ta, titles t
        WHERE a.au_id = ta.au_id AND ta.title_id = t.title_id
        AND a.au_lname LIKE @au_lname  '%'

Examples

A. Pattern Matching with LIKE and %

This example finds all phone numbers in the authors table that begin with the 415 area code:

SELECT phone
    FROM authors
        WHERE phone LIKE '415%'
B. Pattern Matching and Placement of NOT

These two queries are equivalent: they find all phone numbers in the authors table that do not begin with the 415 area code:

SELECT phone
    FROM authors
        WHERE phone NOT LIKE '415%'

SELECT phone
    FROM authors
        WHERE NOT phone LIKE '415%'
C. Multiple Wildcards

This example finds all names that have the characters "en" in them (Bennet, Green, McBadden):

SELECT au_lname
    FROM authors
        WHERE au_lname LIKE '%en%'
D. Single Character Wildcard

This example finds six-letter names that end with "heryl" (Cheryl or Sheryl):

SELECT au_fname
    FROM authors
        WHERE au_fname LIKE '_heryl'
E. Single Character Range

This example finds names ending with "inger" and beginning with any single character between "M" and "Z":

SELECT au_lname
    FROM authors
        WHERE au_lname LIKE '[M-Z]inger'
F. Single Character Listing

This example finds both DeFrance and deFrance:

SELECT au_lname
    FROM authors
        WHERE au_lname LIKE '[dD]eFrance'
G. NOT a Single Character

This example finds names beginning with "M" that have a second letter that is not "c":

SELECT au_lname
    FROM authors
        WHERE au_lname LIKE 'M[^c]%'

See Also

Expressions Search Conditions


Appendix A System Tables Diagram

System Tables Diagram

The following illustration shows the realtionships among the system catalog and database catalog tables.


Appendix B The pubs sample Database

The pubs sample Database

authors Table

Column_name | Datatype | Nullable | Default | Check | Key/Index

au_id | id | no |  | yes (1) | PK, clust.
au_lname | varchar(40) | no |  |  | Composite, nonclust. (3)
au_fname | varchar(20) | no |  |  | Composite, nonclust. (3)
phone | char(12) | no | 'UNKNOWN' |  |
address | varchar(40) | yes |  |  |
city | varchar(20) | yes |  |  |
state | char(2) | yes |  |  |
zip | char(5) | yes |  | yes (2) |
contract | bit | no |  |  |
(1) The au_id CHECK constraint is defined as (au_id LIKE '[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]'). (2) The zip CHECK constraint is defined as (zip LIKE '[0-9][0-9][0-9][0-9][0-9]'). (3) The composite, nonclustered index is defined on au_lname, au_fname.

The following tables show the contents of the authors table. The first column (au_id) is repeated in the lower listing, along with columns #5 through #9. Column #1 is repeated for readability purposes only.

au_id (#1) au_lname (#2) au_fname (#3) phone (#4)

172-32-1176 | White | Johnson | 408 496-7223
213-46-8915 | Green | Marjorie | 415 986-7020
238-95-7766 | Carson | Cheryl | 415 548-7723
267-41-2394 | O'Leary | Michael | 408 286-2428
274-80-9391 | Straight | Dean | 415 834-2919
341-22-1782 | Smith | Meander | 913 843-0462
409-56-7008 | Bennet | Abraham | 415 658-9932
427-17-2319 | Dull | Ann | 415 836-7128
472-27-2349 | Gringlesby | Burt | 707 938-6445
486-29-1786 | Locksley | Charlene | 415 585-4620
527-72-3246 | Greene | Morningstar | 615 297-2723
648-92-1872 | Blotchet-Halls | Reginald | 503 745-6402
672-71-3249 | Yokomoto | Akiko | 415 935-4228
712-45-1867 | del Castillo | Innes | 615 996-8275
722-51-5454 | DeFrance | Michel | 219 547-9982
724-08-9931 | Stringer | Dirk | 415 843-2991
724-80-9391 | MacFeather | Stearns | 415 354-7128
756-30-7391 | Karsen | Livia | 415 534-9219
807-91-6654 | Panteley | Sylvia | 301 946-8853
846-92-7186 | Hunter | Sheryl | 415 836-7128
893-72-1158 | McBadden | Heather | 707 448-4982
899-46-2035 | Ringer | Anne | 801 826-0752
998-72-3567 | Ringer | Albert | 801 826-0752

au_id (#1) | address (#5) | city (#6) | state (#7) | zip (#8) | contract (#9)

172-32-1176 | 10932 Bigge Rd. | Menlo Park | CA | 94025 | 1
213-46-8915 | 309 63rd St. #411 | Oakland | CA | 94618 | 1
238-95-7766 | 589 Darwin Ln. | Berkeley | CA | 94705 | 1
267-41-2394 | 22 Cleveland Av. #14 | San Jose | CA | 95128 | 1
274-80-9391 | 5420 College Av. | Oakland | CA | 94609 | 1
341-22-1782 | 10 Mississippi Dr. | Lawrence | KS | 66044 | 0
409-56-7008 | 6223 Bateman St. | Berkeley | CA | 94705 | 1
427-17-2319 | 3410 Blonde St. | Palo Alto | CA | 94301 | 1
472-27-2349 | PO Box 792 | Covelo | CA | 95428 | 1
486-29-1786 | 18 Broadway Av. | San Francisco | CA | 94130 | 1
527-72-3246 | 22 Graybar House Rd. | Nashville | TN | 37215 | 0
648-92-1872 | 55 Hillsdale Bl. | Corvallis | OR | 97330 | 1
672-71-3249 | 3 Silver Ct. | Walnut Creek | CA | 94595 | 1
712-45-1867 | 2286 Cram Pl. #86 | Ann Arbor | MI | 48105 | 1
722-51-5454 | 3 Balding Pl. | Gary | IN | 46403 | 1
724-08-9931 | 5420 Telegraph Av. | Oakland | CA | 94609 | 0
724-80-9391 | 44 Upland Hts. | Oakland | CA | 94612 | 1
756-30-7391 | 5720 McAuley St. | Oakland | CA | 94609 | 1
807-91-6654 | 1956 Arlington Pl. | Rockville | MD | 20853 | 1
846-92-7186 | 3410 Blonde St. | Palo Alto | CA | 94301 | 1
893-72-1158 | 301 Putnam | Vacaville | CA | 95688 | 0
899-46-2035 | 67 Seventh Av. | Salt Lake City | UT | 84152 | 1
998-72-3567 | 67 Seventh Av. | Salt Lake City | UT | 84152 | 1

discounts Table

Column_name | Datatype | Nullable | Default | Check | Key/Index

discounttype | varchar(40) | no |
stor_id | char(4) | yes | FK stores(stor_id)
lowqty | smallint | yes |
highqty | smallint | yes |
discount | float | no |

discounttype | stor_id | lowqty | highqty | discount

Initial Customer | NULL | NULL | NULL | 10.5
Volume Discount | NULL | 100 | 1000 | 6.7
Customer Discount | 8042 | NULL | NULL | 5.0

employee Table

Column_name Datatype Nullable Default Check Key/Index

emp_id | empid | no |  | yes (1) | PK, nonclust.
fname | varchar(20) | no |  |  | Composite, clust. (2)
minit | char(1) | yes |  |  | Composite, clust. (2)
lname | varchar(30) | no |  |  | Composite, clust. (2)
job_id | smallint | no | 1 |  | FK jobs(job_id)
job_lvl | tinyint | no | 10 |  |
pub_id | char(4) | no | '9952' |  | FK publishers(pub_id)
hire_date | datetime | no | GETDATE( ) |  |
(1) The CHECK constraint is defined as (emp_id LIKE '[A-Z][A-Z][A-Z][1-9][0-9][0-9][0-9][0-9][FM]') OR (emp_id LIKE '[A-Z]-[A-Z][1-9][0-9][0-9][0-9][0-9][FM]') (2) The composite, clustered index is defined on lname, fname, minit.

The following tables show the contents of the authors table. The first column (emp_id) is repeated in the lower listing, along with columns #6 through #8. Column #1 is repeated for readability purposes only.

emp_id (#1) | fname (#2) | minit (#3) | lname (#4) | job_id (#5)

PMA42628M | Paolo | M | Accorti | 13
PSA89086M | Pedro | S | Alfonso | 14
VPA30890F | Victoria | P | Ashworth | 6
H-B39728F | Helen | NULL | Bennett | 12
L-B31947F | Lesley | NULL | Brown | 7
F-C16315M | Francisco | NULL | Chang | 4
PTC11962M | Philip | T | Cramer | 2
A-C71970F | Aria | NULL | Cruz | 10
AMD15433F | Ann | M | Devon | 3
ARD36773F | Anabela | R | Domingues | 8
PHF38899M | Peter | H | Franken | 10
PXH22250M | Paul | X | Henriot | 5
CFH28514M | Carlos | F | Hernández | 5
PDI47470M | Palle | D | Ibsen | 7
KJJ92907F | Karla | J | Jablonski | 9
KFJ64308F | Karin | F | Josephs | 14
MGK44605M | Matti | G | Karttunen | 6
POK93028M | Pirkko | O | Koskitalo | 10
JYL26161F | Janine | Y | Labrune | 5
M-L67958F | Maria | NULL | Larsson | 7
Y-L77953M | Yoshi | NULL | Latimer | 12
LAL21447M | Laurence | A | Lebihan | 5
ENL44273F | Elizabeth | N | Lincoln | 14
PCM98509F | Patricia | C | McKenna | 11
R-M53550M | Roland | NULL | Mendel | 11
RBM23061F | Rita | B | Müller | 5
HAN90777M | Helvetius | A | Nagy | 7
TPO55093M | Timothy | P | O'Rourke | 13
SKO22412M | Sven | K | Ottlieb | 5
MAP77183M | Miguel | A | Paolino | 11
PSP68661F | Paula | S | Parente | 8
M-P91209M | Manuel | NULL | Pereira | 8
MJP25939M | Maria | J | Pontes | 5
M-R38834F | Martine | NULL | Rancé | 9
DWR65030M | Diego | W | Roel | 6
A-R89858F | Annette | NULL | Roulet | 6
MMS49649F | Mary | M | Saveley | 8
CGS88322F | Carine | G | Schmitt | 13
MAS70474F | Margaret | A | Smith | 9
HAS54740M | Howard | A | Snyder | 12
MFS52347M | Martín | F | Sommer | 10
GHT50241M | Gary | H | Thomas | 9
DBT39435M | Daniel | B | Tonini | 11

emp_id (#1) job_lvl (#6) pub_id (#7) hire_date (#8)

PMA42628M | 35 | 0877 | Aug 27 1992 12:00AM
PSA89086M | 89 | 1389 | Dec 24 1990 12:00AM
VPA30890F | 140 | 0877 | Sep 13 1990 12:00AM
H-B39728F | 35 | 0877 | Sep 21 1989 12:00AM
L-B31947F | 120 | 0877 | Feb 13 1991 12:00AM
F-C16315M | 227 | 9952 | Nov 3 1990 12:00AM
PTC11962M | 215 | 9952 | Nov 11 1989 12:00AM
A-C71970F | 87 | 1389 | Oct 26 1991 12:00AM
AMD15433F | 200 | 9952 | Jul 16 1991 12:00AM
ARD36773F | 100 | 0877 | Jan 27 1993 12:00AM
PHF38899M | 75 | 0877 | May 17 1992 12:00AM
PXH22250M | 159 | 0877 | Aug 19 1993 12:00AM
CFH28514M | 211 | 9999 | Apr 21 1989 12:00AM
PDI47470M | 195 | 0736 | May 9 1993 12:00AM
KJJ92907F | 170 | 9999 | Mar 11 1994 12:00AM
KFJ64308F | 100 | 0736 | Oct 17 1992 12:00AM
MGK44605M | 220 | 0736 | May 1 1994 12:00AM
POK93028M | 80 | 9999 | Nov 29 1993 12:00AM
JYL26161F | 172 | 9901 | May 26 1991 12:00AM
M-L67958F | 135 | 1389 | Mar 27 1992 12:00AM
Y-L77953M | 32 | 1389 | Jun 11 1989 12:00AM
LAL21447M | 175 | 0736 | Jun 3 1990 12:00AM
ENL44273F | 35 | 0877 | Jul 24 1990 12:00AM
PCM98509F | 150 | 9999 | Aug 1 1989 12:00AM
R-M53550M | 150 | 0736 | Sep 5 1991 12:00AM
RBM23061F | 198 | 1622 | Oct 9 1993 12:00AM
HAN90777M | 120 | 9999 | Mar 19 1993 12:00AM
TPO55093M | 100 | 0736 | Jun 19 1988 12:00AM
SKO22412M | 150 | 1389 | Apr 5 1991 12:00AM
MAP77183M | 112 | 1389 | Dec 7 1992 12:00AM
PSP68661F | 125 | 1389 | Jan 19 1994 12:00AM
M-P91209M | 101 | 9999 | Jan 9 1989 12:00AM
MJP25939M | 246 | 1756 | Mar 1 1989 12:00AM
M-R38834F | 75 | 0877 | Feb 5 1992 12:00AM
DWR65030M | 192 | 1389 | Dec 16 1991 12:00AM
A-R89858F | 152 | 9999 | Feb 21 1990 12:00AM
MMS49649F | 175 | 0736 | Jun 29 1993 12:00AM
CGS88322F | 64 | 1389 | Jul 7 1992 12:00AM
MAS70474F | 78 | 1389 | Sep 29 1988 12:00AM
HAS54740M | 100 | 0736 | Nov 19 1988 12:00AM
MFS52347M | 165 | 0736 | Apr 13 1990 12:00AM
GHT50241M | 170 | 0736 | Aug 9 1988 12:00AM
DBT39435M | 75 | 0877 | Jan 1 1990 12:00AM

jobs Table

Column_name Datatype Nullable Default Check Key/Index

job_id | smallint | no | IDENTITY(1,1) |  | PK, clust.
job_desc | varchar(50) | no | yes (1) |  |
min_lvl | tinyint | no |  | yes (2) |
max_lvl | tinyint | no |  | yes (3) |

job_id | job_desc | min_lvl | max_lvl

1 | New Hire ¾ Job not specified | 10 | 10
2 | Chief Executive Officer | 200 | 250
3 | Business Operations Manager | 175 | 225
4 | Chief Financial Officier | 175 | 250
5 | Publisher | 150 | 250
6 | Managing Editor | 140 | 225
7 | Marketing Manager | 120 | 200
8 | Public Relations Manager | 100 | 175
9 | Acquisitions Manager | 75 | 175
10 | Productions Manager | 75 | 165
11 | Operations Manager | 75 | 150
12 | Editor | 25 | 100
13 | Sales Representative | 25 | 100
14 | Designer | 25 | 100
(1) The DEFAULT constraint is defined as ("New Position ¾ title not formalized yet"). (2) The min_lvl CHECK constraint is defined as (min_lvl >= 10). (3) The max_lvl CHECK constraint is defined as (max_lvl <= 250).

pub_info Table

Column_name | Datatype | Nullable | Default | Check | Key/Index

pub_id | char(4) | no | PK, clust., FK publishers(pub_id)
logo | image | yes |
pr_info | text | yes |

pub_id logo (1) pr_info (2)

0736 | NEWMOON.BMP | This is sample text data for New Moon Books, publisher 0736 in the pubs database. New Moon Books is located in Boston, Massachusettes.
0877 | BINNET.BMP | This is sample text data for Binnet & Hardley, publisher 0877 in the pubs database. Binnet & Hardley is located in Washington, D.C.
1389 | ALGODATA.BMP | This is sample text data for Algodata Infosystems, publisher 1389 in the pubs database. Algodata Infosystems is located in Berkeley, California.
1622 | 5LAKES.BMP | This is sample text data for Five Lakes Publishing, publisher 1622 in the pubs database. Five Lakes Publishing is located in Chicago, Illinois.
1756 | RAMONA.BMP | This is sample text data for Ramona Publishers, publisher 1756 in the pubs database. Ramona Publishers is located in Dallas, Texas.
9901 | GGGG.BMP | This is sample text data for GGG&G, publisher 9901 in the pubs database. GGG&G is located in München, Germany.
9952 | SCOOTNEY.BMP | This is sample text data for Scootney Books, publisher 9952 in the pubs database. Scootney Books is located in New York City, New York.
9999 | LUCERNE.BMP | This is sample text data for Lucerne Publishing, publisher 9999 in the pubs database. Lucerne Publishing is located in Paris, France.
(1) The information shown here is NOT the actual data. It is the filename from which the bitmap (image data) was loaded. (2) The text shown here is NOT the complete text data. When displaying text data the display is limited to a finite number of characters. This information shows the first 120 characters of the text column.

publishers Table

Column_name | Datatype | Nullable | Default | Check | Key/Index

pub_id | char(4) | no | yes (1) | PK, clust.
pub_name | varchar(40) | yes
city | varchar(20) | yes
state | char(2) | yes
country | varchar(30) | yes | 'USA'
(1) The pub_id CHECK constraint is defined as (pub_id = '1756' OR (pub_id = '1622' OR (pub_id ='0877'
OR (pub_id = '0736' OR (pub_id = '1389')))) OR (pub_id LIKE '99[0-9][0-0]').

pub_id | pub_name | city | state | country

0736 | New Moon Books | Boston | MA | USA
0877 | Binnet & Hardley | Washington | DC | USA
1389 | Algodata Infosystems | Berkeley | CA | USA
1622 | Five Lakes Publishing | Chicago | IL | USA
1756 | Ramona Publishers | Dallas | TX | USA
9901 | GGG&G | München | NULL | Germany
9952 | Scootney Books | New York | NY | USA
9999 | Lucerne Publishing | Paris | NULL | France

roysched Table

Column_name Datatype Nullable Default Check Key/Index

title_id | tid | no | FK titles(title_id)
lorange | int | yes |
hirange | int | yes |
royalty | int | yes |

title_id | lorange | hirange | royalty

BU1032 | 0 | 5000 | 10
BU1032 | 5001 | 50000 | 12
PC1035 | 0 | 2000 | 10
PC1035 | 2001 | 3000 | 12
PC1035 | 3001 | 4000 | 14
PC1035 | 4001 | 10000 | 16
PC1035 | 10001 | 50000 | 18
BU2075 | 0 | 1000 | 10
BU2075 | 1001 | 3000 | 12
BU2075 | 3001 | 5000 | 14
BU2075 | 5001 | 7000 | 16
BU2075 | 7001 | 10000 | 18
BU2075 | 10001 | 12000 | 20
BU2075 | 12001 | 14000 | 22
BU2075 | 14001 | 50000 | 24
PS2091 | 0 | 1000 | 10
PS2091 | 1001 | 5000 | 12
PS2091 | 5001 | 10000 | 14
PS2091 | 10001 | 50000 | 16
PS2106 | 0 | 2000 | 10
PS2106 | 2001 | 5000 | 12
PS2106 | 5001 | 10000 | 14
PS2106 | 10001 | 50000 | 16
MC3021 | 0 | 1000 | 10
MC3021 | 1001 | 2000 | 12
MC3021 | 2001 | 4000 | 14
MC3021 | 4001 | 6000 | 16
MC3021 | 6001 | 8000 | 18
MC3021 | 8001 | 10000 | 20
MC3021 | 10001 | 12000 | 22
MC3021 | 12001 | 50000 | 24
TC3218 | 0 | 2000 | 10
TC3218 | 2001 | 4000 | 12
TC3218 | 4001 | 6000 | 14
TC3218 | 6001 | 8000 | 16
TC3218 | 8001 | 10000 | 18
TC3218 | 10001 | 12000 | 20
TC3218 | 12001 | 14000 | 22
TC3218 | 14001 | 50000 | 24
PC8888 | 0 | 5000 | 10
PC8888 | 5001 | 10000 | 12
PC8888 | 10001 | 15000 | 14
PC8888 | 15001 | 50000 | 16
PS7777 | 0 | 5000 | 10
PS7777 | 5001 | 50000 | 12
PS3333 | 0 | 5000 | 10
PS3333 | 5001 | 10000 | 12
PS3333 | 10001 | 15000 | 14
PS3333 | 15001 | 50000 | 16
BU1111 | 0 | 4000 | 10
BU1111 | 4001 | 8000 | 12
BU1111 | 8001 | 10000 | 14
BU1111 | 12001 | 16000 | 16
BU1111 | 16001 | 20000 | 18
BU1111 | 20001 | 24000 | 20
BU1111 | 24001 | 28000 | 22
BU1111 | 28001 | 50000 | 24
MC2222 | 0 | 2000 | 10
MC2222 | 2001 | 4000 | 12
MC2222 | 4001 | 8000 | 14
MC2222 | 8001 | 12000 | 16
MC2222 | 12001 | 20000 | 18
MC2222 | 20001 | 50000 | 20
TC7777 | 0 | 5000 | 10
TC7777 | 5001 | 15000 | 12
TC7777 | 15001 | 50000 | 14
TC4203 | 0 | 2000 | 10
TC4203 | 2001 | 8000 | 12
TC4203 | 8001 | 16000 | 14
TC4203 | 16001 | 24000 | 16
TC4203 | 24001 | 32000 | 18
TC4203 | 32001 | 40000 | 20
TC4203 | 40001 | 50000 | 22
BU7832 | 0 | 5000 | 10
BU7832 | 5001 | 10000 | 12
BU7832 | 10001 | 15000 | 14
BU7832 | 15001 | 20000 | 16
BU7832 | 20001 | 25000 | 18
BU7832 | 25001 | 30000 | 20
BU7832 | 30001 | 35000 | 22
BU7832 | 35001 | 50000 | 24
PS1372 | 0 | 10000 | 10
PS1372 | 10001 | 20000 | 12
PS1372 | 20001 | 30000 | 14
PS1372 | 30001 | 40000 | 16
PS1372 | 40001 | 50000 | 18

sales Table

Column_name | Datatype | Nullable | Key/Index

stor_id | char(4) | no | Composite PK, clust. (1) , FK stores(stor_id)
ord_num | varchar(20) | no | Composite PK, clust. (1)
ord_date | datetime | no |
qty | smallint | no |
payterms | varchar(12) | no |
title_id | tid | no | Composite PK, clust., (1) FK titles(title_id)
(1) The composite, Primary Key, clustered index is defined on stor_id, ord_num, title_id.

stor_id | ord_num | ord_date | qty | payterms | title_id

6380 | 6871 | Sep 14 1994 12:00AM | 5 | Net 60 | BU1032
6380 | 722a | Sep 13 1994 12:00AM | 3 | Net 60 | PS2091
7066 | A2976 | May 24 1993 12:00AM | 50 | Net 30 | PC8888
7066 | QA7442.3 | Sep 13 1994 12:00AM | 75 | ON invoice | PS2091
7067 | D4482 | Sep 14 1994 12:00AM | 10 | Net 60 | PS2091
7067 | P2121 | Jun 15 1992 12:00AM | 40 | Net 30 | TC3218
7067 | P2121 | Jun 15 1992 12:00AM | 20 | Net 30 | TC4203
7067 | P2121 | Jun 15 1992 12:00AM | 20 | Net 30 | TC7777
7131 | N914008 | Sep 14 1994 12:00AM | 20 | Net 30 | PS2091
7131 | N914014 | Sep 14 1994 12:00AM | 25 | Net 30 | MC3021
7131 | P3087a | May 29 1993 12:00AM | 20 | Net 60 | PS1372
7131 | P3087a | May 29 1993 12:00AM | 25 | Net 60 | PS2106
7131 | P3087a | May 29 1993 12:00AM | 15 | Net 60 | PS3333
7131 | P3087a | May 29 1993 12:00AM | 25 | Net 60 | PS7777
7896 | QQ2299 | Oct 28 1993 12:00AM | 15 | Net 60 | BU7832
7896 | TQ456 | Dec 12 1993 12:00AM | 10 | Net 60 | MC2222
7896 | X999 | Feb 21 1993 12:00AM | 35 | ON invoice | BU2075
8042 | 423LL922 | Sep 14 1994 12:00AM | 15 | ON invoice | MC3021
8042 | 423LL930 | Sep 14 1994 12:00AM | 10 | ON invoice | BU1032
8042 | P723 | Mar 11 1993 12:00AM | 25 | Net 30 | BU1111
8042 | QA879.1 | May 22 1993 12:00AM | 30 | Net 30 | PC1035

stores Table

Column_name | Datatype | Nullable | Default | Check | Key/Index

stor_id | char(4) | no | PK, clust.
stor_name | varchar(40) | yes |
stor_address | varchar(40) | yes |
city | varchar(20) | yes |
state | char(2) | yes |
zip | char(5) | yes |

stor_id stor_name stor_address city state zip

6380 | Eric the Read Books | 788 Catamaugus Ave. | Seattle | WA | 98056
7066 | Barnum's | 567 Pasadena Ave. | Tustin | CA | 92789
7067 | News & Brews | 577 First St. | Los Gatos | CA | 96745
7131 | Doc-U-Mat: Quality Laundry and Books | 24-A Avrogado Way | Remulade | WA | 98014
7896 | Fricative Bookshop | 89 Madison St. | Fremont | CA | 90019
8042 | Bookbeat | 679 Carson St. | Portland | OR | 89076

titleauthor Table

Column_name | Datatype | Nullable | Default | Check | Key/Index

au_id | id | no | Composite PK, clust., (1) FK authors(au_id) (2)
title_id | tid | no | Composite PK, clust., (1) FK titles(title_id) (3)
au_ord | tinyint | yes |
royaltyper | int | yes |
(1) The composite, Primary Key clustered index is defined on au_id, title_id. (2) This Foreign Key also has a nonclustered index on au_id. (3) This Foreign Key also has a nonclustered index on title_id.

au_id title_id au_ord royaltyper

172-32-1176 | PS3333 | 1 | 100
213-46-8915 | BU1032 | 2 | 40
213-46-8915 | BU2075 | 1 | 100
238-95-7766 | PC1035 | 1 | 100
267-41-2394 | BU1111 | 2 | 40
267-41-2394 | TC7777 | 2 | 30
274-80-9391 | BU7832 | 1 | 100
409-56-7008 | BU1032 | 1 | 60
427-17-2319 | PC8888 | 1 | 50
472-27-2349 | TC7777 | 3 | 30
486-29-1786 | PC9999 | 1 | 100
486-29-1786 | PS7777 | 1 | 100
648-92-1872 | TC4203 | 1 | 100
672-71-3249 | TC7777 | 1 | 40
712-45-1867 | MC2222 | 1 | 100
722-51-5454 | MC3021 | 1 | 75
724-80-9391 | BU1111 | 1 | 60
724-80-9391 | PS1372 | 2 | 25
756-30-7391 | PS1372 | 1 | 75
807-91-6654 | TC3218 | 1 | 100
846-92-7186 | PC8888 | 2 | 50
899-46-2035 | MC3021 | 2 | 25
899-46-2035 | PS2091 | 2 | 50
998-72-3567 | PS2091 | 1 | 50
998-72-3567 | PS2106 | 1 | 100

titles Table

Column_name Datatype Nullable Default Check Key/Index

title_id | tid | no |  | PK, clust.
title | varchar(80) | no |  | Nonclust.
type | char(12) | no | 'UNDECIDED' |
pub_id | char(4) | yes |  | FK publishers(pub_id)
price | money | yes |  |
advance | money | yes |  |
royalty | int | yes |  |
ytd_sales | int | yes |  |
notes | varchar(200) | yes |  |
pubdate | datetime | no | GETDATE( ) |

The following tables show the contents of the titles table. The first column (title_id) is repeated in the lower listing, along with columns #5 through #8, #9, and #10. Column #1 is repeated for readability purposes only.

title_id (#1) | title (#2) | type (#3) | pub_id (#4) | price (#5)

BU1032 | The Busy Executive's Database Guide | business | 1389 | 19.99
BU1111 | Cooking with Computers: Surreptitious Balance Sheets | business | 1389 | 11.95
BU2075 | You Can Combat Computer Stress! | business | 0736 | 2.99
BU7832 | Straight Talk About Computers | business | 1389 | 19.99
MC2222 | Silicon Valley Gastronomic Treats | mod_cook | 0877 | 19.99
MC3021 | The Gourmet Microwave | mod_cook | 0877 | 2.99
MC3026 | The Psychology of Computer Cooking | UNDECIDED | 0877 | NULL
PC1035 | But Is It User Friendly? | popular_comp | 1389 | 22.95
PC8888 | Secrets of Silicon Valley | popular_comp | 1389 | 20.00
PC9999 | Net Etiquette | popular_comp | 1389 | NULL
PS1372 | Computer Phobic and Non-Phobic Individuals: Behavior Variations | psychology | 0877 | 21.59
PS2091 | Is Anger the Enemy? | psychology | 0736 | 10.95
PS2106 | Life Without Fear | psychology | 0736 | 7.00
PS3333 | Prolonged Data Deprivation: Four Case Studies | psychology | 0736 | 19.99
PS7777 | Emotional Security: A New Algorithm | psychology | 0736 | 7.99
TC3218 | Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean | trad_cook | 0877 | 20.95
TC4203 | Fifty Years in Buckingham Palace Kitchens | trad_cook | 0877 | 11.95
TC7777 | Sushi, Anyone? | trad_cook | 0877 | 14.99

title_id (#1) advance (#6) royalty (#7) ytd_sales (#8)

BU1032 | 5,000.00 | 10 | 4095
BU1111 | 5,000.00 | 10 | 3876
BU2075 | 10,125.00 | 24 | 18722
BU7832 | 5,000.00 | 10 | 4095
MC2222 | 0.00 | 12 | 2032
MC3021 | 15,000.00 | 24 | 22246
MC3026 | NULL | NULL | NULL
PC1035 | 7,000.00 | 16 | 8780
PC8888 | 8,000.00 | 10 | 4095
PC9999 | NULL | NULL | NULL
PS1372 | 7,000.00 | 10 | 375
PS2091 | 2,275.00 | 12 | 2045
PS2106 | 6,000.00 | 10 | 111
PS3333 | 2,000.00 | 10 | 4072
PS7777 | 4,000.00 | 10 | 3336
TC3218 | 7,000.00 | 10 | 375
TC4203 | 4,000.00 | 14 | 15096
TC7777 | 8,000.00 | 10 | 4095

title_id (#1) notes (#9) pubdate (#10)

BU1032 | An overview of available database systems with emphasis on common business applications. Illustrated. | Jun 12 1991 12:00AM
BU1111 | Helpful hints on how to use your electronic resources to the best advantage. | Jun 9 1991 12:00AM
BU2075 | The latest medical and psychological techniques for living with the electronic office. Easy-to-understand explanations. | Jun 30 1991 12:00AM
BU7832 | Annotated analysis of what computers can do for you: a no-hype guide for the critical user. | Jun 22 1991 12:00AM
MC2222 | Favorite recipes for quick, easy, and elegant meals. | Jun 9 1991 12:00AM
MC3021 | Traditional French gourmet recipes adapted for modern microwave cooking. | Jun 18 1991 12:00AM
MC3026 | NULL | Apr 28 1995 10:36AM
PC1035 | A survey of software for the naive user, focusing on the "friendliness" of each. | Jun 30 1991 12:00AM
PC8888 | Muckraking reporting on the world's largest computer hardware and software manufacturers. | Jun 12 1994 12:00AM
PC9999 | A must-read for computer conferencing. | Apr 28 1995 10:36AM
PS1372 | A must for the specialist, examining the difference between those who hate and fear computers and those who don't. | Oct 21 1991 12:00AM
PS2091 | Carefully researched study of the effects of strong emotions on the body. Metabolic charts included. | Jun 15 1991 12:00AM
PS2106 | New exercise, meditation, and nutritional techniques that can reduce the shock of daily interactions. Popular audience. Sample menus included, exercise video available separately. | Oct 5 1991 12:00AM
PS3333 | What happens when the data runs dry? Searching evaluations of information-shortage effects. | Jun 12 1991 12:00AM
PS7777 | Protecting yourself and your loved ones from undue emotional stress in the modern world. Use of computer and nutritional aids emphasized. | Jun 12 1991 12:00AM
TC3218 | Profusely illustrated in color, this makes a wonderful gift book for a cuisine-oriented friend. | Oct 21 1991 12:00AM
TC4203 | More anecdotes from the Queen's favorite cook describing life among English royalty. Recipes, techniques, tender vignettes. | Jun 12 1991 12:00AM
TC7777 | Detailed instructions on how to make authentic Japanese sushi in your spare time. | Jun 12 1991 12:00AM


Before You Begin

The programming components in Microsoft® SQL Server™ 6.0 enable you to develop sophisticated client/server applications that tap the power of Microsoft SQL Server.

Microsoft SQL Distributed Management Objects (SQL-DMO) enable you to create administrative programs for SQL Server 6.0.

Note This book contains background information about Microsoft SQL Server and provides some information specific to SQL Server 6.0. For information about changes and enhancements specific to SQL Server 6.5, see the supplementary "What's New in SQL Server 6.5."


About Programming SQL Distributed Management Objects

Microsoft SQL Server Programming SQL Distributed Management Objects provides syntax and reference information about the SQL Distributed Management Objects, 32-bit OLE Automation objects for the Microsoft® Windows® 95 and Microsoft® Windows NT™ operating systems. These objects, properties, methods, and collections are used to write scripts and programs that can administer multiple SQL Servers distributed across a network.

This book is written for developers and administrators who are writing scripts or programs to administer SQL Servers. It assumes that you are familiar with SQL Servers and with Microsoft® Visual C++ or the Microsoft® Visual Basic® programming system.

This book also assumes that you are familiar with DB-Library and/or ODBC, and with Transact-SQL™, the enhanced version of SQL (structured query language). For information about Transact-SQL, see the Microsoft SQL Server Transact-SQL Reference.


Document Conventions

Convention | Purpose

UPPERCASE | Represents statement and clause names, structure names, filenames, and paths.
bold | Represents functions and syntax.
italic | Represents variables that appear in text, database names, table names, column names, and index names.
monospace | Represents examples and sample program code.


Finding Further Information

This book contains reference information to help you write SQL-DMO administrative programs for Microsoft SQL Server. Additional information about SQL Server 6.0 is available from the following sources, as well as from the Microsoft® Development Library and Microsoft® TechNet.

The Microsoft Developer Network provides in-depth information for developers. With Level 1 of the Developer Network, you get four quarterly releases of the Development Library, packed with inside information on programming for Microsoft Windows and Windows NT, plus other program benefits. With Level 2 of the Developer Network, you'll receive all the Level 1 benefits plus quarterly releases of the Development Platform, containing the latest Windows and Windows NT Workstation operating systems and API-level SDKs and DDKs from Microsoft. For ordering information, call (800) 759-5474.

Microsoft TechNet is the front-line resource for fast complete answers to technical questions on Microsoft desktop and system products. Through two monthly CDs, you get everything from crucial data on client/server and workgroup computing, systems platforms, and database products to the latest applications support for Microsoft Windows and the Apple® Macintosh®. For ordering information, call your reseller or (800) 344-2121.

Online Help

To access online Help while using SQL-DMO, choose the SQL-DMO Help icon.

SQL Server Documentation

The documentation for SQL Server 6.0 is available online as part of the Microsoft® Development Library and as Microsoft SQL Server Books Online, which is part of Microsoft SQL Server and Microsoft® SQL Workstation.

Important SQL Server Books Online contains the most up-to-date information about SQL Server 6.0, including information that changed or was unavailable when the SQL Server 6.0 books were printed.

Microsoft SQL Server Setup
Provides instructions for installing SQL Server 6.0 servers and clients.
Microsoft SQL Server System Administrator's Companion
Incorporates configuration, administration, and troubleshooting topics. Describes server and client configuration. Explains system administration tasks, such as managing devices and databases, backing up and recovering data, performing replication, scheduling tasks, managing security, and monitoring performance. Describes error conditions and gives troubleshooting procedures.
Microsoft SQL Server Database Developer's Companion
Provides an overview of Transact-SQL, which is an enhanced version of SQL (structured query language). Discusses managing data and database objects, such as tables, views, indexes, stored procedures, defaults, rules, constraints, and user-defined datatypes.
Microsoft SQL Server Transact-SQL Reference
Explains how to use Transact-SQL statements and other features to access databases, and provides syntax and descriptions for Transact-SQL statements, system procedures, utility programs, and system tables.
Microsoft SQL Server Programming SQL Distributed Management Objects
The online version of this book, provides syntax and reference information for the SQL Distributed Management Objects, which are 32-bit OLE Automation objects for the Microsoft Windows 95 and Windows NT operating systems.
Microsoft SQL Server Programming DB-Library for C
Provides syntax and reference information for the DB-Library application programming interface (API), which is used to write C/C++ client programs for the Windows, Windows 95, Windows NT, and MS-DOS® operating systems.
Microsoft SQL Server Programming DB-Library for Visual Basic
Provides syntax and reference information for the DB-Library API, which is used to write Microsoft Visual Basic programming system-based client programs for the Windows operating system.


Obtaining Technical Support

Microsoft offers a variety of support options to help you get the most from Microsoft SQL Server. For information about these options, see the service and support card available in the Microsoft SQL Server and Microsoft SQL Workstation packages, and the online support information in the Microsoft Development Library.

In addition, you can get technical support information from the Microsoft® Knowledge Base (KB), which can help you resolve problems. Information about the Knowledge Base (including how to get KB articles, how to get the KB on CD, and how to contribute to the KB) is available in the Help file KB_MSL.HLP, located in the \SQL60\INSTALL directory.


Chapter 1 Getting Started

Getting Started

SQL Distributed Management Objects (SQL-DMO) are 32-bit Component Object Model (COM) objects for the Microsoft Windows 95 and Windows NT operating systems. The SQL-DMO objects are OLE Automation Compatible. The SQL-DMO object model includes objects, properties, methods, and collections that are used to write programs that can administer multiple SQL Servers distributed across a network. SQL-DMO programs can range from simple Visual Basic scripts to complex C++ applications. SQL-DMO is the foundation of SQL Enterprise Manager.


SQL-DMO Object Model

The following illustration shows the SQL-DMO object model:


SQL-DMO Files

The following SQL-DMO files are included with the SQL Server 32-bit client tools for Windows 95 and Windows NT, which you must install to use SQL-DMO.

In C:\SQL60\DLL

File | Description

SQLOLE.HLP | Help file containing reference information about SQL-DMO objects, properties, methods, lists, and collections.
SQLOLE.REG | SQL-DMO Registry file.
SQLOLE32.DLL | SQL-DMO in-process server and COM custom component.
SQLOLE32.TLB | SQL-DMO type library, usually used by OLE Automation controllers like Visual Basic.

In C:\SQL60\INSTALL

File | Description

SQLOLE42.SQL | Transact-SQL script to create SQL-DMO stored procedures for SQL Server 4.21 servers. You must install these on a SQL Server 4.21 server before SQL-DMO objects can connect to that server.
SQLOLE60.SQL | Transact-SQL script to create SQL-DMO stored procedures for SQL Server 6.0 servers. These are already installed by SQL Server 6.0.

In C:\SQL60\SQLOLE\INCLUDE

File | Description

SQLOLE.H | Header file for C++ programs containing function prototypes for SQL-DMO objects, properties, methods, lists, and collections.
SQLOLEID.H | Header file for C++ programs containing class IDs and interface IDs for SQL-DMO.

In C:\SQL60\SQLOLE\SAMPLES

File | Description

README.TXT | Summary of sample programs available in each directory.


Chapter 2 Using SQL-DMO Objects

Using SQL-DMO Objects

This chapter provides instructions for using SQL-DMO objects in your Visual Basic and C++ programs. The SQL-DMO custom component provides 32-bit COM objects which can be used from 32-bit Visual Basic programs and 32-bit C++ programs.

The SQL-DMO component name or application name is SQLOLE.

For brevity, the sample code included in this chapter does not check for success or handle errors.

Visual Basic

Visual Basic is an OLE Automation controller. You can use Visual Basic to write programs that use SQL-DMO objects. The steps required to use SQL-DMO objects in a Visual Basic program are:

  1. Include the SQL-DMO type library.
  2. Create a SQLServer object.
  3. Connect the SQLServer object.
  4. Use the SQLServer object and other contained objects.
  5. Release the SQLServer object.

Use a period (.) to separate an object variable from the properties, methods and collections of that object.

C++

You can use C++ and OLE functions to write programs that use SQL-DMO objects. The steps required to use SQL-DMO objects in a C++ program are:

  1. Include the SQL-DMO and OLE header files, and link to OLE libraries.
  2. Initialize the COM library.
  3. Create a SQLServer object.
  4. Connect the SQLServer object.
  5. Use the SQLServer object and other contained objects.
  6. Release the SQLServer object.
  7. Uninitialize the COM library.

Use the member-selection operator (->) to separate a "pointer to an object" variable from the property, method, and collection functions.


Including SQL-DMO

The first step to programming with SQL-DMO objects is to include the appropriate type library or header files in your project.

The complete SQL-DMO type library is contained in the SQLOLE32.TLB file, located in the C:\SQL60\DLL directory by default. The type library contains information about all SQL-DMO objects, properties and methods, and is usually used by OLE Automation controllers like Visual Basic.

Visual Basic

To give Visual Basic access to the SQL-DMO object definitions, you should include the SQL-DMO type library in your Visual Basic project or module. Including the type library is required if you want to declare a Visual Basic object variable as a SQL-DMO object type. Including the SQL-DMO type library is not necessary if you want to declare a Visual Basic object variable as a generic Object type.

To include the SQL-DMO type library in your project, you usually follow these steps. From the Tools menu, choose References. The References dialog appears. Choose the Browse button, and include the SQLOLE32.TLB file. This requires that the Visual Basic environment or module code editor be active and running. For example, to create a new Visual Basic module using Excel 5.0 for Windows NT, from the Insert menu, choose Macro and then Module.

C++

The SQL-DMO objects include both ANSI and Unicode custom interfaces. When using ANSI interfaces, all SQL-DMO strings are ANSI strings with one byte per character. When using the Unicode interfaces, all SQL-DMO strings are Unicode strings with two bytes per character. All SQL-DMO strings use the SQLOLE_BSTR string datatype.

The ANSI custom interfaces and ANSI SQLOLE_BSTR strings are used by default. If you want to use the Unicode custom interfaces and Unicode SQLOLE_BSTR strings, you must define UNICODE and _UNICODE before including all the header files. For example:

#define UNICODE
#define _UNICODE

Use the TEXT("str") macro around string values. By default these are ANSI "str" strings. When UNICODE and _UNICODE are defined these are Unicode L"str" strings.

In 32-bit OLE, all BSTR strings are Unicode strings.

To give your C++ program access to the SQL-DMO object definitions, you must include the SQLOLEID.H and SQLOLE.H header files, in addition to the Windows and OLE header files. The SQL-DMO header files are located in the C:\SQL60\SQLOLE\INCLUDE directory by default. The Include setting of the Visual C++ project or the INCLUDE environment variable should point to the directory that contains these files.

You must include the following header files in this order:

  1. WINDOWS.H
  2. INITGUID.H (This file must be included once and only once)
  3. SQLOLEID.H
  4. SQLOLE.H
  • For example:
#include <windows.h>
#include <initguid.h>
#include <sqloleid.h>
#include <sqlole.h>

SQL-DMO does not have a link library. However, to build your SQL-DMO application, you must link to the following OLE libraries:

  • OLE32.LIB
  • OLEAUT32.LIB
  • UUID.LIB

The Library setting of the Visual C++ project or the LIB environment variable should point to the directory that contains these files.


Initializing the COM Library

Before your program can use SQL-DMO objects, the COM library must be initialized.

Visual Basic

Your SQL-DMO program does not need to initialize OLE. Visual Basic automatically initializes OLE and the COM library.

C++

All SQL-DMO and OLE functions return an HRESULT value. The HRESULT contains information about the success or failure of the SQL-DMO or OLE function. You can declare a single HRESULT variable and re-use it. For example:

HRESULT hr;

Before calling any SQL-DMO or COM functions, your SQL-DMO program must initialize the COM library by using the OLE CoInitialize function. For example:

hr = CoInitialize (NULL);

You must pass NULL to CoInitialize.

To initialize OLE you can use the OleInitialize function. This automatically initializes the COM library. For more information about OLE functions, see your OLE programming documentation.


Creating a SQLServer Object

The core of SQL-DMO is the SQLServer object. For each SQL Server you want to connect to, you create an empty SQLServer object, then you connect the SQLServer object to a running SQL Server.

The methods described here are used to create all types of creatable SQL-DMO objects, including a SQLServer object. When a new SQL-DMO object is created, the object is empty, and its properties are initialized to default values.

Visual Basic

There are three methods for creating SQL-DMO objects in Visual Basic. All three methods involve using the Dim statement to declare an object variable of a certain type.

The SQL-DMO application name is SQLOLE. It is recommended that you use the application name SQLOLE when creating and declaring SQL-DMO objects. This avoids ambiguity if another OLE components includes objects with common names, such as Table or Database.

Specific SQL-DMO object type

The preferred method (if your version of Visual Basic supports it) is to use a Dim statement to declare an object variable of a specific SQL-DMO object type. This method requires that the SQL-DMO type library be included in your Visual Basic project. To actually create a new instance of a SQL-DMO object, you can use the New keyword in your Dim statement (if your version of Visual Basic supports it), or you can use CreateObject function.

For example, to create a new SQLServer object using the New keyword:

Dim oSQLServer As New SQLOLE.SQLServer

For example, to declare and create a new SQLServer object using the CreateObject function:

Dim oSQLServer As SQLOLE.SQLServer
Set oSQLServer = CreateObject ("SQLOLE.SQLServer")

Some versions of Visual Basic use virtual function table binding (vtable-binding), or early-binding. The SQL-DMO custom interfaces are used directly (not through the OLE IDispatch interface), resulting in the best performance.

Some versions of Visual Basic use a form of late-binding called dispatch ID binding (dispID-binding) using OLE IDispatch. The IDispatch::Invoke function is used with the dispIDs included in the SQL-DMO type library. This method will give your application slower performance than using the New keyword, but faster performance than using the Object type.

Generic Object type

The other method (supported by all versions of Visual Basic) is to use a Dim statement to declare a new variable of the generic Object type, then use the CreateObject function to create a new instance of a SQL-DMO object and assign it to the object variable. This method does not require the SQL-DMO type library.

For example, to declare and create a new SQLServer object using the generic Object type:

Dim oSQLServer As Object
Set oSQLServer = CreateObject ("SQLOLE.SQLServer")

This method is called late-binding using OLE IDispatch. The IDispatch::GetIDsOfNames function is used to get the dispIDs, which are passed to the IDispatch::Invoke function. This method will give your application slower performance than declaring an object variable of a specific SQL-DMO object type.

C++

There is only one method to create a SQL-DMO object in C++. Declare an object variable of the appropriate SQL-DMO "pointer to an object" type. For an object named Object, the SQL-DMO object type is LPSQLOLEOBJECT. Then use the OLE CoCreateInstance function to create a new instance of a SQL-DMO object. You pass the following parameters to CoCreateInstance:

  1. Class ID of a SQL-DMO object
  2. NULL
  3. CLSCTX_INPROC_SERVER
  4. Interface ID of a SQL-DMO object
  5. Address of the SQL-DMO "pointer to an object" variable (use the address of & operator)

For example, to create a new SQLServer object:

LPSQLOLESERVER pSQLServer = NULL;
hr = CoCreateInstance (CLSID_SQLOLEServer,
    NULL,
    CLSCTX_INPROC_SERVER,
    IID_ISQLOLEServer,
    (LPVOID*)&pSQLServer);

Note A multithreaded program must serialize all access to SQL-DMO to avoid reentrancy.


Connecting the SQLServer Object

After creating a new, empty SQLServer object, you connect that object to a running SQL Server using the Connect method of the new SQLServer object. You pass the following parameters to the Connect method:

  1. SQL Server name
  2. Login ID
  3. Password

When the Connect method is successful, the SQLServer object is filled with information about the connected SQL Server. The SQLServer object and all objects "under" the SQLServer object (in the SQL-DMO object hierarchy) are now valid and available for use. This includes the following:

  • All SQLServer properties (including object properties) are set to the appropriate values.
  • All supported SQLServer methods are available.
  • All SQLServer collections are available and filled with objects as you request them.
  • All objects "under" SQLServer are available for use.

SQL-DMO also adds the connected SQLServer object to the Application.SQLServers collection.

SQL-DMO retrieves information from SQL Server as you request it by using the SQLServer objects. SQL-DMO maintains this SQL Server information in a cache stored in client memory. SQL-DMO improves performance by using this cached information to minimize SQL Server queries. The cache is contained in the collection objects, and you can use the Refresh method to update the cache with current values from SQL Server.

Visual Basic

You can call the Connect method using Visual Basic procedure syntax. For example:

oSQLServer.Connect "myserver", "mylogin", "mypassword"

You can also call the Connect method using Visual Basic function syntax. For example:

Call oSQLServer.Connect ("myserver", "mylogin", "mypassword")
C++

Call the Connect method. For example:

hr = pSQLServer->Connect (TEXT("myserver"),
    TEXT("mylogin"),
    TEXT("mypassword"));


Declaring and Assigning Object Variables

To store a SQL-DMO object returned from another object, you must declare an object variable of the appropriate SQL-DMO object type.

Visual Basic

Declare an object variable of a specific SQL-DMO object type (if your version of Visual Basic supports it). This uses early, vtable-binding or dispID-binding, depending on your version of Visual Basic, and requires that the SQL-DMO type library be included in your Visual Basic project. For example:

Dim oDatabase As SQLOLE.Database

Or you can declare an object variable of the generic Object type. This uses late-binding, and does not require the SQL-DMO type library. For example:

Dim oDatabase As Object

Then assign a returned SQL-DMO object (from a collection, an object property, or a method return value) to the declared object variable. For example:

Set oDatabase = oSQLServer.Databases("pubs")

Note that you can assign a returned SQL-DMO object to an object variable declared using the New keyword (if your version of Visual Basic supports it). Visual Basic will automatically release an object created by the New keyword before assigning a new object to the variable. However, if you are declaring an object variable just to hold a returned SQL-DMO object, do not use the New keyword. The overhead of creating and releasing the object is unnecessary.

C++

Declare an object variable of the appropriate SQL-DMO "pointer to an object" type. All SQL-DMO object types begin with LPSQLOLE.

For example, to declare a new Database object variable and assign the pubs database object (part of the SQLServer.Databases collection) to the new object variable:

LPSQLOLEDATABASE pDatabase = NULL;
hr = pSQLServer->GetDatabaseByName (TEXT("pubs"),
    (LPVOID*)&pDatabase);


Using Property Values

A property is a data item stored in a SQL-DMO object. You can get almost all property values, but you can set (change) only certain property values.


Getting a Property

Because all SQL-DMO property values are read-only or read-write, you can get all property values.

Visual Basic

To get a property, use the following syntax:

[Set] variable = Object.Property

For example, to get a long property:

Dim lTime As Long
lTime = oSQLServer.LoginTimeout

For example, to get a string property:

Dim strHost As String
strHost = oSQLServer.HostName

For example, to get an object property:

Dim oConfiguration As SQLOLE.Configuration
Set oConfiguration = oSQLServer.Configuration

You can also use the Object.Property value directly as part of a more complex expression.

C++

For a property named Property, you use a function named Get Property to get a property value. Because all SQL-DMO functions return an HRESULT, you must pass the address of a program variable (use the address of & operator) of the appropriate type to the Get Property function. The Get Property function will write the current property value to your program variable. Use the following syntax:

pObject->Get Property ( &variable );

For example, to get a long property:

LONG lTime;
pSQLServer->GetLoginTimeout (&lTime);

Getting a string property requires an extra step. A Get Property function for a string property takes a parameter of type SQLOLE_LPBSTR, which is the address of a SQLOLE_BSTR variable. You pass the address of a SQLOLE_BSTR variable to the Get Property function. The Get Property function will allocate a new string and then write the current property value to the newly allocated string. After your program is finished using the string (allocated by SQL-DMO) it must call SQLOLEFreeString macro to deallocate the string.

For example, to get a string property:

SQLOLE_BSTR strHost;
pSQLServer->GetVersionString (&strHost);
// use strHost
SQLOLEFreeString (strHost);

SQLOLEFreeString is mapped to the OLE SysFreeString function, with an appropriate conversion for ANSI strings when you are using the SQL-DMO ANSI interfaces.

For example, to get an object property:

LPSQLOLECONFIGURATION pConfiguration = NULL;
hr = pSQLServer->GetConfiguration (&pConfiguration);


Setting a Property

You can set (change) only read-write SQL-DMO properties.

Visual Basic

To set a property, use the following syntax:

Object.Property = value

For example, to set a long property:

oSQLServer.LoginTimeout = 30

To set a string property:

oSQLServer.HostName = "Gizmo"

Note that you cannot set object properties; they are read-only.

C++

For a property named Property, you use a function named Set Property to set a property to a new value. Pass a program variable of the appropriate type to the Set Property function. The Set Property function will read the new value from the program variable and set the object property to that value. Use the following syntax:

pObject->Set Property ( variable );

For example, to set a long property:

pSQLServer->SetLoginTimeout (30);

To set a string property:

pSQLServer->SetVersionString (TEXT("Gizmo"));

Note that you cannot set object properties; they are read-only.


Using the Properties Collection

The Property object and the Properties collection are only available in Visual Basic.

Visual Basic

Each SQL-DMO object (not including collections) has a Properties collection that contains one Property object for each property (not including object properties or indexed properties) of the SQL-DMO object.

Using the Properties collection and the following properties of the Property object you can:

  • Enumerate the property names of a SQL-DMO object at run time using the Name property.
  • Get and set the value of a property name determined at run time using the Value property.

For example:

For Each oProperty in oSQLServer.Properties
    Debug.Print oProperty.Name & " = " oProperty.Value
Next

The default property of a Property object is the Value property.

C++

The Property object and the Properties collection are not available in C++.


Calling Methods

A method is a function that performs an action using a SQL-DMO object.

Visual Basic

To call a method that takes no parameters, use the following syntax:

[return =] Object.Method

To call a method that takes parameters and doesn't return a value (or to ignore any return value), use the following syntax:

Object.Method [Name1 :=] param1, [Name2 :=] param2, ...

To call a method that takes parameters and returns a value, use the following syntax:

return = Object.Method ( [Name1 :=] param1, [Name2 :=] param2, ... )

The Name items are optional parameter names. If you include parameter names, you can specify the method parameters in any order. If you do not use parameter names, you must specify the method parameters in the required order.

For example:

Dim oQueryResults As SQLOLE.QueryResults
oQueryResults = oSQLServer.ReadErrorLog (0)
C++

To call a method that takes no parameters, use the following syntax:

pObject->Method ( );

To call a method that takes parameters (but no return parameters), use the following syntax:

pObject->Method ( param1, param2, ... );

If the method has a return parameter, you must pass the address of a program variable (use the address of & operator) of the appropriate type as the return parameter. The method will write the return value to your program variable.

To call a method that takes a single return parameter, use the following syntax:

pObject->Method ( &return );

To call a method that takes input parameters (but no optional parameters) and a required or optional return parameter, or a method that takes required and optional input parameters and an optional return parameter, use the following syntax:

pObject->Method ( param1, param2, ..., &return );

To call a method that takes required input parameters, a required return parameter, and optional input parameters, use the following syntax:

pObject->Method ( req_param1, ..., &return, opt_param2, ... );

For example:

LPSQLOLEQUERYRESULTS pQueryResults = NULL;
pSQLServer->ReadErrorLog (&pQueryResults, 0);


Using Collections

A collection contains a group of objects, all of the same type. The name of a collection is the plural name of the object type it contains. For example, the Databases collection contains a group of Database objects.

A collection is contained within a parent object. For example, the SQLServer object contains the Databases collection.


Getting a Collection Object

A collection is really a collection object that contains all the specific objects in the collection. Like all objects, a collection object has properties and methods.

Visual Basic

For a collection named Objects, use the following syntax to refer to a collection object:

Parent.Objects

For example, to refer to the Databases collection of a SQLServer object:

oSQLServer.Databases
C++

For a collection named Objects, you use a function named Get Objects to get a collection object from the parent object. Pass the address of a collection object variable (use the address of & operator) of the appropriate type (LPSQLOLEOBJECTS) to the Get Objects function. The Get Objects function will write the collection object pointer to your object variable. Use the following syntax:

pParent->Get Objects ( &pObjects );

For example, to get the Databases collection object from a SQLServer object:

LPSQLOLEDATABASES pDatabases;
pSQLServer->GetDatabases (&pDatabases);


Getting a Specific Object from a Collection

You must get a specific object from a collection before you can use it.

Visual Basic

Because the Item method is the default method of a collection object, you can get a specific object in a collection by specifying one of the following:

  • Object name
  • Ordinal value (1-based) within the collection

in parentheses after the collection object. You can also use the Item method explicitly. These use the following syntax:

Parent.Objects( {strName | lOrdinal} )

Or

Parent.Objects.Item( {strName | lOrdinal} )

For example, to refer to the pubs database of the SQLServer.Databases collection:

oSQLServer.Databases("pubs")

To refer to the first database of the SQLServer.Databases collection:

oSQLServer.Databases(1)

A parent object has a default collection. You can use the ! default collection specifier instead of the default collection name and item name specifier. Use the following syntax:

Parent!name

The following table lists the default collections for parent SQL-DMO objects.

Parent Object | Default Collection

Configuration | ConfigValues
Executive | Tasks
SQLServer | Databases
Database | Tables
Table | Columns

For example, to refer to the pubs database of the default Databases collection of the SQLServer object:

oSQLServer!pubs

Some SQL-DMO collections support the ItemByID method. This allows you to get a specific object using that object's unique SQL Server identifier. Use the following syntax:

Parent.Objects.ItemByID( lID )

For example, to refer to the database of the SQLServer.Databases collection that has a SQL Server database ID of 1:

oSQLServer.Databases.ItemByID(1)
C++

When you have a pointer to a collection object, you can get a pointer to a specific object in that collection by using the GetItemByOrd or GetItemByName function, or (for collections that support it) by using the GetItemByID function.

To use GetItemByOrd, pass an ordinal value (0-based) and the address of an object variable (use the address of & operator) of the appropriate type (LPSQLOLEOBJECT) to the function. It will write the specific object pointer to your object variable. Use the following syntax:

pObjects->GetItemByOrd ( lOrdinal, &pObject );

To use GetItemByName, pass the name of the specific object and the address of an object variable of the appropriate type (LPSQLOLEOBJECT) to the function. It will write the specific object pointer to your object variable. Use the following syntax:

pObjects->GetItemByName ( strName, &pObject );

Some SQL-DMO objects support the GetItemByID function. This allows you to get a specific object using that object's unique SQL Server identifier. To use GetItemByID, pass the unique object ID and the address of an object variable of the appropriate type (LPSQLOLEOBJECT) to the function. It will write the specific object pointer to your object variable. Use the following syntax:

pObjects->GetItemByID ( lID, &pObject );

For example, to get the pubs database from the SQLServer.Databases collection:

LPSQLOLEDATABASES pDatabases;
pSQLServer->GetDatabases (&pDatabases);
LPSQLOLEDATABASE pDatabase;
pDatabases->GetItemByName (TEXT("pubs"), &pDatabase);

The SQL-DMO custom interfaces also include "shortcut" functions that allow you to get a specific object in a collection directly from the parent object. These single functions can be used instead of getting the collection object first, then getting the specific object. Use the following syntax:

pParent->Get Object ByName ( strName, &pObject );

pParent->Get Object ByOrd ( lOrdinal, &pObject );

pParent->Get Object Count ( &lCount );

For example, to get the pubs database from the SQLServer.Databases collection:

LPSQLOLEDATABASE pDatabase;
pSQLServer->GetDatabaseByName (TEXT("pubs"), &pDatabase);


Iterating Through a Collection

It is often useful to perform a series of operations on every specific object in a collection.

Visual Basic

Use the Visual Basic For Each statement to iterate through all specific objects in a collection. For example:

For Each oDatabase in oSQLServer.Databases
    Debug.Print oDatabase.Name
Next
C++

You can use the GetCount and GetItemByOrd functions of a collection object to iterate through all specific objects in a collection. Use the following syntax for GetCount:

pObjects->GetCount ( &lCount );

For example:

LPSQLOLEDATABASES pDatabases;
LPSQLOLEDATABASE pDatabase;
long i, lCount;
pSQLServer->GetDatabases (&pDatabases);
pDatabases->GetCount (&lCount);
for (i = 0; i < lCount; i+)
{
    pDatabases->GetItemByOrd (i, &pDatabase);
    // use the specific pDatabase object
}

You can also use the Get Object Count and Get Object ByOrd "shortcut" functions of the parent object to iterate through all specific objects in a collection. For example:

LPSQLOLEDATABASE pDatabase;
long i, lCount;
pSQLServer->GetDatabaseCount (&lCount);
for (i = 0; i < lCount; i+)
{
    pSQLServer->GetDatabaseByOrd (i, &pDatabase);
    // use the specific pDatabase object
}


Adding a New Object to a Collection

To add a new SQL-DMO object to a collection, you use the following steps:

  1. Create a new instance of a SQL-DMO object.
  2. Set the properties of the new SQL-DMO object.
  3. Add the new SQL-DMO object to the appropriate collection.

Adding a SQL-DMO object to a collection creates that SQL Server object.

Visual Basic

After creating a new SQL-DMO object with the New keyword of the Dim statement or the CreateObject function, you set the properties of the new object as appropriate for the new object. Then you add the new object to the appropriate collection using the following syntax:

Objects.Add NewObject

C++

After creating a new SQL-DMO object with the CoCreateInstance function, you set the properties of the new object as appropriate for the new object. Then you add the new object to the appropriate collection using the following syntax:

pObjects->Add ( pNewObject );

You can also use the Add Object "shortcut" function of the parent object to add the new object using the following syntax:

pParent->Add Object ( pNewObject );


Removing an Existing Object from a Collection

Removing an existing SQL-DMO object from a collection drops that SQL Server object.

Visual Basic

You remove an existing object from a collection by specifying one of the following:

  • Object name
  • Ordinal value within the collection (the first ordinal value is number 1)

using the following syntax:

Objects.Remove ( {strName | lOrdinal} )

You can also remove an existing object directly using the following syntax:

Object.Remove

C++

You remove an object from a collection by name or by ordinal value (the first ordinal value is number 0) using the following syntax:

pObjects->RemoveByName ( strName );

pObjects->RemoveByOrd ( lOrdinal );

You can also use the Remove Object ByName or Remove Object ByOrd "shortcut" functions of the parent object to remove an existing object by name or by ordinal value (0-based) using the following syntax:

pParent->Remove Object ByName ( strName );

pParent->Remove Object ByOrd ( lOrdinal );


Refreshing a Collection

When you use the Refresh collection method, SQL-DMO refreshes objects with current information from SQL Server. The Refresh method takes a single Boolean parameter, indicating if you want to release all objects in the collection and "under" the collection in the SQL-DMO hierarchy.

  • If True, SQL-DMO releases all objects in the collection and all objects "under" the collection. SQL-DMO then refreshes the collection with current information from SQL Server. All objects "under" the refreshed collection are reinitialized, and current information will be retrieved from SQL Server as you use them. This invalidates all object variables you have that refer to any object in the refreshed collection, or to any object "under" the refreshed collection.
  • If False, SQL-DMO releases only those objects in the collection that have been dropped from SQL Server. SQL-DMO then refreshes the entire collection with current information from SQL Server. It will not release or refresh any objects "under" the collection. This invalidates any object variables you have that refer to objects that are no longer in the refreshed collection because they have been dropped from SQL Server.

Some objects that cache a lot of SQL Server information have a direct Refresh method.

Visual Basic

To use the Refresh collection method, use the following syntax:

Parent.Objects.Refresh ( bRelease )

Do not call Refresh within a For Each loop.

C++

To use the Refresh collection method, use the following syntax:

pObjects->Refresh ( bRelease );


Using Lists

Lists are methods that begin with List and return a list of SQL-DMO objects. You use a list in the same way as a collection, except that you cannot add or remove objects from a list.

An objects in a list is usually a "cross-reference" to an object which is contained in a collection. The List object uses an index of identifiers to get appropriate objects from the collection.


Getting a List Object

A list object includes a group of specific objects. Like all objects, a list object has properties and methods.

Visual Basic

For a list method named ListObjects, use the following syntax to refer to a list object:

Parent.ListObjects

For example, to refer to the ListStartupProcedures list (of StoredProcedure objects) of a SQLServer object:

oSQLServer.ListStartupProcedures

The StoredProcedure objects in this list are contained in the Database.StoredProcedures collection.

C++

Use the ListObjects list method to get a list object from the parent object. Pass the address of a list object variable (use the address of & operator) of the appropriate type (LPSQLOLEOBJECTLIST) to the ListObjects function. The ListObjects function will write the list object pointer to your object variable. Use the following syntax:

pParent->ListObjects ( &pObjectList );

For example, to use the ListStartupProcedures list method to get a StoredProcedure list from a SQLServer object:

LPSQLOLESTOREDPROCEDURELIST pStoredProcedureList;
pSQLServer->ListStartupProcedures (&pStoredProcedureList);

The StoredProcedure objects in this list are contained in the Database.StoredProcedures collection.


Getting a Specific Object from a List

You must get a specific object from a list before you can use it.

Visual Basic

Because the Item method is the default method of a list, you can get a specific object in a list by specifying one of the following:

  • Object name
  • Ordinal value (1-based) within the list

in parentheses after the list object. You can also use the Item method explicitly. Use the following syntax:

Parent.ListObjects( {strName | lOrdinal} )

Or

Parent.ListObjects.Item( {strName | lOrdinal} )

C++

When you have a pointer to a list object, you can get a pointer to a specific object in that list by using the GetItemByOrd or GetItemByName function.

To use GetItemByOrd, pass an ordinal value (0-based) and the address of a list object variable (use the address of & operator) of the appropriate type (LPSQLOLEOBJECTLIST) to the function. It will write the specific object pointer to your object variable. Use the following syntax:

pObjectList->GetItemByOrd ( lOrdinal, &pObject );

To use GetItemByName, pass the name of the specific object and the address of a list variable of the appropriate type (LPSQLOLEOBJECTLIST) to the function. It will write the specific object pointer to your object variable. Use the following syntax:

pObjectList->GetItemByName ( strName, &pObject );


Iterating Through a List

It is often useful to perform a series of operations on every object in a list.

Visual Basic

Use the Visual Basic For Each statement to iterate through all specific objects in a list. For example:

For Each oStoredProcedure in oSQLServer.ListStartupProcedures
    Debug.Print oStoredProcedure.Name
Next
C++

You can use the GetCount and GetItemByOrd functions of a list object to iterate through all specific objects in a list. Use the following syntax for GetCount:

pObjectList->GetCount ( &lCount );

For example:

LPSQLOLESTOREDPROCEDURELIST pStoredProcedureList;
LPSQLOLESTOREDPROCEDURE pStoredProcedure;
long i, lCount;
pSQLServer->ListStartupProcedures (&pStoredProcedureList);
pStoredProcedureList->GetCount (&lCount);
for (i = 0; i < lCount; i+)
{
    pStoredProcedureList->GetItemByOrd (i, &pStoredProcedure);
    // use the specific pDatabase object
}


Refreshing a List

When you use the Refresh list method, SQL-DMO updates the index of identifiers for that list. This does not release or invalidate any object variables you have that refer to an object in the refreshed list.

Visual Basic

To use the Refresh list method, use the following syntax:

Parent.ListObjects.Refresh

Do not call Refresh within a For Each loop.

C++

To use the Refresh list method, use the following syntax:

pListObjects->Refresh ( );


Releasing the SQLServer Object

When your program is finished with a SQL-DMO object it created, you must release the object. After releasing your last reference to a SQL-DMO object, the object variable is invalid and must not be used. To use the object again you must get a new reference to it.

Visual Basic

To release objects you created using the New keyword of a Dim statement or the CreateObject function, set the object variable to Nothing. For example:

Set oSQLServer = Nothing

Visual Basic will automatically release an object when the object variable goes out of scope.

C++

Use the Release function to release objects you created using the OLE CoCreateInstance function. For example:

pSQLServer->Release();


Uninitializing the COM Library

Before your program exits, the COM library must be uninitialized.

Visual Basic

Your SQL-DMO program does not need to uninitialize OLE. Visual Basic automatically uninitializes OLE and COM when your program exits.

C++

After completing all use of SQL-DMO or COM functions, your program must uninitialize the COM library by calling the OLE CoUninitialize function. For example:

CoUninitialize ();

To uninitialize OLE you can use the OleUninitialize function. This automatically uninitializes the COM library.


Error Handling

When a SQL-DMO operation fails, it returns an error number and description. This error can be one of the following:

  • A SQL Server error from the sysmessages table.
  • A DB-Library error. Error numbers range from SQLOLE_E_DBLIBFIRSTERROR through SQLOLE_E_DBLIBLASTERROR.
  • A SQL-DMO error. Error numbers range from SQLOLE_E_FIRSTERROR through SQLOLE_E_LASTERROR.

Each SQL-DMO error number has a SQLOLE_E_ERROR error constant. Use these SQL-DMO error constants (instead of hard-coded error numbers) in your program.

SQL-DMO errors are grouped into categories. Each category has a SQLOLE_ECAT_CATEGORY category constant. To get the category constant, binary And the SQL-DMO error number with SQLOLE_ECAT_MASK.

  • The binary And operator in Visual Basic is And.
  • The binary And operator in C++ is &.

The following table describes each error category:

SQL-DMO Error Category | Description

SQLOLE_ECAT_INVALIDCONTEXT | The requested operation is not valid in the current context.
SQLOLE_ECAT_INVALIDOBJECT | The SQL-DMO object is no longer valid.
SQLOLE_ECAT_ INVALIDOBJECTDEFINITION | The attempt to add a new SQL-DMO object to a collection failed because the properties of the new object were set incorrectly or incompletely.
SQLOLE_ECAT_INVALIDPARAMETER | An invalid parameter was passed to a method or property.
SQLOLE_ECAT_INVALIDPLATFORM | The client or SQL Server platform does not support the requested operation. The version of SQL Server is not supported, the SQL-DMO stored procedures are not properly installed, or the client platform is not supported.
SQLOLE_ECAT_ITEMNOTFOUND | The object name passed to a collection was not found, or the ordinal value passed to a collection was out of range.
SQLOLE_ECAT_UNPRIVILEGEDLOGIN | The current login ID does not have sufficient privilege to perform the requested operation.
SQLOLE_ECAT_EXECUTION | An error occurred when executing a Transact-SQL query.
SQLOLE_ECAT_CONNECTION | The connection to SQL Server was broken and cannot be restored.
SQLOLE_ECAT_RESOURCE | The client or SQL Server does not have sufficient resources to perform the requested operation.

Visual Basic

By default, any SQL-DMO run-time error that occurs is fatal. This will stop execution of your Visual Basic program and display an error message. To handle SQL-DMO run-time errors in your program, you must use an On Error statement.

  • Use an On Error Resume Next statement to continue program execution at the statement immediately following the statement where the error occurred.
  • Use an On Error GoTo HandlerLabel to branch program execution to the HandlerLabel label, making the error handler active.

Vtable-binding

If your version of Visual Basic supports early, vtable-binding, then it supports the Visual Basic Err object, which is used to return SQL-DMO run-time error information to the program. The Err object includes properties that can be used as shown in the following table:

Use | To Get

Err.Number - vbObjectError | SQL-DMO error number
Err.Description | SQL-DMO error description
Err.Source | SQL-DMO component name

Note that you must subtract the Visual Basic constant vbObjectError from the Err.Number property to get the SQL-DMO error number.

For example:

On Error Resume Next
oSQLServer.Connect "myserver", "mylogin", "mypassword"
If Err.Number <> 0 Then
    Debug.Print Err.Source & " Error " & _
        Err.Number - vbObjectError & ": " & _
        Err.Description
End If

DispID-binding, late-binding

If your version of Visual Basic supports dispID-binding or late-binding, then it supports the Err and Error functions, which are used to return SQL-DMO run-time error information to the program. The Err function returns the SQL-DMO error number, and the Error function returns the description of the SQL-DMO error.

For example:

On Error Resume Next
oSQLServer.Connect "myserver", "mylogin", "mypassword"
If Err <> 0 Then
    Debug.Print "SQL-DMO Error " & Err & ": " & Error(Err)
End If
C++

You should use the OLE macros SUCCEEDED(hr) and FAILED(hr) with the HRESULT hr returned by a SQL-DMO function to determine if that SQL-DMO function was successful.

  • SUCCEEDED(hr) will return TRUE if the HRESULT indicates that the SQL-DMO function succeeded.
  • FAILED(hr) will return TRUE if the HRESULT indicates that the SQL-DMO function failed.

For example, to use the FAILED macro:

if FAILED (hr = pSQLServer->Connect (TEXT("myserver"),
    TEXT("mylogin"), TEXT("mypassword")))
{
    // Connection to SQL Server failed
}
else
{
    // Established connection to SQL Server
    // Use pSQLServer object
}

To use the SUCCEEDED macro:

if SUCCEEDED (hr = pSQLServer->Connect (TEXT("myserver"),
    TEXT("mylogin"), TEXT("mypassword")))
{
    // Established connection to SQL Server
    // Use pSQLServer object
}
else
{
    // Connection to SQL Server failed
}

Use the OLE macros HRESULT_CODE(hr) or SCODE_CODE(hr) to get the SQL-DMO error number from the HRESULT hr returned by a SQL-DMO function.

Use the SQL-DMO macro SQLOLE_ECAT(hr) to get the SQL-DMO error category from the HRESULT hr returned by a SQL-DMO function that failed.

SQL-DMO supports the OLE IErrorInfo interface for passing rich error information back to the program. Use the following steps to get rich SQL-DMO error information:

  1. Call the OLE GetErrorInfo function to get an OLE ErrorInfo object (a pointer to the IErrorInfo interface).
  2. Use the ErrorInfo functions, including GetDescription and GetSource, to get rich SQL-DMO error information.
  3. Release the ErrorInfo object.

For example:

if FAILED(hr = pSQLServer->Connect (TEXT("myserver"),
    TEXT("mylogin"), TEXT("mypassword")))
{
    // Connection to SQL Server failed
    // Get OLE ErrorInfo object
    LPERRORINFO pErrorInfo = NULL;
    GetErrorInfo (0, &pErrorInfo);
    // Get SQL-DMO error information
    BSTR strDescription, strSource;
    pErrorInfo->GetDescription (&strDescription);
    pErrorInfo->GetSource (&strSource);
    // Display SQL-DMO error information
    // The SQL-DMO error code is HRESULT_CODE(hr)
    pErrorInfo->Release ();
    SysFreeString (strDescription);
    SysFreeString (strSource);
}


Datatypes

The following table describes the SQL-DMO abstract datatypes and includes the Hungarian notation prefixes used in the SQL-DMO documentation:

SQL-DMO Datatype | Prefix | Description

String | str | A generic string. For example, "Felis catus".
MultiString | mstr | A list of one or more strings delimited by semicolons. For example, "Korat; Maine Coon; Russian Blue".
Identifier | id | A string that must conform to the rules for Transact-SQL identifiers. For example "pubs".
MultiIdentifier | mid | A list of one or more identifiers delimited by semicolons. For example, "authors; titles; pub_info".
Long | l | A 4-byte integer.
Integer | i | A 2-byte integer.
Boolean | b | A True/False value. It can be True or False in Visual Basic. It can be TRUE or FALSE in C++.
Float | f | A 4-byte floating point number. For example, 4.24.
Double | d | An 8-byte floating point number. For example, 9.39.
Date | dat | In Visual Basic, an 8-byte Date value. In C++, a 4-byte integer that has the form YYYYMMDD, where YYYY is the year, MM is the number of the month, and DD is the number of the day. For example, March 22, 1995 is 19950322.

SQL-DMO also uses enumerated datatypes. Each enumeration has a datatype of SQLOLE_INFORMATION_TYPE, and contains a series of SQLOLEInfo_Value constants. The Hungarian notation prefix t is used for enumerated datatypes.

Visual Basic

The following table shows the Visual Basic datatype for each SQL-DMO abstract datatype:

SQL-DMO Datatype | Visual Basic Datatype

String | String
MultiString | String
Identifier | String
MultiIdentifier | String
Long | Long
Integer | Integer
Boolean | Boolean
Float | Single
Double | Double
Date | Date

C++

Because all SQL-DMO functions return an HRESULT, you must pass the address of a program variable (using the address of & operator) for any return parameter (such as a Get Property function) so SQL-DMO can write to your program variable. This is the pointer datatype. For an input parameter (such as a Set Property function), SQL-DMO only reads the program variable. This is the constant datatype.

The following table shows the C++ pointer datatype and constant datatype for each SQL-DMO abstract datatype:

SQL-DMO Datatype | C++ Pointer Datatype | C++ Constant Datatype

String | SQLOLE_LPBSTR | SQLOLE_LPCSTR
MultiString | SQLOLE_LPBSTR | SQLOLE_LPCSTR
Identifier | SQLOLE_LPBSTR | SQLOLE_LPCSTR
MultiIdentifier | SQLOLE_LPBSTR | SQLOLE_LPCSTR
Long | LPLONG | long
Integer | LPINT | int
Boolean | LPBOOL | BOOL
Float | LPFLOAT | float
Double | LPDOUBLE | double
Date | LPLONG | long


Visual Basic Objects

The following lists are the SQL-DMO objects available from Visual Basic. Objects in bold can be created using the New keyword in a Dim statement, or using the CreateObject function. Objects not in bold cannot be created, and can only be returned from other SQL-DMO objects.


SQLServer Scope

Configuration

ConfigValue

Device

Language

Login

RemoteLogin

RemoteServer

SQLServer

SubscriberInfo


Database Scope

Article

Database

DBObject

DBOption

Default

Group

Publication

Rule

StoredProcedure

Subscription

SystemDatatype

TransactionLog

User

UserDefinedDatatype


Table Scope

Check

Column

DRIDefault

Index

Key

Table

Trigger

View


Service Scope

Alert

AlertSystem

Executive

IntegratedSecurity

Operator

Registry

Task


Application Scope

Application

Backup

HistoryFilter

Names

Permission

Property

QueryResults


C++ Objects

The following lists are the SQL-DMO objects available for C++ programs. Each SQL-DMO object has a "pointer to an object" type (used for C++ variable declarations) and an interface ID, and some objects have a class ID. SQL-DMO objects that have a class ID can be created using CoCreateInstance. Objects that do not have a class ID cannot be created, and can only be returned from other SQL-DMO objects.

These values are listed in the following format:

Object
Pointer to object type

Pointer to collection object type ( - if none)

Pointer to list object type ( - if none)

Class ID ( - if none)

Interface ID

The Object is bold if it can be created using CoCreateInstance.

For most SQL-DMO objects, where Object is the name of the SQL-DMO object, the Object name is used as a suffix to the variable type, class ID and interface ID as shown in the following format:

Object
LPSQLOLEOBJECT

LPSQLOLEOBJECTS

LPSQLOLEOBJECTLIST

CLSID_SQLOLEObject

IID_ISQLOLEObject

The SQLServer object is an exception. It only uses the Server suffix for the variable type, class ID, and interface ID, but still uses the complete name SQLServer for the object name.

Note that the Property object and Properties collection are not available to C++ programs.


SQLServer Scope

Configuration
LPSQLOLECONFIGURATION

-

-

-

IID_ISQLOLEConfiguration

ConfigValue
LPSQLOLECONFIGVALUE

LPSQLOLECONFIGVALUES

LPSQLOLECONFIGVALUELIST

-

IID_ISQLOLEConfigValue

Device
LPSQLOLEDEVICE

LPSQLOLEDEVICES

LPSQLOLEDEVICELIST

CLSID_SQLOLEDevice

IID_ISQLOLEDevice

Language
LPSQLOLELANGUAGE

LPSQLOLELANGUAGES

-

CLSID_SQLOLELanguage

IID_ISQLOLELanguage

Login
LPSQLOLELOGIN

LPSQLOLELOGINS

LPSQLOLELOGINLIST

CLSID_SQLOLELogin

IID_ISQLOLELogin

RemoteLogin
LPSQLOLEREMOTELOGIN

LPSQLOLEREMOTELOGINS

-

CLSID_SQLOLERemoteLogin

IID_ISQLOLERemoteLogin

RemoteServer
LPSQLOLEREMOTESERVER

LPSQLOLEREMOTESERVERS

-

CLSID_SQLOLERemoteServer

IID_ISQLOLERemoteServer

SQLServer
LPSQLOLESERVER

LPSQLOLESERVERS

-

CLSID_SQLOLEServer

IID_ISQLOLEServer

SubscriberInfo
LPSQLOLESUBSCRIBERINFO

-

-

-

IID_ISQLOLESubscriberInfo


Database Scope

Article
LPSQLOLEARTICLE

LPSQLOLEARTICLES

LPSQLOLEARTICLELIST

CLSID_SQLOLEArticle

IID_ISQLOLEArticle

Database
LPSQLOLEDATABASE

LPSQLOLEDATABASES

LPSQLOLEDATABASELIST

CLSID_SQLOLEDatabase

IID_ISQLOLEDatabase

DBObject
LPSQLOLEDBOBJECT

LPSQLOLEDBOBJECTS

LPSQLOLEDBOBJECTLIST

-

IID_ISQLOLEDBObject

DBOption
LPSQLOLEDBOPTION

-

-

-

IID_ISQLOLEDBOption

Default
LPSQLOLEDEFAULT

LPSQLOLEDEFAULTS

-

CLSID_SQLOLEDefault

IID_ISQLOLEDefault

Group
LPSQLOLEGROUP

LPSQLOLEGROUPS

-

CLSID_SQLOLEGroup

IID_ISQLOLEGroup

Publication
LPSQLOLEPUBLICATION

LPSQLOLEPUBLICATIONS

-

CLSID_SQLOLEPublication

IID_ISQLOLEPublication

Rule
LPSQLOLERULE

LPSQLOLERULES

-

CLSID_SQLOLERule

IID_ISQLOLERule

StoredProcedure
LPSQLOLESTOREDPROCEDURE

LPSQLOLESTOREDPROCEDURES

LPSQLOLESTOREDPROCEDURELIST

CLSID_SQLOLEStoredProcedure

IID_ISQLOLEStoredProcedure

Subscription
LPSQLOLESUBSCRIPTION

LPSQLOLESUBSCRIPTIONS

-

CLSID_SQLOLESubscription

IID_ISQLOLESubscription

SystemDatatype
LPSQLOLESYSTEMDATATYPE

LPSQLOLESYSTEMDATATYPES

-

-

IID_ISQLOLESystemDatatype

TransactionLog
LPSQLOLETRANSACTIONLOG

-

-

-

IID_ISQLOLETransactionLog

User
LPSQLOLEUSER

LPSQLOLEUSERS

LPSQLOLEUSERLIST

CLSID_SQLOLEUser

IID_ISQLOLEUser

UserDefinedDatatype
LPSQLOLEUSERDEFINEDDATATYPE

LPSQLOLEUSERDEFINEDDATATYPES

LPSQLOLEUSERDEFINEDDATATYPELIST

CLSID_SQLOLEUserDefinedDatatype

IID_ISQLOLEUserDefinedDatatype


Table Scope

Check
LPSQLOLECHECK

LPSQLOLECHECKS

-

CLSID_SQLOLECheck

IID_ISQLOLECheck

Column
LPSQLOLECOLUMN

LPSQLOLECOLUMNS

LPSQLOLECOLUMNLIST

CLSID_SQLOLEColumn

IID_ISQLOLEColumn

DRIDefault
LPSQLOLEDRIDEFAULT

-

-

-

IID_ISQLOLEDRIDefault

Index
LPSQLOLEINDEX

LPSQLOLEINDEXES

-

CLSID_SQLOLEIndex

IID_ISQLOLEIndex

Key
LPSQLOLEKEY

LPSQLOLEKEYS

LPSQLOLEKEYLIST

CLSID_SQLOLEKey

IID_ISQLOLEKey

Table
LPSQLOLETABLE

LPSQLOLETABLES

-

CLSID_SQLOLETable

IID_ISQLOLETable

Trigger
LPSQLOLETRIGGER

LPSQLOLETRIGGERS

-

CLSID_SQLOLETrigger

IID_ISQLOLETrigger

View
LPSQLOLEVIEW

LPSQLOLEVIEWS

-

CLSID_SQLOLEView

IID_ISQLOLEView


Service Scope

Alert
LPSQLOLEALERT

LPSQLOLEALERTS

-

CLSID_SQLOLEAlert

IID_ISQLOLEAlert

AlertSystem
LPSQLOLEALERTSYSTEM

-

-

-

IID_ISQLOLEAlertSystem

Executive
LPSQLOLEEXECUTIVE

-

-

-

IID_ISQLOLEExecutive

IntegratedSecurity
LPSQLOLEINTEGRATEDSECURITY

-

-

-

IID_ISQLOLEIntegratedSecurity

Operator
LPSQLOLEOPERATOR

LPSQLOLEOPERATORS

-

CLSID_SQLOLEOperator

IID_ISQLOLEOperator

Registry
LPSQLOLEREGISTRY

-

-

-

IID_ISQLOLERegistry

Task
LPSQLOLETASK

LPSQLOLETASKS

LPSQLOLETASKLIST

CLSID_SQLOLETask

IID_ISQLOLETask


Application Scope

Application
LPSQLOLEAPPLICATION

-

-

CLSID_SQLOLEApplication

IID_ISQLOLEApplication

Backup
LPSQLOLEBACKUP

-

-

CLSID_SQLOLEBackup

IID_ISQLOLEBackup

HistoryFilter
LPSQLOLEHISTORYFILTER

-

-

CLSID_SQLOLEHistoryFilter

IID_ISQLOLEHistoryFilter

Names
-

LPSQLOLENAMES

LPSQLOLENAMELIST

-

IID_ISQLOLENames

Permission
LPSQLOLEPERMISSION

-

LPSQLOLEPERMISSIONLIST

-

IID_ISQLOLEPermission

QueryResults
LPSQLOLEQUERYRESULTS

-

-

-

IID_ISQLOLEQueryResults


Chapter 3 SQLServer Scope Objects

SQLServer Scope Objects

Configuration Object

ConfigValue Object

Device Object

Language Object

Login Object

RemoteLogin Object

RemoteServer Object

SQLServer Object

SubscriberInfo Object


Configuration Object

Configuration Object Properties Methods Collections

Description

The Configuration object contains a collection of ConfigValue objects. SQL Server configuration options are named values which determine specific SQL Server behavior. Each configuration option has a corresponding object in the ConfigValues collection of the Configuration object. You examine and change a configuration option using the properties of the ConfigValue object. After any configuration option changes are made, you call the ReconfigureCurrentValues or ReconfigureWithOverride method.


Configuration Properties

Configuration Object Properties Methods Collections

Property | Description

Application Application Write: No | The Application object.
Parent SQLServer Write: No | The SQLServer object.
ShowAdvancedOptions Boolean Write: Yes | Determines if advanced configuration options are included in the ConfigValues collection. If True, advanced configuration options are included. If False, advanced configuration options are not included.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Configuration Methods

Configuration Object Properties Methods Collections

ReconfigureCurrentValues

ReconfigureWithOverride


ReconfigureCurrentValues Method

SQLServer.Configuration Object

Description

Accept any and all changes made to SQL Server configuration options. Any changes made to the CurrentValue property of all ConfigValue objects will be accepted by SQL Server. Changes to static configuration options will take effect after SQL Server is stopped and restarted.

Visual Basic

Configuration.ReconfigureCurrentValues

C++

HRESULT pConfiguration->ReconfigureCurrentValues ( );

Reference

RECONFIGURE, sp_configure


ReconfigureWithOverride Method

SQLServer.Configuration Object

Description

Accepts any and all changes made to SQL Server configuration options, ignoring any SQL Server warnings. Any changes made to the CurrentValue property of all ConfigValue objects will be accepted by SQL Server. Changes to static configuration options will take effect after SQL Server is stopped and restarted.

Visual Basic

Configuration.ReconfigureWithOverride

C++

HRESULT pConfiguration->ReconfigureWithOverride ( );

Reference

RECONFIGURE WITH OVERRIDE, sp_configure


Configuration Collections

Configuration Object Properties Methods Collections

Collection | Description

ConfigValues ConfigValues Write: No | The collection of ConfigValue objects.
Parameters Names Write: No | The Names collection that contains command-line parameters passed to SQLSERVR.EXE. Each parameter must include the parameter switch (for example, /e) and the parameter value (for example, C:\SQL60\LOG\ERRORLOG).
Properties Properties Write: No | The collection of Property objects.


ConfigValue Object

ConfigValue Object Properties Collections

Description

Each SQL Server configuration option has a corresponding object in the ConfigValues collection of the Configuration object. You examine configuration option details like minimum and maximum value, and change a configuration option value, using the ConfigValue object for that configuration option.


ConfigValue Properties

ConfigValue Object Properties Collections

Property | Description

Application Application Write: No | The Application object.
CurrentValue Long Write: Yes | The current value of the configuration option. Set this property to change the current value.
Description String Write: No | A description of this configuration option.
DynamicReconfigure Boolean Write: No | Indicates if a change to the configuration option will take effect immediately when you call the ReconfigureCurrentValues or ReconfigureWithOverride method of the Configuration object. This value is True if the configuration option takes effect immediately, or False if SQL Server must be shut down and restarted.
ID SQLOLE_CONFIGVALUE_TYPE Write: No | The type of configuration value.
MaximumValue Long Write: No | The maximum value of the configuration option.
MinimumValue Long Write: No | The minimum value of the configuration option.
Name String Write: No | The name of this configuration option.
Parent Configuration Write: No | The Configuration object.
RunningValue Long Write: No | The configuration value being used by the running SQL Server.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


ConfigValue Collections

ConfigValue Object Properties Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Device Object

Device Object Properties Methods Lists Collections

Description

A Device object is pre-allocated physical storage (usually a file on a hard disk) used by SQL Server for storing database information. There are two general types of devices: database devices and dump devices. SQL Server uses database devices to store an entire database, including the transaction log. SQL Server uses dump devices for backup (dump) and restore (load) operations.


Device Properties

Device Object Properties Methods Lists Collections

Property | Description

Application Application Write: No | The Application object.
Default Boolean Write: Yes | Determines if unused space on this database device should be included in the default device pool. When the user creates a new database or extends an existing database, and either does not specify a database device or specifies the default database device, SQL Server uses available device space from the default device pool for database storage. If True, unused space on this device is included in the default device pool. If False, either this device is not included in the default device pool, or this is a dump device.
DeviceNumber Long Write: No | The virtual device number.
FirstPage Long Write: No | The first virtual page number. This property is -1 for dump devices.
LastPage Long Write: No | The last virtual page number. This property is -1 for dump devices.
MirrorName String Write: No | The full path and filename of the mirror device, if any.
MirrorState SQLOLE_MIRROR_TYPE Write: No | The mirror state.
Name Identifier Write: Yes | The name of this device.
Parent SQLServer Write: No | The SQLServer object.
PhysicalLocation String Write: Before Add | The full path and filename of the device storage space.
Size Long Write: Before Add | The size of this device in megabytes.
SkipTapeLabel Boolean Write: Yes | Determines if ANSI tape labels are ignored for dump devices. If True, ANSI tape labels are ignored. If False, either ANSI tape labels are read for dump devices, or this is a database device.
SpaceAvailable Long Write: No | Unused space in megabytes.
Status Long Write: | The status bitmap.
SystemObject Boolean Write: No | Indicates if this is a SQL Server system device. If True, this is a SQL Server system device. If False, this device was created by a user.
Type SQLOLE_DEVICE_TYPE Write: Yes | The type of the database or dump device.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Device Methods

Device Object Properties Methods Lists Collections

Mirror

ReadBackupHeader

ReMirror

Remove

SwitchToMirrorDevice

SwitchToMirrorTemp

UnMirrorDevice

UnMirrorTemp


Mirror Method

SQLServer.Device Object

Description

Creates a mirror device for an existing database device.

Visual Basic

Device.Mirror ( [MirrorPathName :=] strMirrorPath )

C++

HRESULT pDevice->Mirror ( SQLOLE_LPCSTR strMirrorPath );

Elements

Element | Type | Description

strMirrorPath | String | Full path and filename of mirror device file

Reference

DISK MIRROR


ReadBackupHeader Method

SQLServer.Device Object

Description

Retrieves the dump header information for a dump device. The dump header contains information about every dump currently stored in the dump device. The dump header information is returned in a QueryResults object.

Visual Basic

QueryResults = Device.ReadBackupHeader

C++

HRESULT pDevice->ReadBackupHeader ( LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object

QueryResults

ColumnName | ColumnType

Dumptype | SQLOLE_DTypeInt2
Database | SQLOLE_DTypeChar
Striped | SQLOLE_DTypeInt2
Compressed | SQLOLE_DTypeInt2
Sequence | SQLOLE_DTypeChar
Volume | SQLOLE_DTypeChar
Devicetype | SQLOLE_DTypeInt2
Table | SQLOLE_DTypeChar
Dumpsize | SQLOLE_DTypeChar
Stripeset | SQLOLE_DTypeChar
Stripeset Name | SQLOLE_DTypeChar
Curseq | SQLOLE_DTypeChar
Newseq | SQLOLE_DTypeChar
CreationDate | SQLOLE_DTypeChar
CreationTime | SQLOLE_DTypeChar
ExpireDate | SQLOLE_DTypeChar

Reference

LOAD HEADERONLY


ReMirror Method

SQLServer.Device Object

Description

Reestablishes disk mirroring for a device. The disk mirroring for this dump device must have been previously (and temporarily) disabled using the SwitchToMirrorTemp or UnMirrorTemp method. Disk mirroring will be reestablished to the same state as it was before being disabled.

Visual Basic

Device.ReMirror

C++

HRESULT pDevice->ReMirror ( );

Reference

DISK REMIRROR


Remove Method

SQLServer.Device Object

Description

Drops the SQL Server database or dump device and removes the Device object. For a database device, if any databases are using any space on the device, the database device cannot be removed.

Visual Basic

Device.Remove

C++

HRESULT pDevice->Remove ( );

Reference

sp_dropdevice


SwitchToMirrorDevice Method

SQLServer.Device Object

Description

Permanently stops disk mirroring for a device. Now only the mirror device is used for storage, permanently becoming the new primary database device. The original primary database device is no longer used.

Visual Basic

Device.SwitchToMirrorDevice

C++

HRESULT pDevice->SwitchToMirrorDevice ( );

Reference

DISK UNMIRROR


SwitchToMirrorTemp Method

SQLServer.Device Object

Description

Temporarily disables disk mirroring for a device. Until the ReMirror method is used, only the mirror device is used for storage, and the primary database device is temporarily disabled. Use the ReMirror method to reestablish disk mirroring.

Visual Basic

Device.SwitchToMirrorTemp

C++

HRESULT pDevice->SwitchToMirrorTemp ( );

Reference

DISK UNMIRROR


UnMirrorDevice Method

SQLServer.Device Object

Description

Permanently disables disk mirroring for a device. Now only the primary database device is used for storage, and the mirror device is no longer used.

Visual Basic

Device.UnMirrorDevice

C++

HRESULT pDevice->UnMirrorDevice ( );

Reference

DISK UNMIRROR


UnMirrorTemp Method

SQLServer.Device Object

Description

Temporarily stops disk mirroring for a device. Until the ReMirror method is used, only the primary database device is used for storage, and the mirror device is temporarily disabled. Use the ReMirror method to reestablish disk mirroring.

Visual Basic

Device.UnMirrorTemp

C++

HRESULT pDevice->UnMirrorTemp ( );

Reference

DISK UNMIRROR


Device Lists

Device Object Properties Methods Lists Collections

ListDatabases


ListDatabases List

SQLServer.Device Object

Description

Lists the Database objects that use storage space on a device.

Visual Basic

DatabaseList = Device.ListDatabases

C++

HRESULT pDevice->ListDatabases ( LPSQLOLEDATABASELIST* ppDatabaseList );

Elements

Element | Type | Description

DatabaseList | DatabaseList | Returned list of Database objects


Device Collections

Device Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Language Object

Language Object Properties Methods Collections

Description

A Language object contains all the information about each language supported by SQL Server.


Language Object Properties

Language Properties

Language Object Properties Methods Collections

Property | Description

Alias String Write: Yes | Alternate name for the language.
Application Application Write: No | The Application object.
DateFormat String Write: Before Add | Three characters describing the order of the date parts day, month, and year. Valid values include "dmy", "dym", "mdy", "myd", "ydm", and "ymd".
Days String Write: Before Add | Comma-separated list of day full names, in order from Monday through Sunday.
FirstDayOfWeek Integer Write: Before Add | Number of the first day of the week. The numbers 1 through 7 correspond to the days Monday through Sunday respectively.
ID Long Write: No | The language ID.
Months String Write: Before Add | Comma-separated list of month full names, in order from January through December.
Name String Write: Before Add | Official name for the language.
Parent SQLServer Write: No | The SQLServer object.
ShortMonths String Write: Before Add | Comma-separated list of month short names (first three characters), in order from Jan through Dec.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
Upgrade Long Write: No | Version of SQL Server used for most recent upgrade of the language.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Day Method

SQLServer.Language Object

Description

Returns the full name of a day for a language.

Visual Basic

strDay = Language.Day ( [Day :=] iDay )

C++

HRESULT pLanguage->GetDay (
int iDay,
SQLOLE_LPBSTR pstrDay );

Elements

Element | Type | Description

strDay | String | Returned day full name
iDay | Integer | Number of the day where day number 1 is Monday

Remarks

This is an indexed property.

Reference

syslanguages


Month Method

SQLServer.Language Object

Description

Returns the full name of a month for a language.

Visual Basic

strMonth = Language.Month ( [Month :=] iMonth )

C++

HRESULT pLanguage->GetMonth (
int iMonth,
SQLOLE_LPBSTR pstrMonth );

Elements

Element | Type | Description

strMonth | String | Returned month full name
iMonth | Integer | Number of the month where month number 1 is January

Remarks

This is an indexed property.

Reference

syslanguages


Remove Method

SQLServer.Language Object

Description

Drops the SQL Server language and removes the Language object.

Visual Basic

Language.Remove

C++

HRESULT pLanguage->Remove ( );

Reference

sp_droplanguage


ShortMonth Method

SQLServer.Language Object

Description

Returns the short name of a month for a language.

Visual Basic

strShortMonth = Language.ShortMonth ( iMonth )

C++

HRESULT pLanguage->GetShortMonth (
int iMonth,
SQLOLE_LPBSTR pstrShortMonth );

Elements

Element | Type | Description

strShortMonth | String | Returned month short name
iMonth | Integer | Number of the month where month number 1 is January

Remarks

This is an indexed property.

Reference

syslanguages


Language Collections

Language Object Properties Methods Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Login Object

Login Object Properties Methods Lists Collections

Description

A Login object is a login identifier and password used to connect to SQL Server. A Login object is global to the entire SQL Server, and has corresponding User objects in each database.


Login Properties

Login Object Properties Methods Lists Collections

Property | Description

Application Application Write: No | The Application object.
Database Identifier Write: Yes | The default database used when this login connects to SQL Server.
Language String Write: Yes | The default language used by this login.
ID Long Write: No | The login ID.
Name Identifier Write: Before Add | The login name.
Parent SQLServer Write: No | The SQLServer object.
SystemObject Boolean Write: No | Indicates if this is a SQL Server system login. If True, this is the SA login. If False, this is not the SA login.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


AliasName Method

SQLServer.Login Object

Description

Returns the alias username that a login is associated with for a specific database.

Visual Basic

idAlias = Login.AliasName ( [DatabaseName :=] idDatabase )

C++

HRESULT pLogin->GetAliasName (
SQLOLE_LPCSTR idDatabase,
SQLOLE_LPBSTR pidAlias );

Elements

Element | Type | Description

idAlias | Identifier | Returned alias username
idDatabase | Identifier | Database to retrieve alias username from

Remarks

This is an indexed property.

Reference

sp_addalias


Remove Method

SQLServer.Login Object

Description

Drops the SQL Server login identifier and removes the Login object.

Visual Basic

Login.Remove

C++

HRESULT pLogin->Remove ( );

Reference

sp_droplogin


Script Method

SQLServer.Login Object

Description

Produces a Transact-SQL script that can be used to create the login.

Visual Basic

strSQLScript = Login.Script (
[ScriptType :=] tScriptOptions,
[[ScriptFilePath :=] strFile] )

C++

HRESULT pLogin->Script (
SQLOLE_SCRIPT_TYPE tScriptOptions = SQLOLEScript_Default,
SQLOLE_LPCSTR strFile = NULL,
SQLOLE_LPBSTR pstrSQLScript = NULL );

Elements

Element | Type | Description

strSQLScript | String | Returned Transact-SQL script to create the login
tScriptOptions | SQLOLE_SCRIPT_TYPE | Script options
strFile | String | Full path and filename of Transact-SQL script file to create


SetPassword Method

SQLServer.Login Object

Description

Changes the password for this login. Note that because the password is encrypted, there is no way to read it from server.

Visual Basic

Login.SetPassword (
[OldPassword :=] idOldPassword,
[NewPassword :=] idNewPassword )

C++

HRESULT pLogin->SetPassword (
SQLOLE_LPCSTR idOldPassword,
SQLOLE_LPCSTR idNewPassword );

Elements

Element | Type | Description

idOldPassword | Identifier | Old password
idNewPassword | Identifier | New password

Reference

sp_password


UserName Method

SQLServer.Login Object

Description

Returns the user that a login is associated with for a specific database.

Visual Basic

idUser = Login.UserName ( [DatabaseName :=] idDatabase )

C++

HRESULT pLogin->GetUserName (
SQLOLE_LPCSTR idDatabase,
SQLOLE_LPBSTR pidUser );

Elements

Element | Type | Description

idUser | Identifier | Returned username
idDatabase | Identifier | Database to retrieve username from

Remarks

This is an indexed property.

Reference

sp_adduser


Login Lists

Login Object Properties Methods Lists Collections

ListTasks


ListTasks List

SQLServer.Login Object

Description

Lists the Task objects owned by this login.

Visual Basic

TaskList = Login.ListTasks

C++

HRESULT pLogin->ListTasks ( LPSQLOLETASKLIST* ppTaskList );

Elements

Element | Type | Description

TaskList | TaskList | Returned list of Task objects


Login Collections

Login Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


RemoteLogin Object

RemoteLogin Object Properties Methods Collections

Description

A RemoteLogin object is used when a remote server connects to the local SQL Server. The RemoteLogin specifies the association between a remote login from a specific remote server and a local login. Each RemoteServer object can have multiple RemoteLogin objects.


RemoteLogin Properties

RemoteLogin Object Properties Methods Collections

Property | Description

Application Application Write: No | The Application object.
LocalName Identifier Write: Before Add | The local login used by the local SQL Server. When the remote server connects using this RemoteLogin and the remote login specified by the RemoteName property, the local SQL Server uses this local login.
Parent RemoteServer Write: No | The RemoteServer object.
RemoteName Identifier Write: Before Add | The remote login on the remote server. When the remote server connects using this RemoteLogin, the local SQL Server uses the local login specified by the LocalName property. This is the "Name" property of the RemoteLogins collection.
Trusted Boolean Write: Yes | Determines if the remote password is checked when this RemoteLogin connects to SQL Server. If True, the remote password is checked, and the connection attempt is denied if the remote password does not match the local password. If False, the remote password is not checked, and the connection attempt succeeds.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


RemoteLogin Methods

RemoteLogin Object Properties Methods Collections

Remove


Remove Method

SQLServer.RemoteServer.RemoteLogin Object

Description

Drops the SQL Server remote login and removes the RemoteLogin object.

Visual Basic

RemoteLogin.Remove

C++

HRESULT pRemoteLogin->Remove ( );

Reference

sp_dropremotelogin


RemoteLogin Collections

RemoteLogin Object Properties Methods Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


RemoteServer Object

RemoteServer Object Properties Methods Lists Collections

Description

A RemoteServers object is a remote SQL Server that is known to the local SQL Server.


RemoteServer Properties

RemoteServer Object Properties Methods Lists Collections

Property | Description

Application Application Write: No | The Application object.
ID Long Write: No | The remote server ID.
Name Identifier Write: Before Add | The name of the remote server.
NetName Identifier Write: Yes | The network name of the remote server.
Options SQLOLE_SRVOPTION_TYPE Write: No | The bitmap of remote server options that are currently enabled.
Parent SQLServer Write: No | The SQLServer object.
SubscriberInfo SubscriberInfo Write: No | The SubscriberInfo object.
TopologyX Long Write: No | Reserved.
TopologyY Long Write: No | Reserved.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | The temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


RemoteServer Methods

RemoteServer Object Properties Methods Lists Collections

BeginAlter

CancelAlter

DoAlter

ExecuteImmediate

ExecuteWithResults

Refresh

Remove

SetOptions

SetTopologyXY

Subscribe

UnSubscribe


BeginAlter Method

SQLServer.RemoteServer Object

Description

Marks the start of a single unit of changes to RemoteServer properties. Normally, each change to a single property is a separate update to SQL Server. To group multiple property changes into a single unit, first call the BeginAlter method, then make the desired property changes. To commit the unit of property changes to SQL Server using a single update, call the DoAlter method. To cancel the unit of property changes (made since calling BeginAlter), call the CancelAlter method.

Visual Basic

RemoteServer.BeginAlter

C++

HRESULT pRemoteServer->BeginAlter ( );


DoAlter Method

SQLServer.RemoteServer Object

Description

Stops a unit of RemoteServer property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will not be committed to SQL Server.

Visual Basic

RemoteServer.CancelAlter

C++

HRESULT pRemoteServer->CancelAlter ( );


CancelAlter Method

SQLServer.RemoteServer Object

Description

Commits a unit of RemoteServer property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will be committed to SQL Server using a single update.

Visual Basic

RemoteServer.DoAlter

C++

HRESULT pRemoteServer->DoAlter ( );


ExecuteImmediate Method

SQLServer.RemoteServer Object

Description

Executes a Transact-SQL statement on a remote server. No results are returned to the application.

Visual Basic

RemoteServer.ExecuteImmediate ( [Command :=] strSQLStatement )

C++

HRESULT pRemoteServer->ExecuteImmediate ( SQLOLE_LPCSTR strSQLStatement );

Elements

Element | Type | Description

strSQLStatement | String | SQL statement

Reference

sp_sqlexec


ExecuteWithResults Method

SQLServer.RemoteServer Object

Description

Executes a Transact-SQL statement on a remote server. Returns results in a QueryResults object.

Visual Basic

QueryResults = RemoteServer.ExecuteWithResults ( [Command :=] strSQLStatement )

C++

HRESULT pRemoteServer->ExecuteWithResults (
SQLOLE_LPCSTR strSQLStatement,
LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
strSQLStatement | String | SQL statement

QueryResults

The contents of the QueryResults object depend on the Transact-SQL statement.

Reference

sp_sqlexec


Refresh Method

SQLServer.RemoteServer Object

Description

Updates RemoteServer properties with current values from SQL Server.

Visual Basic

RemoteServer.Refresh

C++

HRESULT pRemoteServer->Refresh ( );


Remove Method

SQLServer.RemoteServer Object

Description

Drops the SQL Server remote server and removes the RemoteServer object.

Visual Basic

RemoteServer.Remove

C++

HRESULT pRemoteServer->Remove ( );

Reference

sp_dropserver


SetOptions Method

SQLServer.RemoteServer Object

Description

Changes server options for a remote server.

Visual Basic

RemoteServer.SetOptions (
[Options :=] tServerOptions,
[Setting :=] bSetting )

C++

HRESULT pRemoteServer->SetOptions (
SQLOLE_SRVOPTION_TYPE tServerOptions,
BOOL bSetting );

Elements

Element | Type | Description

tServerOptions | SQLOLE_SRVOPTION_TYPE | Bitmap of server options to set
bSetting | Boolean | New setting for all the specified options

Reference

sp_serveroption


SetTopologyXY Method

SQLServer.RemoteServer Object

Description

Reserved. Do not use this method.

Visual Basic

RemoteServer.SetTopologyXY (
[X :=] lX,
[Y :=] lY )

C++

HRESULT pRemoteServer->SetSetTopologyXY (
long lX,
long lY );

Elements

Element | Type | Description

lX | Long | X value
lY | Long | Y value


Subscribe Method

SQLServer.RemoteServer Object

Description

Subscribes to a publication on a remote server.

Visual Basic

RemoteServer.Subscribe (
[DatabaseName :=] idPubDatabase,
[PublicationName :=] idPublication,
[[ArticleName :=] idArticle,]
[[SubscribingDB :=] idSubDatabase,]
[[SyncType :=] tSync] )

C++

HRESULT pRemoteServer->Subscribe (
SQLOLE_LPCSTR idPubDatabase,
SQLOLE_LPCSTR idPublication,
SQLOLE_LPCSTR idArticle = NULL,
SQLOLE_LPCSTR idSubDatabase = NULL,
SQLOLE_SUBSYNC_TYPE tSync = SQLOLESubSync_Auto );

Elements

Element | Type | Description

idPubDatabase | Identifier | Database on the remote server that is publishing the article.
idPublication | Identifier | Publication that contains the article.
idArticle | Identifier | Article to subscribe to. Default is all articles.
idSubDatabase | Identifier | Destination database on the local server that is subscribing to the article. Default is the same database as idPubDatabase.
tSync | SQLOLE_SUBSYNC_TYPE | Synchronization type.

Reference

sp_subscribe


UnSubscribe Method

SQLServer.RemoteServer Object

Description

Stops an existing subscription from a remote server.

Visual Basic

RemoteServer.UnSubscribe (
[DatabaseName :=] idPubDatabase,
[[PublicationName :=] idPublication,]
[[ArticleName :=] idArticle] )

C++

HRESULT pRemoteServer->UnSubscribe (
SQLOLE_LPCSTR idPubDatabase,
SQLOLE_LPCSTR idPublication = NULL,
SQLOLE_LPCSTR idArticle = NULL );

Elements

Element | Type | Description

idPubDatabase | Identifier | Database on the remote server that is publishing the article.
idPublication | Identifier | Publication that contains the article. Default is all publications.
idArticle | Identifier | Article in publication to unsubscribe from. Default is all articles.

Reference

sp_unsubscribe


RemoteServer Lists

RemoteServer Object Properties Methods Lists Collections

EnumArticles

EnumPublicationDatabases

EnumPublications

EnumPublicationSyncTask

EnumSubscriptionDatabases

EnumSubscriptions

EnumTasks


EnumArticles List

SQLServer.RemoteServer Object

Description

Lists the articles contained in the specified publication and database for a remote server. List is returned in a QueryResults object.

Visual Basic

QueryResults = RemoteServer.EnumArticles (
[DatabaseName :=] idPubDatabase,
[PublicationName :=] idPublication )

C++

HRESULT pRemoteServer->EnumArticles (
SQLOLE_LPCSTR idPubDatabase,
SQLOLE_LPCSTR idPublication,
LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
idPubDatabase | Identifier | Database on the remote server that contains the publication
idPublication | Identifier | Publication that contains the articles to list

QueryResults

ColumnName | ColumnType

article id | SQLOLE_DTypeInt4
article name | SQLOLE_DTypeChar
base table | SQLOLE_DTypeChar
destination table | SQLOLE_DTypeChar
synchronization object | SQLOLE_DTypeChar
type | SQLOLE_DTypeInt1
status | SQLOLE_DTypeInt1
filter | SQLOLE_DTypeChar
description | SQLOLE_DTypeChar
insert_command | SQLOLE_DTypeChar
update_command | SQLOLE_DTypeChar
delete_command | SQLOLE_DTypeChar
creation script path | SQLOLE_DTypeChar
vertical partition | SQLOLE_DTypeBit
pre_creation_cmd | SQLOLE_DTypeInt1
filter_clause | SQLOLE_DTypeText


EnumPublicationDatabases List

SQLServer.RemoteServer Object

Description

Lists the databases on a remote server which can publish articles. List is returned in a QueryResults object.

Visual Basic

QueryResults = RemoteServer.EnumPublicationDatabases

C++

HRESULT pRemoteServer->EnumPublicationDatabases (
LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object

QueryResults

ColumnName | ColumnType

name | SQLOLE_DTypeChar


EnumPublications List

SQLServer.RemoteServer Object

Description

Lists publications of the specified database on a remote server. List is returned in a QueryResults object.

Visual Basic

QueryResults = RemoteServer.EnumPublications ( [DatabaseName :=] idPubDatabase )

C++

HRESULT pRemoteServer->EnumPublications (
SQLOLE_LPCSTR idPubDatabase,
LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
idPubDatabase | Identifier | Database on the remote server that contains the publication

QueryResults

ColumnName | ColumnType

pubid | SQLOLE_DTypeInt4
name | SQLOLE_DTypeChar
restricted | SQLOLE_DTypeBit
status | SQLOLE_DTypeInt1
task | SQLOLE_DTypeInt4
replication frequency | SQLOLE_DTypeInt1
synchronization method | SQLOLE_DTypeInt1
description | SQLOLE_DTypeChar


EnumPublicationSyncTask List

SQLServer.RemoteServer Object

Description

Returns information about a scheduled synchronization task for a publication and database on a remote server. The synchronization task information is returned in a QueryResults object.

Visual Basic

QueryResults = RemoteServer.EnumPublicationSyncTask (
[DatabaseName :=] idPubDatabase,
[PublicationName :=] idPublication )

C++

HRESULT pRemoteServer->EnumPublicationSyncTask (
SQLOLE_LPCSTR idPubDatabase,
SQLOLE_LPCSTR idPublication,
LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
idPubDatabase | Identifier | Database on the remote server that contains the publication
idPublication | Identifier | Publication

QueryResults

ColumnName | ColumnType

name | SQLOLE_DTypeChar
id | SQLOLE_DTypeInt4
subsystem | SQLOLE_DTypeChar
server | SQLOLE_DTypeChar
username | SQLOLE_DTypeChar
ownerloginname | SQLOLE_DTypeChar
databasename | SQLOLE_DTypeChar
enabled | SQLOLE_DTypeInt1
freqtype | SQLOLE_DTypeInt4
freqinterval | SQLOLE_DTypeInt4
freqsubtype | SQLOLE_DTypeInt4
freqsubinterval | SQLOLE_DTypeInt4
freqrelativeinterval | SQLOLE_DTypeInt4
freqrecurrencefactor | SQLOLE_DTypeInt4
activestartdate | SQLOLE_DTypeInt4
activeenddate | SQLOLE_DTypeInt4
activestarttimeofday | SQLOLE_DTypeInt4
activeendtimeofday | SQLOLE_DTypeInt4
lastrundate | SQLOLE_DTypeInt4
lastruntime | SQLOLE_DTypeInt4
nextrundate | SQLOLE_DTypeInt4
nextruntime | SQLOLE_DTypeInt4
runpriority | SQLOLE_DTypeInt4
emailoperatorname | SQLOLE_DTypeChar
retryattempts | SQLOLE_DTypeInt4
retrydelay | SQLOLE_DTypeInt4
datecreated | SQLOLE_DTypeDateTime
datemodified | SQLOLE_DTypeDateTime
command | SQLOLE_DTypeChar
lastruncompletionlevel | SQLOLE_DTypeInt4
lastrunduration | SQLOLE_DTypeInt4
lastrunretries | SQLOLE_DTypeInt4
loghistcompletionlevel | SQLOLE_DTypeInt4
emailcompletionlevel | SQLOLE_DTypeInt4
description | SQLOLE_DTypeChar
tagadditionalinfo | SQLOLE_DTypeChar
tagobjectid | SQLOLE_DTypeInt4
tagobjecttype | SQLOLE_DTypeInt4

Reference

sp_helppublicationsync


EnumSubscriptionDatabases List

SQLServer.RemoteServer Object

Description

Lists the databases on a remote server that can subscribe to articles. List is returned in a QueryResults object.

Visual Basic

QueryResults = RemoteServer.EnumSubscriptionDatabases

C++

HRESULT pRemoteServer->EnumSubscriptionDatabases ( LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object

QueryResults

ColumnName | ColumnType

name | SQLOLE_DTypeChar

Reference

sp_helpsubscription


EnumSubscriptions List

SQLServer.RemoteServer Object

Description

Lists subscriptions to the specified article on a remote server. List is returned in a QueryResults object.

Visual Basic

QueryResults = RemoteServer.EnumSubscriptions (
[DatabaseName :=] idPubDatabase,
[PublicationName :=] idPublication,
[ArticleName :=] idArticle )

C++

HRESULT pRemoteServer->EnumSubscriptions (
SQLOLE_LPCSTR idPubDatabase,
SQLOLE_LPCSTR idPublication,
SQLOLE_LPCSTR idArticle,
LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
idPubDatabase | Identifier | Database on the remote server that is publishing the article
idPublication | Identifier | Publication that contains the article
idArticle | Identifier | Article

QueryResults

ColumnName | ColumnType

subscriber | SQLOLE_DTypeChar
publication | SQLOLE_DTypeChar
article | SQLOLE_DTypeChar
destination database | SQLOLE_DTypeChar
subscription status | SQLOLE_DTypeInt1
synchronization type | SQLOLE_DTypeInt1

Reference

sp_helpsubscription


EnumTasks List

SQLServer.RemoteServer Object

Description

Lists tasks on a remote server. List is returned in a QueryResults object.

Visual Basic

QueryResults = RemoteServer.EnumTasks (
[[TaskName :=] idTaskName,]
[[TaskID :=] nTaskID] )

C++

HRESULT pRemoteServer->EnumTasks (
LPSQLOLEQUERYRESULTS* ppQueryResults,
SQLOLE_LPCSTR idTaskName = NULL,
long nTaskID = 0 );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
idTaskName | Identifier | Name of the task
nTaskID | Long | Task ID

QueryResults

ColumnName | ColumnType

name | SQLOLE_DTypeChar
id | SQLOLE_DTypeInt4
subsystem | SQLOLE_DTypeChar
server | SQLOLE_DTypeChar
username | SQLOLE_DTypeChar
ownerloginname | SQLOLE_DTypeChar
databasename | SQLOLE_DTypeChar
enabled | SQLOLE_DTypeInt1
freqtype | SQLOLE_DTypeInt4
freqinterval | SQLOLE_DTypeInt4
freqsubtype | SQLOLE_DTypeInt4
freqsubinterval | SQLOLE_DTypeInt4
freqrelativeinterval | SQLOLE_DTypeInt4
freqrecurrencefactor | SQLOLE_DTypeInt4
activestartdate | SQLOLE_DTypeInt4
activeenddate | SQLOLE_DTypeInt4
activestarttimeofday | SQLOLE_DTypeInt4
activeendtimeofday | SQLOLE_DTypeInt4
lastrundate | SQLOLE_DTypeInt4
lastruntime | SQLOLE_DTypeInt4
nextrundate | SQLOLE_DTypeInt4
nextruntime | SQLOLE_DTypeInt4
runpriority | SQLOLE_DTypeInt4
emailoperatorname | SQLOLE_DTypeChar
retryattempts | SQLOLE_DTypeInt4
retrydelay | SQLOLE_DTypeInt4
datecreated | SQLOLE_DTypeDateTime
datemodified | SQLOLE_DTypeDateTime
command | SQLOLE_DTypeChar
lastruncompletionlevel | SQLOLE_DTypeInt4
lastrunduration | SQLOLE_DTypeInt4
lastrunretries | SQLOLE_DTypeInt4
loghistcompletionlevel | SQLOLE_DTypeInt4
emailcompletionlevel | SQLOLE_DTypeInt4
description | SQLOLE_DTypeChar
tagadditionalinfo | SQLOLE_DTypeChar
tagobjectid | SQLOLE_DTypeInt4
tagobjecttype | SQLOLE_DTypeInt4

Reference

sp_helptask


RemoteServer Collections

RemoteServer Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.
RemoteLogins RemoteLogins Write: No | The collection of RemoteLogin objects.


SQLServer Object

SQLServer Object Properties Methods Lists Collections

Description

The SQLServer object is the top level object for the SQL Server OLE object model. All other SQL-DMO objects are either contained within or accessed through a SQLServer object.

A SQLServer object is associated with a single SQL Server, and contains a single connection to that SQL Server. You use the Connect method to establish a connection to SQL Server.


SQLServer Methods

SQLServer Object Properties Methods Lists Collections

BeginTransaction

Close

CommandShellImmediate

CommandShellWithResults

CommitTransaction

Connect

Continue

DisConnect

ExecuteImmediate

ExecuteWithResults

KillDatabase

KillProcess

Pause

ProcessInputBuffer

ProcessOutputBuffer

PurgeHistory

ReadBackupHeader

ReadErrorLog

ReConnect

RemoveSubscriberSubscriptions

RollbackTransaction

SaveTransaction

Start

StatusInfoRefetchInterval

ShutDown

UnloadODSDLL

VerifyConnection


BeginTransaction Method

SQLServer Object

Description

Begins a transaction.

Visual Basic

SQLServer.BeginTransaction ( [[TransactionName :=] idTransaction] )

C++

HRESULT pSQLServer->BeginTransaction ( SQLOLE_LPCSTR idTransaction = NULL );

Elements

Element | Type | Description

idTransaction | Identifier | Transaction name

Reference

BEGIN TRANSACTION


Close Method

SQLServer Object

Description

Disconnects from SQL Server and closes the SQLServer object.

Visual Basic

SQLServer.Close

C++

HRESULT pSQLServer->Close ( );


CommandShellImmediate Method

SQLServer Object

Description

Executes an operating system command. Output from the command is not returned.

Visual Basic

SQLServer.CommandShell ( [Command :=] strCommand )

C++

HRESULT pSQLServer->CommandShell ( SQLOLE_LPCSTR
strCommand );

Elements

Element | Type | Description

strCommand | String | Operating system command

Reference

xp_cmdshell


CommandShellWithResults Method

SQLServer Object

Description

Executes an operating system command. Output from the command is returned in a QueryResults object.

Visual Basic

QueryResults = SQLServer.CommandShellWithResults ( [Command :=] strCommand )

C++

HRESULT pSQLServer->CommandShellWithResults (
SQLOLE_LPCSTR strCommand,
LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
strCommand | String | Operating system command

Remarks

The contents of the QueryResults object depend on the operating system command.

Reference

xp_cmdshell


CommitTransaction Method

SQLServer Object

Description

Commits an open transaction.

Visual Basic

SQLServer.CommitTransaction ( [[TransactionName :=] idTransaction] )

C++

HRESULT pSQLServer->CommitTransaction ( SQLOLE_LPCSTR idTransaction = NULL );

Elements

Element | Type | Description

idTransaction | Identifier | Transaction name

Reference

COMMIT TRANSACTION


Connect Method

SQLServer Object

Description

Connects to SQL Server.

Visual Basic

SQLServer.Connect (
[[ServerName :=] strServer,]
[[Login :=] idLogin,]
[[Password :=] idPassword] )

C++

HRESULT pSQLServer->Connect (
SQLOLE_LPCSTR strServer = NULL,
SQLOLE_LPCSTR idLogin = NULL,
SQLOLE_LPCSTR idPassword = NULL );

Elements

Element | Type | Description

strServer | String | Name of SQL Server
idLogin | Identifier | Login
idPassword | Identifier | Password


Continue Method

SQLServer Object

Description

Continues a paused SQL Server.

Visual Basic

SQLServer.Continue

C++

HRESULT pSQLServer->Continue ( );


DisConnect Method

SQLServer Object

Description

Disconnects from SQL Server.

Visual Basic

SQLServer.DisConnect

C++

HRESULT pSQLServer->DisConnect ( );


ExecuteImmediate Method

SQLServer Object

Description

Executes a Transact-SQL statement on a SQL Server. No results are returned to the application.

Visual Basic

SQLServer.ExecuteImmediate (
[Command :=] strSQLStatement,
[[ExecType :=] tExecOption] )

C++

HRESULT pSQLServer->ExecuteImmediate (
SQLOLE_LPCSTR strSQLStatement,
SQLOLE_EXEC_TYPE tExecOption = SQLOLEExec_Default );

Elements

Element | Type | Description

strSQLStatement | String | SQL statement
tExecOption | SQLOLE_EXEC_TYPE | Options for executing this SQL statement

Reference

EXECUTE


ExecuteWithResults Method

SQLServer Object

Description

Executes a Transact-SQL statement on a SQL Server. Returns results in a QueryResults object.

Visual Basic

QueryResults = SQLServer.ExecuteWithResults ( [Command :=] strSQLStatement )

C++

HRESULT pSQLServer->ExecuteWithResults (
SQLOLE_LPCSTR strSQLStatement,
LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
strSQLStatement | String | SQL statement

QueryResults

ColumnName | ColumnType

name | SQLOLE_DTypeChar

Reference

EXECUTE


KillDatabase Method

SQLServer Object

Description

Removes a damaged database. Use this when Database.Remove fails.

Visual Basic

SQLServer.KillDatabase ( [DatabaseName :=] idDatabase )

C++

HRESULT pSQLServer->KillDatabase ( SQLOLE_LPCSTR idDatabase );

Elements

Element | Type | Description

idDatabase | Identifier | Database name

Reference

DBCC DBREPAIR


KillProcess Method

SQLServer Object

Description

Terminates a SQL Server process.

Visual Basic

SQLServer.KillProcess ( [ProcessID :=] lProcess )

C++

HRESULT pSQLServer->KillProcess ( long lProcess );

Elements

Element | Type | Description

lProcess | Long | SQL Server process ID

Remarks

A SQLServer object cannot use KillProcess to terminate its own connection.

Reference

KILL


Pause Method

SQLServer Object

Description

Pauses a running SQL Server.

Visual Basic

SQLServer.Pause

C++

HRESULT pSQLServer->Pause ( );


ProcessInputBuffer Method

SQLServer Object

Description

Retrieves the SQL Server input buffer for a SQL Server process.

Visual Basic

strInputBuffer = SQLServer.ProcessInputBuffer ( [ProcessID :=] lProcess )

C++

HRESULT pSQLServer->GetProcessInputBuffer (
long lProcess,
SQLOLE_LPBSTR pstrInputBuffer );

Elements

Element | Type | Description

strInputBuffer | String | Returned SQL Server input buffer
lProcess | Long | SQL Server process

Remarks

This is an indexed property.

Reference

DBCC INPUTBUFFER


ProcessOutputBuffer Method

SQLServer Object

Description

Retrieves the SQL Server output buffer for a SQL Server process.

Visual Basic

strOutputBuffer = SQLServer.ProcessOutputBuffer ( [ProcessID :=] lProcess )

C++

HRESULT pSQLServer->GetProcessOutputBuffer (
long lProcess,
SQLOLE_LPBSTR pstrOutputBuffer );

Elements

Element | Type | Description

strOutputBuffer | String | Returned SQL Server output buffer
lProcess | Long | SQL Server process

Remarks

This is an indexed property.

Reference

DBCC OUTPUTBUFFER


PurgeHistory Method

SQLServer Object

Description

Removes information from the task history log. Set the properties of a created HistoryFilter object as desired and pass it to the PurgeHistory method.

Visual Basic

SQLServer.PurgeHistory ( [[HistoryFilter :=] HistoryFilter] )

C++

HRESULT pSQLServer->PurgeHistory ( LPSQLOLEHISTORYFILTER HistoryFilter = NULL );

Elements

Element | Type | Description

HistoryFilter | HistoryFilter | HistoryFilter object

Remarks

Only the system administrator can purge history information for tasks owned by other users.

Reference

sp_purgehistory


ReadBackupHeader Method

SQLServer Object

Description

Retrieves the dump header information for a Backup object. The dump header contains information about every dump currently stored in the dump device. The dump header information is returned in a QueryResults object.

Visual Basic

QueryResults = SQLServer.ReadBackupHeader ( [LoadSpec :=] Backup )

C++

HRESULT pSQLServer->ReadBackupHeader (
LPSQLOLEBACKUP Backup,
LPSQLOLEQUERYRESULTS* ppQueryResults );

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
Backup | Backup | Backup object containing the backup specifications

QueryResults

ColumnName | ColumnType

Dumptype | SQLOLE_DTypeInt2
Database | SQLOLE_DTypeChar
Striped | SQLOLE_DTypeInt2
Compressed | SQLOLE_DTypeInt2
Sequence | SQLOLE_DTypeChar
Volume | SQLOLE_DTypeChar
Devicetype | SQLOLE_DTypeInt2
Table | SQLOLE_DTypeChar
Dumpsize | SQLOLE_DTypeChar
Stripeset | SQLOLE_DTypeChar
Stripeset Name | SQLOLE_DTypeChar
Curseq | SQLOLE_DTypeChar
Newseq | SQLOLE_DTypeChar
CreationDate | SQLOLE_DTypeChar
CreationTime | SQLOLE_DTypeChar
ExpireDate | SQLOLE_DTypeChar

Reference

LOAD HEADERONLY


ReadErrorLog Method

SQLServer Object

Description

Reads the specified SQL Server error log. Returns results in a QueryResult object.

Visual Basic

QueryResults = SQLServer.ReadErrorLog ( [[LogNumber :=] lLogNumber] )

C++

HRESULT pSQLServer->ReadErrorLog (
LPSQLOLEQUERYRESULTS* ppQueryResults,
long lLogNumber = 0 );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
lLogNumber | Long | Log number

QueryResults

ColumnName | ColumnType

C:\SQL60\LOG\ERRORLOG | SQLOLE_DTypeChar


ReConnect Method

SQLServer Object

Description

Reestablishes a connection to SQL Server that was previously closed using DisConnect.

Visual Basic

SQLServer.ReConnect

C++

HRESULT pSQLServer->ReConnect ( );


RemoveSubscriberSubscriptions Method

SQLServer Object

Description

Removes subscriptions for a subscriber from this SQL Server.

Visual Basic

SQLServer.RemoveSubscriberSubscriptions (
[Subscriber :=] idSubServer,
[[SourceDatabase :=] idDatabase] )

C++

HRESULT pSQLServer->RemoveSubscriberSubscriptions (
SQLOLE_LPCSTR idSubServer,
SQLOLE_LPCSTR SourceDatabase = NULL );

Elements

Element | Type | Description

idSubServer | Identifier | Subscriber SQL Server.
idDatabase | Identifier | Database to remove subscriptions from. Default is all databases.


RollbackTransaction Method

SQLServer Object

Description

Rolls back an open transaction.

Visual Basic

SQLServer.RollbackTransaction ( [[TransactionOrSavepointName :=] idTransactionOrSavepoint] )

C++

HRESULT pSQLServer->RollbackTransaction ( SQLOLE_LPCSTR idTransactionOrSavepoint = NULL );

Elements

Element | Type | Description

idTransactionOrSavepoint | Identifier | The transaction name

Reference

ROLLBACK TRANSACTION


SaveTransaction Method

SQLServer Object

Description

Sets a savepoint within an open transaction.

Visual Basic

SQLServer.SaveTransaction ( [SavepointName :=] idSavepoint )

C++

HRESULT pSQLServer->SaveTransaction ( SQLOLE_LPCSTR
idSavepoint );

Elements

Element | Type | Description

idSavepoint | Identifier | The savepoint name

Reference

SAVE TRANSACTION


Start Method

SQLServer Object

Description

Starts a stopped SQL Server.

Visual Basic

SQLServer.Start (
[[Server :=] strServer,]
[[Login :=] idLogin,]
[[Password :=] idPassword,]
[[MasterDBPath :=] strMasterDatabasePath,]
[[ErrorLogPath :=] strErrorLogPath,]
[[MasterMirrorPath :=] strMasterMirrorPath,]
[[StartMode :=] tStartMode] )

C++

HRESULT pSQLServer->Start (
SQLOLE_LPCSTR strServer = NULL,
SQLOLE_LPCSTR idLogin = NULL,
SQLOLE_LPCSTR idPassword = NULL,
SQLOLE_LPCSTR strMasterDatabasePath = NULL,
SQLOLE_LPCSTR strErrorLogPath = NULL,
SQLOLE_LPCSTR strMasterMirrorPath = NULL,
SQLOLE_STARTSRV_TYPE tStartMode = SQLOLEStart_Defaults );

Elements

Element | Type | Description

strServer | String | Name of SQL Server to start
idLogin | Identifier | Login
idPassword | Identifier | Password
strMasterDatabasePath | String | Path to master database
strErrorLogPath | String | Path to error log
strMasterMirrorPath | String | Path to master mirror
tStartMode | SQLOLE_STARTSRV_TYPE | Start mode


StatusInfoRefetchInterval Method

SQLServer Object

Description

Gets or sets the refetch interval for retrieiving the Status and SpaceAvailable properties for all Database objects in the SQLServer.Databases collection.

Visual Basic

lRefetchInterval = SQLServer.StatusInfoRefetchInterval ( [StatusInfoType :=] tStatusInfo )

SQLServer.StatusInfoRefetchInterval ( [StatusInfoType :=] tStatusInfo ) = lRefetchInterval

C++

HRESULT pSQLServer->GetStatusInfoRefetchInterval (
SQLOLE_STATUSINFO_TYPE tStatusInfo,
LPLONG plRefetch );

HRESULT pSQLServer->SetStatusInfoRefetchInterval (
SQLOLE_STATUSINFO_TYPE tStatusInfo,
long lRefetch );

Elements

Element | Type | Description

lRefetchInterval | Long | Refetch interval in seconds
tStatusInfo | SQLOLE_STATUSINFO_TYPE | Status information to set or get

Remarks

When the Status and SpaceAvailable properties are retrieved for one Database object, SQL-DMO retrieves and caches these properties for all Databases. If you get one of these properties within lRefetchInterval seconds after the last retrieval, the information from the cache will be used. If you get one of these properties more than lRefetchInterval seconds after the last retrieval, these properties of all Databases will be retrieved from SQL Server again. Setting lRefetchInterval to 0 disables this behavior. The default is 30 seconds.

This is an indexed property.


ShutDown Method

SQLServer Object

Description

Stops a running SQL Server.

Visual Basic

SQLServer.ShutDown ( [[Wait :=] bWait] )

C++

HRESULT pSQLServer->ShutDown ( BOOL bWait = TRUE );

Elements

Element | Type | Description

bWait | Boolean | If True, SQL Server waits for current operations to complete before stopping. If False, SQL Server stops immediately.

Reference

SHUTDOWN


UnloadODSDLL Method

SQLServer Object

Description

Unloads an Open Data Services DLL, such as an extended stored procedure DLL, from SQL Server memory.

Visual Basic

SQLServer.UnloadODSDLL ( [DLLName :=] strDLL )

C++

HRESULT pSQLServer->UnloadODSDLL ( SQLOLE_LPCSTR strDLL );

Elements

Element | Type | Description

strDLL | String | Open Data Services DLL file

Reference

DBCC dllname(FREE)


VerifyConnection Method

SQLServer Object

Description

Returns the state of a connection or a connection verification option.

Visual Basic

bStatus = SQLServer->VerifyConnection ( [[ReconnectIfDead :=]
tVerifyType] )

C++

HRESULT pSQLServer->VerifyConnection (
LPBOOL pbStatus,
SQLOLE_VERIFYCONN_TYPE tVerifyType = SQLOLEConn_ReconnectIfDead );

Elements

Element | Type | Description

bStatus | Boolean | Indicates the status of the tVerifyType value. If True, the connection is valid or the option is enabled. If False, the indicated connection is broken or the option is disabled.
tVerifyType | SQLOLE_VERIFYCONN_TYPE | Connection status or connection verification option.


SQLServer Lists

SQLServer Object Properties Methods Lists Collections

EnumAvailableMedia

EnumDirectories

EnumErrorLogs

EnumHistory

EnumLocks

EnumProcesses

EnumPublicationDatabases

EnumServerAttributes

EnumSubscriberSubscriptions

EnumSubscriptionDatabases

EnumVersionInfo

ListStartupProcedures


EnumAvailableMedia List

SQLServer Object

Description

Lists available media. List is returned in a QueryResults object.

Visual Basic

QueryResults = SQLServer.EnumAvailableMedia ( [[MediaType :=] tMedia] )

C++

HRESULT pSQLServer->EnumAvailableMedia (
LPSQLOLEQUERYRESULTS* ppQueryResults,
SQLOLE_MEDIA_TYPE tMedia = SQLOLEMedia_All );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
tMedia | SQLOLE_MEDIA_TYPE | Media type

QueryResults

ColumnName | ColumnType

name | SQLOLE_DTypeChar
low free | SQLOLE_DTypeInt4
high free | SQLOLE_DTypeInt4
media type | SQLOLE_DTypeInt1


EnumDirectories List

SQLServer Object

Description

Lists directories on the SQL Server computer. List is returned in a QueryResults object.

Visual Basic

QueryResults = SQLServer.EnumDirectories ( [PathName :=] strPath )

C++

HRESULT pSQLServer->EnumDirectories (
SQLOLE_LPCSTR strPath,
LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
strPath | String | Path name

QueryResults

ColumnName | ColumnType

subdirectory | SQLOLE_DTypeChar


EnumErrorLogs List

SQLServer Object

Description

Lists SQL Server error logs. List is returned in a QueryResults object.

Visual Basic

QueryResults = SQLServer.EnumErrorLogs

C++

HRESULT pSQLServer->EnumErrorLogs ( LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object

QueryResults

ColumnName | ColumnType

Archive # | SQLOLE_DTypeInt4
Date | SQLOLE_DTypeChar


EnumHistory List

SQLServer Object

Description

Lists SQL Server task history. List is returned in a QueryResults object. Set the properties of a created HistoryFilter object as desired and pass it to the EnumHistory method.

Visual Basic

QueryResults = SQLServer.EnumHistory ( [[HistoryFilter :=] HistoryFilter] )

C++

HRESULT pSQLServer->EnumHistory (
LPSQLOLEQUERYRESULTS* ppQueryResults,
LPSQLOLEHISTORYFILTER HistoryFilter = NULL );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
HistoryFilter | HistoryFilter | HistoryFilter object

QueryResults

ColumnName | ColumnType

id | SQLOLE_DTypeInt4
eventid | SQLOLE_DTypeInt4
messageid | SQLOLE_DTypeInt4
severity | SQLOLE_DTypeInt4
taskname | SQLOLE_DTypeChar
source | SQLOLE_DTypeChar
category | SQLOLE_DTypeChar
runstatus | SQLOLE_DTypeInt4
rundate | SQLOLE_DTypeInt4
runtime | SQLOLE_DTypeInt4
runduration | SQLOLE_DTypeInt4
reviewstatus | SQLOLE_DTypeChar
emailoperatorname | SQLOLE_DTypeChar
retries | SQLOLE_DTypeInt4
comments | SQLOLE_DTypeChar
timesskipped | SQLOLE_DTypeInt4

Reference

sp_helphistory


EnumLocks List

SQLServer Object

Description

Lists the locks held by a SQL Server process. List is returned in a QueryResults object.

Visual Basic

QueryResults = SQLServer.EnumLocks ( [[WhoByID :=] lProcess] )

C++

HRESULT pSQLServer->EnumLocks (
LPSQLOLEQUERYRESULTS* ppQueryResults,
long lProcess = -1 );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
lProcess | Long | Process

QueryResults

ColumnName | ColumnType

spid | SQLOLE_DTypeInt2
locktype | SQLOLE_DTypeChar
tablename | SQLOLE_DTypeChar
page | SQLOLE_DTypeInt4
dbname | SQLOLE_DTypeChar

Reference

sp_lock


EnumProcesses List

SQLServer Object

Description

Lists the processes connected to SQL Server. List is returned in a QueryResults object.

Visual Basic

QueryResults = SQLServer.EnumProcesses ( [[WhoByNameOrID :=]
{idLogin | lProcess}] )

C++

HRESULT pSQLServer->EnumProcesses (
LPSQLOLEQUERYRESULTS* ppQueryResults,
SQLOLE_LPCSTR idLogin = NULL,
long lProcess = -1 );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
idLogin | Identifier | Login
lProcess | Long | Process

QueryResults

ColumnName | ColumnType

spid | SQLOLE_DTypeInt2
status | SQLOLE_DTypeChar
loginname | SQLOLE_DTypeChar
hostname | SQLOLE_DTypeChar
program_name | SQLOLE_DTypeChar
cmd | SQLOLE_DTypeChar
dbname | SQLOLE_DTypeChar
cpu | SQLOLE_DTypeInt4
memusage | SQLOLE_DTypeInt4
blocked | SQLOLE_DTypeInt2

Reference

sp_who


EnumPublicationDatabases List

SQLServer Object

Description

Lists publication databases. List is returned in a QueryResults object.

Visual Basic

QueryResults = SQLServer.EnumPublicationDatabases

C++

HRESULT pSQLServer->EnumPublicationDatabases ( LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object

QueryResults

ColumnName | ColumnType

name | SQLOLE_DTypeChar

Reference

sp_helpreplicationdb


EnumServerAttributes List

SQLServer Object

Description

Lists SQL Server attributes and current settings. List is returned in a QueryResults object.

Visual Basic

QueryResults = SQLServer.EnumServerAttributes

C++

HRESULT pSQLServer->EnumServerAttributes (
LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object

QueryResults

ColumnName | ColumnType

attribute_id | SQLOLE_DTypeInt4
attribute_name | SQLOLE_DTypeChar
attribute_value | SQLOLE_DTypeChar

Reference

sp_server_info


EnumSubscriberSubscriptions List

SQLServer Object

Description

Lists the subscription information for a subscriber SQL Server. List is returned in a QueryResults object.

Visual Basic

QueryResults = SQLServer.EnumSubscriberSubscriptions (
[Subscriber :=] idSubscriberServer,
[[SourceDatabase :=] idDatabase] )

C++

HRESULT pSQLServer->EnumSubscriberSubscriptions (
SQLOLE_LPCSTR idSubscriberServer,
LPSQLOLEQUERYRESULTS* ppQueryResults,
SQLOLE_LPCSTR idDatabase = NULL );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
idSubscriberServer | Identifier | Subscriber SQL Server
idDatabase | Identifier | Database

QueryResults

ColumnName | ColumnType

cSubscriber | SQLOLE_DTypeChar
cPubDBName | SQLOLE_DTypeChar
cPublication | SQLOLE_DTypeChar
cArticle | SQLOLE_DTypeChar


EnumSubscriptionDatabases List

SQLServer Object

Description

Lists subscription databases. List is returned in a QueryResults object.

Visual Basic

QueryResults = SQLServer.EnumSubscriptionDatabases

C++

HRESULT pSQLServer->EnumSubscriptionDatabases ( LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object

QueryResults

ColumnName | ColumnType

name | SQLOLE_DTypeChar

Reference

sp_helpreplicationdb


EnumVersionInfo List

SQLServer Object

Description

Lists version information. List is returned in a QueryResults object.

Visual Basic

QueryResults = SQLServer.EnumVersionInfo ( [[Prefixes :=] mstrPrefixes] )

C++

HRESULT pSQLServer->EnumVersionInfo (
LPSQLOLEQUERYRESULTS* ppQueryResults,
SQLOLE_LPCSTR mstrPrefixes = NULL );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
mstrPrefixes | MultiString | Delimited list of one or more prefix strings

QueryResults

ColumnName | ColumnType

Index | SQLOLE_DTypeInt2
Name | SQLOLE_DTypeChar
Internal_Value | SQLOLE_DTypeInt4
Character_Value | SQLOLE_DTypeChar

Reference

xp_msver


ListStartupProcedures List

SQLServer Object

Description

Lists the stored procedures that start automatically when SQL Server is started.

Visual Basic

StoredProcedureList = SQLServer.ListStartupProcedures

C++

HRESULT pSQLServer->ListStartupProcedures ( LPSQLOLESTOREDPROCEDURELIST* ppStoredProcedureList );

Elements

Element | Type | Description

StoredProcedureList | StoredProcedureList | Returned list of StoredProcedure objects

Reference

sp_helpstartup


SQLServer Collections

SQLServer Object Properties Methods Lists Collections

Collection | Description

Alerts Alerts Write: No | The collection of Alert objects.
Databases Databases Write: No | The collection of Database objects.
Devices Devices Write: No | The collection of Device objects.
Languages Languages Write: No | The collection of Language objects.
Logins Logins Write: No | The collection of Login objects.
Operators Operators Write: No | The collection of Operator objects.
Properties Properties Write: No | The collection of Property objects.
RemoteServers RemoteServers Write: No | The collection of RemoteServer objects.


SubscriberInfo Object

SubscriberInfo Object Properties Methods Collections

Description

A SubscriberInfo object contains all the replication subscribing information about a RemoteServer.


SubscriberInfo Properties

SubscriberInfo Object Properties Methods Collections

Property | Description

ActiveEndDate Date Write: Yes | The date and time before which this task is active.
ActiveStartDate Date Write: Yes | The date and time after which this task is active.
Application Application Write: No | The Application object.
CommitTransactionCount Long Write: Yes | The maximum number of transactions that will be sent to the remote server at a time.
FlushFrequency Long Write: Yes | The number of hours after distribution to wait before flushing.
FrequencyInterval Long Write: Yes | The the number of days between daily tasks, day of the week for weekly tasks, or the day of the month for monthly tasks, on which this task will occur.
FrequencyRecurrenceFactor Long Write: Yes | The number of weeks between weekly tasks, or the number of months between monthly tasks.
FrequencyRelativeInterval SQLOLE_FREQRELATIVE_TYPE Write: Yes | The day of the month for monthly relative tasks, on which this task will occur.
FrequencySubDay SQLOLE_FREQSUB_TYPE Write: Yes | Within a specifc day, the subday frequency unit of time, by minute or by hour.
FrequencySubDayInterval Long Write: Yes | The number of minutes between minutely tasks, or the number of hours between hourly tasks.
FrequencyType SQLOLE_FREQUENCY_TYPE Write: Yes | The primary frequency unit of time.
LogBatchSize Long Write: Yes | Reserved. Do not change this property.
Login Identifier Write: Yes | Reserved. Do not change this property.
Parent RemoteServer Write: No | The RemoteServer object.
Password Identifier Write: Yes | Reserved. Do not change this property.
Type Long Write: Yes | The type of subscription server. If 0, the remote server is running SQL Server 95. If 1, the remote server is running SQL Server version 4.2x.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


SubscriberInfo Methods

SubscriberInfo Object Properties Methods Collections

BeginAlter

CancelAlter

DoAlter

Refresh


BeginAlter Method

SQLServer.RemoteServer.SubscriberInfo Object

Description

Marks the start of a single unit of changes to SubscriberInfo properties. Normally, each change to a single property is a separate update to SQL Server. To group multiple property changes into a single unit, first call the BeginAlter method, then make the desired property changes. To commit the unit of property changes to SQL Server using a single update, call the DoAlter method. To cancel the unit of property changes (made since calling BeginAlter), call the CancelAlter method.

Visual Basic

SubscriberInfo.BeginAlter

C++

HRESULT pSubscriberInfo->BeginAlter ( );


CancelAlter Method

SQLServer.RemoteServer.SubscriberInfo Object

Description

Stops a unit of SubscriberInfo property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will not be committed to SQL Server.

Visual Basic

SubscriberInfo.CancelAlter

C++

HRESULT pSubscriberInfo->CancelAlter ( );


DoAlter Method

SQLServer.RemoteServer.SubscriberInfo Object

Description

Commits a unit of SubscriberInfo property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will be committed to SQL Server using a single update.

Visual Basic

SubscriberInfo.DoAlter

C++

HRESULT pSubscriberInfo->DoAlter ( );


Refresh Method

SQLServer.RemoteServer.SubscriberInfo Object

Description

Updates SubscriberInfo properties with current values from SQL Server.

Visual Basic

SubscriberInfo.Refresh

C++

HRESULT pSubscriberInfo->Refresh ( );


SubscriberInfo Collections

SubscriberInfo Object Properties Methods Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Chapter 4 Database Scope Objects

Database Scope Objects

Article Object

Database Object

DBObject Object

DBOption Object

Default Object

Group Object

Publication Object

Rule Object

StoredProcedure Object

Subscription Object

SystemDatatype Object

TransactionLog Object

User Object

UserDefinedDatatype Object


Article Object

Article Object Properties Methods Lists Collections

Description

An Article contains information about an article contained in a publication.


Article Properties

Article Object Properties Methods Lists Collections

Property | Description

Application Application Write: No | The Application object.
CreationScriptPath String Write: Yes | The full Universal Naming Convention (UNC) path and filename of the initial synchronization creation script for the article.
DeleteCommand String Write: Yes | The Transact-SQL statement to execute upon delete. If empty, construct the delete from the log.
Description String Write: Yes | A description for the article.
DestinationTableName Identifier Write: Yes | The name of the destination table on the subscribing server.
FilterClause String Write: Yes | The Transact-SQL WHERE clause used to filter the article for horizontal partitioning.
ID Long Write: No | The article ID.
InitialSyncObjectName Identifier Write: Yes | The table or view used to create the initial synchronization output file, if one was manually created. Values written to this property will be ignored when the article has no horizontal or vertical partitioning.
InsertCommand String Write: Yes | The Transact-SQL statement to execute upon insert. If empty, construct the insert from the log.
Name Identifier Write: Yes | The name of the article.
Parent Database Write: No | The Database object.
PreCreationMethod SQLOLE_PREARTICLE_TYPE Write: Yes | The type of command executed on the destination table before synchronization occurs.
ReplicateAllColumns Boolean Write: No | Indicates if all columns of the source table are replicated. If True, all columns of the source table are replicated. If False, the source table has been vertically partitioned and only some columns are replicated.
ReplicationFilterProcName Identifier Write: Yes | The stored procedure that is used to filter the table for horizontal partitioning, if one was manually created. Values written to the property will be ignored if there is no horizontal or vertical filterin.
ReplicationType SQLOLE_REPLICATION_TYPE Write: Yes | The type of replication to use for this article.
TableName Identifier Write: Before Add | The source table being published and replicated.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UpdateCommand String Write: Yes | The Transact-SQL statement to execute upon update. If empty, construct the update from the log.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Article Methods

Article Object Properties Methods Lists Collections

AddReplicatedColumns

BeginAlter

CancelAlter

DoAlter

Remove

RemoveReplicatedColumns

ScriptDestinationTable


AddReplicatedColumns Method

SQLServer.Database.Publication.Article Object

Description

Adds a list of columns of the source table to the group of columns that are replicated, if the Article is vertically partitioned.

Visual Basic

Article.AddReplicatedColumns ( [Columns :=] midColumns )

C++

HRESULT pArticle->AddReplicatedColumns ( SQLOLE_LPCSTR midColumns );

Elements

Element | Type | Description

midColumns | MultiString | Delimited list of columns. If empty, the vertical partition is cleared and all columns are included in the article.

Reference

sp_articlecolumn


BeginAlter Method

SQLServer.Database.Publication.Article Object

Description

Marks the start of a single unit of changes to Article properties. Normally, each change to a single property is a separate update to SQL Server. To group multiple property changes into a single unit, first call the BeginAlter method, then make the desired property changes. To commit the unit of property changes to SQL Server using a single update, call the DoAlter method. To cancel the unit of property changes (made since calling BeginAlter), call the CancelAlter method.

Visual Basic

Article.BeginAlter

C++

HRESULT pArticle->BeginAlter ( );


CancelAlter Method

SQLServer.Database.Publication.Article Object

Description

Stops a unit of Article property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will not be committed to SQL Server.

Visual Basic

Article.CancelAlter

C++

HRESULT pArticle->CancelAlter ( );


DoAlter Method

SQLServer.Database.Publication.Article Object

Description

Commits a unit of Article property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will be committed to SQL Server using a single update.

Visual Basic

Article.DoAlter

C++

HRESULT pArticle->DoAlter ( );


Remove Method

SQLServer.Database.Publication.Article Object

Description

Drops the SQL Server article and removes the Article object.

Visual Basic

Article.Remove

C++

HRESULT pArticle->Remove ( );

Reference

sp_droparticle


RemoveReplicatedColumns Method

SQLServer.Database.Publication.Article Object

Description

Removes a series of columns of the source table from the group of columns that are replicated.

Visual Basic

Article.RemoveReplicatedColumns ( [Columns :=] midColumns )

C++

HRESULT pArticle->RemoveReplicatedColumns ( SQLOLE_LPCSTR midColumns );

Elements

Element | Type | Description

midColumns | MultiIdentifier | Delimited list of columns

Reference

sp_articlecolumn


ScriptDestinationTable Method

SQLServer.Database.Publication.Article Object

Description

Produces a Transact-SQL script that can be used to create the subscribing (destination) table. This script includes the column subset if the Article is vertically partitioned.

Visual Basic

strSQLScript = Article.ScriptDestinationTable (
[ScriptType :=] tScriptOptions,
[[ScriptFilePath :=] strFile] )

C++

HRESULT pArticle->ScriptDestinationTable (
SQLOLE_SCRIPT_TYPE tScriptOptions = SQLOLEScript_Default,
SQLOLE_LPCSTR strFile = NULL,
SQLOLE_LPBSTR pstrSQLScript = NULL );

Elements

Element | Type | Description

strSQLScript | String | Returned Transact-SQL script
tScriptOptions | SQLOLE_SCRIPT_TYPE | Script options
strFile | String | Full path and file name of Transact-SQL script file to create


Article Lists

Article Object Properties Methods Lists Collections

ListReplicatedColumns


ListReplicatedColumns List

SQLServer.Database.Publication.Article Object

Description

Returns a list of Column objects of the source table that are currently replicated.

Visual Basic

ColumnList = Article.ListReplicatedColumns

C++

HRESULT pArticle->ListReplicatedColumns ( LPSQLOLECOLUMNLIST* ppColumnList );

Elements

Element | Type | Description

ColumnList | ColumnList | Returned list of Column objects

Reference

sp_helparticlecolumns


Article Collections

Article Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.
Subscriptions Subscriptions Write: No | The collection of Subscription objects.


Database Object

Database Object Properties Methods Lists Collections

Description

A Database object contains other objects (like Table, View, and StoredProcedure objects) which contain or interact with data.


Database Properties

Database Object Properties Methods Lists Collections

Property | Description

Application Application Write: No | The Application object.
CreateDate String Write: No | The date and time this database was created.
CreateForLoad Boolean Write: Before Add | Determines if this database was created with the FOR LOAD option.
DataSpaceUsage Float Write: No | The space in megabytes (accurate to two decimal places) used to store data.
DboLogin Boolean Write: No | Indicates if the login used for the connection (contained in the SQLServer object) has DBO privilege in this database.
DBOption DBOption Write: No | The DBOption object for this database.
IndexSpaceUsage Float Write: No | The space in megabytes (accurate to two decimal places) used to store indexes.
ID Long Write: No | The database ID.
MinimumSize Long Write: No | The minimum size this database can be shrunk to.
Name Identifier Write: Yes | The name of this database.
Owner Identifier Write: No | The login of the database owner.
Parent SQLServer Write: No | The SQLServer object.
Size Long Write: No | The total storage space in megabytes allocated for this database. This includes both used and available space.
SpaceAvailable Long Write: No | The unused storage space in kilobytes available for new data.
SpaceAvailableInMB Float Write: No | The unused storage space in megabytes (accurate to two decimal places) available for new data.
Status SQLOLE_DBSTATUS_TYPE Write: No | The status of this database.
SystemObject Boolean Write: No | Indicates if this is a SQL Server system database. If True, this is a SQL Server system database. If False, this database was created by a user.
TransactionLog TransactionLog Write: No | The TransactionLog object for this database.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.
UserName Identifier Write: Yes | Name of the current database user. The SA or DBO can change this property to that of existing user in this database, thus impersonating that other user.
UserProfile SQLOLE_DBUSERPROFILE_TYPE Write: No | The database profile information for the currently connected user.
Version Long Write: No | The version of the database from sysdatabases.


Database Methods

Database Object Properties Methods Lists Collections

CheckAllocations

CheckCatalog

Checkpoint

CheckTables

CheckTextAllocsFast

CheckTextAllocsFull

Dump

ExecuteImmediate

ExecuteWithResults

ExtendOnDevices

GenerateBackupSQL

GetDatatypeByName

GetMemoryUsage

GetObjectByName

Grant

IsValidKeyDatatype

Load

ManualSyncCompleted

ManualSyncPending

RecalcSpaceUsage

Remove

Revoke

SetOwner

Shrink

SpaceAllocatedOnDevice


CheckAllocations Method

SQLServer.Database Object

Description

Checks the internal allocation consistency of the database. This includes checking that data and index pages are consistent with the allocation information in the extent.

Visual Basic

strOutput = Database.CheckAllocations

C++

HRESULT pDatabase->CheckAllocations ( SQLOLE_LPBSTR pstrOutput );

Elements

Element | Type | Description

strOutput | String | The output returned by the internal consistency check

Reference

DBCC NEWALLOC


CheckCatalog Method

SQLServer.Database Object

Description

Checks the consistency of system tables and relationships between system tables for this database.

Visual Basic

strOutput = Database.CheckCatalog

C++

HRESULT pDatabase->CheckCatalog ( SQLOLE_LPBSTR pstrOutput );

Elements

Element | Type | Description

strOutput | String | The output returned by the internal consistency check

Reference

DBCC CHECKCATALOG


Checkpoint Method

SQLServer.Database Object

Description

Flushes the SQL Server cache, writing all changed pages to disk.

Visual Basic

Database.Checkpoint

C++

HRESULT pDatabase->Checkpoint ( );

Reference

CHECKPOINT


CheckTables Method

SQLServer.Database Object

Description

Checks the internal consistency of the data and index pages of every table in the database.

Visual Basic

strOutput = Database.CheckTables

C++

HRESULT pDatabase->CheckTables ( SQLOLE_LPBSTR pstrOutput );

Elements

Element | Type | Description

strOutput | String | The output returned by the internal consistency check

Reference

DBCC CHECKDB, DBCC CHECKTABLE


CheckTextAllocsFast Method

SQLServer.Database Object

Description

Checks the internal allocation consistency of text and image pages of every table in this database. This check is faster than the CheckTextAllocsFull method because it only checks data in existing text and image columns.

Visual Basic

strOutput = Database.CheckTextAllocsFast

C++

HRESULT pDatabase->CheckTextAllocsFast ( SQLOLE_LPBSTR pstrOutput );

Elements

Element | Type | Description

strOutput | String | The output returned by the internal consistency check

Reference

DBCC TEXTALL (..., FAST), DBCC TEXTALLOC (..., FAST)


CheckTextAllocsFull Method

SQLServer.Database Object

Description

Checks the internal allocation consistency of text and image pages of every table in this database. This check is slower and more thorough than CheckTextAllocsFast method because it checks the entire database for text and image data.

Visual Basic

strOutput = Database.CheckTextAllocsFull

C++

HRESULT pDatabase->CheckTextAllocsFull ( SQLOLE_LPBSTR pstrOutput );

Elements

Element | Type | Description

strOutput | String | The output returned by the internal consistency check

Reference

DBCC TEXTALL (..., FULL), DBCC TEXTALLOC (..., FULL)


Dump Method

SQLServer.Database Object

Description

Backs up a database to a dump device. Set the properties of a created Backup object as desired and pass it to the Dump method.

Visual Basic

Database.Dump ( [DumpSpec :=] Backup )

C++

HRESULT pDatabase->Dump ( LPSQLOLEBACKUP pBackup );

Elements

Element | Type | Description

Backup | Backup | Created Backup object that specifies how to execute database backup

Reference

DUMP DATABASE


ExecuteImmediate Method

SQLServer.Database Object

Description

Executes a Transact-SQL statement on a database. No results are returned to the application.

Visual Basic

Database.ExecuteImmediate (
[Command :=] strSQLStatement,
[[ExecType :=] tExecOption] )

C++

HRESULT pDatabase->ExecuteImmediate (
SQLOLE_LPCSTR strSQLStatement,
SQLOLE_EXEC_TYPE tExecOption = SQLOLEExec_Default );

Elements

Element | Type | Description

strSQLStatement | String | SQL statement
tExecOption | SQLOLE_EXEC_TYPE | Options for executing this SQL statement

Reference

EXECUTE


ExecuteWithResults Method

SQLServer.Database Object

Description

Executes a Transact-SQL statement on a database. Returns results in a QueryResults object.

Visual Basic

QueryResults = Database.ExecuteWithResults ( [Command :=] strSQLStatement )

C++

HRESULT pDatabase->ExecuteWithResults (
SQLOLE_LPCSTR strSQLStatement,
LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
strSQLStatement | String | SQL statement

QueryResults

The contents of the QueryResults object depend on the Transact-SQL statement.

Reference

EXECUTE


ExtendOnDevices Method

SQLServer.Database Object

Description

Increases the amount of storage space allocated to a database. The existing database storage space is extended to include available space on database devices.

Visual Basic

Database.ExtendOnDevices ( [DeviceNames :=] strDevices )

C++

HRESULT pDatabase->ExtendOnDevices ( SQLOLE_LPCSTR strDevices );

Elements

Element | Type | Description

strDevices | String | Comma delimited list of one or more database device usage specifiers. Each usage specifier consists of the database device name, an equal sign, and a size in megabytes.

Reference

ALTER DATABASE


GenerateBackupSQL Method

SQLServer.Database Object

Description

Generates a series of Transact-SQL statements (script) that can be used to backup this database. Set the properties of a created Backup object as desired and pass it to the GenerateBackupSQL method.

Visual Basic

strScript = Database.GenerateBackupSQL ( [DumpSpec :=] Backup )

C++

HRESULT pDatabase->GenerateBackupSQL (
LPSQLOLEBACKUP pBackup,
SQLOLE_LPBSTR pstrScript );

Elements

Element | Type | Description

strScript | String | Generated Transact-SQL backup script
Backup | Backup | Created Backup object that specifies how to execute the database backup

Remarks

To schedule this backup script, set the Task.Command property to the string returned by this method.


GetDatatypeByName Method

SQLServer.Database Object

Description

Returns a DBObject object that contains the specified system datatype or user-defined datatype object.

Visual Basic

DBObject = Database.GetDatatypeByName ( [TypeName :=] idDatatype )

C++

HRESULT pDatabase->GetDatatypeByName (
SQLOLE_LPCSTR idDatatype,
LPSQLOLESTDOBJECT* ppDBObject );

Elements

Element | Type | Description

DBObject | DBObject | Returned DBObject object
idDatatype | Identifier | Name of a system datatype or a user-defined datatype


GetMemoryUsage Method

SQLServer.Database Object

Description

Returns detailed reports on SQL Server memory usage.

Visual Basic

strOutput = Database.GetMemoryUsage

C++

HRESULT pDatabase->GetMemoryUsage ( SQLOLE_LPBSTR pstrOutput );

Elements

Element | Type | Description

strOutput | String | The output returned by the internal consistency check

Reference

DBCC MEMUSAGE


GetObjectByName Method

SQLServer.Database Object

Description

Returns a DBObject object that contains the specified SQL Server object.

Visual Basic

DBObject = Database.GetObjectByName (
[ObjectName :=] idSQLObject,
[[ObjectType :=] tObjectType] )

C++

HRESULT pDatabase->GetObjectByName (
SQLOLE_LPCSTR idSQLObject,
LPSQLOLEDBOBJECT* ppDBObject,
SQLOLE_OBJECT_TYPE tObjectType =
SQLOLEObj_AllDatabaseObjects );

Elements

Element | Type | Description

DBObject | DBObject | Returned DBObject object
idSQLObject | Identifier | Name of SQL Server object to return
tObjectType | SQLOLE_OBJECT_TYPE | Type of object. If you do not know the object type, SQL-DMO must query the server to determine it. If you pass it in, this overhead is not required.


Grant Method

SQLServer.Database Object

Description

Gives statement permissions to a list of SQL Server users and groups.

Visual Basic

Database.Grant (
[Privileges :=] tPrivileges,
[GranteeNames :=] midUserGroupList )

C++

HRESULT pDatabase->Grant (
SQLOLE_PRIVILEGE_TYPE tPrivileges,
SQLOLE_LPCSTR midUserGroupList );

Elements

Element | Type | Description

tPrivileges | SQLOLE_PRIVILEGE_TYPE | Types of statement privileges to grant
midUserGroupList | MultiIdentifier | Delimited list of one or more users and groups

Reference

GRANT


IsValidKeyDatatype Method

SQLServer.Database Object

Description

Indicates if the proposed key datatype is valid for use as a key column, and if it is compatible with the proposed reference datatype.

Visual Basic

bValid = Database.IsValidKeyDatatype (
[KeyColType :=] idKeyDatatype,
[[ReferencingColType :=] idReferenceDatatype] )

C++

HRESULT pDatabase->IsValidKeyDatatype (
SQLOLE_LPCSTR idKeyDatatype,
LPBOOL pbValid,
SQLOLE_LPCSTR idReferenceDatatype = NULL );

Elements

Element | Type | Description

bValid | Boolean | Returned value indicates if the key datatype is valid and compatible with the reference datatype. If True, the key datatype is valid and compatible with the reference datatype. If False, the key datatype is either not valid or not compatible with the reference datatype.
idKeyDatatype | Identifier | Name of the key datatype
idReferenceDatatype | Identifier | Name of the reference datatype


Load Method

SQLServer.Database Object

Description

Restores a database using an existing backup from a dump device. Set the properties of a created Backup object as desired and pass it to the Load method.

Visual Basic

Database.Load ( [LoadSpec :=] Backup )

C++

HRESULT pDatabase->Load ( LPSQLOLEBACKUP pBackup );

Elements

Element | Type | Description

Backup | Backup | Created Backup object that specifies how to execute database backup

Reference

LOAD DATABASE


ManualSyncCompleted Method

SQLServer.Database Object

Description

Marks a manual synchronization as having been completed by the user.

Visual Basic

Database.ManualSyncCompleted (
[PubServerName :=] idServer,
[PubDatabaseName :=] idDatabase,
[PublicationName :=] idPublication,
[[ArticleName :=] idArticle] )

C++

HRESULT pDatabase->ManualSyncCompleted (
SQLOLE_LPCSTR idServer,
SQLOLE_LPCSTR idDatabase,
SQLOLE_LPCSTR idPublication,
SQLOLE_LPCSTR idArticle = NULL );

Elements

Element | Type | Description

idServer | Identifier | Publishing server
idDatabase | Identifier | Database
idPublication | Identifier | Publication
idArticle | Identifier | Article

Reference

repl_syncdone


ManualSyncPending Method

SQLServer.Database Object

Description

Indicates if manual synchronization has been specified but not yet completed. Call ManualSyncCompleted when you have completed the manual synchronization.

Visual Basic

bSyncPending = Database.ManualSyncPending (
[PubServerName :=] idServer,
[PubDatabaseName :=] idDatabase,
[PublicationName :=] idPublication,
[ArticleName :=] idArticle )

C++

HRESULT pDatabase->ManualSyncPending (
SQLOLE_LPCSTR idServer,
SQLOLE_LPCSTR idDatabase,
SQLOLE_LPCSTR idPublication,
SQLOLE_LPCSTR idArticle,
LPBOOL pbSyncPending );

Elements

Element | Type | Description

bSyncPending | Boolean | Indicates if manual synchronization is pending. If True, manual synchronization has not been completed. If False, the user has indicated that manual synchronization has been completed by the user.
idServer | Identifier | Publishing server
idDatabase | Identifier | Database
idPublication | Identifier | Publication
idArticle | Identifier | Article

Remarks

This is an indexed property.


RecalcSpaceUsage Method

SQLServer.Database Object

Description

Recalculates the latest space usage information for the database.

Visual Basic

Database.RecalcSpaceUsage

C++

HRESULT pDatabase->RecalcSpaceUsage ( );


Remove Method

SQLServer.Database Object

Description

Drops the SQL Server database and removes the Database object.

Visual Basic

Database.Remove

C++

HRESULT pDatabase->Remove ( );

Reference

DROP DATABASE


Revoke Method

SQLServer.Database Object

Description

Removes statement permissions from a list of SQL Server users and groups.

Visual Basic

Database.Revoke (
[Privileges :=] tPrivileges,
[RevokeeNames :=] midUserGroupList )

C++

HRESULT pDatabase->Revoke (
SQLOLE_PRIVILEGE_TYPE tPrivileges,
SQLOLE_LPCSTR midUserGroupList );

Elements

Element | Type | Description

tPrivileges | SQLOLE_PRIVILEGE_TYPE | Types of statement privileges to revoke
midUserGroupList | MultiIdentifier | Delimited list of one or more users and groups

Reference

REVOKE


SetOwner Method

SQLServer.Database Object

Description

Changes the owner of a database (DBO) to a new login.

Visual Basic

Database.SetOwner (
[LoginName :=] idLogin,
[[TransferAliases :=] bTransfer,]
[[OverrideIfAlreadyUser :=] bOverride] )

C++

HRESULT pDatabase->SetOwner (
SQLOLE_LPCSTR idLogin,
BOOL bTransfer = FALSE,
BOOL bOverride = FALSE );

Elements

Element | Type | Description

idLogin | Identifier | Login of the new database owner
bTransfer | Boolean | Determines if existing aliases and permissions are transferred to the new database owner. The default is False.
bOverride | Boolean | Determines if the database ownership should still be changed if the new login is already a user in this database. If True, the specified login will become the new database owner. If False, the specified login will become the new database owner only if that login is not a user in this database. The default is False.

Remarks

This is an indexed property.

Reference

sp_changedbowner


Shrink Method

SQLServer.Database Object

Description

Reduces the space allocated to a database

Visual Basic

Database.Shrink ( [NewSizeInMB :=] lNewSizeInMB )

C++

HRESULT pDatabase->Shrink ( long lNewSizeInMB );

Elements

Element | Type | Description

lNewSizeInMB | Long | New size of the database in megabytes

Reference

DBCC SHRINKDB


SpaceAllocatedOnDevice Method

SQLServer.Database Object

Description

Returns the total amount of storage space this database has allocated on the specified device.

Visual Basic

lAllocated = Database.SpaceAllocatedOnDevice ( [DeviceName :=] idDevice )

C++

HRESULT pDatabase->GetSpaceAllocatedOnDevice (
SQLOLE_LPCSTR idDevice,
LPLONG plAllocated );

Elements

Element | Type | Description

lAllocated | Long | Total allocated storage space in megabytes
idDevice | Identifier | Device name

Remarks

This is an indexed property.


Database Lists

Database Object Properties Methods Lists Collections

EnumCandidateKeys

EnumDependencies

EnumLocks

ListDatabasePermissions

ListDevices

ListObjectPermissions

ListObjects


EnumCandidateKeys List

SQLServer.Database Object

Description

Lists all available primary keys in the database. List is returned in a QueryResults object.

Visual Basic

QueryResults = Database.EnumCandidateKeys

C++

HRESULT pDatabase->EnumCandidateKeys ( LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object

QueryResults

ColumnName | ColumnType

candidate_table | SQLOLE_DTypeChar
candidate_key | SQLOLE_DTypeChar


EnumDependencies List

SQLServer.Database Object

Description

Lists all user-created objects in the database in dependency order. These objects must be created in this order. List is returned in a QueryResults object.

Visual Basic

QueryResults = Database.EnumDependencies ( [[DependencyType :=] tDependency] )

C++

HRESULT pDatabase->EnumDependencies (
LPSQLOLEQUERYRESULTS* ppQueryResults, SQLOLE_DEPENDENCY_TYPE tDependency = SQLOLEDep_Parents );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
tDependency | SQLOLE_DEPENDENCY_TYPE | Dependency type

QueryResults

This method can return up to three results sets.

ColumnName | ColumnType

oType | SQLOLE_DTypeInt4
oRuleDefName | SQLOLE_DTypeChar
oOwner | SQLOLE_DTypeChar
oSequence | SQLOLE_DTypeInt2

ColumnName | ColumnType

oType | SQLOLE_DTypeInt4
oUDDTName | SQLOLE_DTypeChar
oOwner | SQLOLE_DTypeChar
oSequence | SQLOLE_DTypeInt2

ColumnName | ColumnType

oType | SQLOLE_DTypeInt4
oObjName | SQLOLE_DTypeChar
oOwner | SQLOLE_DTypeChar
oSequence | SQLOLE_DTypeInt2


EnumLocks List

SQLServer.Database Object

Description

Lists the locks held by a SQL Server process. List is returned in a QueryResults object.

Visual Basic

QueryResults = Database.EnumLocks ( [[Who :=] lProcess] )

C++

HRESULT pDatabase->EnumLocks (
LPSQLOLEQUERYRESULTS* ppQueryResults,
long lProcess = -1 );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
lProcess | Long | SQL Server process

QueryResults

ColumnName | ColumnType

spid | SQLOLE_DTypeInt2
locktype | SQLOLE_DTypeChar
tablename | SQLOLE_DTypeChar
page | SQLOLE_DTypeInt4
dbname | SQLOLE_DTypeChar


ListDatabasePermissions List

SQLServer.Database Object

Description

Returns a list of Permission objects containing the statement privileges for this database.

Visual Basic

PermissionList = Database.ListDatabasePermissions ( [[PrivilegeTypes :=] tPrivileges] )

C++

HRESULT pDatabase->ListDatabasePermissions (
LPSQLOLEPERMISSIONLIST* ppPermissionList,
SQLOLE_PRIVILEGE_TYPE tPrivileges =
SQLOLEPriv_AllDatabasePrivs );

Elements

Element | Type | Description

PermissionList | PermissionList | Returned list of Permission objects
tPrivileges | SQLOLE_PRIVILEGE_TYPE | Types of statement privileges to list


ListDevices List

SQLServer.Database Object

Description

Returns a list of Device objects used by this database.

Visual Basic

DeviceList = Database.ListDevices

C++

HRESULT pDatabase->ListDevices ( LPSQLOLEDEVICELIST* ppDeviceList );

Elements

Element | Type | Description

DeviceList | DeviceList | Returned list of Device objects


ListObjectPermissions List

SQLServer.Database Object

Description

Returns a list of Permission objects containing the object privileges for this database.

Visual Basic

PermissionList = Database.ListObjectPermissions ( [[PrivilegeTypes :=] tPrivileges] )

C++

HRESULT pDatabase->ListObjectPermissions (
LPSQLOLEPERMISSIONLIST* ppPermissionList ,
SQLOLE_PRIVILEGE_TYPE tPrivileges = SQLOLEPriv_AllObjectPrivs );

Elements

Element | Type | Description

PermissionList | PermissionList | Returned list of Permission objects
tPrivileges | SQLOLE_PRIVILEGE_TYPE | Types of object privileges to list


ListObjects List

SQLServer.Database Object

Description

Returns a list of DBObject objects containing the database objects stored in the database.

Visual Basic

DBObjectList = Database.ListObjects (
[[ObjectTypes :=] tObjects,]
[[SortBy :=] tSortBy] )

C++

HRESULT pDatabase->ListObjects (
LPSQLOLEDBOBJECTLIST* ppDBObjectList,
SQLOLE_OBJECT_TYPE tObjects = SQLOLEObj_AllDatabaseObjects,
SQLOLE_OBJSORT_TYPE tSortBy = SQLOLEObjSort_Name );

Elements

Element | Type | Description

DBObjectList | DBObjectList | Returned list of DBObject objects
tObjects | SQLOLE_OBJECT_TYPE | Types of database objects to list
tSortBy | SortType | How the list is sorted


Database Collections

Database Object Properties Methods Lists Collections

Collection | Description

Defaults Defaults Write: No | The collection of Default objects.
Groups Groups Write: No | The collection of Group objects.
Properties Properties Write: No | The collection of Property objects.
Publications Publications Write: No | The collection of Publication objects.
Rules Rules Write: No | The collection of Rule objects.
StoredProcedures StoredProcedures Write: No | The collection of StoredProcedure objects.
SystemDatatypes SystemDatatypes Write: No | The collection of SystemDatatype objects.
Tables Tables Write: No | The collection of Table objects.
UserDefinedDatatypes UserDefinedDatatypes Write: No | The collection of UserDefinedDatatype objects.
Users Users Write: No | The collection of User objects.
Views Views Write: No | The collection of View objects.


DBObject Object

DBObject Object Properties Methods Lists Collections

Description

The DBObject object is a generic object that contains information appropriate for all types of database objects. A DBObject is closely tied to a specific SQL-DMO object, but presents a generic interface that allows the same code to apply to multiple object types.

A DBObject can represent a Table, View, Rule, Default, StoredProcedure, Trigger, or UserDefinedDatatype object.


DBObject Properties

DBObject Object Properties Methods Lists Collections

Property | Description

CreateDate String Write: No | The date and time the object was created.
ID Long Write: No | The object ID.
Name Identifier Write: Yes | The name of the object.
Owner Identifier Write: No | The user that created the object.
Parent Database Write: No | The Database object.
SystemObject Boolean Write: No | Indicates if this is a SQL Server system object. If True, this is a SQL Server system object. If False, this object was created by a user.
Type SQLOLE_OBJECT_TYPE Write: No | The type of object.
TypeName String Write: No | Description of the type of the object.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


DBObject Methods

DBObject Object Properties Methods Lists Collections

Remove

Script


Remove Method

SQLServer.Database.DBObject Object

Description

Drops the underlying SQL Server object and removes the SQL-DMO object from its parent collection.

Visual Basic

DBObject.Remove

C++

HRESULT pDBObject->Remove ( );


Script Method

SQLServer.Database.DBObject Object

Description

Generates a series of Transact-SQL statements (script) to create the underlying object.

Visual Basic

strScript = DBObject.Script (
[[ScriptType :=] tScriptType,]
[[ScriptFilePath :=] strFile] )

C++

HRESULT pDBObject->Script (
SQLOLE_SCRIPT_TYPE tScriptType = SQLOLEScript_Default,
SQLOLE_LPCSTR strFile = NULL,
SQLOLE_LPBSTR pstrScript = NULL );

Elements

Element | Type | Description

strScript | String | Generated Transact-SQL script
tScriptType | SQLOLE_SCRIPT_TYPE | Type of script to generate
strFile | String | Full path and file name to use to store the Transact-SQL script


DBObject Lists

DBObject Object Properties Methods Lists Collections

EnumDependencies

ListPermissions

ListUserPermissions


EnumDependencies List

SQLServer.Database.DBObject Object

Description

Lists the database objects that depend on this DBObject, or database objects that this DBObject depends on, in dependency order. List is returned in a QueryResults object.

Visual Basic

QueryResults = DBObject.EnumDependencies ( [[DependencyType :=] tDependency] )

C++

HRESULT pDBObject->EnumDependencies (
LPSQLOLEQUERYRESULTS* ppQueryResults,
SQLOLE_DEPENDENCY_TYPE tDependency = SQLOLEDep_Parents );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
tDependency | SQLOLE_DEPENDENCY_TYPE | Type of dependencies to return

QueryResults

This method can return up to three results sets.

ColumnName | ColumnType

oType | SQLOLE_DTypeInt4
oRuleDefName | SQLOLE_DTypeChar
oOwner | SQLOLE_DTypeChar
oSequence | SQLOLE_DTypeInt2

ColumnName | ColumnType

oType | SQLOLE_DTypeInt4
oUDDTName | SQLOLE_DTypeChar
oOwner | SQLOLE_DTypeChar
oSequence | SQLOLE_DTypeInt2

ColumnName | ColumnType

oType | SQLOLE_DTypeInt4
oObjName | SQLOLE_DTypeChar
oOwner | SQLOLE_DTypeChar
oSequence | SQLOLE_DTypeInt2


ListPermissions List

SQLServer.Database.DBObject Object

Description

Returns a list of Permission objects containing the object privileges for this object.

Visual Basic

PermissionList = DBObject.ListPermissions ( [[PrivilegeTypes :=] tPrivileges] )

C++

HRESULT pDBObject->ListPermissions (
LPSQLOLEPERMISSIONLIST* ppPermissionList ,
SQLOLE_PRIVILEGE_TYPE tPrivileges = SQLOLEPriv_AllObjectPrivs );

Elements

Element | Type | Description

PermissionList | PermissionList | Returned list of Permission objects
tPrivileges | SQLOLE_PRIVILEGE_TYPE | Types of object privileges to list

Reference

sp_helpprotect


ListUserPermissions List

SQLServer.Database.DBObject Object

Description

Returns a list of Permission objects containing the specified user's privileges for this object.

Visual Basic

PermissionList = DBObject.ListUserPermissions ( [UserName :=] idUser )

C++

HRESULT pDBObject->ListUserPermissions (
SQLOLE_LPCSTR idUser,
LPSQLOLEPERMISSIONLIST* ppPermissionList );

Elements

Element | Type | Description

PermissionList | PermissionList | Returned list of Permission objects
idUser | Identifier | User

Reference

sp_helpprotect


DBObject Collections

DBObject Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


DBOption Object

DBOption Object Properties Methods Collections

Description

A DBOption object contains all the database options for a database. These options can be set by the database owner. The DBOption object is a property of the Database object.


DBOption Properties

DBOption Object Properties Methods Collections

Property | Description

ColumnsNullByDefault Boolean Write: Yes | Determines if columns in newly created tables allow nulls by default. If True, columns will allow null values unless they are explicitly defined as not allowing null values (NOT NULL). If False, columns will not allow null values unless they are explicitly defined as allowing null values.
DBOUseOnly Boolean Write: Yes | Determines if only the database owner can use the database. If True, only the database owner can use the database. If False, every user can use the database.
EnablePublishing Boolean Write: Yes | Determines if articles can be published for replication in this database. If True, articles can be published and replication from this database is enabled. If False, this database cannot publish articles for replication.
EnableSubscribing Boolean Write: Yes | Determines if published articles can be subscribed to by this database. If True, articles can be subscribed to and replication to this database is enabled. If False, this database cannot subscribe to articles for replication.
NoCheckpointOnRecovery Boolean Write: Yes | Determines if an up-to-date copy of a database is kept. If True, an up-to-date copy of the database is kept. If False, a checkpoint record is added to a database after it is recovered due to restarting SQL Server.
Offline Boolean Write: Yes | Determines if the database if offline and unavailable for use. If True, the database is unavailable. If False, the database is online and available for use as normal.
Parent Database Write: No | The Database object.
ReadOnly Boolean Write: Yes | Determines if all changes to the database are disabled. If True, the database is read only and cannot be changed. If False, the data can be changed as normal.
SelectIntoBulkCopy Boolean Write: Yes | Determines if the following unlogged operations are allowed in the database: WRITETEXT, SELECT INTO into a permanent table, and fast bulk copy into a table with no indexes. If True, unlogged operations are allowed and you can use the above statements. If False, unlogged operations are not allowed.
SingleUser Boolean Write: Yes | Determines if only one user at a time can use the database. If True, the database is in single user mode. If False, multiple users can access the database as normal.
TruncateLogOnCheckpoint Boolean Write: Yes | Determines if the transaction log is truncated (committed transactions are removed) every time the automatic CHECKPOINT checking process occurs. If True, the transaction log is truncated automatically on CHECKPOINT. If False, the transaction log is not truncated automatically.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


DBOption Methods

DBOption Object Properties Methods Collections

Refresh


Refresh Method

SQLServer.Database.DBOption Object

Description

Updates DBOption properties with current database options from SQL Server.

Visual Basic

DBOption.Refresh

C++

HRESULT pDBOption->Refresh ( );


DBOption Collections

DBOption Object Properties Methods Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Default Object

Default Object Properties Methods Lists Collections

Description

A Default object is a value which is stored in a column or datatype if no other value is supplied.


Default Object Properties

Default Properties

Default Object Properties Methods Lists Collections

Property | Description

Application Application Write: No | The Application object.
CreateDate String Write: No | The date and time the default was created.
ID Long Write: No | The object ID of the default.
Name Identifier Write: Yes | The name of the default.
Owner Identifier Write: No | The user who created the default.
Parent Database Write: No | The Database object.
Text String Write: Before Add | The Transact-SQL statement used to create the default.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


BindToColumn Method

SQLServer.Database.Default Object

Description

Binds a default to a column of an existing table.

Visual Basic

Default.BindToColumn (
[TableName :=] idTable,
[ColumnName :=] idColumn )

C++

HRESULT pDefault->BindToColumn (
SQLOLE_LPCSTR idTable,
SQLOLE_LPCSTR idColumn );

Elements

Element | Type | Description

idTable | Identifier | Table
idColumn | Identifier | Column

Reference

sp_bindefault


BindToDatatype Method

SQLServer.Database.Default Object

Description

Binds a default with an existing user-defined datatype.

Visual Basic

Default.BindToDatatype (
[DatatypeName :=] idDatatype,
[[FutureOnly :=] bFutureOnly] )

C++

HRESULT pDefault->BindToDatatype (
SQLOLE_LPCSTR idDatatype,
BOOL bFutureOnly = FALSE );

Elements

Element | Type | Description

idDatatype | Identifier | User-defined datatype
bFutureOnly | Boolean | Determines if existing columns of the specified datatype are prevented from inheriting the new default. If True, existing columns are not bound to the new default. If False, existing columns are bound to the new default. The default is False.

Reference

sp_bindefault


Remove Method

SQLServer.Database.Default Object

Description

Drops the SQL Server default and removes the Default object.

Visual Basic

Default.Remove ( )

C++

HRESULT pDefault->Remove ( );

Reference

DROP DEFAULT


Script Method

SQLServer.Database.Default Object

Description

Generates a series of Transact-SQL statements (script) to create the default.

Visual Basic

strScript = Default.Script (
[[ScriptType :=] tScriptType,]
[[ScriptFilePath :=] strFile] )

C++

HRESULT pDefault->Script (
SQLOLE_SCRIPT_TYPE tScriptType = SQLOLEScript_Default,
SQLOLE_LPCSTR strFile = NULL,
SQLOLE_LPBSTR pstrScript = NULL );

Elements

Element | Type | Description

strScript | String | Generated Transact-SQL script
tScriptType | SQLOLE_SCRIPT_TYPE | Type of script to generate
strFile | String | Full path and file name to use to store the Transact-SQL script


UnbindFromColumn Method

SQLServer.Database.Default Object

Description

Breaks an existing binding between a default and a column of a table.

Visual Basic

Default.UnbindFromColumn (
[TableName :=] idTable,
[ColumnName :=] idColumn )

C++

HRESULT pDefault->UnbindFromColumn (
SQLOLE_LPCSTR idTable,
SQLOLE_LPCSTR idColumn );

Elements

Element | Type | Description

idTable | Identifier | Table
idColumn | Identifier | Column

Reference

sp_unbindefault


UnbindFromDatatype Method

SQLServer.Database.Default Object

Description

Breaks an existing binding between a default and a user-defined datatype.

Visual Basic

Default.UnbindFromDatatype (
[DatatypeName :=] idDatatype,
[[FutureOnly :=] bFutureOnly] )

C++

HRESULT pDefault->UnbindFromDatatype (
SQLOLE_LPCSTR idDatatype,
BOOL bFutureOnly = FALSE );

Elements

Element | Type | Description

idDatatype | Identifer | User-defined datatype
bFutureOnly | Boolean | Determines if existing columns of the specified datatype are prevented from losing the old default. If True, existing columns keep the old default. If False, existing columns lose the old default. The default is False.

Reference

sp_unbindefault


Default Lists

Default Object Properties Methods Lists Collections

ListBoundColumns

ListBoundDatatypes


ListBoundColumns List

SQLServer.Database.Default Object

Description

Returns a list of Column objects that are currently bound to this Default.

Visual Basic

ColumnList = Default.ListBoundColumns

C++

HRESULT pDefault->ListBoundColumns ( LPSQLOLECOLUMNLIST* ppColumnList );

Elements

Element | Type | Description

ColumnList | ColumnList | Returned list of Column objects

Reference

sp_helpconstraint


ListBoundDatatypes List

SQLServer.Database.Default Object

Description

Returns a list of UserDefinedDatatype objects that are currently bound to this Default.

Visual Basic

UserDefinedDatatypeList = Default.ListBoundDatatypes

C++

HRESULT pDefault->ListBoundDatatypes ( LPSQLOLEUSERDEFINEDDATATYPELIST*
ppUserDefinedDatatypeList );

Elements

Element | Type | Description

UserDefinedDatatypeList | UserDefinedDatatypeList | Returned list of UserDefinedDatatype objects


Default Collections

Default Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Group Object

Group Object Properties Methods Lists Collections

Description

A Group object contains information about a collection of users.


Group Properties

Group Object Properties Methods Lists Collections

Property | Description

Application Application Write: No | The Application object.
ID Long Write: No | The group ID.
Name Identifier Write: Before Add | The name of the group.
Parent Database Write: No | The Database object.
SystemObject Boolean Write: No | Indicates if this is a SQL Server system group. If True, this is the public group. If False, this is not the public group.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Group Methods

Group Object Properties Methods Lists Collections

Remove

Script


Remove Method

SQLServer.Database.Group Object

Description

Drops the SQL Server group and removes the Group object.

Visual Basic

Group.Remove

C++

HRESULT pGroup->Remove ( );

Remarks

You cannot remove the public group.

Reference

sp_dropgroup


Script Method

SQLServer.Database.Group Object

Description

Generates a series of Transact-SQL statements (script) to create the group.

Visual Basic

strScript = Group.Script (
[[ScriptType :=] tScriptType,]
[[ScriptFilePath :=] strFile] )

C++

HRESULT pGroup->Script (
SQLOLE_SCRIPT_TYPE tScriptType = SQLOLEScript_Default,
SQLOLE_LPCSTR strFile = NULL,
SQLOLE_LPBSTR pstrScript = NULL );

Elements

Element | Type | Description

strScript | String | Generated Transact-SQL script
tScriptType | SQLOLE_SCRIPT_TYPE | Type of script to generate
strFile | String | Full path and file name to use to store the Transact-SQL script


Group Lists

Group Object Properties Methods Lists Collections

ListDatabasePermissions

ListObjectPermissions

ListUsers


ListDatabasePermissions List

SQLServer.Database.Group Object

Description

Returns a list of Permission objects containing the statement privileges for this group.

Visual Basic

PermissionList = Group.ListDatabasePermissions ( [[PrivilegeTypes :=] tPrivileges] )

C++

HRESULT pGroup->ListDatabasePermissions (
LPSQLOLEPERMISSIONLIST* ppPermissionList ,
SQLOLE_PRIVILEGE_TYPE tPrivileges =
SQLOLEPriv_AllDatabasePrivs );

Elements

Element | Type | Description

PermissionList | PermissionList | Returned list of Permission objects
tPrivileges | SQLOLE_PRIVILEGE_TYPE | Types of statement privileges to list


ListObjectPermissions List

SQLServer.Database.Group Object

Description

Returns a list of Permission objects containing the object privileges for this group.

Visual Basic

PermissionList = Group.ListObjectPermissions ( [[PrivilegeTypes :=] tPrivileges] )

C++

HRESULT pGroup->ListObjectPermissions (
LPSQLOLEPERMISSIONLIST* ppPermissionList,
SQLOLE_PRIVILEGE_TYPE tPrivileges = SQLOLEPriv_AllObjectPrivs );

Elements

Element | Type | Description

PermissionList | PermissionList | Returned list of Permission objects
tPrivileges | SQLOLE_PRIVILEGE_TYPE | Types of object privileges to list


ListUsers List

SQLServer.Database.Group Object

Description

Returns a list of User objects that are members of this group.

Visual Basic

UserList = Group.ListUsers

C++

HRESULT pGroup->ListUsers ( LPSQLOLEUSERLIST* ppUserList );

Elements

Element | Type | Description

UserList | UserList | Returned list of User objects


Group Collections

Group Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Publication Object

Publication Object Properties Methods Lists Collections

Description

A Publication object contains information about a publication (containing articles) used for replication.


Publication Properties

Publication Object Properties Methods Lists Collections

Property | Description

Application Application Write: No | The Application object.
Description String Write: Yes | A description for the publication.
Enabled Boolean Write: Yes | Determines if the publication can be replicated. If True, the publication is enabled for replication. If False, the publication is not enabled for replication and cannot be replicated.
ID Long Write: No | The publication ID.
InitialSyncMethod SQLOLE_INITIALSYNC_TYPE Write: Yes | The initial synchronization method provided by the publication server for this publication and used to synchronize the subscription server prior to beginning scheduled replication.
InitialSyncTask Task Write: No | The Task object used for initial synchronization.
Name Identifier Write: Yes | The name of the publication.
Parent Database Write: No | The Database object.
ReplicationFrequency SQLOLE_REPFREQ_TYPE Write: Yes | The replication frequency of the publication.
Restricted Boolean Write: Yes | Determines whether the publication is restricted to authorized subscription servers. If True, only authorized subscription servers can subscribe to this publication. If False, any server can subscribe to this publication.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Publication Methods

Publication Object Properties Methods Lists Collections

BeginAlter

CancelAlter

DoAlter

Remove


BeginAlter Method

SQLServer.Database.Publication Object

Description

Marks the start of a single unit of changes to Publication properties. Normally, each change to a single property is a separate update to SQL Server. To group multiple property changes into a single unit, first call the BeginAlter method, then make the desired property changes. To commit the unit of property changes to SQL Server using a single update, call the DoAlter method. To cancel the unit of property changes (made since calling BeginAlter), call the CancelAlter method.

Visual Basic

Publication.BeginAlter

C++

HRESULT pPublication->BeginAlter ( );


CancelAlter Method

SQLServer.Database.Publication Object

Description

Stops a unit of Publication property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will not be committed to SQL Server.

Visual Basic

Publication.CancelAlter

C++

HRESULT pPublication->CancelAlter ( );


DoAlter Method

SQLServer.Database.Publication Object

Description

Commits a unit of Publication property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will be committed to SQL Server using a single update.

Visual Basic

Publication.DoAlter

C++

HRESULT pPublication->DoAlter ( );


Remove Method

SQLServer.Database.Publication Object

Description

Drops the SQL Server publication and removes the Publication object.

Visual Basic

Publication.Remove

C++

HRESULT pPublication->Remove ( );

Reference

sp_droppublication


Publication Lists

Publication Object Properties Methods Lists Collections

EnumFullSubscribers


EnumFullSubscribers List

SQLServer.Database.Publication Object

Description

Lists the servers that subscribe to all articles in this publication. List is returned in a QueryResults object.

Visual Basic

QueryResults = Publication.EnumFullSubscribers

C++

HRESULT pPublication->EnumFullSubscribers ( LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object

QueryResults

ColumnName | ColumnType

subscriber | SQLOLE_DTypeChar


Publication Collections

Publication Object Properties Methods Lists Collections

Property | Description

Articles Articles Write: | The collection of Article objects.
Properties Properties Write: No | The collection of Property objects.


Rule Object

Rule Object Properties Methods Lists Collections

Description

A Rule object contains information that defines a domain of valid values that can be stored in a column or datatype.


Rule Object Properties

Rule Properties

Rule Object Properties Methods Lists Collections

Property | Description

Application Application Write: No | The Application object.
CreateDate String Write: No | The date and time this rule was created.
ID Long Write: No | The object ID of the rule.
Name Identifier Write: Yes | The name of the rule.
Owner Identifier Write: No | The user ID of the user who created the rule.
Parent Database Write: No | The Database object.
Text String Write: Before Add | The Transact-SQL statement used to create the rule.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


BindToColumn Method

SQLServer.Database.Rule Object

Description

Binds a rule to a column of an existing table.

Visual Basic

Rule.BindToColumn (
[TableName :=] idTable,
[ColumnName :=] idColumn )

C++

HRESULT pRule->BindToColumn (
SQLOLE_LPCSTR idTable,
SQLOLE_LPCSTR idColumn );

Elements

Element | Type | Description

idTable | Identifier | Table
idColumn | Identifier | Column

Reference

sp_bindrule


BindToDatatype Method

SQLServer.Database.Rule Object

Description

Binds a rule with an existing user-defined datatype.

Visual Basic

Rule.BindToDatatype (
[DatatypeName :=] idDatatype,
[[FutureOnly :=] bFutureOnly] )

C++

HRESULT pRule->BindToDatatype (
SQLOLE_LPCSTR idDatatype,
BOOL bFutureOnly = FALSE );

Elements

Element | Type | Description

idDatatype | Identifer | User-defined datatype
bFutureOnly | Boolean | Determines if existing columns of the specified datatype are prevented from inheriting the new rule. If True, existing columns are not bound to the new rule. If False, existing columns are bound to the new rule. The default is False.

Reference

sp_bindrule


Remove Method

SQLServer.Database.Rule Object

Description

Drops the SQL Server rule and removes the Rule object.

Visual Basic

Rule.Remove ( );

C++

HRESULT pRule->Remove ( );

Reference

DROP RULE


Script Method

SQLServer.Database.Rule Object

Description

Generates a series of Transact-SQL statements (script) to create the default.

Visual Basic

strScript = Rule.Script (
[[ScriptType :=] tScriptType,]
[[ScriptFilePath :=] strFile] )

C++

HRESULT pRule->Script (
SQLOLE_SCRIPT_TYPE tScriptType = SQLOLEScript_Default,
SQLOLE_LPCSTR strFile = NULL,
SQLOLE_LPBSTR pstrScript = NULL );

Elements

Element | Type | Description

strScript | String | Generated Transact-SQL script
tScriptType | SQLOLE_SCRIPT_TYPE | Type of script to generate
strFile | String | Full path and file name to use to store the Transact-SQL script


UnbindFromColumn Method

SQLServer.Database.Rule Object

Description

Breaks an existing binding between a rule and a column of a table.

Visual Basic

Rule.UnbindFromColumn (
[TableName :=] idTable,
[ColumnName :=] idColumn )

C++

HRESULT pRule->UnbindFromColumn (
SQLOLE_LPCSTR idTable,
SQLOLE_LPCSTR idColumn );

Elements

Element | Type | Description

idTable | Identifier | Table
idColumn | Identifier | Column

Reference

sp_unbindrule


UnbindFromDatatype Method

SQLServer.Database.Rule Object

Description

Breaks an existing binding between a rule and a user-defined datatype.

Visual Basic

Rule.UnbindFromDatatype (
[DatatypeName :=] idDatatype,
[[FutureOnly :=] bFutureOnly] )

C++

HRESULT pRule->UnbindFromDatatype (
SQLOLE_LPCSTR idDatatype,
BOOL bFutureOnly = FALSE );

Elements

Element | Type | Description

idDatatype | Identifer | User-defined datatype
bFutureOnly | Boolean | Determines if existing columns of the specified datatype are prevented from losing the old rule. If True, existing columns keep the old rule. If False, existing columns lose the old rule. The default is False.

Reference

sp_unbindrule


Rule Lists

Rule Object Properties Methods Lists Collections

ListBoundColumns

ListBoundDatatypes


ListBoundColumns List

SQLServer.Database.Rule Object

Description

Returns a list of Column objects that are currently bound to this Rule.

Visual Basic

ColumnList = Rule.ListBoundColumns

C++

HRESULT pRule->ListBoundColumns ( LPSQLOLECOLUMNLIST* ppColumnList );

Elements

Element | Type | Description

ColumnList | ColumnList | Returned list of Column objects

Reference

sp_helpconstraint


ListBoundDatatypes List

SQLServer.Database.Rule Object

Description

Returns a list of UserDefinedDatatype objects that are currently bound to this Rule.

Visual Basic

UserDefinedDatatypeList = Rule.ListBoundDatatypes

C++

HRESULT pRule->ListBoundDatatypes ( LPSQLOLEUSERDEFINEDDATATYPELIST*
ppUserDefinedDatatypeList );

Elements

Element | Type | Description

UserDefinedDatatypeList | UserDefinedDatatypeList | Returned list of UserDefinedDatatype objects


Rule Collections

Rule Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


StoredProcedure Object

StoredProcedure Object Properties Methods Lists Collections

Description

A StoredProcedure object is a named set of Transact-SQL statements that are stored within a database. A standard stored procedure is a Transact-SQL procedure stored within the database. An extended stored procedure is an external DLL function.


StoredProcedure Object Properties

StoredProcedure Properties

StoredProcedure Object Properties Method Lists Collections

Property | Description

Application Application Write: No | The Application object.
CreateDate String Write: No | The date and time the stored procedure was created.
ID Long Write: No | The object ID of the stored procedure.
Name Identifier Write: Yes | The name of the stored procedure.
Owner Identifier Write: No | The user who created the stored procedure.
Parent Database Write: No | The Database object.
Startup Boolean Write: Before Add | Determines if this stored procedure is executed automatically when SQL Server starts. If True, this stored procedure is executed automatically when SQL Server starts. If False, it is not executed automatically.
SystemObject Boolean Write: No | Indicates if this is a SQL Server system stored procedure. If True, this is a SQL Server system stored procedure. If False, this stored procedure was created by a user.
Text String Write: Before Add | The original Transact-SQL statement used to create the standard stored procedure, or the full path and file name of the extended stored procedure DLL.
Type SQLOLE_PROCEDURE_TYPE Write: No | The type of stored procedure.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Grant Method

SQLServer.Database.StoredProcedure Object

Description

Gives stored procedure privileges to a list of SQL Server users and groups.

Visual Basic

StoredProcedure.Grant (
[Privileges :=] tPrivileges,
[GranteeNames :=] midUserGroupList )

C++

HRESULT pStoredProcedure->Grant (
SQLOLE_PRIVILEGE_TYPE tPrivileges,
SQLOLE_LPCSTR midUserGroupList );

Elements

Element | Type | Description

tPrivileges | SQLOLE_PRIVILEGE_TYPE | Types of stored procedure privileges to grant
midUserGroupList | MultiIdentifier | Delimited list of one or more users and groups

Reference

GRANT


Remove Method

SQLServer.Database.StoredProcedure Object

Description

Drops the SQL Server stored procedure and removes the StoredProcedure object.

Visual Basic

StoredProcedure.Remove

C++

HRESULT pStoredProcedure->Remove ( );

Reference

DROP PROCEDURE


Revoke Method

SQLServer.Database.StoredProcedure Object

Description

Removes stored procedure privileges from a list of SQL Server users and groups.

Visual Basic

StoredProcedure.Revoke (
[Privileges :=] tPrivileges,
[RevokeeNames :=] midUserGroupList )

C++

HRESULT pStoredProcedure->Revoke (
SQLOLE_PRIVILEGE_TYPE tPrivileges,
SQLOLE_LPCSTR midUserGroupList );

Elements

Element | Type | Description

tPrivileges | SQLOLE_PRIVILEGE_TYPE | Types of stored procedure privileges to revoke
midUserGroupList | MultiIdentifier | Delimited list of one or more users and groups

Reference

REVOKE


Script Method

SQLServer.Database.StoredProcedure Object

Description

Generates a series of Transact-SQL statements (script) to create the stored procedure.

Visual Basic

strScript = StoredProcedure.Script (
[[ScriptType :=] tScriptType,]
[[ScriptFilePath :=] strFile] )

C++

HRESULT pStoredProcedure->Script (
SQLOLE_SCRIPT_TYPE tScriptType = SQLOLEScript_Default,
SQLOLE_LPCSTR strFile = NULL,
SQLOLE_LPBSTR pstrScript = NULL );

Elements

Element | Type | Description

strScript | String | Generated Transact-SQL script
tScriptType | SQLOLE_SCRIPT_TYPE | Type of script to generate
strFile | String | Full path and file name to use to store the Transact-SQL script


StoredProcedure Lists

StoredProcedure Object Properties Methods Lists Collections

EnumDependencies

EnumParameters

ListPermissions

ListUserPermissions


EnumDependencies List

SQLServer.Database.StoredProcedure Object

Description

Lists the database objects that depend on this stored procedure, or database objects that this stored procedure depends on, in dependency order. List is returned in a QueryResults object.

Visual Basic

QueryResults = StoredProcedure.EnumDependencies (
[[DependencyType :=] tDependency] )

C++

HRESULT pStoredProcedure->EnumDependencies (
LPSQLOLEDBOBJECTLIST* ppQueryResults,
SQLOLE_DEPENDENCY_TYPE tDependency = SQLOLEDep_Parents );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
tDependency | SQLOLE_DEPENDENCY_TYPE | Type of dependencies to return

QueryResults

This method can return up to three results sets.

ColumnName | ColumnType

oType | SQLOLE_DTypeInt4
oRuleDefName | SQLOLE_DTypeChar
oOwner | SQLOLE_DTypeChar
oSequence | SQLOLE_DTypeInt2

ColumnName | ColumnType

oType | SQLOLE_DTypeInt4
oUDDTName | SQLOLE_DTypeChar
oOwner | SQLOLE_DTypeChar
oSequence | SQLOLE_DTypeInt2

ColumnName | ColumnType

oType | SQLOLE_DTypeInt4
oObjName | SQLOLE_DTypeChar
oOwner | SQLOLE_DTypeChar
oSequence | SQLOLE_DTypeInt2


EnumParameters List

SQLServer.Database.StoredProcedure Object

Description

Lists the parameters of a stored procedure. List is returned in a QueryResults object.

Visual Basic

QueryResults = StoredProcedure.EnumParameters

C++

HRESULT pStoredProcedure->EnumParameters ( LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object

QueryResults

ColumnName | ColumnType

name | SQLOLE_DTypeChar
name | SQLOLE_DTypeChar
length | SQLOLE_DTypeInt1
colid | SQLOLE_DTypeInt1
output | SQLOLE_DTypeInt4


ListPermissions List

SQLServer.Database.StoredProcedure Object

Description

Returns a list of Permission objects containing the privileges for this stored procedure.

Visual Basic

PermissionList = StoredProcedure.ListPermissions ( [[PrivilegeTypes :=] tPrivileges] )

C++

HRESULT pStoredProcedure->ListPermissions (
LPSQLOLEPERMISSIONLIST* ppPermissionList,
SQLOLE_PRIVILEGE_TYPE tPrivileges = SQLOLEPriv_Execute );

Elements

Element | Type | Description

PermissionList | PermissionList | Returned list of Permission objects
tPrivileges | SQLOLE_PRIVILEGE_TYPE | Types of stored procedure privileges to list

Reference

sp_helpprotect


ListUserPermissions List

SQLServer.Database.StoredProcedure Object

Description

Returns a list of Permission objects containing the specified user's privileges for this stored procedure.

Visual Basic

PermissionList = StoredProcedure.ListUserPermissions ( [UserName :=] idUser )

C++

HRESULT pStoredProcedure->ListUserPermissions (
SQLOLE_LPCSTR idUser,
LPSQLOLEPERMISSIONLIST* ppPermissionList );

Elements

Element | Type | Description

PermissionList | PermissionList | Returned list of Permission objects
idUser | Identifier | User

Reference

sp_helpprotect


StoredProcedure Collections

StoredProcedure Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Subscription Object

SQL Server Object Properties Methods Collections

Description

A Subscription object contains article objects that are replicated.


Subscription Properties

Subscription Object Properties Methods Collections

Property | Description

Application Application Write: No | The Application object.
DestinationDatabase Identifier Write: Yes | The name of the destination database.
InitialSyncType SQLOLE_SUBSYNC_TYPE Write: Yes | The type of initial synchronization event used to synchronize the subscription server.
Parent Database Write: No | The Database object.
ServerName Identifier Write: Yes | The name of the subscription server.
Status SQLOLE_SUBSTATUS_TYPE Write: Yes | The status of the subscription.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Subscription Methods

Subscription Object Properties Methods Collections

BeginAlter

CancelAlter

DoAlter

Remove


BeginAlter Method

SQLServer.Database.Publication.Article.Subscription Object

Description

Marks the start of a single unit of changes to Subscription properties. Normally, each change to a single property is a separate update to SQL Server. To group multiple property changes into a single unit, first call the BeginAlter method, then make the desired property changes. To commit the unit of property changes to SQL Server using a single update, call the DoAlter method. To cancel the unit of property changes (made since calling BeginAlter), call the CancelAlter method.

Visual Basic

Subscription.BeginAlter

C++

HRESULT pSubscription->BeginAlter ( );


CancelAlter Method

SQLServer.Database.Publication.Article.Subscription Object

Description

Stops a unit of Subscription property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will not be committed to SQL Server.

Visual Basic

Subscription.CancelAlter

C++

HRESULT pSubscription->CancelAlter ( );


DoAlter Method

SQLServer.Database.Publication.Article.Subscription Object

Description

Commits a unit of Subscription property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will be committed to SQL Server using a single update.

Visual Basic

Subscription.DoAlter

C++

HRESULT pSubscription->DoAlter ( );


Remove Method

SQLServer.Database.Publication.Article.Subscription Object

Description

Drops the SQL Server subscription and the Subscription object.

Visual Basic

Subscription.Remove

C++

HRESULT pSubscription->Remove ( );

Reference

sp_dropsubscriber


Subscription Collections

Subscription Object Properties Methods Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


SystemDatatype Object

SystemDatatype Object Properties Collections

Description

A SystemDatatype object contains information about a system supplied datatype.


SystemDatatype Collections

SystemDatatype Object Properties Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


TransactionLog Object

TransactionLog Object Properties Methods Lists Collections

Description

The TransactionLog object contains all the information about a database's transaction log. Each database has a single transaction log, and the TransactionLog object is a property of the Database object.


TransactionLog Properties

TransactionLog Object Properties Methods Lists Collections

Property | Description

Application Application Write: No | The Application object.
CreateDate String Write: No | The date and time the transaction log was created.
IsLogOnSeparateDevice Boolean Write: No | Indicates if this transaction log is on a separate database device. If True, the transaction log is on a separate device and the Dump method can be used. If False, the transaction log is not on a separate device and the Dump method cannot be used.
LastDump String Write: No | The date and time this transaction log was last backed up.
Parent Database Write: No | The Database object.
Size Long Write: No | The total size in megabytes of the transaction log.
SpaceAvailable Long Write: No | The total space in kilobytes available for future log growth.
SpaceAvailableinMB Float Write: No | The total space in megabytes (accurate to two decimal places) available for future log growth.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


TransactionLog Methods

TransactionLog Object Properties Methods Lists Collections

DedicateLogDevices

Dump

GenerateBackupSQL

Load

SpaceAllocatedOnDevice

Truncate

UndedicateLogDevices


DedicateLogDevices Method

SQLServer.Database.TransactionLog Object

Description

Marks database devices as usable only for transaction log information.

Visual Basic

TransactionLog.DedicateLogDevices ( [DeviceNames :=] mstrDevices )

C++

HRESULT pTransactionLog->DedicateLogDevices ( SQLOLE_LPCSTR mstrDevices );

Elements

Element | Type | Description

mstrDevices | MultiString | Delimited list of one or more database device usage specifiers. Each usage specifier consists of either the database device name alone, or the database device name, an equal sign, and a size in megabytes.

Reference

ALTER DATABASE, sp_logdevice


Dump Method

SQLServer.Database.TransactionLog Object

Description

Backs up a transaction log to a dump device. Set the properties of a created Backup object as desired and pass it to the Dump method.

Visual Basic

TransactionLog.Dump ( [DumpSpec :=] Backup )

C++

HRESULT pTransactionLog->Dump ( LPSQLOLEBACKUP pBackup );

Elements

Element | Type | Description

Backup | Backup | Created Backup object that specifies how to execute transaction log backup

Reference

DUMP TRANSACTION


GenerateBackupSQL Method

SQLServer.Database.TransactionLog Object

Description

Generates a series of Transact-SQL statements that can be used to backup this TransactionLog. Set the properties of a created Backup object as desired and pass it to the GenerateBackupSQL method.

Visual Basic

strScript = TransactionLog.GenerateBackupSQL ( [DumpSpec :=] Backup )

C++

HRESULT pTransactionLog->GenerateBackupSQL (
LPSQLOLEBACKUP pBackup,
SQLOLE_LPBSTR pstrScript );

Elements

Element | Type | Description

strScript | String | Generated Transact-SQL backup script
Backup | Backup | Created Backup object that specifies how to execute the transaction log backup

Remarks

To schedule this backup script, set the Task.Command property to the string returned by this method.


Load Method

SQLServer.Database.TransactionLog Object

Description

Restores a transaction log using an existing backup from a dump device. Set the properties of a created Backup object as desired and pass it to the Load method.

Visual Basic

TransactionLog.Load ( [LoadSpec :=] Backup )

C++

HRESULT pTransactionLog->Load ( LPSQLOLEBACKUP pBackup );

Elements

Element | Type | Description

Backup | Backup | Created Backup object that specifies how to execute transaction log backup

Reference

LOAD TRANSACTION


SpaceAllocatedOnDevice Method

SQLServer.Database.TransactionLog Object

Description

Returns the total amount of storage space this transaction log has allocated on the specified device.

Visual Basic

lAllocated = TransactionLog.SpaceAllocatedOnDevice ( [DeviceName :=] idDevice )

C++

HRESULT pTransactionLog->GetSpaceAllocatedOnDevice (
SQLOLE_LPCSTR idDevice,
LPLONG plAllocated );

Elements

Element | Type | Description

lAllocated | Long | Total allocated storage space in megabytes
idDevice | Identifier | Device name

Remarks

This is an indexed property.


Truncate Method

SQLServer.Database.TransactionLog Object

Description

Removes the committed transactions from the transaction log without making a backup.

Visual Basic

TransactionLog.Truncate

C++

HRESULT pTransactionLog->Truncate ( );

Reference

DUMP TRANSACTION ... WITH TRUNCATE_ONLY


UndedicateLogDevices Method

SQLServer.Database.TransactionLog Object

Description

Marks database devices as usable for both data and transaction log information. This method can only be used on the TransactionLog of a newly created Database object before the Database is added to the SQLServer.Databases collection.

Visual Basic

TransactionLog.UndedicateLogDevices ( [DeviceNames :=] mstrDevices )

C++

HRESULT pTransactionLog->UndedicateLogDevices ( SQLOLE_LPCSTR mstrDevices );

Elements

Element | Type | Description

mstrDevices | MultiString | Delimited list of one or more database device usage specifiers. Each usage specifier consists of either the database device name alone, or the database device name, an equal sign, and a size in megabytes.


TransactionLog Lists

TransactionLog Object Properties Methods Lists Collections

ListDevices


ListDevices List

SQLServer.Database.TransactionLog Object

Description

Returns a list of Device objects used by this transaction log.

Visual Basic

DeviceList = TransactionLog.ListDevices

C++

HRESULT pTransactionLog->ListDevices ( LPSQLOLEDEVICELIST* ppDeviceList );

Elements

Element | Type | Description

DeviceList | DeviceList | Returned list of Device objects


TransactionLog Collections

TransactionLog Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


User Object

User Object Properties Methods Lists Collections

Description

A User object contains information about a database user. Each User is associated with a single SQL Server login.


User Properties

User Object Properties Methods Lists Collections

Property | Description

Application Application Write: No | The Application object.
Group Identifier Write: Yes | The group this user is a member of. To set this property to a new group, the group must exist.
ID Long Write: No | The unique user ID of the database user. A user ID of 1 is the database owner.
Login Identifier Write: Before Add | The SQL Server login associated with this database user.
Name Identifier Write: Before Add | The name of the database user.
Parent Database Write: No | The Database object.
SystemObject Boolean Write: No | Indicates if this is a SQL Server system user. If True, this is a SQL Server system user (such as DBO). If False, this user was created by a user.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


User Methods

User Object Properties Methods Lists Collections

AddAlias

Remove

RemoveAlias

Script


AddAlias Method

SQLServer.Database.User Object

Description

Associates a list of existing logins with this database user. Each of the logins must not currently be associated with a database user or have an existing alias.

Visual Basic

User.AddAlias ( [LoginNames :=] midLogins )

C++

HRESULT pUser->AddAlias ( SQLOLE_LPCSTR midLogins );

Elements

Element | Type | Description

midLogins | MultiIdentifier | Delimited list of logins

Reference

sp_addalias


Remove Method

SQLServer.Database.User Object

Description

Drops the SQL Server database user and removes the User object.

Visual Basic

User.Remove

C++

HRESULT pUser->Remove ( );

Reference

sp_dropuser


RemoveAlias Method

SQLServer.Database.User Object

Description

Removes the existing alias association between a list of logins that are aliased to this database user.

Visual Basic

User.RemoveAlias ( [LoginNames :=] midLogins )

C++

HRESULT pUser->RemoveAlias ( SQLOLE_LPCSTR midLogins );

Elements

Element | Type | Description

midLogins | MultiIdentifier | Delimited list of logins

Reference

sp_dropalias


Script Method

SQLServer.Database.User Object

Description

Generates a series of Transact-SQL statements (script) to create the user.

Visual Basic

strScript = User.Script (
[[ScriptType :=] tScriptType,]
[[ScriptFilePath :=] strFile] )

C++

HRESULT pUser->Script (
SQLOLE_SCRIPT_TYPE tScriptType = SQLOLEScript_Default,
SQLOLE_LPCSTR strFile = NULL,
SQLOLE_LPBSTR pstrScript = NULL );

Elements

Element | Type | Description

strScript | String | Generated Transact-SQL script
tScriptType | SQLOLE_SCRIPT_TYPE | Type of script to generate
strFile | String | Full path and file name to use to store the Transact-SQL script


User Lists

User Object Properties Methods Lists Collections

ListAliases

ListDatabasePermissions

ListObjectPermissions

ListOwnedObjects


ListAliases List

SQLServer.Database.User Object

Description

Returns a list of Login objects that are currently aliased to this user.

Visual Basic

LoginList = User.ListAliases

C++

HRESULT pUser->ListAliases ( LPSQLOLELOGINLIST* ppLoginList );

Elements

Element | Type | Description

LoginList | LoginList | Returned list of Login objects


ListDatabasePermissions List

SQLServer.Database.User Object

Description

Returns a list of Permission objects containing the statement privileges for this user.

Visual Basic

PermissionList = User.ListDatabasePermissions ( [[PrivilegeTypes :=] tPrivileges] )

C++

HRESULT pUser->ListDatabasePermissions (
LPSQLOLEPERMISSIONLIST* ppPermissionList ,
SQLOLE_PRIVILEGE_TYPE tPrivileges =
SQLOLEPriv_AllDatabasePrivs );

Elements

Element | Type | Description

PermissionList | PermissionList | Returned list of Permission objects
tPrivileges | SQLOLE_PRIVILEGE_TYPE | Types of statement privileges to list


ListObjectPermissions List

SQLServer.Database.User Object

Description

Returns a list of Permission objects containing the object privileges for this user.

Visual Basic

PermissionList = User.ListObjectPermissions ( [[PrivilegeTypes :=] tPrivileges] )

C++

HRESULT pUser->ListObjectPermissions (
LPSQLOLEPERMISSIONLIST* ppPermissionList ,
SQLOLE_PRIVILEGE_TYPE tPrivileges = SQLOLEPriv_AllObjectPrivs );

Elements

Element | Type | Description

PermissionList | PermissionList | Returned list of Permission objects
tPrivileges | SQLOLE_PRIVILEGE_TYPE | Types of object privileges to list


ListOwnedObjects List

SQLServer.Database.User Object

Description

Returns a list of DBObject objects that this user owns.

Visual Basic

DBObjectList = User.ListOwnedObjects (
[[ObjectTypes :=] tObjects,]
[[SortBy :=] tSortBy] )

C++

HRESULT pUser->ListOwnedObjects (
LPSQLOLEDBOBJECTLIST* ppDBObjectList,
SQLOLE_OBJECT_TYPE tObjects = SQLOLEObj_AllDatabaseObjects,
SQLOLE_OBJSORT_TYPE tSortBy = SQLOLEObjSort_Name );

Elements

Element | Type | Description

DBObjectList | DBObjectList | Returned list of DBObject objects
tObjects | SQLOLE_OBJECT_TYPE | Types of database objects to list
tSortBy | SortType | How to sort the list


User Collections

User Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


UserDefinedDatatype Object

UserDefinedDatatype Object Properties Methods Lists Collections

Description

A UserDefinedDatatype object contains information about a new datatype that has been created by the user.


UserDefinedDatatype Object Properties

UserDefinedDatatype Properties

UserDefinedDatatype Object Properties Methods Lists Collections

Property | Description

AllowIdentity Boolean Write: No | Indicates if the system datatype can be used as an identity column. If True, a column of this datatype can have the identity property. If False, a column of this datatype cannot have the identity property.
AllowNulls Boolean Write: Before Add | Determines if the user defined datatype accepts NULL values. If True, the user defined datatype allows NULL values. If False, NULL values are not allowed.
Application Application Write: No | The Application object.
BaseType Identifier Write: Before Add | The system datatype this user defined datatype is based on. To set this property to a new default, the default must exist.
Default Identifier Write: Yes | The default that is currently bound to this datatype.
ID Long Write: No | The type ID from sysobjects.usertype.
Length Long Write: Before Add | The number of bytes used to store a value of this datadatatype.
Name Identifier Write: Yes | The name of the user defined datatype.
NumericPrecision Long Write: Before Add | The precision of an exact numeric datatype.
NumericScale Long Write: Before Add | The scale of an exact numeric datatype.
Owner Identifier Write: NO | The user who created this user defined datatype.
Parent Database Write: No | The Database object.
Rule Identifier Write: Yes | The rule currently bound to this user defined datatype. To set this property to a new rule, the rule must exist.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Remove Method

SQLServer.Database.UserDefinedDatatype Object

Description

Drops an existing user-defined datatype and removes the UserDefinedDatatype object.

Visual Basic

UserDefinedDatatype.Remove

C++

HRESULT pUserDefinedDatatype->Remove ( );

Reference

sp_droptype


Script Method

SQLServer.Database.UserDefinedDatatype Object

Description

Generates a series of Transact-SQL statements (script) to create the user-defined datatype.

Visual Basic

strScript = UserDefinedDatatype.Script (
[[ScriptType :=] tScriptType,]
[[ScriptFilePath :=] strFile] )

C++

HRESULT pUserDefinedDatatype->Script (
SQLOLE_SCRIPT_TYPE tScriptType = SQLOLEScript_Default,
SQLOLE_LPCSTR strFile = NULL,
SQLOLE_LPBSTR pstrScript = NULL );

Elements

Element | Type | Description

strScript | String | Generated Transact-SQL script
tScriptType | SQLOLE_SCRIPT_TYPE | Type of script to generate
strFile | String | Full path and file name to use to store the Transact-SQL script


UserDefinedDatatype List

UserDefinedDatatype Object Properties Methods Lists Collections

ListBoundColumns


ListBoundColumns List

SQLServer.Database.UserDefinedDatatype Object

Description

Returns a list of Column objects that this user-defined datatype is bound to.

Visual Basic

ColumnList = UserDefinedDatatype.ListBoundColumns

C++

HRESULT pUserDefinedDatatype->ListBoundColumns ( LPSQLOLECOLUMNLIST* ppColumnList );

Elements

Element | Type | Description

ColumnList | ColumnList | Returned list of Column objects


UserDefinedDatatype Collections

UserDefinedDatatype Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Chapter 5 Table Scope Objects

Table Scope Objects

Check Object

Column Object

DRIDefault Object

Index Object

Key Object

Table Object

Trigger Object

View Object


Check Object

Check Object Properties Methods Collections

Description

A Check object contains information about a check constraint. It may constrain one or more columns.


Check Properties

Check Object Properties Methods Collections

Property | Description

Application Application Write: No | The Application object.
ExcludeReplication Boolean Write: Yes | Determines if this Check constraint is ignored during replication. If True, this Check is ignored for data inserted by replication. If False, this Check is enforced for data inserted by replication.
Name Identifier Write: Yes | The Check constraint name. If empty when a new Check object is added to the Table.Checks collection, one will automatically be generated.
Parent Table Write: No | The Table object.
Text String Write: Before Add | The original Transact-SQL search condition used to create this Check.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Check Methods

Check Object Properties Methods Collections

Remove

Script


Remove Method

SQLServer.Database.Table.Check Object

Description

Drops the SQL Server check constraint and removes the Check object.

Visual Basic

Check.Remove

C++

HRESULT pCheck->Remove ( );


Script Method

SQLServer.Database.Table.Check Object

Description

Generates a series of Transact-SQL statements (script) to create the check constraint (using ALTER TABLE).

Visual Basic

strScript = Check.Script (
[[ScriptType :=] tScriptType,]
[[ScriptFilePath :=] strFile] )

C++

HRESULT pCheck->Script (
SQLOLE_SCRIPT_TYPE tScriptType = SQLOLEScript_Default,
SQLOLE_LPCSTR strFile = NULL,
SQLOLE_LPBSTR pstrScript = NULL );

Elements

Element | Type | Description

strScript | String | Generated Transact-SQL script
tScriptType | SQLOLE_SCRIPT_TYPE | Type of script to generate
strFile | String | Full path and file name to use to store the Transact-SQL script


Check Collections

Check Object Properties Methods Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Column Object

Column Object Properties Methods Lists Collections

Description

A Column object defines a specific type of information that is maintained in a table.


Column Object Properties

Column Properties

Column Object Properties Methods Lists Collections

Property | Description

AllowNulls Boolean Write: Before Add | Determines if the column allows NULL values. If True, the column allows NULL values. If False, NULL values are not allowed in the column.
Application Application Write: No | The Application object.
DataType Identifier Write: Before Add | The system or user-defined datatype of the column.
Default Identifier Write: Yes | The default bound to the column.
DRIDefault DRIDefault Write: No | The DRIDefault object for this column.
ID Long Write: No | The column ID and ordinal number in the table.
Identity Boolean Write: Before Add | Determines if this column has the identity property. If True, this is the single identity column for this table. If False, this column does not have the identity property.
IdentityIncrement Long Write: Before Add | The value added to the previous identity value to get the next identity value.
IdentitySeed Long Write: Before Add | The value automatically assigned to the identity column of the first row inserted into the table.
InPrimaryKey Boolean Write: Before Add | Indicates if this column is part of the primary key for this table. If True, this column is part of the primary key. If False, this column is not part of the primary key.
Length Long Write: Before Add | The number of bytes used to store a value in this column.
Name Identifier Write: Yes | The column name.
NumericPrecision Long Write: Before Add | The precision of an exact numeric datatype column.
NumericScale Long Write: Before Add | The scale of an exact numeric datatype column.
Parent Table Write: No | The Table object.
PhysicalDataType Identifier Write: No | The system datatype that the user-defined datatype is based on.
Rule Identifier Write: Yes | The rule bound to the column.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Column Methods

Column Object Properties Methods Lists Collections

Remove


Remove Method

SQLServer.Database.Table.Column Object

Description

Removes the Column object from a new but not added Table.

Visual Basic

Column.Remove

C++

HRESULT pColumn->Remove ( );


Column Lists

Column Object Properties Methods Lists Collections

ListKeys


ListKeys Method

SQLServer.Database.Table.Column Object

Description

Returns a list of Key objects that include this Column.

Visual Basic

KeyList = Column.ListKeys

C++

HRESULT pColumn->ListKeys ( LPSQLOLEKEYLIST* ppKeyList );

Elements

Element | Type | Description

KeyList | KeyList | Returned list of Key objects


Column Collections

Column Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


DRIDefault Object

DRIDefault Object Properties Methods Collections

Description

A DRIDefault object contains information about a default constraint for a column. A DRIDefault is a property of a Column object.


DRIDefault Properties

DRIDefault Object Properties Methods Collections

Property | Description

Application Application Write: No | The Application object.
Name Identifier Write: Yes | The DRIDefault name, optional on column creation. SQL-DMO will automatically generate one if blank.
Parent Column Write: No | The Column object.
Text String Write: Yes | The Transact-SQL expression used to create this DRIDefault. If not empty when the DRIDefault property of a new Column object is added to the Table.Columns collection, the default constraint will also be created when the table and column are created; otherwise, the default constraint is not created. If set to an empty string, the DRIDefault is removed from the column.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


DRIDefault Methods

DRIDefault Object Properties Methods Collections

Remove

Script


Remove Method

SQLServer.Database.Table.Column.DRIDefault Object

Description

Drops the SQL Server default constraint and removes the DRIDefault object.

Visual Basic

DRIDefault.Remove

C++

HRESULT pDRIDefault->Remove ( );


Script Method

SQLServer.Database.Table.Column.DRIDefault Object

Description

Generates a series of Transact-SQL statements (script) to create the default constraint (using ALTER TABLE).

Visual Basic

strScript = DRIDefault.Script (
[[ScriptType :=] tScriptType,]
[[ScriptFilePath :=] strFile] )

C++

HRESULT pDRIDefault->Script (
SQLOLE_SCRIPT_TYPE tScriptType = SQLOLEScript_Default,
SQLOLE_LPCSTR strFile = NULL,
SQLOLE_LPBSTR pstrScript = NULL );

Elements

Element | Type | Description

strScript | String | Generated Transact-SQL script
tScriptType | SQLOLE_SCRIPT_TYPE | Type of script to generate
strFile | String | Full path and file name to use to store the Transact-SQL script


DRIDefault Collections

DRIDefault Object Properties Methods Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Index Object

Index Object Properties Methods Lists Collections

Description

An Index object is used to speed up access to a table. There are two types of indexes: a clustered index, where data is stored in the same order as the index, and a nonclustered index, where data is unordered and stored separately from the index.


Index Object Properties

Index Properties

Index Object Properties Methods Lists Collections

Property | Description

Application Application Write: No | The Application object.
FillFactor Long Write: Before Add | The percent of each page that SQL Server will fill with index data when creating a new index on a table. Valid values are 0 through 100.
ID Long Write: No | The object ID of the index.
Name Identifier Write: Yes | The name of the index.
Parent Table Write: No | The Table object.
SpaceUsed Long Write: No | Storage space in kilobytes used by this index.
Type SQLOLE_INDEX_TYPE Write: Before Add | The type of index.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Index Object Methods

Index Methods

Index Object Properties Methods Lists Collections

GenerateCreationSQL

IndexedColumns

Rebuild

RecalcSpaceUsage

Remove

Script

UpdateStatistics


GenerateCreationSQL Method

SQLServer.Database.Table.Index Object

Description

Generates a series of Transact-SQL statements (script) that can be used to create this index on another table.

Visual Basic

Index.GenerateCreationSQL ( [TargetTable :=] idTargetTable )

C++

HRESULT pIndex->GenerateCreationSQL (
LPSQLOLETABLE idTargetTable,
SQLOLE_LPBSTR pstrScript );

Elements

Element | Type | Description

strScript | String | Generated Transact-SQL backup script
idTargetTable | Identifier | Table that the script will create the index on

Remarks

To schedule this index creation script, set the Task.Command property to the string returned by this method.


IndexedColumns Method

SQLServer.Database.Table.Index Object

Description

Sets the list of columns to be included in a new index.

Visual Basic

Index.IndexedColumns ( [ColumnNames :=] midColumns )

C++

HRESULT pIndex->SetIndexedColumns ( SQLOLE_LPCSTR midColumns );

Elements

Element | Type | Description

midColumns | MultiIdentifier | Delimited list of one or more columns

Remarks

This is an indexed property.


Rebuild Method

SQLServer.Database.Table.Index Object

Description

Drops and re-creates the index.

Visual Basic

Index.Rebuild

C++

HRESULT pIndex->Rebuild ( );

Remarks

If you need to redefine an Index (for example, change the fill factor or add a column), then you must first Remove the Index, then Add a new one.


RecalcSpaceUsage Method

SQLServer.Database.Table.Index Object

Description

Recalculates the latest space usage information for the index.

Visual Basic

Index.RecalcSpaceUsage

C++

HRESULT pIndex->RecalcSpaceUsage ( );


Remove Method

SQLServer.Database.Table.Index Object

Description

Drops the SQL Server index and removes the Index object.

Visual Basic

Index.Remove

C++

HRESULT pIndex->Remove ( );


Script Method

SQLServer.Database.Table.Index Object

Description

Generates a series of Transact-SQL statements (script) to create the index.

Visual Basic

strScript = Index.Script (
[[ScriptType :=] tScriptType,]
[[ScriptFilePath :=] strFile] )

C++

HRESULT pIndex->Script (
SQLOLE_SCRIPT_TYPE tScriptType = SQLOLEScript_Default,
SQLOLE_LPCSTR strFile = NULL,
SQLOLE_LPBSTR pstrScript = NULL );

Elements

Element | Type | Description

strScript | String | Generated Transact-SQL script
tScriptType | SQLOLE_SCRIPT_TYPE | Type of script to generate
strFile | String | Full path and file name to use to store the Transact-SQL script


UpdateStatistics Method

SQLServer.Database.Table.Index Object

Description

Updates data distribution statistics for this index.

Visual Basic

Index.UpdateStatistics

C++

HRESULT pIndex->UpdateStatistics ( );

Reference

UPDATE STATISTICS


Index Object Lists

Index Lists

Index Object Properties Methods Lists Collections

EnumStatistics

ListIndexedColumns


EnumStatistics Method

SQLServer.Database.Table.Index Object

Description

Returns statistical information in the distribution page for the index.

Visual Basic

QueryResults = Index.EnumStatistics

C++

HRESULT pIndex->EnumStatistics ( LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object

QueryResults

This method can return up to three results sets.

ColumnName | ColumnType

Updated | SQLOLE_DTypeChar
Rows | SQLOLE_DTypeInt4
Steps | SQLOLE_DTypeInt4
Density | SQLOLE_DTypeFloat4

ColumnName | ColumnType

All density | SQLOLE_DTypeFloat4
Columns | SQLOLE_DTypeChar

ColumnName | ColumnType

Steps | SQLOLE_DTypeChar


ListIndexedColumns List

SQLServer.Database.Table.Index Object

Description

Returns a list of Column objects that are included in this index.

Visual Basic

ColumnList = Index.ListIndexedColumns

C++

HRESULT pIndex->ListIndexedColumns ( LPSQLOLECOLUMNLIST* ppColumnList );

Elements

Element | Type | Description

ColumnList | ColumnList | Returned list of Column objects


Index Collections

Index Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Key Object

Key Object Properties Methods Collections

Description

A Key object contains information about primary, unique or foreign keys of a Table. Each Key is made up of one or more columns from a table.


Key Properties

Key Object Properties Methods Collections

Property | Description

Application Application Write: No | The Application object.
Clustered Boolean Write: Before Add | Determines if the unique index associated with this Key is a clustered index. If True, this Key has a unique clustered index. If False, this Key has a unique nonclustered index. The default is False.
FillFactor Long Write: Before Add | The percentage of each page that SQL Server will fill with index data when creating a unique index for a new Key. Valid values are 0 through 100.
Name Identifier Write: Yes | The name of the Key. Optional on Keys.Add; SQL-DMO will automatically generate one if blank.
Parent Table Write: No | The Table object.
ReferencedKey Identifier Write: No | The key of the ReferencedTable which this foreign key references, if this is a foreign key.
ReferencedTable Identifier Write: Yes | The table that includes columns referenced by the KeyColumns of this Key. Data values in the KeyColumns must exist in the ReferencedColumns of this table.
Type SQLOLE_KEY_TYPE Write: Yes | The Key type.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Key Methods

Key Object Properties Methods Collections

Remove

Script


Remove Method

SQLServer.Database.Table.Key Object

Description

Drops the SQL Server key and removes the Key object.

Visual Basic

Key.Remove

C++

HRESULT pKey->Remove ( );


Script Method

SQLServer.Database.Table.Key Object

Description

Generates a series of Transact-SQL statements (script) to create the key (using ALTER TABLE).

Visual Basic

strScript = Key.Script (
[[ScriptType :=] tScriptType,]
[[ScriptFilePath :=] strFile] )

C++

HRESULT pKey->Script (
SQLOLE_SCRIPT_TYPE tScriptType = SQLOLEScript_Default,
SQLOLE_LPCSTR strFile = NULL,
SQLOLE_LPBSTR pstrScript = NULL );

Elements

Element | Type | Description

strScript | String | Generated Transact-SQL script
tScriptType | SQLOLE_SCRIPT_TYPE | Type of script to generate
strFile | String | Full path and file name to use to store the Transact-SQL script


Key Collections

Key Object Properties Methods Collections

Collection | Description

KeyColumns Names Write: No | The Names collection that contains columns included in this Key.
Properties Properties Write: No | The collection of Property objects.
ReferencedColumns Names Write: No | The Names collection that contains referenced columns of the ReferencedTable property. Data values in the KeyColumns (Names) collection must exist in these columns of the ReferencedTable.


Table Object

Table Object Properties Methods Lists Collections

Description

A Table object contains rows of data in the database.


Table Object Properties

Table Properties

Table Object Properties Methods Lists Collections

Property | Description

Application Application Write: No | The Application object.
Attributes SQLOLE_TABLEATT_TYPE Write: No | The attributes of this table.
ClusteredIndex Index Write: No | The clustered Index object.
CreateDate String Write: No | The date and time this table was created.
DataSpaceUsed Long Write: No | Storage space in kilobytes used by the rows of this table.
ID Long Write: No | The object ID of the table.
IndexSpaceUsed Long Write: No | Storage space in kilobytes used by the indexes on this table.
Name Identifier Write: Yes | The name of the table.
Owner Identifier Write: No | The user who created the table.
Parent Database Write: No | The Database object.
PrimaryKey Key Write: No | The primary Key object for this table.
Rows Long Write: No | The number of rows currently in this table.
SystemObject Write: | Indicates if this is a SQL Server system table. If True, this is a SQL Server system table. If False, this table was created by a user.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Table Object Methods

Table Methods

Table Object Properties Methods Lists Collections

BeginAlter

CancelAlter

CheckTable

CheckTextAllocsFast

CheckTextAllocsFull

DoAlter

DoAlterWithNoCheck

Grant

InsertColumn

RecalcSpaceUsage

ReCompileReferences

Refresh

Remove

Revoke

Script

TruncateData

UpdateStatistics


BeginAlter Method

SQLServer.Database.Table Object

Description

Marks the start of a single unit of changes to Table properties. Normally, each change to a single property is a separate update to SQL Server. To group multiple property changes into a single unit, first call the BeginAlter method, then make the desired property changes. To commit the unit of property changes to SQL Server using a single update, call the DoAlter method. To cancel the unit of property changes (made since calling BeginAlter), call the CancelAlter method.

Visual Basic

Table.BeginAlter

C++

HRESULT pTable->BeginAlter ( );


CancelAlter Method

SQLServer.Database.Table Object

Description

Stops a unit of Table property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will not be committed to SQL Server.

Visual Basic

Table.CancelAlter

C++

HRESULT pTable->CancelAlter ( );


CheckTable Method

SQLServer.Database.Table Object

Description

Checks the internal consistency of the data and index pages of this table.

Visual Basic

strOutput = Table.CheckTables

C++

HRESULT pTable->CheckTables ( SQLOLE_LPBSTR pstrOutput );

Elements

Element | Type | Description

strOutput | String | The output returned by the internal consistency check

Reference

DBCC CHECKTABLE


CheckTextAllocsFast Method

SQLServer.Database.Table Object

Description

Checks the internal allocation consistency of text and image pages of this table. This check is faster than the CheckTextAllocsFull method because it only checks data in existing text and image columns.

Visual Basic

strOutput = Table.CheckTextAllocsFast

C++

HRESULT pTable->CheckTextAllocsFast ( SQLOLE_LPBSTR pstrOutput );

Elements

Element | Type | Description

strOutput | String | The output returned by the internal consistency check

Reference

DBCC TEXTALLOC (..., FAST)


CheckTextAllocsFull Method

SQLServer.Database.Table Object

Checks the internal allocation consistency of text and image pages of this table. This check is slower and more thorough than CheckTextAllocsFast method because it checks the entire table for text and image data.

Visual Basic

strOutput = Table.CheckTextAllocsFull

C++

HRESULT pTable->CheckTextAllocsFull ( SQLOLE_LPBSTR pstrOutput );

Elements

Element | Type | Description

strOutput | String | The output returned by the internal consistency check

Reference

DBCC TEXTALLOC (..., FULL)


DoAlter Method

SQLServer.Database.Table Object

Description

Commits a unit of Table property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will be committed to SQL Server using a single update.

Visual Basic

Table.DoAlter

C++

HRESULT pTable->DoAlter ( );


DoAlterWithNoCheck Method

SQLServer.Database.Table Object

Description

Commits a unit of Table property changes previously marked with BeginAlter using ALTER TABLE ... WITH NOCHECK. All property changes made since calling BeginAlter will be committed to SQL Server using a single update.

Visual Basic

Table.DoAlterWithNoCheck

C++

HRESULT pTable->DoAlterWithNoCheck ( );

Remarks

To add a check constraint or foreign key constraint to a table using the WITH NOCHECK option, first call the BeginAlter method, then make the property changes, then call DoAlterWithNoCheck.

Reference

ALTER TABLE ... WITH NOCHECK


Grant Method

SQLServer.Database.Table Object

Description

Gives table privileges to a list of SQL Server users and groups.

Visual Basic

Table.Grant (
[Privileges :=] tPrivileges,
[GranteeNames :=] midUserGroupList,
[[ColumnNames :=] midColumnList] )

C++

HRESULT pTable->Grant (
SQLOLE_PRIVILEGE_TYPE tPrivileges,
SQLOLE_LPCSTR midUserGroupList,
SQLOLE_LPCSTR midColumnList = NULL );

Elements

Element | Type | Description

tPrivileges | SQLOLE_PRIVILEGE_TYPE | Types of statement privileges to grant
midUserGroupList | MultiIdentifier | Delimited list of one or more users and groups
midColumnList | MultiIdentifier | Delimited list of one or more columns

Reference

GRANT


InsertColumn Method

SQLServer.Database.Table Object

Description

Inserts a new column into an existing table or a new but not added Table. To insert a new column as the last column of an existing table, first call the BeginAlter method, then call InsertColumn, then call the DoAlter method. To insert a new column into the specified position of a new Table, call InsertColumn before adding the new Table to the Database.Tables collection.

Visual Basic

Table.InsertColumn (
[NewColumn :=] Column,
[BeforeColumnName :=] idBeforeColumn )

C++

HRESULT pTable->InsertColumn (
LPSQLOLECOLUMN pColumn,
SQLOLE_LPCSTR idBeforeColumn );

Elements

Element | Type | Description

Column | Column | Column object to be inserted.
idBeforeColumn | Identifier | If not empty, the Column object will inserted before this column name. If empty, the Column object will be the last column of the table. To insert a new column into an existing table, this value must be empty.


RecalcSpaceUsage Method

SQLServer.Database.Table Object

Description

Recalculates the latest space usage information for the table.

Visual Basic

Table.RecalcSpaceUsage

C++

HRESULT pTable->RecalcSpaceUsage ( );


ReCompileReferences Method

SQLServer.Database.Table Object

Description

Causes each stored procedure and trigger that references the table to be recompiled the next time it is executed.

Visual Basic

Table.ReCompileReferences

C++

HRESULT pTable->ReCompileReferences ( );

Reference

sp_recompile


Refresh Method

SQLServer.Database.Table Object

Description

Updates Table properties with current information from SQL Server. This method will also refresh all the collections of this Table.

Visual Basic

Table.Refresh

C++

HRESULT pTable->Refresh ( );

Remarks

SQL-DMO will release only those objects in the Table collections that have been removed from SQL Server. This invalidates any object variables you have that refer to objects in the refreshed Table collections that have been removed from SQL Server.


Remove Method

SQLServer.Database.Table Object

Description

Drops the SQL Server table and removes the Table object.

Visual Basic

Table.Remove

C++

HRESULT pTable->Remove ( );

Reference

DROP TABLE


Revoke Method

SQLServer.Database.Table Object

Description

Removes table privileges from a list of SQL Server users and groups.

Visual Basic

Table.Revoke (
[Privileges :=] tPrivileges,
[RevokeeNames :=] midUserGroupList,
[[ColumnNames :=] midColumnList] )

C++

HRESULT pTable->Revoke (
SQLOLE_PRIVILEGE_TYPE tPrivileges,
SQLOLE_LPCSTR midUserGroupList,
SQLOLE_LPCSTR midColumnList = NULL );

Elements

Element | Type | Description

tPrivileges | SQLOLE_PRIVILEGE_TYPE | Types of statement privileges to revoke
midUserGroupList | MultiIdentifier | Delimited list of one or more users and groups
midColumnList | MultiIdentifier | Delimited list of one or more columns

Reference

REVOKE


Script Method

SQLServer.Database.Table Object

Description

Generates a series of Transact-SQL statements (script) to create the table.

Visual Basic

strScript = Table.Script (
[[ScriptType :=] tScriptType,]
[[ScriptFilePath :=] strFile,]
[[NewName :=] strNewName] )

C++

HRESULT pTable->Script (
SQLOLE_SCRIPT_TYPE tScriptType = SQLOLEScript_Default,
SQLOLE_LPCSTR strFile = NULL,
SQLOLE_LPCSTR strNewName = NULL,
SQLOLE_LPBSTR pstrScript = NULL );

Elements

Element | Type | Description

strScript | String | Generated Transact-SQL script
tScriptType | SQLOLE_SCRIPT_TYPE | Type of script to generate
strFile | String | Full path and file name to use to store the Transact-SQL script
strNewName | Identifier | A new table name if desired


TruncateData Method

SQLServer.Database.Table Object

Description

Deletes all rows from this table.

Visual Basic

Table.TruncateData

C++

HRESULT pTable->TruncateData ( );

Reference

TRUNCATE TABLE


UpdateStatistics Method

SQLServer.Database.Table Object

Description

Updates data distribution statistics for all indexes on this table.

Visual Basic

Table.UpdateStatistics

C++

HRESULT pTable->UpdateStatistics ( );

Reference

UPDATE STATISTICS


Table Object Lists

Table Lists

Table Object Properties Methods Lists Collections

EnumDependencies

EnumLastStatisticsUpdates

EnumReferencedKeys

EnumReferencedTables

EnumReferencingKeys

EnumReferencingTables

ListArticles

ListPermissions

ListUserPermissions


EnumDependencies List

SQLServer.Database.Table Object

Description

Lists the database objects that depend on this Table, or database objects that this Table depends on, in dependency order. List is returned in a QueryResults object.

Visual Basic

QueryResults = Table.EnumDependencies ( [[DependencyType :=] tDependency] )

C++

HRESULT pTable->EnumDependencies (
LPSQLOLEQUERYRESULTS* ppQueryResults, SQLOLE_DEPENDENCY_TYPE tDependency = SQLOLEDep_Parents );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
tDependency | SQLOLE_DEPENDENCY_TYPE | Dependency type

QueryResults

This method can return up to three results sets.

ColumnName | ColumnType

oType | SQLOLE_DTypeInt4
oRuleDefName | SQLOLE_DTypeChar
oOwner | SQLOLE_DTypeChar
oSequence | SQLOLE_DTypeInt2

ColumnName | ColumnType

oType | SQLOLE_DTypeInt4
oUDDTName | SQLOLE_DTypeChar
oOwner | SQLOLE_DTypeChar
oSequence | SQLOLE_DTypeInt2

ColumnName | ColumnType

oType | SQLOLE_DTypeInt4
oObjName | SQLOLE_DTypeChar
oOwner | SQLOLE_DTypeChar
oSequence | SQLOLE_DTypeInt2


EnumLastStatisticsUpdates List

SQLServer.Database.Table Object

Description

Lists the dates that the indexes on this table were last updated. List is returned in a QueryResults object.

Visual Basic

QueryResults = Table.EnumLastStatisticsUpdates ( [[IndexName :=] idIndex] )

C++

HRESULT pTable->EnumLastStatisticsUpdates (
LPSQLOLEQUERYRESULTS* ppQueryResults,
SQLOLE_LPCSTR idIndex = NULL );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object.
idIndex | Identifier | Index. The default is all indexes on the table.

QueryResults

ColumnName | ColumnType

name | SQLOLE_DTypeChar
last update | SQLOLE_DTypeDateTime

Reference

STATS_DATE


EnumReferencedKeys List

SQLServer.Database.Table Object

Description

Lists the keys of other tables that are referenced by the keys of this Table. List is returned in a QueryResults object.

Visual Basic

QueryResults = Table.EnumReferencedKeys (
[[ReferencedTableName :=] idTable,]
[[IncludeAllCandidates :=] bIncludeCandidates] )

C++

HRESULT pTable->EnumReferencedKeys (
LPSQLOLEQUERYRESULTS* ppQueryResults,
SQLOLE_LPCSTR idTable = NULL,
BOOL bIncludeCandidates = NULL );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
idTable | Identifier | Table to list the keys of
bIncludeCandidates | Boolean | Determines if all possible candidate tables are included in the list, even those not referenced. If True, candidate tables are included. If False, candidate tables are not included.

QueryResults

ColumnName | ColumnType

candidate_table | SQLOLE_DTypeChar
candidate_key | SQLOLE_DTypeChar
referenced | SQLOLE_DTypeBit

Remarks

The returned QueryResults contains a column indicating if a key is referenced.


EnumReferencedTables List

SQLServer.Database.Table Object

Description

Lists the tables that are referenced by they keys of this Table. List is returned in a QueryResults object.

Visual Basic

QueryResults = Table.EnumReferencedTables ( [[IncludeAllCandidates :=] bIncludeCandidates] )

C++

HRESULT pTable->EnumReferencedTables (
LPSQLOLEQUERYRESULTS* ppQueryResults,
BOOL bIncludeCandidates = NULL );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
bIncludeCandidates | Boolean | Determines if all possible candidate tables are included in the list, even those not referenced. If True, candidate tables are included. If False, candidate tables are not included.

QueryResults

ColumnName | ColumnType

candidate_table | SQLOLE_DTypeChar
candidate_key | SQLOLE_DTypeChar
referenced | SQLOLE_DTypeBit

Remarks

The returned QueryResults contains a column indicating if a key is referenced.


EnumReferencingKeys List

SQLServer.Database.Table Object

Description

Lists the keys of other tables that reference this Table. List is returned in a QueryResults object.

Visual Basic

QueryResults = Table.EnumReferencingKeys (
[[ReferencedTableName :=] idTable,]
[[IncludeAllCandidates :=] bIncludeCandidates] )

C++

HRESULT pTable->EnumReferencingKeys (
LPSQLOLEQUERYRESULTS* ppQueryResults,
SQLOLE_LPCSTR idTable = NULL,
BOOL bIncludeCandidates = NULL );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
idTable | Identifier | Table to list the keys of
bIncludeCandidates | Boolean | Determines if all possible candidate tables are included in the list, even those not referenced. If True, candidate tables are included. If False, candidate tables are not included.

QueryResults

ColumnName | ColumnType

candidate_table | SQLOLE_DTypeChar
candidate_key | SQLOLE_DTypeChar
referenced | SQLOLE_DTypeBit

Remarks

The returned QueryResults contains a column indicating if a key is referenced.


EnumReferencingTables List

SQLServer.Database.Table Object

Description

Lists the other tables that reference this Table. List is returned in a QueryResults object.

Visual Basic

QueryResults = Table.EnumReferencingTables ( [[IncludeAllCandidates :=] bIncludeCandidates] )

C++

HRESULT pTable->EnumReferencingTables (
LPSQLOLEQUERYRESULTS * ppQueryResults,
BOOL bIncludeCandidates = NULL );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
bIncludeCandidates | Boolean | Determines if all possible candidate tables are included in the list, even those not referenced. If True, candidate tables are included. If False, candidate tables are not included.

QueryResults

ColumnName | ColumnType

candidate_table | SQLOLE_DTypeChar
candidate_key | SQLOLE_DTypeChar
referenced | SQLOLE_DTypeBit

Remarks

The returned QueryResults contains a column indicating if a key is referenced.


ListArticles List

SQLServer.Database.Table Object

Description

Returns a list of Article objects that publish this table for replication.

Visual Basic

ArticleList = Table.ListArticles

C++

HRESULT pTable->ListArticles ( LPSQLOLEARTICLELIST* ppArticleList );

Elements

Element | Type | Description

ArticleList | ArticleList | Returned list of Article objects


ListPermissions List

SQLServer.Database.Table Object

Description

Returns a list of Permission objects containing the object privileges for this table.

Visual Basic

PermissionList = Table.ListPermissions ( [[PrivilegeTypes :=] tPrivileges] )

C++

HRESULT pTable->ListPermissions (
LPSQLOLEPERMISSIONLIST* ppPermissionList,
SQLOLE_PRIVILEGE_TYPE tPrivileges = SQLOLEPriv_AllObjectPrivs );

Elements

Element | Type | Description

PermissionList | PermissionList | Returned list of Permission objects
tPrivileges | SQLOLE_PRIVILEGE_TYPE | Types of object privileges to list


ListUserPermissions List

SQLServer.Database.Table Object

Description

Returns a list of Permission objects containing the specified user's privileges for this table.

Visual Basic

PermissionList = Table.ListUserPermissions ( [UserName :=] idUser )

C++

HRESULT pTable->ListUserPermissions (
SQLOLE_LPCSTR idUser,
LPSQLOLEPERMISSIONLIST* ppPermissionList );

Elements

Element | Type | Description

PermissionList | PermissionList | Returned list of Permission objects
idUser | Identifier | User


Table Collections

Table Object Properties Methods Lists Collections

Property | Description

Checks Checks Write: No | The collection of Check objects.
Columns Columns Write: No | The collection of Column objects.
Indexes Indexes Write: No | The collection of Index objects.
Keys Keys Write: No | The collection of Key objects.
Properties Properties Write: No | The collection of Property objects.
Triggers Triggers Write: No | The collection of Trigger objects.


Trigger Object

Trigger Object Properties Methods Lists Collections

Description

A Trigger object contains Transact-SQL statements that are executed when data in a specific table is inserted, updated, or deleted.


Trigger Properties

Trigger Object Properties Methods Lists Collections

Property | Description

Application Application Write: No | The Application object.
CreateDate String Write: No | The date and time the trigger was created.
ID Long Write: No | The object ID of the trigger.
Name Identifier Write: Yes | The name of the trigger.
Owner Identifier Write: No | The user who created the trigger.
Parent Table Write: No | The Table object.
SystemObject Boolean Write: No | Indicates if this is a SQL Server system trigger. If True, this is a SQL Server system trigger. If False, this trigger was created by a user.
Text String Write: Before Add | The Transact-SQL statements used to create the trigger.
Type SQLOLE_TRIGGER_TYPE Write: Before Add | The type of trigger.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Trigger Methods

Trigger Object Properties Methods Lists Collections

Remove

Script


Remove Method

SQLServer.Database.Table.Trigger Object

Description

Drops the SQL Server trigger and removes the Trigger object.

Visual Basic

Trigger.Remove

C++

HRESULT pTrigger->Remove ( );

Reference

DROP TRIGGER


Script Method

SQLServer.Database.Table.Trigger Object

Description

Generates a series of Transact-SQL statements (script) to create the trigger.

Visual Basic

strScript = Trigger.Script (
[[ScriptType :=] tScriptType,]
[[ScriptFilePath :=] strFile] )

C++

HRESULT pTrigger->Script (
SQLOLE_SCRIPT_TYPE tScriptType = SQLOLEScript_Default,
SQLOLE_LPCSTR strFile = NULL,
SQLOLE_LPBSTR pstrScript = NULL );

Elements

Element | Type | Description

strScript | String | Generated Transact-SQL script
tScriptType | SQLOLE_SCRIPT_TYPE | Type of script to generate
strFile | String | Full path and file name to use to store the Transact-SQL script


Trigger List

Trigger Object List

Trigger Object Properties Methods Lists Collections

EnumDependencies


EnumDependencies List

SQLServer.Database.Table.Trigger Object

Description

Lists the database objects that depend on this Trigger, or database objects that this Trigger depends on, in dependency order. List is returned in a QueryResults object.

Visual Basic

QueryResults = Trigger.EnumDependencies ( [[DependencyType :=] tDependency] )

C++

HRESULT pTrigger->EnumDependencies (
LPSQLOLEQUERYRESULTS* ppQueryResults, SQLOLE_DEPENDENCY_TYPE tDependency = SQLOLEDep_Parents );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
tDependency | SQLOLE_DEPENDENCY_TYPE | Dependency type

QueryResults

This method can return up to three results sets.

ColumnName | ColumnType

oType | SQLOLE_DTypeInt4
oRuleDefName | SQLOLE_DTypeChar
oOwner | SQLOLE_DTypeChar
oSequence | SQLOLE_DTypeInt2

ColumnName | ColumnType

oType | SQLOLE_DTypeInt4
oUDDTName | SQLOLE_DTypeChar
oOwner | SQLOLE_DTypeChar
oSequence | SQLOLE_DTypeInt2

ColumnName | ColumnType

oType | SQLOLE_DTypeInt4
oObjName | SQLOLE_DTypeChar
oOwner | SQLOLE_DTypeChar
oSequence | SQLOLE_DTypeInt2


Trigger Collections

Trigger Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


View Object

View Object Properties Methods Lists Collections

Description

A View object is logically similar to a table. It is defined by a SELECT statement (the Text property) that includes specific columns (either actual or aggregated) from one or more tables in a database.


View Object Properties

View Properties

View Object Properties Methods Lists Collections

Property | Description

Application Application Write: No | The Application object.
CreateDate String Write: No | The date and time the view was created.
ID Long Write: No | The object ID of the view.
Name Identifier Write: Yes | The name of the view.
Owner Identifier Write: No | The user who created the view.
Parent Database Write: No | The Database object.
SystemObject Boolean Write: No | Indicates if this is a SQL Server system view. If True, this is a SQL Server system view. If False, this view was created by a user.
Text LargeText Write: Before Add | The original Transact-SQL statement used to create the view.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


View Object Methods

View Methods

View Object Properties Methods Lists Collections

Grant

Remove

Revoke

Script


Grant Method

SQLServer.Database.View Object

Description

Gives view privileges to a list of SQL Server users and groups.

Visual Basic

View.Grant (
[Privileges :=] tPrivileges,
[GranteeNames :=] midUserGroupList,
[[ColumnNames :=] midColumnList] )

C++

HRESULT pView->Grant (
SQLOLE_PRIVILEGE_TYPE tPrivileges,
SQLOLE_LPCSTR midUserGroupList,
SQLOLE_LPCSTR midColumnList = NULL );

Elements

Element | Type | Description

tPrivileges | SQLOLE_PRIVILEGE_TYPE | Types of statement privileges to grant
midUserGroupList | MultiIdentifier | Delimited list of one or more users and groups
midColumnList | MultiIdentifier | Delimited list of one or more columns

Reference

GRANT


Remove Method

SQLServer.Database.View Object

Description

Drops the SQL Server view and removes the View object.

Visual Basic

View.Remove

C++

HRESULT pView->Remove ( );

Reference

DROP VIEW


Revoke Method

SQLServer.Database.View Object

Description

Removes view privileges from a list of SQL Server users and groups.

Visual Basic

View.Revoke (
[Privileges :=] tPrivileges,
[RevokeeNames :=] midUserGroupList,
[[ColumnNames :=] midColumnList] )

C++

HRESULT pView->Revoke (
SQLOLE_PRIVILEGE_TYPE tPrivileges,
SQLOLE_LPCSTR midUserGroupList,
SQLOLE_LPCSTR midColumnList = NULL );

Elements

Element | Type | Description

tPrivileges | SQLOLE_PRIVILEGE_TYPE | Types of statement privileges to revoke
midUserGroupList | MultiIdentifier | Delimited list of one or more users and groups
midColumnList | MultiIdentifier | Delimited list of one or more columns

Reference

REVOKE


Script Method

SQLServer.Database.View Object

Description

Generates a series of Transact-SQL statements (script) to create the view.

Visual Basic

strScript = View.Script (
[[ScriptType :=] tScriptType,]
[[ScriptFilePath :=] strFile] )

C++

HRESULT pView->Script (
SQLOLE_SCRIPT_TYPE tScriptType = SQLOLEScript_Default,
SQLOLE_LPCSTR strFile = NULL,
SQLOLE_LPBSTR pstrScript = NULL );

Elements

Element | Type | Description

strScript | String | Generated Transact-SQL script
tScriptType | SQLOLE_SCRIPT_TYPE | Type of script to generate
strFile | String | Full path and file name to use to store the Transact-SQL script


View Object Lists

View Lists

View Object Properties Methods Lists Collections

EnumDependencies

ListColumns

ListPermissions

ListUserPermissions


ListColumns List

SQLServer.Database.View Object

Description

Returns a list of Column objects that are contained in this view.

Visual Basic

ColumnList = View.ListColumns

C++

HRESULT pView->ListColumns ( LPSQLOLECOLUMNLIST* ppColumnList );

Elements

Element | Type | Description

ColumnList | ColumnList | Returned list of Column objects

Remarks

The InPrimaryKey property of the Column objects in the list cannot be read.


EnumDependencies List

SQLServer.Database.View Object

Description

Lists the database objects that depend on this View, or database objects that this View depends on, in dependency order. List is returned in a QueryResults object.

Visual Basic

QueryResults = View.EnumDependencies ( [[DependencyType :=] tDependency] )

C++

HRESULT pView->EnumDependencies (
LPSQLOLEQUERYRESULTS* ppQueryResults, SQLOLE_DEPENDENCY_TYPE tDependency = SQLOLEDep_Parents );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
tDependency | SQLOLE_DEPENDENCY_TYPE | Dependency type

QueryResults

This method can return up to three results sets.

ColumnName | ColumnType

oType | SQLOLE_DTypeInt4
oRuleDefName | SQLOLE_DTypeChar
oOwner | SQLOLE_DTypeChar
oSequence | SQLOLE_DTypeInt2

ColumnName | ColumnType

oType | SQLOLE_DTypeInt4
oUDDTName | SQLOLE_DTypeChar
oOwner | SQLOLE_DTypeChar
oSequence | SQLOLE_DTypeInt2

ColumnName | ColumnType

oType | SQLOLE_DTypeInt4
oObjName | SQLOLE_DTypeChar
oOwner | SQLOLE_DTypeChar
oSequence | SQLOLE_DTypeInt2


ListPermissions List

SQLServer.Database.View Object

Description

Returns a list of Permission objects containing the object privileges for this view.

Visual Basic

PermissionList = View.ListPermissions ( [[PrivilegeTypes :=] tPrivileges] )

C++

HRESULT pView->ListPermissions (
LPSQLOLEPERMISSIONLIST* ppPermissionList,
SQLOLE_PRIVILEGE_TYPE tPrivileges = SQLOLEPriv_AllObjectPrivs );

Elements

Element | Type | Description

PermissionList | PermissionList | Returned list of Permission objects
tPrivileges | SQLOLE_PRIVILEGE_TYPE | Types of object privileges to list

Reference

sp_helpprotect


ListUserPermissions List

SQLServer.Database.View Object

Description

Returns a list of Permission objects containing the specified user's privileges for this view.

Visual Basic

PermissionList = View.ListUserPermissions ( [UserName :=] idUser )

C++

HRESULT pView->ListUserPermissions (
SQLOLE_LPCSTR idUser,
LPSQLOLEPERMISSIONLIST* ppPermissionList );

Elements

Element | Type | Description

PermissionList | PermissionList | Returned list of Permission objects
idUser | Identifier | User

Reference

sp_helpprotect


View Collections

View Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Chapter 6 Service Scope Objects

Service Scope Objects

Alert Object

AlertSystem Object

Executive Object

IntegratedSecurity Object

Operator Object

Registry Object

Task Object


Alert Object

Alert Object Properties Methods Lists Collections

An Alert object contains all the information that defines a SQL Server alert.


Alert Properties

Alert Object Properties Methods Lists Collections

Property | Description

Application Application Write: No | The Application object.
CountResetDate Date Write: Yes | The date and time the OccuranceCount property was last set to zero.
DatabaseName Identifier Write: Yes | The database for this alert. If specified, this alert will fire only for events in this database.
DelayBetweenResponses Long Write: Yes | The delay in seconds between the previous response and the next response for a recurring alert. Set this property to limit the number of responses for the same event.
Enabled Boolean Write: Yes | Determines if the alert is active. If True, this alert is active and can be fired by SQL Executive. If False, this alert is disabled and will not fire.
EventCategory String Write: No | Reserved. Do not change this property.
EventDescriptionKeyword String Write: Yes | A string to do a case-insensitive search for in the event description. If specified, this alert will fire only for events which have a description that contains this string.
EventID String Write: No | Reserved. Do not change this property.
EventSource String Write: No | Reserved. Do not change this property. (Currently "MSSQLServer").
HasEmailNotification Long Write: No | The number of operators that receive e-mail notification when this alert fires.
HasPagerNotification Long Write: No | The number of operators that receive pager notification when this alert fires.
ID Long Write: No | The alert ID.
IncludeEventDescription NotifyType Write: Yes | The notification types in which to include the event description.
LastOccuranceDate Date Write: Yes | The date and time when this alert was last fired.
LastResponseDate Date Write: Yes | The date and time when a response last occurred for this alert. This is affected by the DelayBetweenResponses property.
MessageID Long Write: Yes | The SQL Server message number that will fire this alert. If you specify the MessageID property you cannot specify the Severity property.
Name String Write: Yes | The alert name. It must be unique.
NotificationMessage String Write: Yes | The custom text (maximum of 255 characters) to send along with the response when this alert is fired.
OccuranceCount Long Write: Yes | The number of times this alert has been fired since the date and time specified by the CountResetDate property. To clear this count, set this property to zero.
Parent SQLServer Write: No | The SQLServer object.
Severity Long Write: Yes | The SQL Server message severity that will fire this event. If you specify the Severity property you cannot specify the MessageID property.
TaskName String Write: Yes | The task to execute when this alert is fired.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Alert Methods

Alert Object Properties Methods Lists Collections

AddNotification

BeginAlter

CancelAlter

DoAlter

Refresh

Remove

RemoveNotification

UpdateNotification


AddNotification Method

SQLServer.Alert Object

Description

Adds a new operator to the list of operators to notify when this Alert fires.

Visual Basic

Alert.AddNotification (
[OperatorName :=] strOperator,
[NotifyMethod :=] tNotify )

C++

HRESULT pAlert->AddNotification (
SQLOLE_LPCSTR strOperator,
SQLOLE_NOTIFY_TYPE tNotify );

Elements

Element | Type | Description

strOperator | String | Operator to notify when this alert fires
tNotify | SQLOLE_NOTIFY_TYPE | Type of notification to use

Reference

sp_addnotification


BeginAlter Method

SQLServer.Alert Object

Description

Marks the start of a single unit of changes to Alert properties. Normally, each change to a single property is a separate update to SQL Server. To group multiple property changes into a single unit, first call the BeginAlter method, then make the desired property changes. To commit the unit of property changes to SQL Server using a single update call the DoAlter method. To cancel the unit of property changes (made since calling BeginAlter) call the CancelAlter method.

Visual Basic

Alert.BeginAlter

C++

HRESULT pAlert->BeginAlter ( );


CancelAlter Method

SQLServer.Alert Object

Description

Cancels a unit of Alert property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will not be committed to SQL Server.

Visual Basic

Alert.CancelAlter

C++

HRESULT pAlert->CancelAlter ( );


DoAlter Method

SQLServer.Alert Object

Description

Commits a unit of Alert property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will be committed to SQL Server using a single update.

Visual Basic

Alert.DoAlter

C++

HRESULT pAlert->DoAlter ( );


Refresh Method

SQLServer.Alert Object

Description

Updates Alert properties with current values from SQL Server.

Visual Basic

Alert.Refresh

C++

HRESULT pAlert->Refresh ( );


Remove Method

SQLServer.Alert Object

Description

Drops the SQL Server alert and removes the Alert object.

Visual Basic

Alert.Remove

C++

HRESULT pAlert->Remove ( );

Reference

sp_dropalert


RemoveNotification Method

SQLServer.Alert Object

Description

Removes an operator from the list of operators to notify when this Alert fires.

Visual Basic

Alert.RemoveNotification ( [OperatorName :=] strOperator )

C++

HRESULT pAlert->RemoveNotification ( SQLOLE_LPCSTR strOperator );

Elements

Element | Type | Description

strOperator | String | Operator to remove

Reference

sp_dropnotification


UpdateNotification Method

SQLServer.Alert Object

Description

Updates the notification method of an operator that is already on the list of operators to notify when this Alert fires.

Visual Basic

Alert.UpdateNotification (
[OperatorName :=] strOperator,
[NotifyMethod :=] tNotify );

C++

HRESULT pAlert->UpdateNotification (
SQLOLE_LPCSTR strOperator,
SQLOLE_NOTIFY_TYPE tNotify );

Elements

Element | Type | Description

strOperator | String | Operator to notify when this alert fires
tNotify | SQLOLE_NOTIFY_TYPE | Type of notification to use

Reference

sp_updatealert, sp_updatenotification


Alert Lists

Alert Object Properties Methods Lists Collections

EnumNotifications


EnumNotifications List

SQLServer.Alert Object

Description

Lists the operator notifications for this Alert. List is returned in a QueryResults object.

Visual Basic

QueryResults = Alert.EnumNotifications (
[NotifyMethod :=] tNotify,
[OperatorsToEnum :=] tOperators,
[[OperatorName :=] strOperator] )

C++

HRESULT pAlert->EnumNotifications (
SQLOLE_NOTIFY_TYPE tNotify,
SQLOLE_ENUMNOTIFY_TYPE tOperators,
LPSQLOLEQUERYRESULTS* ppQueryResults,
SQLOLE_LPCSTR strOperator = NULL );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object.
tNotify | SQLOLE_NOTIFY_TYPE | Type of notification to list.
tOperators | SQLOLE_ENUMNOTIFY_TYPE | Which operators to list.
strOperator | String | Specific operator. This parameter is used only when tOperators is SQLOLEEnumNotify_Target.

QueryResults

ColumnName | ColumnType

operator_id | SQLOLE_DTypeInt4
operator_name | SQLOLE_DTypeChar
use_email | SQLOLE_DTypeInt4
use_pager | SQLOLE_DTypeInt4
has_email | SQLOLE_DTypeBit
has_pager | SQLOLE_DTypeBit

Reference

sp_helpnotification


Alert Collections

Alert Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


AlertSystem Object

AlertSystem Object Properties Methods Collections

Description

The AlertSystem object contains information about the alert engine. The AlertSystem object is a property of the Executive object.


AlertSystem Properties

AlertSystem Object Properties Methods Collections

Property | Description

Application Application Write: No | The Application object.
FailSafeOperator Identifier Write: Yes | The operator to notify if, when an Alert fires, no operators are defined or available for that Alert.
ForwardingServer Identifier Write: Yes | The SQL Server that is providing Alert services for this SQLServer.
ForwardingSeverity Long Write: Yes | Alerts with a severity of this property value or higher will be forwarded to the ForwardingServer. Valid severity values are 1 through 25, 110, 120, 130, and 140.
NotificationMethod Write: Yes | Type of notification to use when the FailSafeOperator is notified.
PagerCCTemplate String Write: Yes | The template for creating the CC line of a pager notification. If this property contains the string "<#A#>", the AlertSystem will replace this string with the PagerAddress value of the Operator that this pager notification is sent to.
PagerSendSubjectOnly Boolean Write: Yes | Determines if only the subject line is sent with pager notifications. If True, only the subject line (and no message text) is sent with the pager notification. If True, the subject line and the message text are sent with the pager notification.
PagerSubjectTemplate String Write: Yes | The template for creating the Subject line of a pager notification. If this property contains the string "<#S#>", the AlertSystem will replace this string with the alert subject before this pager notification is sent. If empty, the AlertSystem will use the alert subject.
PagerToTemplate String Write: Yes | The template for creating the To line of a pager notification. If this property contains the string "<#A#>", the AlertSystem will replace this string with the PagerAddress value of the Operator that this pager notification is sent to. If empty, the AlertSystem will use the PagerAddress of the Operator.
Parent Executive Write: No | The Executive object.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


AlertSystem Methods

AlertSystem Object Properties Methods Collections

BeginAlter

CancelAlter

DoAlter

Refresh


BeginAlter Method

SQLServer.Executive.AlertSystem Object

Description

Marks the start of a single unit of changes to AlertSystem properties. Normally, each change to a single property is a seperate update to SQL Server. To group multiple property changes into a single unit, first call the BeginAlter method, then make the desired property changes. To commit the unit of property changes to SQL Server using a single update, call the DoAlter method. To cancel the unit of property changes (made since calling BeginAlter), call the CancelAlter method.

Visual Basic

AlertSystem.BeginAlter

C++

HRESULT pAlertSystem->BeginAlter ( );


CancelAlter Method

SQLServer.Executive.AlertSystem Object

Description

Stops a unit of AlertSystem property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will not be committed to SQL Server.

Visual Basic

AlertSystem.CancelAlter

C++

HRESULT pAlertSystem->CancelAlter ( );


DoAlter Method

SQLServer.Executive.AlertSystem Object

Description

Commits a unit of AlertSystem property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will be committed to SQL Server using a single update.

Visual Basic

AlertSystem.DoAlter

C++

HRESULT pAlertSystem->DoAlter ( );


Refresh Method

SQLServer.Executive.AlertSystem Object

Description

Updates AlertSystem properties with current information from SQL Server.

Visual Basic

AlertSystem.Refresh

C++

HRESULT pAlertSystem->Refresh ( );


AlertSystem Collections

AlertSystem Properties Methods Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Executive Object

Executive Object Properties Methods Lists Collections

Description

The Executive object contains information about the scheduling engine used to schedule tasks and alerts.


Executive Properties

Executive Object Properties Methods Lists Collections

Property | Description

AlertSystem AlertSystem Write: No | The AlertSystem object.
Application Application Write: No | The Application object.
AutoStart Boolean Write: Yes | Determines if the Executive service starts automatically when Windows NT starts. If True, the Executive starts when Windows NT starts. If False, the Executive must be started manually.
LimitHistoryRows Boolean Write: Yes | Determines if old task history rows (in the syshistory table) are overwritten with new ones. If True, the LimitHistoryRowsMax property limits the number of rows. If False, there is no limit to the number of rows.
LimitHistoryRowsMax Long Write: Yes | The maximum number of task history rows (in the syshistory table) to keep. When this number is exceeded, old task history rows are purged to make room for new ones.
Parent SQLServer Write: No | The SQLServer object.
RestartSQLServer Boolean Write: Yes | Determines if the Exective service will automatically restart SQL Server. If True, the Executive will restart SQL Server when it detects that SQL Server has stopped unexpectedly. If False, the Executive will not attempt to restart SQL Server.
RestartSQLServerInterval Long Write: Yes | The time in minutes between checks made by the Executive to confirm that SQL Server is still running. Valid values are 1 through 60. This property is only used when RestartSQLServer is True.
Status SQLOLE_SVCSTATUS_TYPE Write: No | Service status.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Executive Methods

Executive Object Properties Methods Lists Collections

BeginAlter

CancelAlter

DoAlter

ReassignLoginTasks

Refresh

RemoveLoginTasks

Start

Stop


BeginAlter Method

SQLServer.Executive Object

Description

Marks the start of a single unit of changes to Executive properties. Normally, each change to a single property is a seperate update to SQL Server. To group multiple property changes into a single unit, first call the BeginAlter method, then make the desired property changes. To commit the unit of property changes to SQL Server using a single update, call the DoAlter method. To cancel the unit of property changes (made since calling BeginAlter), call the CancelAlter method.

Visual Basic

Executive.BeginAlter

C++

HRESULT pExecutive->BeginAlter ( );


CancelAlter Method

SQLServer.Executive Object

Description

Stops a unit of Executive property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will not be committed to SQL Server.

Visual Basic

Executive.CancelAlter

C++

HRESULT pExecutive->CancelAlter ( );


DoAlter Method

SQLServer.Executive Object

Description

Commits a unit of Executive property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will be committed to SQL Server using a single update.

Visual Basic

Executive.DoAlter

C++

HRESULT pExecutive->DoAlter ( );


ReassignLoginTasks Method

SQLServer.Executive Object

Description

Reassigns all tasks currently owned by the specified login to a new login.

Visual Basic

Executive.ReassignLoginTasks (
[OldLogin :=] idOldLogin,
[NewLogin :=] idNewLogin )

C++

HRESULT pExecutive->ReassignLoginTasks (
SQLOLE_LPCSTR idOldLogin,
SQLOLE_LPCSTR idNewLogin );

Elements

Element | Type | Description

idOldLogin | Identifier | Login of current owner
idNewLogin | Identifier | Login of new owner


Refresh Method

SQLServer.Executive Object

Description

Updates Executive properties with current information from SQL Server.

Visual Basic

Executive.Refresh

C++

HRESULT pExecutive->Refresh ( );


RemoveLoginTasks Method

SQLServer.Executive Object

Description

Drops and removes all tasks owned by a specific login.

Visual Basic

Executive.RemoveLoginTasks ( [Login :=] idLogin )

C++

HRESULT pExecutive->RemoveLoginTasks ( SQLOLE_LPCSTR idLogin );

Elements

Element | Type | Description

idLogin | Identifier | Login


Start Method

SQLServer.Executive Object

Description

Starts a stopped Executive service.

Visual Basic

Executive.Start

C++

HRESULT pExecutive->Start ( );


Stop Method

SQLServer.Executive Object

Description

Stops a running Executive service.

Visual Basic

Executive.Stop

C++

HRESULT pExecutive->Stop ( );


Executive Lists

Executive Object Properties Methods Lists Collections

EnumQueuedTasks

EnumSubSystems

ListSubSystemTasks


EnumQueuedTasks List

SQLServer.Executive Object

Description

Lists tasks currently executing. List is returned in a QueryResults object.

Visual Basic

QueryResults = Executive.EnumQueuedTasks

C++

HRESULT pExecutive->EnumQueuedTasks ( LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object

QueryResults

ColumnName | ColumnType

Value | SQLOLE_DTypeChar
Data | SQLOLE_DTypeChar


EnumSubSystems List

SQLServer.Executive Object

Description

Lists Executive subsystems. List is returned in a QueryResults object.

Visual Basic

QueryResults = Executive.EnumSubSystems

C++

HRESULT pExecutive->EnumSubSystems ( LPSQLOLEQUERYRESULTS* ppQueryResults );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object

QueryResults

ColumnName | ColumnType

Value | SQLOLE_DTypeChar
Data | SQLOLE_DTypeChar


ListSubSystemTasks List

SQLServer.Executive Object

Description

Returns a list of Task objects for a specific subsystem.

Visual Basic

TaskList = Executive.ListSubSystemTasks ( [SubSystem :=] strSubSystem )

C++

HRESULT pExecutive->ListSubSystemTasks (
SQLOLE_LPCSTR strSubSystem,
LPSQLOLETASKLIST* ppDBObjectList );

Elements

Element | Type | Description

TaskList | TaskList | Returned list of Task objects
strSubSystem | String | Subsystem to list tasks of. Can be "Distribution", "LogReader", or "Sync".


Executive Collections

Executive Object Properties Methods Lists Collections

Property | Description

Properties Properties Write: No | The collection of Property objects.
Tasks Tasks Write: No | The collection of Task objects.


IntegratedSecurity Object

IntegratedSecurity Object Properties Methods Lists Collections

Description

The IntegratedSecurity object contains all the information about how SQL Server security and logins are integrated with Windows NT group and user accounts.


IntegratedSecurity Properties

IntegratedSecurity Object Properties Methods Lists Collections

Property | Description

Application Application Write: No | The Application object.
AuditLevel SQLOLE_AUDIT_TYPE Write: Yes | The audit level.
DefaultDomain String Write: Yes | The default Windows NT domain name used for trusted connections. For Windows NT user accounts from this domain, SQL Server uses the Windows NT username alone when attempting to find a matching SQL Server login. For Windows NT user accounts not from this DefaultDomain, SQL Server adds that user's Windows NT domain name and an underscore to the front of the Windows NT username when attempting to find a matching SQL Server login.
DefaultLogin Identifier Write: Yes | The default SQL Server login used for trusted connections when the Windows NT username does not match any of the existing SQL Server logins.
ImpersonateClient Boolean Write: Yes | Determines if xp_cmdshell impersonates the security context of the client connection. If True, xp_cmdshell runs in the security context of the client connection. If False, xp_cmdshell runs in the security context of the SQL Server. The default is False.
MapDollarSign String Write: Yes | Which one of several special characters in a Windows NT username is automatically mapped to a dollar sign ($) character in the SQL Server login. This value may be "domain separator", "space", "null", or any single character.
MapPoundSign String Write: Yes | Which one of several special characters in a Windows NT username is automatically mapped to a pound sign (#) character in the SQL Server login. This value may be "domain separator", "space", "null", or any single character.
MapUnderscore String Write: Yes | Which one of several special characters in a Windows NT username is automatically mapped to an underscore (_) character in the SQL Server login. This value may be "domain separator", "space", "null", or any single character.
Parent SQLServer Write: No | The SQLServer object.
SecurityMode SQLOLE_SECURITY_TYPE Write: Yes | The login security mode.
SetHostName Boolean Write: Yes | Determines if SQL Server uses the Windows NT username as the host name for trusted connections. If True, the host name is always the Windows NT username. If False, the host name is whatever value is specified by the client application.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


IntegratedSecurity Methods

IntegratedSecurity Object Properties Methods Lists Collections

GrantNTLogin

Refresh

RevokeNTLogin


GrantNTLogin Method

SQLServer.IntegratedSecurity Object

Description

Gives a Windows NT group or user account access to SQL Server.

Visual Basic

IntegratedSecurity.GrantNTLogin (
[Account :=] strAccount,
[[LoginType :=] tLoginType] )

C++

HRESULT pIntegratedSecurity->GrantNTLogin (
SQLOLE_LPCSTR strAccount,
SQLOLE_INTSECLOGIN_TYPE tLoginType =
SQLOLEIntSecLogin_User );

Elements

Element | Type | Description

strAccount | String | Windows NT group or user account
tLoginType | SQLOLE_INTSECLOGIN_TYPE | Login type

Reference

xp_grantlogin


Refresh Method

SQLServer.IntegratedSecurity Object

Description

Updates IntegratedSecurity properties with current values from SQL Server.

Visual Basic

IntegratedSecurity.Refresh

C++

HRESULT pIntegratedSecurity->Refresh ( );


RevokeNTLogin Method

SQLServer.IntegratedSecurity Object

Description

Revokes existing SQL Server access from a Windows NT group or user account access. The Windows NT group or user account must have previously been given access to SQL Server using the GrantNTLogin method.

Visual Basic

IntegratedSecurity.RevokeNTLogin ( [Account :=] strAccount )

C++

HRESULT pIntegratedSecurity->RevokeNTLogin ( SQLOLE_LPCSTR strAccount );

Elements

Element | Type | Description

strAccount | String | Windows NT group or user account

Reference

xp_revokelogin


IntegratedSecurity Lists

IntegratedSecurity Object Properties Methods Lists Collections

EnumAccountInfo

EnumNTDomainGroups


EnumAccountInfo List

SQLServer.IntegratedSecurity Object

Description

Lists information about a Windows NT group or user account and how it is used by SQL Server. List is returned in a QueryResults object.

Visual Basic

QueryResults = IntegratedSecurity.EnumAccountInfo (
[[Account :=] strAccount,]
[[ListAll :=] bListAll] )

C++

HRESULT pIntegratedSecurity->EnumAccountInfo ( LPSQLOLEQUERYRESULTS* ppQueryResults,
SQLOLE_LPCSTR strAccount = NULL,
BOOL bListAll = FALSE );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
strAccount | String | Windows NT group or user account
bListAll | Boolean | Determines if information is returned for all Windows NT groups

QueryResults

ColumnName | ColumnType

account name | SQLOLE_DTypeChar
type | SQLOLE_DTypeChar
privilege | SQLOLE_DTypeChar
mapped login name | SQLOLE_DTypeChar
permission path | SQLOLE_DTypeChar

Reference

xp_logininfo


EnumNTDomainGroups List

SQLServer.IntegratedSecurity Object

Description

Lists the Windows NT groups that are defined in a specified Windows NT domain. List is returned in a QueryResults object.

Visual Basic

QueryResults = IntegratedSecurity.EnumNTDomainGroups ( [[Domain :=] strDomain] )

C++

HRESULT pIntegratedSecurity->EnumNTDomainGroups ( LPSQLOLEQUERYRESULTS* ppQueryResults,
SQLOLE_LPCSTR strDomain = NULL );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
strDomain | String | Windows NT domain

QueryResults

ColumnName | ColumnType

group | SQLOLE_DTypeChar
comment | SQLOLE_DTypeChar

Reference

xp_enumgroups


IntegratedSecurity Collections

IntegratedSecurity Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Operator Object

Operator Object Properties Methods Lists Collections

Description

An Operator object contains all the information about a SQL Server operator.


Operator Properties

Operator Object Properties Methods Lists Collections

Property | Description

Application Application Write: No | The Application object.
EmailAddress String Write: Yes | The email name (address) for this operator.
Enabled Boolean Write: Yes | Determines if this operator is available to receive alert notifications. If True, this operator can receive notifications when an alert fires. If False, this operator will not receive any alert notifications.
ID Long Write: No | The operator ID.
LastEmailDate Date Write: No | The date and time this operator last received an email alert notification.
LastPageDate Date Write: No | The date and time this operator last received a pager alert notification.
Name String Write: Yes | The operator name.
PagerDays SQLOLE_WEEKDAY_TYPE Write: Yes | The days of the week during which this operator is available to receive a pager alert notification.
PagerAddress String Write: Yes | The pager email address.
Parent SQLServer Write: No | The SQLServer object.
SaturdayPagerEndTime Date Write: Yes | The time of day on Saturday before which this operator is available to receive a pager alert notification.
SaturdayPagerStartTime Date Write: Yes | The time of day on Saturday after which this operator is available to receive a pager alert notification.
SundayPagerEndTime Date Write: Yes | The time of day on Sunday before which this operator is available to receive a pager alert notification.
SundayPagerStartTime Date Write: Yes | The time of day on Sunday after which this operator is available to receive a pager alert notification.
WeekdayPagerEndTime Date Write: Yes | The time of day on a weekday (Monday through Friday) before which this operator is available to receive a pager alert notification.
WeekdayPagerStartTime Date Write: Yes | The time of day on a weekday (Monday through Friday) after which this operator is available to receive a pager alert notification.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Operator Methods

Operator Object Properties Methods Lists Collections

AddNotification

BeginAlter

CancelAlter

DoAlter

Refresh

Remove

RemoveNotification

UpdateNotification


AddNotification Method

SQLServer.Operator Object

Description

Adds a new alert to the list of alerts that notify this operator when the alert fires.

Visual Basic

Operator.AddNotification (
[AlertName :=] strAlert,
[NotifyMethod :=] tNotify )

C++

HRESULT pOperator->AddNotification (
SQLOLE_LPCSTR strAlert,
SQLOLE_NOTIFY_TYPE tNotify );

Elements

Element | Type | Description

strAlert | String | Alert that will notify this Operator when the alert fires
tNotify | SQLOLE_NOTIFY_TYPE | Type of notification to use

Reference

sp_addnotification


BeginAlter Method

SQLServer.Operator Object

Description

Marks the start of a single unit of changes to Operator properties. Normally, each change to a single property is a seperate update to SQL Server. To group multiple property changes into a single unit, first call the BeginAlter method, then make the desired property changes. To commit the unit of property changes to SQL Server using a single update, call the DoAlter method. To cancel the unit of property changes (made since calling BeginAlter), call the CancelAlter method.

Visual Basic

Operator.BeginAlter

C++

HRESULT pOperator->BeginAlter ( );


CancelAlter Method

SQLServer.Operator Object

Description

Cancels a unit of Operator property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will not be committed to SQL Server.

Visual Basic

Operator.CancelAlter

C++

HRESULT pOperator->CancelAlter ( );


DoAlter Method

SQLServer.Operator Object

Description

Commits a unit of Operator property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will be committed to SQL Server using a single update.

Visual Basic

Operator.DoAlter

C++

HRESULT pOperator->DoAlter ( );


Refresh Method

SQLServer.Operator Object

Description

Updates Operator properties with current values from SQL Server.

Visual Basic

Operator.Refresh

C++

HRESULT pOperator->Refresh ( );


Remove Method

SQLServer.Operator Object

Description

Drops the SQL Server operator and removes the Operator object.

Visual Basic

Operator.Remove

C++

HRESULT pOperator->Remove ( );

Remarks

You cannot remove an Operator who is the current AlertSystem.FailSafeOperator.

Reference

sp_dropoperator


RemoveNotification Method

SQLServer.Operator Object

Description

Removes an alert from the list of alerts that notify the Operator when the alert fires.

Visual Basic

Operator.RemoveNotification ( [AlertName :=] strAlert )

C++

HRESULT pOperator->RemoveNotification ( SQLOLE_LPCSTR strAlert );

Elements

Element | Type | Description

strAlert | String | Alert to remove

Reference

sp_dropnotification


UpdateNotification Method

SQLServer.Operator Object

Description

Updates the notification method of an alert that is already on the list of alerts that notify this Operator when the alert fires.

Visual Basic

Operator.UpdateNotification (
[AlertName :=] strAlert,
[NotifyMethod :=] tNotify )

C++

HRESULT pOperator->UpdateNotification (
SQLOLE_LPCSTR strAlert,
SQLOLE_NOTIFY_TYPE tNotify );

Elements

Element | Type | Description

strAlert | String | Alert that will notify this Operator when the alert fires
tNotify | SQLOLE_NOTIFY_TYPE | Type of notification to use

Reference

sp_updateoperator, sp_updatenotification


Operator Lists

Operator Object Properties Methods Lists Collections

EnumNotifications


EnumNotifications List

SQLServer.Operator Object

Description

Lists the alert notifications for this Operator. List is returned in a QueryResults object.

Visual Basic

QueryResults = Operator.EnumNotifications (
[NotifyMethod :=] tNotify,
[AlertsToEnum :=] tAlerts,
[[OperatorName :=] strAlert] )

C++

HRESULT pOperator->EnumNotifications (
SQLOLE_NOTIFY_TYPE tNotify,
SQLOLE_ENUMNOTIFY_TYPE tAlerts,
LPSQLOLEQUERYRESULTS* ppQueryResults,
SQLOLE_LPCSTR strAlert = NULL );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
tNotify | SQLOLE_NOTIFY_TYPE | Type of notification to list
tAlerts | SQLOLE_ENUMNOTIFY_TYPE | Which alerts to list
strAlert | String | Specific alert. This parameter is used only when tAlerts is SQLOLEEnumNotify_Target.

QueryResults

ColumnName | ColumnType

operator_id | SQLOLE_DTypeInt4
operator_name | SQLOLE_DTypeChar
use_email | SQLOLE_DTypeInt4
use_pager | SQLOLE_DTypeInt4
has_email | SQLOLE_DTypeBit
has_pager | SQLOLE_DTypeBit

Reference

sp_helpnotification


Operator Collections

Operator Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Registry Object

Registry Object Properties Collections

Description

The Registry object contains all of the information stored in the Windows NT Registry for a SQL Server.


Registry Properties

Registry Object Properties Collections

Property | Description

Application Application Write: No | The Application object.
AutostartLicensing Boolean Write: Yes | Determines if license logging is started automatically when SQL Server starts. If True, licensing is started automatically when SQL Server starts. If False, licensing must be started manually.
AutostartMail Boolean Write: Yes | Determines if Mail is started when SQL Server starts. If True, Mail is started automatically when SQL Server starts. If False, Mail must be started manually.
AutostartServer Boolean Write: Yes | Determines if SQL Server is started when Windows NT starts. If True, SQL Server is started automatically when Windows NT starts. If False, SQL Server must be started manually.
CaseSensitive Boolean Write: No | Indicates if SQL Server is case-sensitive. If True, SQL Server is using a case-sensitive sort order. If False, SQL Server is using a case-insensitive sort order.
CharacterSet String Write: No | Description of the character set and code page used by SQL Server.
ErrorLogPath String Write: Yes | The full path and file name of the SQL Server error log.
MailAccountName String Write: Yes | The Mail account name.
MailPassword String Write: Yes | The password for the Mail account specified by the MailAccountName property.
MasterDBPath String Write: Yes | The full path and file name of the database device that contains the MASTER database.
NTEventLogging Boolean Write: No | Indicates if Windows NT event logging is enabled. If True, SQL Server sends all events to the Windows NT event log as well as the SQL Server error log. If False, SQL Server sends events only to the SQL Server error log.
NumberOfProcessors Long Write: No | The number of processors on the SQL Server computer.
Parent SQLServer Write: No | The SQLServer object.
PerfMonMode SQLOLE_PERFMON_TYPE Write: Yes | The mode of the performance monitor.
PhysicalMemory Long Write: No | The total physical memory in megabytes on the SQL Server computer.
RegisteredOrganization String Write: No | The name of the organization provided when SQL Server was installed.
RegisteredOwner String Write: No | The name of the owner provided when SQL Server was installed.
SortOrder String Write: No | Description of the sort order used by SQL Server.
SQLRootPath String Write: Yes | The full path where SQL Server was installed.
TapeLoadWaitTime Long Write: Yes | The number of minutes SQL Server will wait when trying to read a tape that has not been loaded in the drive. A value of -1 means no wait timeout; SQL Server will not sop waiting. A value of 0 means SQL Server will only try once to access a tape in the drive..
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Registry Collections

Registry Object Properties Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Task Object

Task Object Properties Methods Lists Collections

Description

A Task object contains information about a scheduled task.


Task Properties

Task Object Properties Methods Lists Collections

Property | Description

ActiveEndDate Date Write: Yes | The date and time after which this task is active.
ActiveStartDate Date Write: Yes | The date and time before which this task is active.
Application Application Write: No | The Application object.
Command String Write: Yes | The Transact-SQL statement to execute for this task.
Database Identifier Write: Yes | Database to execute this task in.
DateCreated String Write: No | The date and time this task was created.
DateModified String Write: No | The date and time this task was last changed.
Description String Write: Yes | Description of this task.
EmailCompletionLevel SQLOLE_COMPLETION_TYPE Write: Yes | The task completion status which causes notification of the operator by email.
EmailOperator String Write: Yes | Mail address of operator for notifications.
Enabled Boolean Write: Yes | Determines if this task is active and enabled. If True, this task is active and will be fired when scheduled. If False, the task is disabled and will not be fired.
FrequencyInterval Long Write: Yes | The number of days between daily tasks, the day of the week for weekly tasks, or the day of the month for monthly tasks, on which this task will occur.
FrequencyRecurrenceFactor Long Write: Yes | The number of weeks between weekly tasks, or the number of months between monthly tasks.
FrequencyRelativeInterval SQLOLE_FREQRELATIVE_TYPE Write: Yes | The day of the month for monthly relative tasks, on which this task will occur.
FrequencySubDay SQLOLE_FREQSUB_TYPE Write: Yes | Within a specific day, the subday frequency unit of time, by minute or by hour.
FrequencySubDayInterval Long Write: Yes | The number of minutes between minutely tasks, or the number of hours between hourly tasks.
FrequencyType SQLOLE_FREQUENCY_TYPE Write: Yes | The primary frequency unit of time.
ID Long Write: No | The task ID.
LastRunCompletionLevel SQLOLE_COMPLETION_TYPE Write: No | The task completion status of the last execution of this task.
LastRunDate Date Write: No | The date and time this task was last executed.
LastRunDuration Long Write: No | The duration of the last execution of this task. Has the form HHHHMMSS, where HHHH is the number of hours, MM is the number of minutes, and SS is the number of seconds.
LastRunRetries Long Write: No | The number of retry attempts during the previous exection of this task.
LogHistoryCompletionLevel SQLOLE_COMPLETION_TYPE Write: Yes | The task completion status which causes task history information to be logged.
Name Identifier Write: Yes | Task name.
NextRunDate Date Write: No | The date and time this task will next execute.
Owner Identifier Write: No | The user who created this task.
Parent Executive Write: No | The Executive object.
RetryAttempts Long Write: Yes | The number of retries to attempt when a task execution fails.
RetryDelay Long Write: Yes | The delay in minutes between retry attempts.
RunPriority SQLOLE_RUNPRIORITY_TYPE Write: Yes | The Windows NT thread priority to use when executing this task.
SubSystem String Write: Yes | The subsystem used by a replication task. Can be "Distribution", "LogReader", or "Sync".
TagAdditionalInfo String Write: Yes | Temporary storage space contained in this object used by replication. For Task objects created by the application, this temporary storage space is available for private use by the application. SQL-DMO does not use this property.
TagObjectID Long Write: Yes | Temporary storage space contained in this object used by replication. For Task objects created by the application, this temporary storage space is available for private use by the application. SQL-DMO does not use this property.
TagObjectType Long Write: Yes | Temporary storage space contained in this object used by replication. For Task objects created by the application, this temporary storage space is available for private use by the application. SQL-DMO does not use this property.
TargetSQLServer Identifier Write: Yes | The SQL Server to execute this task on. For use with replication tasks only.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
User Identifer Write: Yes | The database user to use when executing this task.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Task Methods

Task Object Properties Methods Lists Collections

BeginAlter

CancelAlter

DoAlter

Invoke

PurgeHistory

Reassign

Refresh

Remove


BeginAlter Method

SQLServer.Executive.Task Object

Description

Marks the start of a single unit of changes to Task properties. Normally, each change to a single property is a separate update to SQL Server. To group multiple property changes into a single unit, first call the BeginAlter method, then make the desired property changes. To commit the unit of property changes to SQL Server using a single update, call the DoAlter method. To cancel the unit of property changes (made since calling BeginAlter), call the CancelAlter method.

Visual Basic

Task.BeginAlter

C++

HRESULT pTask->BeginAlter ( );


CancelAlter Method

SQLServer.Executive.Task Object

Description

Cancels a unit of Task property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will not be committed to SQL Server.

Visual Basic

Task.CancelAlter

C++

HRESULT pTask->CancelAlter ( );


DoAlter Method

SQLServer.Executive.Task Object

Description

Commits a unit of Task property changes previously marked with BeginAlter. All property changes made since calling BeginAlter will be committed to SQL Server using a single update.

Visual Basic

Task.DoAlter

C++

HRESULT pTask->DoAlter ( );


Invoke Method

SQLServer.Executive.Task Object

Description

Executes this task immediately.

Visual Basic

Task.Invoke

C++

HRESULT pTask->Invoke ( );


PurgeHistory Method

SQLServer.Executive.Task Object

Description

Purges the history for this task. Set the properties of a created HistoryFilter object as desired and pass it to the PurgeHistory method.

Visual Basic

Task.PurgeHistory ( [[HistoryFilter :=] HistoryFilter] )

C++

HRESULT pTask->PurgeHistory ( LPSQLOLEHISTORYFILTER HistoryFilter = NULL );

Elements

Element | Type | Description

HistoryFilter | HistoryFilter | HistoryFilter object

Reference

sp_purgehistory


Reassign Method

SQLServer.Executive.Task Object

Description

Assigns ownership of this Task to a new login.

Visual Basic

Task.Reassign ( [NewLogin :=] idLogin )

C++

HRESULT pTask->Reassign ( SQLOLE_LPCSTR idLogin );

Elements

Element | Type | Description

idLogin | Identifier | Login


Refresh Method

SQLServer.Executive.Task Object

Description

Updates Task properties with current values from SQL Server.

Visual Basic

Task.Refresh

C++

HRESULT pTask->Refresh ( );


Task Lists

Task Object Properties Methods Lists Collections

EnumHistory


EnumHistory List

SQLServer.Executive.Task Object

Description

Lists the event history for this task. List is returned in a QueryResults object. Set the properties of a created HistoryFilter object as desired and pass it to the EnumHistory method.

Visual Basic

QueryResults = Task.EnumHistory ( [[HistoryFilter :=] HistoryFilter] )

C++

HRESULT pTask->EnumHistory (
LPSQLOLEQUERYRESULTS* ppQueryResults,
LPSQLOLEHISTORYFILTER HistoryFilter = NULL );

Elements

Element | Type | Description

QueryResults | QueryResults | Returned QueryResults object
HistoryFilter | HistoryFilter | HistoryFilter object

QueryResults

ColumnName | ColumnType

id | SQLOLE_DTypeInt4
eventid | SQLOLE_DTypeInt4
messageid | SQLOLE_DTypeInt4
severity | SQLOLE_DTypeInt4
taskname | SQLOLE_DTypeChar
source | SQLOLE_DTypeChar
category | SQLOLE_DTypeChar
runstatus | SQLOLE_DTypeInt4
rundate | SQLOLE_DTypeInt4
runtime | SQLOLE_DTypeInt4
runduration | SQLOLE_DTypeInt4
reviewstatus | SQLOLE_DTypeChar
emailoperatorname | SQLOLE_DTypeChar
retries | SQLOLE_DTypeInt4
comments | SQLOLE_DTypeChar
timesskipped | SQLOLE_DTypeInt4

Reference

sp_helphistory


Task Collections

Task Object Properties Methods Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Chapter 7 Application Scope Objects

Application Scope Objects

Application Object

Backup Object

HistoryFilter Object

Names Object

Permission Object

Property Object

QueryResults Object


Application Object

Application Object Properties Methods Collections

Description

The Application object is a standard OLE object which provides common properties and methods for managing the application environment. Each SQL-DMO application has a single Application object.


Application Object Properties

Application Properties

Application Object Properties Methods Collections

Property | Description

Application Application Write: No | The Application object.
DBLibraryVersionString String Write: No | The DB-Library version string.
FullName String Write: No | The full path and filename of the SQL-DMO component object layer.
Name String Write: No | The name of the SQL-DMO component object layer.
Parent Application Write: No | The Application object.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.
VersionMajor Long Write: No | The SQL-DMO component object layer version number to the left of the decimal point.
VersionMinor Long Write: No | The SQL-DMO component object layer version number to the right of the decimal point.


Application Object Methods

Application Methods

Application Object Properties Methods Collections

Quit


Quit Method

Application Object

Description

Closes all connections used by SQLServer objects in the Application.SQLServers collection, and releases all existing SQL-DMO objects. This invalidates all object variables that refer to SQL-DMO objects. You cannot use or reference any SQL-DMO objects created before you called the Quit method. To continue using SQL-DMO objects after calling this method, you must create new SQL-DMO objects.

Visual Basic

Application.Quit

C++

HRESULT pApplication->Quit ( );


Backup Object

Backup Object Properties Collections

Description

A Backup object contains complete information used to perform a backup or restore of a Database or TransactionLog. First create a new Backup object, then set the properties to the appropriate values, and then pass the Backup object to the Dump, Load, or GenerateBackupSQL method of the Database or TransactionLog object, or the SQLServer.ReadBackupHeader method.


Backup Properties

Backup Object Properties Collections

Property | Description

Application Application Write: No | The Application object.
DiskDevices MultiString Write: Yes | Delimited list of hard disk device and volume specifiers. Each specifier consists of the full path and file name of the hard disk device, an equal sign, and an optional volume name.
DumpDevices MultiString Write: Yes | Delimited list of dump device and volume specifiers. Each specifier consists of the dump device name, an equal sign, and an optional volume name.
DumpExpirationDate String Write: String | The date and time when the disk or tape device expires. Any attempt to overwrite a dump before this date will fail.
DumpInitDeviceBefore Boolean Write: Yes | Determines if the disk or tape device is initialized before a dump is performed. If True, the dump starts at the beginning of the device, and any existing data on the device is overwritten. If False, the dump is appended to the end of the device. The default is False.
DumpRetainDays Long Write: Yes | The number of days after a dump has been performed to retain that dump. Any attempt to overwrite a dump before this number of days has elapsed will fail.
FloppyDevices MultiString Write: Yes | Delimited list of floppy disk device and volume specifiers. Each specifier consists of the full path and file name of the floppy disk device, an equal sign, and an optional volume name.
LoadFileNumber Long Write: Yes | The file to load from a tape or disk device.
LoadTableBatchPages Long Write: Yes | The number of data pages to load between transaction commits during the load of a single table. The default is 0.
Parent Application Write: No | The Application object.
SkipTapeHeader Boolean Write: Yes | Determines if the ANSI headers are skipped when dumping to or loading from a tape device. If True, ANSI tape headers are skipped. If False, ANSI tape headers are read. The default is False.
TapeDevices MultiString Write: Yes | Delimited list of tape device and volume specifiers. Each specifier consists of the full path and file name of the tape device, an equal sign, and an optional volume name.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UnloadTapeAfter Boolean Write: Yes | Determines if a tape is automatically rewound and unloaded when a dump or load completes. If True, the tape is automatically rewound and unloaded. If False, the tape is left alone. The default is False.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Backup Collections

Backup Object Properties Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


HistoryFilter Object

HistoryFilter Object Properties Collections

Description

The HistoryFilter object is used to qualify task history rows to list or purge. First create a new HistoryFilter object, then set the properties to the appropriate values, and then pass the HistoryFilter object to the EnumHistory or PurgeHistory method of the SQLServer or Task object.


HistoryFilter Properties

HistoryFilter Object Properties Collections

Property | Description

Application Application Write: No | The Application object.
CategoryName String Write: Yes | The event category name to include.
CompletionTypes SQLOLE_COMPLETION_TYPE Write: Yes | The types of task completions to include.
EndDate Date Write: Yes | The date and time before which to include tasks.
EventID Long Write: Yes | The event ID to include.
EventTypes SQLOLE_EVENT_TYPE Write: Yes | The types of task events to include.
MessageID Long Write: Yes | The message ID to include.
MinimumRetries Long Write: Yes | The minimum number of retry attempts made for a task.
MinimumRunDuration Date Write: Yes | The minimum length of time a task took to complete.
MinimumTimesSkipped Long Write: Yes | The minimum number of times a task was skipped.
OldestFirst Boolean Write: Yes | Determines if the list is sorted by the ascending time of task occurrence. If True, the oldest task is listed first. If False, the newest task is listed first.
Parent Application Write: No | The Application object.
Severity Long Write: Yes | The severity to include.
Source String Write: Yes | The event source to include.
StartDate Date Write: Yes | The date and time after which to include tasks.
TaskID Long Write: Yes | The task ID to include. If you are not the system administrator and you are passing this to SQLServer.PurgeHistory, you must specify a task and you must be its owner.
TaskName Identifier Write: Yes | The name of the task to include. If you are not the system administrator and you are passing this to SQLServer.PurgeHistory, you must specify a task and you must be its owner.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


HistoryFilter Collections

HistoryFilter Object Properties Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Names Object

Names Object Properties Methods

Description

A Names collection contains strings instead of objects.


Names Properties

Names Object Properties Methods

Property | Description

Application Application Write: No | The Application object.
Parent Object Write: No | The Object object, where Object is the parent object.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Names Methods

Names Object Properties Methods

The Names collection has the following standard SQL-DMO collection methods that operate on strings instead of objects:

Visual Basic | C++

Add | Add
Remove | RemoveByName, RemoveByOrd
Refresh | Refresh

The Names collection has the following additional methods:

FindName

Insert

Replace


FindName Method

Names Object

Description

Returns the ordinal value of a string in the Names collection.

Visual Basic

lOrdinal = Names.FindName ( [Name :=] strName )

C++

HRESULT pNames->FindName (
SQLOLE_LPCSTR szName,
LPLONG plOrdinal );

Elements

Element | Type | Description

lOrdinal | Long | Returned ordinal value into the collection. For Visual Basic the first ordinal value is number 1. For C++ the first ordinal value is 0.
strName | String | String to find.


Insert Method

Names Object

Description

Inserts a new string into the Names collection.

Visual Basic

Names.Insert (
[NewName :=] strName,
[InsertBeforeItem :=] {strBeforeName | lBeforeOrdinal} )

C++

HRESULT pNames->InsertByName (
SQLOLE_LPCSTR strName,
SQLOLE_LPCSTR strBeforeName );

HRESULT pNames->InsertByOrd (
SQLOLE_LPCSTR strName,
long lBeforeOrdinal );

Elements

Element | Type | Description

strName | String | New string to insert into Names collection.
strBeforeName | String | Name before which the new string is inserted. If empty, the new string is added as the last string in the Names collection.
lBeforeOrdinal Long Ordinal value into the collection of the Name before which the new Name is inserted.

For Visual Basic the first ordinal value is number 1. If 0 is specified, the new string is added as the last string in the Names collection.

For C++ the first ordinal value is 0. If -1 is specified, the new string is added as the last string in the Names collection.

Remarks

For the Configuration.Parameters Names collection, new strings are always inserted as the last string in the collection.


Replace Method

Names Object

Description

Replaces an existing string in the Names collection.

Visual Basic

Names.Replace (
[NewName :=] strName,
[ReplaceItem :=] {strReplaceName | lReplaceOrdinal} )

C++

HRESULT pNames->ReplaceByName (
SQLOLE_LPCSTR strName,
SQLOLE_LPCSTR strReplaceName );

HRESULT pNames->ReplaceByOrd (
SQLOLE_LPCSTR strName,
long lReplaceOrdinal );

Elements

Element | Type | Description

strName | String | New string to insert into Names collection.
strReplaceName | String | String to replace.
lReplaceOrdinal | Long | Index into the Names collection of the Name to replace. For Visual Basic the first ordinal value is number 1. For C++ the first ordinal value is 0.


Permission Object

Permission Object Properties Lists Collections

Description

A Permission object contains information about a database user's object or statement privileges. It is returned by various ListItemPermissions methods of various objects.


Permission Properties

Permission Object Properties Lists Collections

Property | Description

Application Application Write: No | The Application object.
Granted Boolean Write: No | Indicates if the privilege was granted. If True, this privilege is granted. If False, the privilege is revoked.
Grantee Identifier Write: No | The database user or group this privilege applies to.
ObjectID Long Write: No | The object ID this privilege applies to.
ObjectName Identifier Write: No | The object name this privilege applies to.
ObjectOwner Identifier Write: No | The database user that owns the object this privilege applies to.
ObjectType SQLOLE_OBJECT_TYPE Write: No | The type of the object this privilege applies to.
ObjectTypeName String Write: No | The name of the type of the object this privilege applies to.
Parent Application Write: No | The Application object.
PrivilegeType SQLOLE_PRIVILEGE_TYPE Write: No | The type of privilege.
PrivilegeTypeName String Write: No | The name of the privilege type.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


Permission Lists

Permission Object Properties Lists Collections

ListPrivilegeColumns


ListPrivilegeColumns List

Permission Object

Description

Returns a list of Column objects included in SELECT or UPDATE privileges for a table or view, if this Privilege object is of that type.

Visual Basic

ColumnList = Permission.ListPrivilegeColumns

C++

HRESULT pPermission->ListPrivilegeColumns ( LPSQLOLECOLUMNLIST* ppColumnList );

Elements

Element | Type | Description

ColumnList | ColumnList | Returned list of Column objects


Permission Collections

Permission Object Properties Lists Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Property Object

Property Object Properties Collections

Description

A Property object contains information about a property of a SQL-DMO object. Each SQL-DMO object (not including collections) has a Properties collection that contains one Property object for each property (not including object properties or indexed properties) of the SQL-DMO object.

The Property object and the Properties collections are only available to Visual Basic programs and other OLE Automation controllers. They are not available to C++ programs.


Property Properties

Property Object Properties Collections

Property | Description

Application Application Write: No | The Application object.
Get Boolean Write: No | Indicates if this property can ever be read. If True, this property value can be read, but it might not be readable now. If False, this property value can never be read.
Name String Write: No | The name of the property.
Parent Object Write: No | The Object object, where Object is the parent object.
Set Boolean Write: No | Indicates if this property can ever be changed. If True, this property value can be changed, but it might not be changeable now. If False, this property value can never be changed.
Type Long Write: No | The Visual Basic type of the property.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.
Value Datatype Write: Yes | The current property value, where Datatype is the datatype of the property.


Property Collections

Property Object Properties Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


QueryResults Object

QueryResults Object Properties Methods Collections

Description

A QueryResults object contains the result set from an executed Transact-SQL query. All EnumItems list methods return a QueryResults object. The ExecuteWithResults method of the SQLServer, Database, and RemoteServer objects also returns a QueryResults object. The query results returned from SQL Server are stored in memory and cannot be changed.

To retrieve data from a specific result set, set the CurrentResultSet property to the desired result set. Then call the desired GetColumnDatatype method to get a value from a single column of a single row, or call the GetRangeString method to return a block of row and column data.


QueryResults Properties

QueryResults Object Properties Methods Collections

Property | Description

Application Application Write: No | The Application object.
Columns Long Write: No | The number of columns in the current result set.
CurrentResultSet Long Write: Yes | The current result set. The first result set is number 1. Set this property to change the current result set.
Parent Application Write: No | The Application object.
ResultSets Long Write: No | The number of result sets.
Rows Long Write: No | The number of rows in the current result set.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


QueryResults Methods

QueryResults Object Properties Methods Collections

ColumnMaxLength

ColumnName

ColumnType

GetColumnBool

GetColumnDouble

GetColumnFloat

GetColumnLong

GetColumnString

GetRangeString

Refresh


ColumnMaxLength Method

QueryResults Object

Description

Returns the maximum length of a column in the current result set.

Visual Basic

lMaxLength = QueryResults.ColumnMaxLength ( [Column :=] lColumn )

C++

HRESULT pQueryResults->GetColumnMaxLength (
long lColumn,
LPLONG plMaxLength );

Elements

Element | Type | Description

lMaxLength | Long | Returned maximum column length
plColumn | Long | Column number of the current result set

Remarks

This is an indexed property.


ColumnName Method

QueryResults Object

Description

Returns the name of a column in the current result set.

Visual Basic

strName = QueryResults.ColumnName ( [Column :=] lColumn )

C++

HRESULT pQueryResults->GetColumnName (
long lColumn,
SQLOLE_LPBSTR strName );

Elements

Element | Type | Description

strName | String | Returned column name
lColumn | Long | Column number of the current result set

Remarks

This is an indexed property.


ColumnType Method

QueryResults Object

Description

Returns the datatype of a column in the current result set.

Visual Basic

tDatatype = QueryResults.ColumnType ( [Column :=] lColumn )

C++

HRESULT pQueryResults->GetColumnType (
long lColumn,
SQLOLE_QUERY_DATATYPE* tDatatype );

Elements

Element | Type | Description

tDatatype | QueryDatatype | Returned column datatype
lColumn | Long | Column number of the current result set

Remarks

This is an indexed property.


GetColumnBool Method

QueryResults Object

Description

Returns the data, converted to a boolean value, in a column of a row in the current result set.

Visual Basic

bColumnData = QueryResults.GetColumnBool (
[Row :=] lRow,
[Column :=] lColumn )

C++

HRESULT pQueryResults->GetColumnBool (
long lRow,
long lColumn,
LPBOOL pbColumnData );

Elements

Element | Type | Description

bColumnData | Boolean | Returned column data
lRow | Long | Row number of the current result set
lColumn | Long | Column number of the specified row


GetColumnDouble Method

QueryResults Object

Description

Returns the data, converted to a double value, in a column of a row in the current result set.

Visual Basic

dColumnData = QueryResults.GetColumnDouble (
[Row :=] lRow,
[Column :=] lColumn )

C++

HRESULT pQueryResults->GetColumnDouble (
long lRow,
long lColumn,
LPDOUBLE pdColumnData );

Elements

Element | Type | Description

dColumnData | Double | Returned column data
lRow | Long | Row number of the current result set
lColumn | Long | Column number of the specified row


GetColumnFloat Method

QueryResults Object

Description

Returns the data, converted to a float value, in a column of a row in the current result set.

Visual Basic

fColumnData = QueryResults.GetColumnFloat (
[Row :=] lRow,
[Column :=] lColumn )

C++

HRESULT pQueryResults->GetColumnFloat (
long lRow,
long lColumn,
LPFLOAT pfColumnData );

Elements

Element | Type | Description

fColumnData | Float | Returned column data
lRow | Long | Row number of the current result set
lColumn | Long | Column number of the specified row


GetColumnLong Method

QueryResults Object

Description

Returns the data, converted to a long value, in a column of a row in the current result set.

Visual Basic

lColumnData = QueryResults.GetColumnLong (
[Row :=] lRow,
[Column :=] lColumn )

C++

HRESULT pQueryResults->GetColumnLong (
long lRow,
long lColumn,
LPLONG plColumnData );

Elements

Element | Type | Description

lColumnData | Long | Returned column data
lRow | Long | Row number of the current result set
lColumn | Long | Column number of the specified row


GetColumnString Method

QueryResults Object

Description

Returns the data, converted to a string value, in a column of a row in the current result set.

Visual Basic

strColumnData = QueryResults.GetColumnString (
[Row :=] lRow,
[Column :=] lColumn )

C++

HRESULT pQueryResults->GetColumnString (
long lRow,
long lColumn,
SQLOLE_LPBSTR pstrColumnData );

Elements

Element | Type | Description

strColumnData | String | Returned column data
lRow | Long | Row number of the current result set
lColumn | Long | Column number of the specified row


GetRangeString Method

QueryResults Object

Description

Returns a single string containing a block of rows and columns from the current result set.

Visual Basic

strOutput = QueryResults->GetRangeString (
[[Top :=] lTop,]
[[Left :=] lLeft,]
[[Bottom :=] lBottom,]
[[Right :=] lRight,]
[[RowDelim :=] strRowDelimiter,]
[[ColDelim :=] strColumnDelimiter,]
[[ColWidths :=] mstrColumnWidthList] )

C++

HRESULT pQueryResults->GetRangeString (
SQLOLE_LPBSTR pstrOutput,
long lTop = 0,
long lLeft = 1,
long lBottom = -1,
long lRight = -1,
SQLOLE_LPCSTR strRowDelimiter = NULL,
SQLOLE_LPCSTR strColumnDelimiter = NULL,
SQLOLE_LPCSTR mstrColumnWidthList = NULL );

Elements

Element | Type | Description

strOutput | String | Returned block of rows and columns from the current result set.
lTop | Long | First row to return.
lLeft | Long | First column to return.
lBottom | Long | Last row to return.
lRight | Long | Last column to return.
strRowDelimiter | String | String placed between each row. The default is the newline string.
strColumnDelimiter | String | String placed between each column. The default is the tap character.
mstrColumnWidthList | MultiString | Delimited list of column width values. For a given column, data shorter than the specified width will be padded with spaces to fill the entire width, and data longer than the specified width will be truncated to the width. If the number of width values is greater than the number of columns requested, the extra width values are ignored. If the number of width values is less than the number of columns requested, the default width values will be used for the last columns.


Refresh Method

QueryResults Object

Description

Updates QueryResults data with current values from SQL Server by reexecuting the Transact-SQL query.

Visual Basic

QueryResults.Refresh

C++

HRESULT pQueryResults->Refresh ( );


QueryResults Collections

QueryResults Object Properties Methods Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.


Chapter 8 Enumerated Datatypes

Enumerated Datatypes

SQLOLE_AUDIT_TYPE

SQLOLE_COMPLETION_TYPE

SQLOLE_CONFIGVALUE_TYPE

SQLOLE_COPYDATA_TYPE

SQLOLE_DATAFILE_TYPE

SQLOLE_DBSTATUS_TYPE

SQLOLE_DBUSERPROFILE_TYPE

SQLOLE_DEPENDENCY_TYPE

SQLOLE_DEVICE_TYPE

SQLOLE_ENUMNOTIFY_TYPE

SQLOLE_ERROR_TYPE

SQLOLE_EVENT_TYPE

SQLOLE_EXEC_TYPE

SQLOLE_FREQRELATIVE_TYPE

SQLOLE_FREQSUB_TYPE

SQLOLE_FREQUENCY_TYPE

SQLOLE_INDEX_TYPE

SQLOLE_INITIALSYNC_TYPE

SQLOLE_INTSECLOGIN_TYPE

SQLOLE_KEY_TYPE

SQLOLE_MEDIA_TYPE

SQLOLE_MIRROR_TYPE

SQLOLE_MONTHDAY_TYPE

SQLOLE_NOTIFY_TYPE

SQLOLE_OBJECT_TYPE

SQLOLE_OBJSORT_TYPE

SQLOLE_PERFMON_TYPE

SQLOLE_PREARTICLE_TYPE

SQLOLE_PRIVILEGE_TYPE

SQLOLE_PROCEDURE_TYPE

SQLOLE_QUERY_DATATYPE

SQLOLE_REPFREQ_TYPE

SQLOLE_REPLICATION_TYPE

SQLOLE_RUNPRIORITY_TYPE

SQLOLE_SCRIPT_TYPE

SQLOLE_SECURITY_TYPE

SQLOLE_SRVOPTION_TYPE

SQLOLE_SRVUSERPROFILE_TYPE

SQLOLE_STARTSRV_TYPE

SQLOLE_STATUSINFO_TYPE

SQLOLE_SUBSTATUS_TYPE

SQLOLE_SUBSYNC_TYPE

SQLOLE_SVCSTATUS_TYPE

SQLOLE_TABLEATT_TYPE

SQLOLE_TRIGGER_TYPE

SQLOLE_VERIFYCONN_TYPE

SQLOLE_WEEKDAY_TYPE


SQLOLE_AUDIT_TYPE

Values

SQLOLEAudit_None
SQLOLEAudit_Success
SQLOLEAudit_Failure
SQLOLEAudit_All


SQLOLE_COMPLETION_TYPE

Values

SQLOLEComp_Unknown
SQLOLEComp_None
SQLOLEComp_Success
SQLOLEComp_Failure
SQLOLEComp_Always
SQLOLEComp_Running
SQLOLEComp_Aborted
SQLOLEComp_Skipped
SQLOLEComp_All


SQLOLE_CONFIGVALUE_TYPE

Values

SQLOLEConfig_RecoveryInterval
SQLOLEConfig_AllowUpdates
SQLOLEConfig_UserConnections
SQLOLEConfig_Memory
SQLOLEConfig_OpenDatabases
SQLOLEConfig_Locks
SQLOLEConfig_OpenObjects
SQLOLEConfig_ProcedureCache
SQLOLEConfig_FillFactor
SQLOLEConfig_DatabaseSize
SQLOLEConfig_MediaRetention
SQLOLEConfig_RecoveryFlags
SQLOLEConfig_NestedTriggers
SQLOLEConfig_RemoteAccess
SQLOLEConfig_DefaultLanguage
SQLOLEConfig_LanguageInCache
SQLOLEConfig_TempdbInRamMB
SQLOLEConfig_MaxAsyncIO
SQLOLEConfig_MaxWorkerThreads
SQLOLEConfig_NetworkPacketSize
SQLOLEConfig_RAWorkerThreads
SQLOLEConfig_ShowAdvancedOption
SQLOLEConfig_LEThresholdPercent
SQLOLEConfig_LEThresholdMaximum
SQLOLEConfig_BackupThreads
SQLOLEConfig_BackupBufferSize
SQLOLEConfig_TimeSlice
SQLOLEConfig_RemoteSites
SQLOLEConfig_DefaultSortorderId
SQLOLEConfig_HashBuckets
SQLOLEConfig_SortPages
SQLOLEConfig_MaxLazywriteIO
SQLOLEConfig_RASlotsPerThread
SQLOLEConfig_RAPrefetches
SQLOLEConfig_RADelay
SQLOLEConfig_RACacheMissLimit
SQLOLEConfig_RACacheHitLimit
SQLOLEConfig_SpinCounter
SQLOLEConfig_FreeBuffers
SQLOLEConfig_SMPConcurrency
SQLOLEConfig_PriorityBoost
SQLOLEConfig_RemoteLoginTimeout
SQLOLEConfig_RemoteQueryTimeout
SQLOLEConfig_LEThresholdMinimum
SQLOLEConfig_LogwriteSleepMS
SQLOLEConfig_SetWorkingSetSize


SQLOLE_DATAFILE_TYPE

Values

SQLOLEDataFile_Default
SQLOLEDataFile_CommaDelimitedChar
SQLOLEDataFile_TabDelimitedChar
SQLOLEDataFile_SpecialDelimitedChar
SQLOLEDataFile_NativeFormat


SQLOLE_DBSTATUS_TYPE

Values

SQLOLEDBStat_Normal
SQLOLEDBStat_Loading
SQLOLEDBStat_Recovering
SQLOLEDBStat_Suspect
SQLOLEDBStat_Offline
SQLOLEDBStat_Inaccessible
SQLOLEDBStat_EmergencyMode
SQLOLEDBStat_All


SQLOLE_DBUSERPROFILE_TYPE

Values

SQLOLEDbUserProf_None
SQLOLEDbUserProf_DboLogin
SQLOLEDbUserProf_CreateTable
SQLOLEDbUserProf_CreateView
SQLOLEDbUserProf_CreateProcedure
SQLOLEDbUserProf_DumpDatabase
SQLOLEDbUserProf_CreateDefault
SQLOLEDbUserProf_DumpTransaction
SQLOLEDbUserProf_CreateRule
SQLOLEDbUserProf_AllProfileBits
SQLOLEDbUserProf_InvalidLogin
SQLOLEDbUserProf_InaccessibleDb
SQLOLEDbUserProf_DbNotAvailable


SQLOLE_DEPENDENCY_TYPE

Values

SQLOLEDep_Parents
SQLOLEDep_FullHierarchy
SQLOLEDep_OrderDescending
SQLOLEDep_Children
SQLOLEDep_ReturnInputObject
SQLOLEDep_FirstLevelOnly
SQLOLEDep_DRIOnly
SQLOLEDep_Valid


SQLOLE_DEVICE_TYPE

Values

SQLOLEDevice_Unknown
SQLOLEDevice_Database
SQLOLEDevice_DiskDump
SQLOLEDevice_FloppyADump
SQLOLEDevice_FloppyBDump
SQLOLEDevice_TapeDump
SQLOLEDevice_Reserved
SQLOLEDevice_CDROM


SQLOLE_ENUMNOTIFY_TYPE

Values

SQLOLEEnumNotify_Min
SQLOLEEnumNotify_All
SQLOLEEnumNotify_Actual
SQLOLEEnumNotify_Target
SQLOLEEnumNotify_Max


SQLOLE_ERROR_TYPE

Values

SQLOLE_E_DBLIBFIRSTERROR |
SQLOLE_E_DBLIBLASTERROR |
SQLOLE_E_FIRSTERROR |
SQLOLE_ECAT_MASK |
SQLOLE_ECAT_ INVALIDCONTEXT |
SQLOLE_E_ALREADYCONN | This server object is already connected.
SQLOLE_E_ALREADYCOLL | This object is already in a collection.
SQLOLE_E_NOTCONN | This server object is not connected.
SQLOLE_E_CANTDROPSERVER | You cannot drop a server. Use Server.Close when the object is no longer needed.
SQLOLE_E_NOCOMPLEXALTER | Modifying or removing existing table columns, or inserting new ones prior to end of table, is not supported.
SQLOLE_E_PROPNEEDSCREATE | This property or method is not available until the object (or its parent if appropriate) has been added to a collection.
SQLOLE_E_COLTYPEFIXED | Column type '%s' is fixed length; no length may be specified.
SQLOLE_E_COLTYPENONNULL | Column type '%s' may not be specified to allow NULL values.
SQLOLE_E_CANTCHANGEUDDT | Cannot change the base type, length, or nullability of an existing User-defined datatype.
SQLOLE_E_BASETYPEFIXED | Base datatype '%s' is fixed length; no length may be specified.
SQLOLE_E_BASETYPENONNULL | Base datatype '%s' may not be specified to allow NULL values.
SQLOLE_E_ENUMORDINAL | This is an enumeration-only list object and must be indexed by ordinal.
SQLOLE_E_CANTRENAMEUSER | Existing User's User name and Login name cannot be changed.
SQLOLE_E_ CANTRENAMEGROUP | Existing Group name cannot be changed.
SQLOLE_E_ CANTRENAMELOGIN | Existing Login's name cannot be changed.
SQLOLE_E_ CANTRENAMEDEVICE | Existing Device's name, type, size, physical location, or label skipping cannot be changed.
SQLOLE_E_NOTDUMPPROP | This property or method cannot be used with a dump device.
SQLOLE_E_NOSERVERASSOC | No server has been associated with this object.
SQLOLE_E_NOTCOLLTYPE | This object type does not match the collection's type. It cannot be added.
SQLOLE_E_ CANTMODIFYDRIINDEX | This index was generated by a DRI 'PRIMARY KEY' or 'UNIQUE KEY' CONSTRAINT and cannot be modified or dropped.
SQLOLE_E_ CANTCHANGEPROCTYPE | Existing StoredProcedure type cannot be changed.
SQLOLE_E_ CANTMODIFYINDEX | This property or method cannot be set or invoked after the index has been created.
SQLOLE_E_INVALIDPRIVOBJ | This object type cannot have granted privileges.
SQLOLE_E_ CANTCHANGETRIGTYPE | Existing trigger type cannot be changed.
SQLOLE_E_NOVIEWCOLALTER | Columns of a view cannot be modified. The base corresponding base table's column must be used.
SQLOLE_E_ CANTRENAMELANGUAGE | Existing language's name, months, short months, days, dateformat, and first day of week cannot be changed.
SQLOLE_E_ CANTRENAMERSERVER | Existing Remote Server's name cannot be changed.
SQLOLE_E_ CANTRENAMERLOGIN | Existing Remote Login's local name and remote name cannot be changed.
SQLOLE_E_MUSTBEDBDEV | This method or property can only be used with a database device.
SQLOLE_E_ NOINACTIVEMIRROR | This device has no inactive mirror.
SQLOLE_E_NOACTIVEMIRROR | This device has no active mirror.
SQLOLE_E_NOMIRROR | This device has no active or inactive mirror.
SQLOLE_E_ SERVERDISCONNECTED | This server has been DisConnected. You must ReConnect to perform this operation.
SQLOLE_E_ CANTRENAMESERVER | You cannot change the name, login, password, login timeout, login security, or network packet size for a server object while it is connected.
SQLOLE_E_CANTMODIFYTEXT | Modifying the text of an existing Rule, Default, Stored Procedure, View, or Trigger is not allowed. You must drop and recreate the object.
SQLOLE_E_ CANTMODIFYSYSTABLE | System tables cannot be altered, dropped, or otherwise modified.
SQLOLE_E_ LOGINALREADYALIASED | The Login '%s' is already aliased to user '%s' in this database.
SQLOLE_E_ LOGINALREADYUSER | The Login '%s' is already assigned to user '%s' in this database.
SQLOLE_E_CACHENORESULTS | This cache contains no result sets, or the current result set contains no rows.
SQLOLE_E_ALREADYCREATED | This object has already been created.
SQLOLE_E_NOTDISCONN | This server is already Connected.
SQLOLE_E_ CANTMODIFYARTTABLE | You cannot change the Source Table of an existing Article.
SQLOLE_E_ CANTMODIFYSUBSERVER | You cannot change the Subscribing Server of an existing Subscription.
SQLOLE_E_ BASETYPENOTNUMERIC | Base datatype '%s' is not a numeric type; no precision or scale may be specified.
SQLOLE_E_ TOFILEBUTNOFILENAME | ScriptMode specified as ToFileOnly, but no filename specified -- recheck parameters.
SQLOLE_E_ MUSTBEDISTSERVER | The distribution server is either undefined or not the current server, so the Distribution Working Directory cannot be set.
SQLOLE_E_CANTMODIFYKEY | You cannot modify an existing Key's Clustered, FillFactor, or ReferencedTable properties.
SQLOLE_E_LISTCANTREFRESH | This object list cannot be refreshed; you must Release it and re-invoke the method which returned it.
SQLOLE_E_NOCOLTABLE | This column object is not associated with a table.
SQLOLE_E_MUSTBEINALTER | Modifying this property can only be done when the table is in Alter mode (BeginAlter has been called).
SQLOLE_E_ CANTUNDEDICATELOGDEVICE | Cannot undedicate a dedicated log device in this version of SQL Server.
SQLOLE_ECAT_ INVALIDOBJECT |
SQLOLE_E_OBJECTDROPPED | This object has been dropped from the server.
SQLOLE_E_NOTSQLOLEOBJECT | The passed object is not a SQLOLE object.
SQLOLE_E_OBJECTDETACHED | This object has been detached from SQLOLE, as the result of a refresh, automatic shutdown, error, or App.Quit.
SQLOLE_E_SERVERCLOSED | This server object has been Closed. It can no longer be used.
SQLOLE_ECAT_ INVALIDOBJECTDEFINITION |
SQLOLE_E_ NOCOLUMNSADDED | No new columns or constraints have been added to this table object
SQLOLE_E_ COLUMNINCOMPLETE | Column definition must include name, datatype, length if appropriate to datatype, and null specification if adding to an existing table.
SQLOLE_E_TABLEINCOMPLETE | Table name not specified.
SQLOLE_E_UDDTINCOMPLETE | Datatype definition must include name, base datatype, and length if appropriate to base datatype.
SQLOLE_E_RULEINCOMPLETE | Rule definition must include name and text of rule.
SQLOLE_E_ DEFAULTINCOMPLETE | Default definition must include name and text of default.
SQLOLE_E_VIEWINCOMPLETE | View definition must include name and text of view.
SQLOLE_E_USERINCOMPLETE | User's Login name not specified.
SQLOLE_E_GROUPINCOMPLETE | Group name not specified.
SQLOLE_E_PROCINCOMPLETE | Stored procedure definition must include name and text (for Standard StoredProcedure) or libraryname (for Extended StoredProcedure).
SQLOLE_E_ USERALREADYEXISTS | User '%s' already exists.
SQLOLE_E_ GROUPALREADYEXISTS | Group '%s' already exists.
SQLOLE_E_ COLUMNALREADYEXISTS | Column '%s' already exists.
SQLOLE_E_ OBJECTALREADYEXISTS | User '%s' already owns an object named '%s' in this database.
SQLOLE_E_ INDEXALREADYEXISTS | Index '%s' on table '%s' already exists.
SQLOLE_E_DBALREADYEXISTS | Database '%s' already exists.
SQLOLE_E_ LOGINALREADYEXISTS | Login '%s' already exists.
SQLOLE_E_ DEVICEALREADYEXISTS | Device '%s' already exists.
SQLOLE_E_SKIPONLYTAPE | Skip option is only valid for tape dump devices.
SQLOLE_E_ DEVICEINCOMPLETE | Device definition must include logical name, physical name, device type, and size if defining a database device.
SQLOLE_E_ PROCALREADYEXISTS | StoredProcedure '%s' already exists.
SQLOLE_E_ UDDTALREADYEXISTS | UserDefinedDatatype '%s' already exists.
SQLOLE_E_ TABLEALREADYEXISTS | Table '%s' already exists.
SQLOLE_E_ RULEALREADYEXISTS | Rule '%s' already exists.
SQLOLE_E_ DEFAULTALREADYEXISTS | Default '%s' already exists.
SQLOLE_E_ VIEWALREADYEXISTS | View '%s' already exists.
SQLOLE_E_INDEXINCOMPLETE | Index definition must include a name and at least one column to index.
SQLOLE_E_TRIGINCOMPLETE | Trigger definition must include name and text.
SQLOLE_E_ TRIGALREADYEXISTS | Trigger '%s' on table '%s' already exists.
SQLOLE_E_ LANGUAGEINCOMPLETE | Language definition must include name, months, shortmonths, and days.
SQLOLE_E_ LANGUAGEALREADYEXISTS | Language '%s' already exists.
SQLOLE_E_LOGININCOMPLETE | Login name not specified.
SQLOLE_E_ RSERVERINCOMPLETE | Remote Server name not specified.
SQLOLE_E_ RSERVERALREADYEXISTS | Remote Server '%s' already exists.
SQLOLE_E_ NULLRLOGINALREADYEXISTS | A NULL Remote Login already exists for this Remote Server.
SQLOLE_E_ RLOGINALREADYEXISTS | A Remote Login with the remote name '%s' already exists for this Remote Server.
SQLOLE_E_ REMOTENEEDSLOCAL | A Remote Login's Remote Name cannot be specified without also specifying a Local Name.
SQLOLE_E_ BACKUPNEEDSDEVICE | You must specify a backup device for Dump or Load.
SQLOLE_E_ NEEDMANUALFILTERNAME | Specifying the ManualSyncView ReplicationType requires supplying the name of an existing (manually-created) view.
SQLOLE_E_TASKINCOMPLETE | You must specify a task name.
SQLOLE_E_ARTINCOMPLETE | Article definition must include Article name and the name of the Table being published.
SQLOLE_E_PUBINCOMPLETE | Publication definition must include Publication name.
SQLOLE_E_SUBINCOMPLETE | Subscription definition must include the subscribing Remote Server's name.
SQLOLE_E_ALERTINCOMPLETE | Alert definition must include name.
SQLOLE_E_ OPERATORINCOMPLETE | Operator definition must include name.
SQLOLE_E_NAMEMUSTMATCH | The name specified in the Text property's 'CREATE ...' statement must match the Name property, and must be followed by valid TSQL statements.
SQLOLE_E_ TRIGREQTABLENAME | You must specify the Parent Table's name in the Text property's 'CREATE...' statement.
SQLOLE_E_MUSTBESYNCTASK | Tasks created as a Publication's InitialSyncTask must have a 'SYNC' SubSystem.
SQLOLE_E_ NOEVENTCOMPLETION | Either of the EventTypes or CompletionTypes properties may be set, but not both.
SQLOLE_E_FKEYINCOMPLETE | Foreign Key definition must include a referenced Table name and list of columns in the referenced Table which matches the number of columns in the Key Table.
SQLOLE_E_KEYINCOMPLETE | DRI Key definition must include key type and a list of columns in the key.
SQLOLE_E_ KEYALREADYEXISTS | A Key with this name already exists on this table.
SQLOLE_E_CHECKINCOMPLETE | DRI Check definition must include text of the data validation.
SQLOLE_E_ DRIDEFAULTINCOMPLETE | DRI Default definition must include text of the data value, which may be '' (a blank string) for NULL.
SQLOLE_E_ CHECKALREADYEXISTS | A Check with this name already exists on this table.
SQLOLE_E_ ONLYONEPRIMARYKEY | There is already a primary key in this table's key collection.
SQLOLE_E_ NEEDMANUALVIEWNAME | Specifying the ManualFilterProc ReplicationType requires supplying the name of an existing (manually-created) stored procedure.
SQLOLE_ECAT_ INVALIDPARAMETER |
SQLOLE_E_ BADCOLLEN | Column length must be between 1 and 255 (0 is allowed for non-length datatypes).
SQLOLE_E_ INVALIDPERFMONSET | The PerfMonMode must be either Continuous or OnDemand.
SQLOLE_E_BADDEVICETYPE | Invalid device type.
SQLOLE_E_ SIZEGREATERTHAN0 | Size must be greater than 0.
SQLOLE_E_ RESULTSETOUTOFRANGE | Specified result set is outside the range of result sets returned by this query.
SQLOLE_E_ OUTPUTPARAMREQUIRED | You must specify an output parameter.
SQLOLE_E_PROPTEXTNONNULL | The text for this property cannot be blank or NULL.
SQLOLE_E_BADPROCTYPE | Invalid StoredProcedure type.
SQLOLE_E_BADFILLFACTOR | Fill factor must be between 0 (use default) and 100.
SQLOLE_E_INVALIDINDEXTYPE | Invalid index-type option.
SQLOLE_E_INVALIDPRIVTYPE | Invalid privilege-type option for this object.
SQLOLE_E_BADTRIGTYPE | Invalid trigger-type option.
SQLOLE_E_ INVALIDDAYOFWEEK | Day of week index must be between 1 and 7.
SQLOLE_E_INVALIDMONTH | Month index must be between 1 and 12.
SQLOLE_E_BADDAYCOUNT | You must enter exactly 7 day names.
SQLOLE_E_BADMONTHCOUNT | You must enter exactly 12 month names.
SQLOLE_E_BADCONFIGVALUE | New values for configuration option '%s' must be between %ld and %ld.
SQLOLE_E_ INVALIDPARAMINDEX | Invalid index parameter type; must be string or numeric ordinal, or an object; check documentation for this function.
SQLOLE_E_ INVALIDPARAMRANGE | Invalid parameter or parameter value out of range.
SQLOLE_E_INVALIDDBOBJTYPE | Invalid database-object type.
SQLOLE_E_ ROWCOLOUTOFRANGE | Row or column specified is outside the range of the specified query result set.
SQLOLE_E_NONUNIQUENAME | The object name '%s' is not unique.
SQLOLE_E_ NOTIMESTAMPUDDT | User-defined datatypes based on the 'timestamp' datatype are not allowed.
SQLOLE_E_INVALIDNAME | The name '%s' is not a valid object identifier, or is not a valid format for this property or method.
SQLOLE_E_ INVALIDCOMPLETION | Assigned CompletionLevel must be Failure or Success.
SQLOLE_E_NAMETOOLONG | Maximum string length for this property or method is %ld.
SQLOLE_E_INVALIDFREQTYPE | FrequencyType must be Daily, Weekly, or Monthly.
SQLOLE_E_ INVALIDFREQSUBDAY | FrequencySubDay must be Hour, Minute, or Second.
SQLOLE_E_ INVALIDFREQRELINTERVAL | FrequencyRelativeInterval must be First, Second, Third, Fourth, or Last.
SQLOLE_E_ BADWEEKLYINTERVAL | Weekly Interval must be one or more WeekDay values; consult your documentation.
SQLOLE_E_ BADMONTHLYINTERVAL | Monthly Relative Interval must be a single MonthDay value; consult your documentation.
SQLOLE_E_ BADMONTHLYRELINTERVAL | Monthly Relative Interval must be a single First thru Fourth, or Last; consult your documentation.
SQLOLE_E_INVALIDSRVOPTION | Invalid Remote Server option.
SQLOLE_E_ INVALIDRUNPRIORITY | Invalid Run Priority.
SQLOLE_E_DBNAMEREQUIRED | Database name required.
SQLOLE_E_ PUBNAMEREQUIRED | Publication name required.
SQLOLE_E_ PROPINDEXOUTOFRANGE | Specified index is out of the range of properties for this object.
SQLOLE_E_ INVALIDNOTIFYTYPE | Property must be a valid SQLOLE_NOTIFY_TYPE.
SQLOLE_E_ INVALIDENUMNOTIFYTYPE | Property must be a valid SQLOLE_ENUMNOTIFY_TYPE.
SQLOLE_E_INVALIDWEEKDAY | Weekday parameter must be a bitmask of SQLOLE_WEEKDAY_TYPE (1, 2, 4, 8, 16, 32, 64).
SQLOLE_E_ INVALIDOBJECTTYPE | The input object's type is invalid for this method.
SQLOLE_E_OBJECTREQUIRED | An input object must be specified.
SQLOLE_E_INVALIDEVENTTYPE | Invalid event type; must be a valid (non-Unknown) value in SQLOLE_EVENT_TYPE.
SQLOLE_E_ INVALIDCOMPLETIONTYPE | Invalid completion type; must be a valid (non-Unknown) value in SQLOLE_COMPLETION_TYPE.
SQLOLE_E_INVALIDKEYTYPE | Invalid key type.
SQLOLE_E_ TABLEMUSTBECREATED | This property or method requires that the table object already be created on the server.
SQLOLE_E_ INVALIDPREARTICLE | Invalid article pre-creation method.
SQLOLE_E_ INVALIDSECURITYMODE | Invalid Security mode.
SQLOLE_E_INVALIDPREC | Numeric precision must be greater than 0 and less than or equal to the maximum precision (%ld) specified for this server.
SQLOLE_E_ INVALIDDEPENDENCYTYPE | DependencyType must be a valid value from SQLOLE_DEPENDENCY_TYPE.
SQLOLE_E_ INVALIDVERIFYCONNTYPE | VerifyType must be a valid value from SQLOLE_VERIFYCONN_TYPE.
SQLOLE_E_ INVALIDSTATUSINFOTYPE | The StatusInfoType must be a non-Unknown member of the SQLOLE_STATUSINFO_TYPE enumeration.
SQLOLE_E_ INVALIDFORWARDINGSEVERITY | The ForwardingSeverity must be between 1 and 25, or 110, 120, 130, or 140.
SQLOLE_E_ INVALIDFORWARDINGSERVER | The ForwardingServer cannot be the current server.
SQLOLE_E_ INVALIDRESTARTINTERVAL | The RestartSQLServerInterval must be between 1 and 60 minutes.
SQLOLE_E_ INVALIDHISTORYROWSMAX | The LimitHistoryRowsMax must be greater than 1.
SQLOLE_E_NAMETOOSHORT | Minimum string length for this property or method is %ld.
SQLOLE_E_UNEXPECTED | Unexpected parameter value or other condition.
SQLOLE_ECAT_ INVALIDPLATFORM |
SQLOLE_E_BACKUPSQL60ONLY | Backup options other than UnloadTapeAfter, DumpInitDeviceBefore, LoadFileNumber, and single backup devices require Microsoft SQL Server Version 6.0 or later.
SQLOLE_E_MSSQLONLY | This method or property is only available for Microsoft SQL Servers.
SQLOLE_E_WIN95REQUIRESCONN | This method is not available to unconnected servers unless on Windows NT clients.
SQLOLE_E_NOTONWIN95 | This method is only available on Windows NT clients.
SQLOLE_E_SQL60ONLY | This property or method requires Microsoft SQL Server Version 6.0 or later.
SQLOLE_E_REPLSQL60ONLY | Replication and Scheduling Management requires Microsoft SQL Server Version 6.0 or later.
SQLOLE_E_ STARTUPPROCSQL60ONLY | Specifying startup procedures requires Microsoft SQL Server Version 6.0 or later.
SQLOLE_E_NEEDSQLOLEPROCS | This server has not installed version %ld.%ld or later of the Microsoft SQL-DMO (SQLOLE) stored procedures for its SQL Server version. The connection is denied.
SQLOLE_E_ALTERSQL60ONLY | Changing this property after object creation requires Microsoft SQL Server Version 6.0 or later.
SQLOLE_E_ SORTEDDATAREORGSQL60ONLY | Specifying SQLOLEIndex_SortedDataReorg requires Microsoft SQL Server Version 6.0 or later.
SQLOLE_E_MSSQLNTONLY | This version of the Microsoft SQL Distributed Managment Objects requires a Microsoft Windows NT SQL Server version 4.21 or later.
SQLOLE_E_ WIN95REQUIRESSQL60 | This method or property is not available on a pre-6.0 version of Microsoft SQL Server when SQL-DMO is running on Windows 95.
SQLOLE_ECAT_ ITEMNOTFOUND |
SQLOLE_E_RULENOTFOUND | Rule '%s' not found.
SQLOLE_E_DEFAULTNOTFOUND | Default '%s' not found.
SQLOLE_E_TYPENOTFOUND | Data type '%s' not found.
SQLOLE_E_LOGINNOTFOUND | Login '%s' not found.
SQLOLE_E_GROUPNOTFOUND | Group '%s' not found.
SQLOLE_E_LANGNOTFOUND | Language '%s' not found.
SQLOLE_E_DBNOTFOUND | Database '%s' not found.
SQLOLE_E_DEVICENOTFOUND | Device '%s' not found.
SQLOLE_E_COLUMNNOTFOUND | Column '%s' not found in table '%s'.
SQLOLE_E_ORDOUTOFRANGE | The passed ordinal is out of range of the specified collection.
SQLOLE_E_NAMENOTFOUND | The name '%s' was not found in the specified collection.
SQLOLE_E_USERNOTFOUND | User '%s' not found.
SQLOLE_E_NAMENOTINCACHE | Internal error: Name not found in cache.
SQLOLE_E_ PROPNAMENOTFOUND | Specified name is not a property of this object.
SQLOLE_E_IDNOTFOUND | The ID '%ld' was not found in the specified collection.
SQLOLE_ECAT_ UNPRIVILEGEDLOGIN |
SQLOLE_E_MUSTBESAORDBO | Only the System Administrator or Database Owner can perform this operation.
SQLOLE_E_MUSTBESAORLOGIN | You must be logged in as 'sa' or this object's login to perform this operation.
SQLOLE_E_MUSTBESA | You must be logged in as 'sa' to perform this operation.
SQLOLE_ECAT_EXECUTION |
SQLOLE_E_SYSPROCERROR | SQL Server message text.
SQLOLE_E_CACHEEXECERROR | Error encountered on executing or updating associated query.
SQLOLE_E_INACCESSIBLEDB | This database has been marked Inaccessible.
SQLOLE_E_ BATCHCOMPLETEWITHERRORS | SQL Server message text.
SQLOLE_ECAT_CONNECTION |
SQLOLE_E_CANTRECONNDEADCONN | This server connection has been unexpectedly broken and cannot be reconnected.
SQLOLE_ECAT_RESOURCE |
SQLOLE_E_OUTOFMEMORY | Out of memory.
SQLOLE_E_NOMOREDEVNOS | The maximum of 256 devices already exists on this server.
SQLOLE_E_LASTERROR |


SQLOLE_EVENT_TYPE

Values

SQLOLEEvent_Unknown
SQLOLEEvent_Info
SQLOLEEvent_Warning
SQLOLEEvent_Error
SQLOLEEvent_AuditSuccess
SQLOLEEvent_AuditFailure
SQLOLEEvent_All


SQLOLE_EXEC_TYPE

Values

SQLOLEExec_Default
SQLOLEExec_NoCommandTerm
SQLOLEExec_ContinueOnError
SQLOLEExec_NoExec
SQLOLEExec_ParseOnly


SQLOLE_FREQRELATIVE_TYPE

Values

SQLOLEFreqRel_Unknown
SQLOLEFreqRel_First
SQLOLEFreqRel_Second
SQLOLEFreqRel_Third
SQLOLEFreqRel_Fourth
SQLOLEFreqRel_Last
SQLOLEFreqRel_Valid


SQLOLE_FREQSUB_TYPE

Values

SQLOLEFreqSub_Unknown
SQLOLEFreqSub_Once
SQLOLEFreqSub_Minute
SQLOLEFreqSub_Hour
SQLOLEFreqSub_Valid


SQLOLE_FREQUENCY_TYPE

Values

SQLOLEFreq_Unknown
SQLOLEFreq_OneTime
SQLOLEFreq_OnDemand
SQLOLEFreq_Daily
SQLOLEFreq_Weekly
SQLOLEFreq_Monthly
SQLOLEFreq_MonthlyRelative
SQLOLEFreq_Autostart
SQLOLEFreq_Recurring
SQLOLEFreq_Valid


SQLOLE_INDEX_TYPE

Values

SQLOLEIndex_Default
SQLOLEIndex_IgnoreDupKey
SQLOLEIndex_Unique
SQLOLEIndex_IgnoreDupRow
SQLOLEIndex_Clustered
SQLOLEIndex_AllowDupRow
SQLOLEIndex_SortedData
SQLOLEIndex_SortedDataReorg
SQLOLEIndex_Valid
SQLOLEIndex_DRIPrimaryKey
SQLOLEIndex_DRIUniqueKey
SQLOLEIndex_DRIIndex


SQLOLE_INITIALSYNC_TYPE

Values

SQLOLEInitSync_Unknown
SQLOLEInitSync_Min
SQLOLEInitSync_BCPNative
SQLOLEInitSync_BCPChar
SQLOLEInitSync_TableDumpLoad
SQLOLEInitSync_Max


SQLOLE_INTSECLOGIN_TYPE

Values

SQLOLEIntSecLogin_Unknown
SQLOLEIntSecLogin_Min
SQLOLEIntSecLogin_Admin
SQLOLEIntSecLogin_User
SQLOLEIntSecLogin_Replication
SQLOLEIntSecLogin_Max


SQLOLE_KEY_TYPE

Values

SQLOLEKey_Unknown
SQLOLEKey_Primary
SQLOLEKey_Unique
SQLOLEKey_Foreign


SQLOLE_MEDIA_TYPE

Values

SQLOLEMedia_Floppy
SQLOLEMedia_FixedDisk
SQLOLEMedia_Tape
SQLOLEMedia_CDROM
SQLOLEMedia_All


SQLOLE_MIRROR_TYPE

Values

SQLOLEMirror_None
SQLOLEMirror_Inactive
SQLOLEMirror_RunningOnMirror
SQLOLEMirror_Active


SQLOLE_MONTHDAY_TYPE

Values

SQLOLEMonth_Unknown
SQLOLEMonth_MinValid
SQLOLEMonth_Sunday
SQLOLEMonth_Monday
SQLOLEMonth_Tuesday
SQLOLEMonth_Wednesday
SQLOLEMonth_Thursday
SQLOLEMonth_Friday
SQLOLEMonth_Saturday
SQLOLEMonth_Day
SQLOLEMonth_WeekDay
SQLOLEMonth_WeekEndDay
SQLOLEMonth_MaxValid


SQLOLE_NOTIFY_TYPE

Values

SQLOLENotify_None
SQLOLENotify_Email
SQLOLENotify_Pager
SQLOLENotify_Both
SQLOLENotify_Valid


SQLOLE_OBJECT_TYPE

Values

SQLOLEObj_Unknown
SQLOLEObj_Application
SQLOLEObj_UserDefinedDatatype
SQLOLEObj_SystemTable
SQLOLEObj_View
SQLOLEObj_UserTable
SQLOLEObj_StoredProcedure
SQLOLEObj_Default
SQLOLEObj_Rule
SQLOLEObj_Trigger
SQLOLEObj_AllDatabaseUserObjects
SQLOLEObj_AllDatabaseObjects
SQLOLEObj_SystemDatatype
SQLOLEObj_User
SQLOLEObj_Group
SQLOLEObj_Index
SQLOLEObj_Key
SQLOLEObj_Column
SQLOLEObj_DBObject
SQLOLEObj_DBOption
SQLOLEObj_ProcedureParameter
SQLOLEObj_Permission
SQLOLEObj_IntegratedSecurity
SQLOLEObj_Check
SQLOLEObj_DRIDefault
SQLOLEObj_SQLServer
SQLOLEObj_Database
SQLOLEObj_Device
SQLOLEObj_Login
SQLOLEObj_Language
SQLOLEObj_RemoteServer
SQLOLEObj_RemoteLogin
SQLOLEObj_Configuration
SQLOLEObj_ConfigValue
SQLOLEObj_AlertSystem
SQLOLEObj_Executive
SQLOLEObj_QueryResults
SQLOLEObj_TransactionLog
SQLOLEObj_Registry
SQLOLEObj_Transfer
SQLOLEObj_Backup
SQLOLEObj_Task
SQLOLEObj_Alert
SQLOLEObj_Operator
SQLOLEObj_HistoryFilter
SQLOLEObj_Publication
SQLOLEObj_Article
SQLOLEObj_Subscription
SQLOLEObj_SubscriberInfo
SQLOLEObj_AutoProperty


SQLOLE_OBJSORT_TYPE

Values

SQLOLEObjSort_Name
SQLOLEObjSort_Type
SQLOLEObjSort_Owner
SQLOLEObjSort_Date


SQLOLE_PERFMON_TYPE

Values

SQLOLEPerfmon_None
SQLOLEPerfmon_MinSet
SQLOLEPerfmon_Continuous
SQLOLEPerfmon_OnDemand
SQLOLEPerfmon_MaxSet


SQLOLE_PREARTICLE_TYPE

Values

SQLOLEPreArt_Min
SQLOLEPreArt_None
SQLOLEPreArt_DropTable
SQLOLEPreArt_DeleteRows
SQLOLEPreArt_TruncateTable
SQLOLEPreArt_Max


SQLOLE_PRIVILEGE_TYPE

Values

SQLOLEPriv_Unknown
SQLOLEPriv_Select
SQLOLEPriv_Insert
SQLOLEPriv_Update
SQLOLEPriv_Delete
SQLOLEPriv_Execute
SQLOLEPriv_References
SQLOLEPriv_AllObjectPrivs
SQLOLEPriv_CreateTable
SQLOLEPriv_CreateDatabase
SQLOLEPriv_CreateView
SQLOLEPriv_CreateProcedure
SQLOLEPriv_DumpDatabase
SQLOLEPriv_CreateDefault
SQLOLEPriv_DumpTransaction
SQLOLEPriv_CreateRule
SQLOLEPriv_AllDatabasePrivs


SQLOLE_PROCEDURE_TYPE

Values

SQLOLEProc_Unknown
SQLOLEProc_Standard
SQLOLEProc_Extended
SQLOLEProc_Macro
SQLOLEProc_ReplicationFilter


SQLOLE_QUERY_DATATYPE

Values

SQLOLE_DTypeUnknown
SQLOLE_DTypeChar
SQLOLE_DTypeText
SQLOLE_DTypeVarchar
SQLOLE_DTypeVarBinary
SQLOLE_DTypeBinary
SQLOLE_DTypeImage
SQLOLE_DTypeFloat4
SQLOLE_DTypeFloat8
SQLOLE_DTypeInt1
SQLOLE_DTypeInt2
SQLOLE_DTypeInt4
SQLOLE_DTypeMoney4
SQLOLE_DTypeMoney
SQLOLE_DTypeDateTime
SQLOLE_DTypeDateTime4
SQLOLE_DTypeBit


SQLOLE_REPFREQ_TYPE

Values

SQLOLERepFreq_Unknown
SQLOLERepFreq_Min
SQLOLERepFreq_Continuous
SQLOLERepFreq_Snapshot
SQLOLERepFreq_Max


SQLOLE_REPLICATION_TYPE

Values

SQLOLERep_Unknown
SQLOLERep_LogBased
SQLOLERep_ManualFilterProc
SQLOLERep_LogBasedManualFilterProc
SQLOLERep_ManualSyncView
SQLOLERep_LogBasedManualSyncView
SQLOLERep_LogBasedManualBoth
SQLOLERep_Valid


SQLOLE_RUNPRIORITY_TYPE

Values

SQLOLERunPri_Unknown
SQLOLERunPri_Min
SQLOLERunPri_Idle
SQLOLERunPri_Lowest
SQLOLERunPri_BelowNormal
SQLOLERunPri_Normal
SQLOLERunPri_AboveNormal
SQLOLERunPri_Highest
SQLOLERunPri_TimeCritical


SQLOLE_SCRIPT_TYPE

Values

SQLOLEScript_Default
SQLOLEScript_Drops
SQLOLEScript_ObjectPermissions
SQLOLEScript_PrimaryObject
SQLOLEScript_ClusteredIndexes
SQLOLEScript_Triggers
SQLOLEScript_DatabasePermissions
SQLOLEScript_Permissions
SQLOLEScript_ToFileOnly
SQLOLEScript_Bindings
SQLOLEScript_AppendToFile
SQLOLEScript_NoDRI
SQLOLEScript_UDDTsToBaseType
SQLOLEScript_42Syntax
SQLOLEScript_ODBCSyntax
SQLOLEScript_IncludeIfNotExists
SQLOLEScript_NonClusteredIndexes
SQLOLEScript_Indexes
SQLOLEScript_Aliases
SQLOLEScript_NoCommandTerm
SQLOLEScript_DRIIndexes
SQLOLEScript_IncludeHeaders
SQLOLEScript_OwnerQualify
SQLOLEScript_TimestampToBinary


SQLOLE_SECURITY_TYPE

Values

SQLOLESecurity_Min
SQLOLESecurity_Normal
SQLOLESecurity_Integrated
SQLOLESecurity_Mixed
SQLOLESecurity_Max


SQLOLE_SRVOPTION_TYPE

Values

SQLOLESrvOpt_Unknown
SQLOLESrvOpt_RPC
SQLOLESrvOpt_Publisher
SQLOLESrvOpt_Subscriber
SQLOLESrvOpt_Distributor
SQLOLESrvOpt_DistPublisher
SQLOLESrvOpt_Valid


SQLOLE_SRVUSERPROFILE_TYPE

Values

SQLOLESrvUserProf_None
SQLOLESrvUserProf_SaLogin
SQLOLESrvUserProf_CreateDatabase
SQLOLESrvUserProf_AllProfileBits


SQLOLE_STARTSRV_TYPE

Values

SQLOLEStart_NoServiceControl
SQLOLEStart_NTErrorLogging
SQLOLEStart_SingleUser
SQLOLEStart_StartAndConnect
SQLOLEStart_RealTime
SQLOLEStart_Defaults


SQLOLE_STATUSINFO_TYPE

Values

SQLOLEStatInfo_Unknown
SQLOLEStatInfo_DatabaseStatus
SQLOLEStatInfo_DatabaseSpace
SQLOLEStatInfo_All


SQLOLE_SUBSTATUS_TYPE

Values

SQLOLESubStat_Unknown
SQLOLESubStat_Min
SQLOLESubStat_Inactive
SQLOLESubStat_Unsynced
SQLOLESubStat_Active
SQLOLESubStat_Max


SQLOLE_SUBSYNC_TYPE

Values

SQLOLESubSync_Unknown
SQLOLESubSync_Min
SQLOLESubSync_Documentation
SQLOLESubSync_Auto
SQLOLESubSync_None
SQLOLESubSync_Max


SQLOLE_SVCSTATUS_TYPE

Values

SQLOLESvc_Unknown
SQLOLESvc_Running
SQLOLESvc_Paused
SQLOLESvc_Stopped
SQLOLESvc_Starting
SQLOLESvc_Stopping
SQLOLESvc_Continuing
SQLOLESvc_Pausing


SQLOLE_TABLEATT_TYPE

Values

SQLOLETabAtt_Identity
SQLOLETabAtt_SystemObject
SQLOLETabAtt_ForeignKey
SQLOLETabAtt_Referenced
SQLOLETabAtt_Published
SQLOLETabAtt_Replicated
SQLOLETabAtt_Check
SQLOLETabAtt_Replica
SQLOLETabAtt_PrimaryKey
SQLOLETabAtt_Unique
SQLOLETabAtt_Default
SQLOLETabAtt_ReplCheck
SQLOLETabAtt_HasConstraint


SQLOLE_TRIGGER_TYPE

Values

SQLOLETrig_Unknown
SQLOLETrig_Insert
SQLOLETrig_Update
SQLOLETrig_Delete
SQLOLETrig_All


SQLOLE_VERIFYCONN_TYPE

Values

SQLOLEConn_LastState
SQLOLEConn_CurrentState
SQLOLEConn_ReconnectIfDead
SQLOLEConn_Valid


SQLOLE_WEEKDAY_TYPE

Values

SQLOLEWeek_Unknown
SQLOLEWeek_Sunday
SQLOLEWeek_Monday
SQLOLEWeek_Tuesday
SQLOLEWeek_Wednesday
SQLOLEWeek_Thursday
SQLOLEWeek_Friday
SQLOLEWeek_Saturday
SQLOLEWeek_WeekDays
SQLOLEWeek_WeekEnds
SQLOLEWeek_EveryDay


Before You Begin

The programming components in Microsoft® SQL Server™ 6.5 enable you to develop sophisticated client/server applications that tap the power of Microsoft SQL Server from workstations running the Microsoft® Windows NT™, Microsoft® Windows® 95, and Microsoft® Windows® operating systems.

SQL Server 6.5 includes the Microsoft® Distributed Transaction Coordinator (MS DTC), which provides a robust, high-performance, scalable, easy-to-use distributed transaction facility for the Microsoft Windows NT and Microsoft® Windows® 95 operating systems. MS DTC addresses the challenges of processing transactions over a distributed set of software components that exist on a system of networked computers. MS DTC is fully integrated with Microsoft SQL Server and provides a transaction manager in SQL Enterprise Manager at each computer that manages distributed transactions.

MS DTC provides a management interface that allows you to start and stop MS DTC, view current MS DTC statistics and traces, force the outcomes of in-doubt transactions, and set various global MS DTC options.


About Guide to Microsoft Distributed Transaction Coordinator

This book is organized as follows:

  • Chapter 1, Introduction provides an introduction to transactions written by Jim Gray
  • Chapter 2, Setup provides instructions for installing and setting up MS DTC
  • Chapter 3, Administration provides details about the MS DTC user interface in SQL Enterprise Manager
  • Chapter 4, Application Development provides information about how to use MS DTC with Transact-SQL and C or C++ applications
  • Chapter 5, MS DTC Programmer's Reference provides information about he supported ITransaction methods


Document Conventions

This documentation uses the following conventions to distinguish elements of text:

Convention | Purpose
UPPERCASE | Represents statement and clause names, structure names, datatypes, filenames, and paths.
SMALL CAPITALS | Represent key names, such as ctrl.
bold | Represents functions, configuration-file entries, and syntax.
italic | Represents database names, table names, column names, index names, binding types, and variables that appear in text.
monospace | Represents examples and sample program code.


Finding Further Information

This book contains reference information to help you use the MS DTC. Information about SQL Server is available from the following sources, as well as from the Microsoft® Development Library and Microsoft® TechNet.

The Microsoft Developer Network provides in-depth information for developers. With Level 1 of the Developer Network, you get four quarterly releases of the Development Library, packed with inside information on programming for Microsoft Windows and Windows NT, plus other program benefits. With Level 2 of the Developer Network, you'll receive all the Level 1 benefits plus quarterly releases of the Development Platform, containing the latest Windows and Windows NT Workstation operating systems and API-level SDKs and DDKs from Microsoft. For ordering information, call (800) 759-5474.

Microsoft TechNet is the front-line resource for fast complete answers to technical questions on Microsoft desktop and system products. Through two monthly CDs, you get everything from crucial data on client/server and workgroup computing, systems platforms, and database products to the latest applications support for Microsoft Windows and the Apple® Macintosh®. For ordering information, call your reseller or (800) 344-2121.


SQL Server Documentation

The documentation for SQL Server 6.5 is available online as part of the Microsoft® Development Library and as Microsoft SQL Server Books Online, which is part of Microsoft SQL Server and Microsoft® SQL Workstation.

Important SQL Server Books Online contains the most up-to-date information about SQL Server 6.5, including information that changed or was unavailable when the SQL Server 6.5 books were printed.

Microsoft SQL Server Setup
Provides instructions for installing SQL Server 6.0 servers and clients.
Microsoft SQL Server System Administrator's Companion
Incorporates configuration, administration, and troubleshooting topics. Describes server and client configuration. Explains system administration tasks, such as managing devices and databases, backing up and recovering data, performing replication, scheduling tasks, managing security, and monitoring performance. Describes error conditions and gives troubleshooting procedures.
Microsoft SQL Server Database Developer's Companion
Provides an overview of Transact-SQL, which is an enhanced version of SQL (structured query language). Discusses managing data and database objects, such as tables, views, indexes, stored procedures, defaults, rules, constraints, and user-defined datatypes.
Microsoft SQL Server Transact-SQL Reference
Explains how to use Transact-SQL statements and other features to access databases, and provides syntax and descriptions for Transact-SQL statements, system procedures, utility programs, and system tables.
Microsoft SQL Server Programming SQL Distributed Management Objects
Provides syntax and reference information for the SQL Distributed Management Objects, which are 32-bit OLE Automation objects for the Microsoft® Windows® 95 and Windows NT operating systems. These objects, properties, methods, and collections are used to write scripts and programs that can administer multiple SQL Servers distributed across a network.
Microsoft SQL Server Programming DB-Library for C
Provides syntax and reference information for the DB-Library application programming interface (API), which is used to write C/C++ client programs for the Windows, Windows 95, Windows NT, and MS-DOS operating systems.
Microsoft SQL Server Programming DB-Library for Visual Basic
Provides syntax and reference information for the DB-Library API, which is used to write Microsoft® Visual Basic® programming system-based client programs for the Windows operating system.


Obtaining Technical Support

Microsoft offers a variety of support options to help you get the most from Microsoft SQL Server. For information about these options, see the service and support information available on the Microsoft SQL Server and Microsoft SQL Workstation CD sleeves, and the online support information in the Microsoft Development Library.

In addition, you can get technical support information from the Microsoft® Knowledge Base (KB), which can help you resolve problems. Information about the Knowledge Base (including how to get KB articles, how to get the KB on CD, and how to contribute to the KB) is available in the Help file KB_MSL.HLP, located in the \MSSQL\INSTALL directory.


Chapter 1 Introduction - By Jim Gray

Introduction - By Jim Gray

The ACID Properties

Execution Scenarios

Distributed Transactions

Concept Summary

It is difficult to write applications. With time, we are discovering concepts and techniques that allow us to build large applications. Modularity, structuring an application as independent modules, allows you to build complex systems from simpler parts and to get software reuse. Object-oriented concepts, as embodied in Microsoft® Component Object Model (COM), provide a technique that allows you to write modular applications.

When an application is structured as components, the individual parts can reside together in a single computer, or they can interact by using remote procedure calls across a network. So, components give both modularity and natural distribution.

Structuring an application into independent components creates the problem of managing the components. Monolithic programs fail and are restarted as a unit. However, with a modular system, the failure of one component must not corrupt the other modules. There must be a way to isolate faults and limit fault propagation. Transactions provide modular execution and thus simplify and automate fault handling. They provide a simple conceptual execution framework for both implementers and users.

The user thinks of a transaction as a single change event that either happens or doesn't happen. Implementers think of a transaction as a programming style that allows them to write modules that can participate in distributed computations. Suppose you want to transfer money from one bank account to another. The implementers and the users want to make sure that either both accounts change or neither changes. It is hard to make this work in a distributed system¾computers can fail and messages can be lost. Transactions provide a way to bundle a set of operations into an atomic execution unit.

The atomic all-or-nothing property is not new: it appears throughout life. For example, if you enter a contract, an escrow officer coordinates the transaction: the escrow officer collects the signatures of each party to the contract. The contract is final when the escrow officer announces that everyone has signed. A minister conducting a marriage ceremony first asks the bride and groom, "Do you take this person to be your spouse?" If they both respond "I do," the minister pronounces them married. A director on a movie set first asks, "Ready on the set?" If all respond yes, the director then calls, "Action!" A helmsman on a sailboat preparing to tack first asks the crew, "Ready about?" If they all respond yes, then the helmsman shouts, "Helm's a'lee!" and turns the boat. The escrow officer makes the contract, the director makes the movie, the minister makes the marriage, and the helmsman makes the tack, an atomic transaction.

These scenarios illustrate the basic principle of a transaction: several independent entities must agree. If any party disagrees, the deal is off. Once they all agree, the transaction can occur. The Microsoft Distributed Transaction Coordinator (MS DTC) performs this transaction coordination role for the other components of the COM architecture.

In MS DTC terminology, the director is called the transaction manager. The participants in the transaction that implement transaction-protected resources, such as relational databases, are called resource managers.

An application begins a transaction by calling the transaction manager's BeginTransaction method. This creates a transaction object that represents the transaction. The application then calls the resource managers to do the work of the transaction.

The application's call to each resource manager identifies the application's current transaction. For example, if the application is using a relational database, it calls the ODBC interface, which associates the transaction object with the ODBC connection. Thereafter, all database calls made over that connection are performed on behalf of the transaction until the transaction is ended.

When a resource manager first does work on behalf of a transaction, it enlists in the transaction by calling the transaction manager. As the transaction progresses, the transaction manager keeps track of each of the resource managers enlisted in the transaction.

Typically, the application completes the transaction by calling the Commit transaction method. If the application is unable to complete the transaction, it calls the Abort transaction method, which undoes the transaction. If the application fails, MS DTC aborts the transaction.

When the application successfully completes the transaction's work and calls Commit, it calls the MS DTC to commit the transaction. MS DTC goes through a two-phase commit protocol to get all enlisted resource managers to commit. The two-phase commit protocol ensures that all the resource managers commit the transaction or all abort it. In the first phase, the MS DTC asks each resource manager if it is prepared to commit. If all participants say yes, then in the second phase MS DTC broadcasts the commit message to all of them. If any part of the transaction fails, if a resource manager fails to respond to the prepare request, or if a resource manager responds no, then MS DTC notifies all of the resource managers that the transaction aborted.

MS DTC is a big part of the COM architecture. Transaction managers are a key part of most database systems. Transaction managers are also an optional part of some operating systems. Microsoft believes that transactions are essential for distributed applications¾transactions provide modular execution, which complements COM's modular programming. So, Microsoft implemented transaction management software for both Microsoft® Windows® 95 and Microsoft® Windows NT™ operating systems.

Combining the transaction concept with COM required innovation. Traditional transaction systems required considerable skill to install and manage. The challenge of integrating MS DTC with Microsoft's operating system was to automate installation, management, and use. Many of the concepts and techniques had to be reinvented for the new client/server, object-oriented, and visual management environments.

In its first release, MS DTC works with one resource manager: Microsoft® SQL Server™. MS DTC implements the OLE transaction interfaces. All OLE transaction interfaces are public so that any resource manager can become an OLE transaction resource manager. In the future, Microsoft and other software companies will add other transactional resource managers, such as distributed object systems, transactional file systems, transaction queuing systems, and workflow management systems.


The ACID Properties

Transactions provide the ACID properties.

Atomicity
A transaction either commits or aborts. If a transaction commits, all of its effects remain. If it aborts, all of its effects are undone. For example, in renaming an object, the new name is created and the old name is deleted (commit), or nothing changes (abort).
Consistency
A transaction is a correct transformation of the system state. It preserves the state invariants. For example, by adding an element to a doubly linked list, all four forward and backward pointers are updated.
Isolation
Concurrent transactions are isolated from the updates of other incomplete transactions. These updates do not constitute a consistent state. This property is often called serializability. For example, a second transaction traversing the doubly linked list mentioned in the consistency example will see the list before or after the insert, but it will see only complete changes.
Durability
Once a transaction commits, its effects will persist even if there are system failures. For example, after the rename in the atomicity example, the object will have the new name even if the system fails and is restarted right after the commit completes.

It is up to the application to decide what consistency is and to bracket its computation with BeginTransaction and Commit transaction methods to delimit these consistent transformations. Transactional resource managers provide consistent, isolated, and durable transformations of the objects they manage. MS DTC manages transactions that involve multiple resource managers, perhaps distributed among multiple computers. MS DTC creates transaction objects, tracks migration of transactions among resource managers, and implements the two-phase commit protocol to make these transactions atomic and durable.


Execution Scenarios

We have already discussed the end user's view of transactions: transactions are ACID execution units that either commit or abort. If a transaction commits, its effects are durable. If a transaction aborts, its effects are undone. Applications,resource managers, and transaction managers cooperate to implement the ACID properties. Let's look at the role of each of these participants.


The Application's Role in Transactions

The application programmer's model of transactions is simple: applications either succeed or fail. The application begins a transaction by getting a transaction object. All subsequent work by that application is associated with that transaction object.

When the program reaches a consistent state, it calls the Commit transaction method. If the commit succeeds, the transaction is durably committed. If the commit fails, the transaction is aborted. If the program finds that it cannot complete the transaction, it may call the Abort transaction method to undo the transaction's effects. This is a simple way to clean up complex failure cases.

If the application fails before it calls Commit, the transaction manager will abort the transaction and tell each enlisted resource manager to undo the transaction's effects. If a computer or resource manager fails, the transaction will also be aborted. Once the transaction has successfully committed, the resource managers and the transaction manager will ensure that the transaction's effects are durable, even if there are subsequent failures.

The following figure shows the three possible outcomes of a transaction.


A Resource Manager's Role in Transactions

When a resource manager first comes on the scene, it contacts its local transaction manager to declare the resource manager's presence. Then the resource manager waits for execution requests from applications. When a request arrives tagged with a new transaction object, the resource manager enlists in the transaction. By enlisting, the resource manager ensures that it will get callbacks from the transaction manager when the transaction commits or aborts.

The resource manager then performs the transaction's requests. For example, the transaction might insert, delete, or update records in a relational database. The resource manager keeps enough information to allow it to either undo or redo the transaction's work on those resources. There are many ways to do this; keeping versions of data or keeping a log (journal) of the changes are two common techniques.

When the application calls Commit, the transaction manager initiates the two-phase commit protocol. The transaction manager first asks each enlisted resource manager if it is prepared to commit the transaction. The resource manager must prepare to commit¾it readies itself to either commit or abort the transaction.

Typically, the resource manager records the old and new data in stable storage so that the resource manager can recover even if the system fails. If the resource manager cannot prepare successfully, it informs the transaction manager that it cannot prepare and the transaction manager aborts the transaction. If the resource manager can prepare, it tells the transaction manager and waits for the transaction manager's decision whether to commit or abort the transaction.

Once prepared, a resource manager must wait until it gets a commit or abort callback from the transaction manager. Most transactions commit, although a few transactions abort.

Typically, the entire prepare and commit protocol completes in a fraction of a second.

If there are system or communication failures, the commit or abort notification may not arrive for minutes or hours. During this period, the resource manager is in doubt about the outcome of the transaction. It does not know whether the transaction committed or aborted. While the resource manager is in doubt about the transaction, it keeps locks on the data that is modified by the transaction, thereby isolating these changes from any other transactions.

The discussion so far shows how distributed transactions are made atomic in a fault-free environment. Now we consider how MS DTC helps resource managers make transactions atomic and durable when a resource manager fails. If a resource manager fails and then restarts, the resource manager must reconstruct the committed state of the resources it manages. The reconstructed state must reflect all of the effects of committed transactions and none of the effects of aborted transactions. When a resource manager fails, all of its enlisted transactions are aborted except for those that prepared or committed prior to the failure. When the resource manager restarts, it asks the transaction manager about the outcome of the in-doubt transactions in which it enlisted. The transaction manager tells the resource manager the outcome of each in-doubt transaction and the resource manager commits or aborts these transactions accordingly.

In summary, the two-phase commit protocol and the resource managers combine to make transactions atomic and durable.


The Transaction Manager's Role in Transactions

The transaction manager is the manager of transaction objects. It creates transaction objects and manages their atomicity and durability. Applications ask the transaction manager to create a transaction object by calling the transaction manager's BeginTransaction method.

When a resource manager first participates in a transaction, it calls the transaction manager to enlist in the transaction. The transaction manager tracks the resource managers who enlist in the transaction. Later the application calls Commit or Abort, or the transaction is aborted by a resource manager or a failure.

Commit and Abort are additional transaction methods on transactional objects. When asked to commit a transaction, the transaction manager initiates a two-phase commit protocol. During phase one, it asks all enlisted resource managers to prepare. During phase two, the transaction manager tells the resource managers whether the transaction committed or aborted. The two-phase commit protocol has many optimizations, including the read-only optimization and the transfer-of-commit optimization. MS DTC implements some of these optimizations, but the functionality, described in the figure below, remains the same: atomicity and durability.

The transaction manager keeps a log on disk. The log is a sequential file that records transaction events. The transaction manager records transaction starts, enlistments, and commit decisions in the log. During normal processing, the transaction manager only writes the log. If the transaction manager fails, it reconstructs the transaction's most recent state by reading the log. So, the transaction manager uses the log to make the transaction's state durable.

The transaction manager also provides an operations interface to manage transactions. It records important operational events in the system log. These events can be displayed by using the system event viewer. It has a graphical management interface that is integrated with SQL Enterprise Manager. The graphical management interface lets the operator configure the system, view transactions, and abort or commit in-doubt transactions.


Distributed Transactions

The discussion so far has assumed that all the applications and resource managers were on a single computer (a single Windows system). MS DTC also supports transactions distributed across two or more Windows systems. Each system has a local transaction manager. All applications and resource managers talk to their local transaction managers. The transaction managers cooperate to manage transactions that span systems.

When a transaction first visits a new system (when the first request tagged with the transaction arrives at that system), the two systems involved in the request establish a relationship. The system making the request informs its local transaction manager that the transaction has an outgoing relationship to the transaction manager on the second system. Similarly, the system receiving the request informs its local transaction manager that the transaction has an incoming relationship with the transaction manager on the first system.

These outgoing-incoming relationships form a tree of transaction manager relationships called the transaction's commit tree. The enlisted resource managers are also members of this commit tree; they have an outgoing-incoming relationship to their local transaction manager.

When a distributed transaction commits or aborts, the prepare, commit and abort messages flow outward on the commit tree. Any node of the tree can unilaterally abort a transaction anytime before it agrees to the prepare request sent at phase one. Once a node has prepared, it remains prepared and in doubt until the commit coordinator tells it to commit or abort the transaction. The root transaction manager of the commit tree is the global commit coordinator. It makes the decision to commit or abort the transaction and is never in doubt.

The next illustration shows the message flow of phase one of the two-phase commit protocol of a distributed transaction.

The next illustration shows the message flow of phase two of the two-phase commit protocol of a distributed transaction.

If a computer fails and then restarts, the transaction manager at that computer will determine the outcome of all in-doubt transactions. The transaction manager reads its log file to determine the outcome of transactions for which it was the commit coordinator. For incoming transactions from other systems, the transaction manager reads the log file to determine if it was previously notified of the transaction's outcome. For incoming transactions that remain in doubt, the transaction manager queries the incoming transaction manager to learn the transaction's outcome. The transaction manager also responds to queries from other transaction managers regarding in-doubt outgoing transactions sent to them. This is similar to the protocol that transaction managers and resource managers follow at restart. The transaction manager determines the outcome of each in-doubt transaction and, when asked, tells the resource managers the transaction's outcome.

In-doubt transactions are especially troublesome for distributed transactions. System or communication failures can leave transactions in doubt for a long time. While the transaction is in doubt, the resources modified by the transaction may remain locked and unavailable to others. MS DTC provides a way for the system operator to resolve transactions that remain in doubt for too long. The operator can use a graphical management interface at the commit coordinator system to determine the transaction's outcome. The operator also can use the graphical management interface at the in-doubt system to force the in-doubt transaction to commit or abort. When the systems reconnect, MS DTC detects these operator actions and it flags inconsistent actions.


Concept Summary

Transactions are ACID (atomic, consistent, isolated, durable) modules of execution. They complement COM's program module structure. The Microsoft Distributed Transaction Coordinator (MS DTC) provides a transaction manager for each computer that manages transactions at that computer. Applications call the transaction manager to begin a transaction. BeginTransaction returns a transaction object. The application includes the transaction object with requests to resource managers. When a resource manager first begins working on a transaction, it enlists in the transaction. When the application has made a consistent transformation of the state, it asks the transaction manager to commit the transaction with the Commit transaction method. If the application cannot complete the transaction, the application program aborts it by using the Abort transaction method. If the application fails or a participating resource manager fails, then MS DTC aborts the transaction.

MS DTC uses a two-phase commit algorithm in which (1) the transaction manager requests each enlisted resource manager to prepare to commit, and (2) if all successfully prepare, then the transaction manager broadcasts the commit decision. If any resource manager cannot prepare, the transaction manager broadcasts an abort decision to everyone involved in the transaction. While a resource manager is prepared, it is in doubt about whether the transaction committed or aborted. The transaction manager keeps a sequential log so that its commit or abort decisions will be durable. If a resource manager or transaction manager fails, they reconcile in-doubt transactions when they reconnect.

For distributed transactions, each computer has a local transaction manager. When a transaction works at multiple computers, the transaction managers track incoming and outgoing transactions. Each transaction manager performs all the enlistment, prepare, commit, and abort calls for local resource managers (those on that computer). When committing a transaction distributed among several computers, the transaction manager sends prepare, commit, and abort messages to all its outgoing transaction managers. When a transaction manager is in doubt about a distributed transaction, the transaction manager queries the incoming transaction manager. The root transaction manager is never in doubt. If an in-doubt transaction persists for too long, the system operator can force the transaction to commit or abort.


Chapter 2 Setup

Setup

You install the Microsoft Distributed Transaction Coordinator (MS DTC) by using the Microsoft SQL Server 6.5 setup program. The setup program provides the following MS DTC installations:

  • Complete MS DTC service on a database server
  • MS DTC client utility on a client computer

The SQL Server setup program automatically installs the complete MS DTC service as a component of SQL Server.

Installing the MS DTC client utility on a client computer is required only when the client application resides on the same computer, and the client application begins an MS DTC transaction with the C or C++ BEGIN TRANSACTION statement. The MS DTC client utility is not required if the client application resides on the same computer as a complete MS DTC service.

Each installation option and its related files are described in the following sections.


Planning an MS DTC Network Configuration

Before you install MS DTC, decide which MS DTC components to install on each network node.

An MS DTC transaction can begin on either a client computer or a server.

The transaction begins on the client when the application uses the C or C++ BEGIN TRANSACTION statement. In this case, the MS DTC client utility must be installed on the client computer to begin the transaction and propagate it from the client to the server.

The transaction begins on the server when the Transact-SQL BEGIN DISTRIBUTED TRANSACTION statement is used. The BEGIN DISTRIBUTED TRANSACTION statement can reside either in the client application or a SQL Server stored procedure. In this case, the MS DTC client utility is not required on the client computer.

Regardless of whether a transaction begins on a client or a server, one complete MS DTC service on a participating network node must function as the transaction's commit coordinator.


The Commit Coordinator

Each complete MS DTC installation coordinates the two-phase commit protocol with its local SQL Server. One complete MS DTC installation on the network is responsible for globally coordinating the entire transaction. This MS DTC is the commit coordinator. It instructs the subordinate MS DTCs on the network to conduct the two-phase commit protocol with their local SQL Servers and ensures that the transaction either commits or aborts on all nodes. Once it has determined the transaction's outcome, the commit coordinator informs the application of the outcome.

If a transaction begins on the client, then the commit coordinator is the MS DTC specified by the application. If the application does not specify a commit coordinator, then it uses the default coordinator specified in the client computer's local system registry (for details, see Configuring the MS DTC Client Utility.

If a transaction begins on a server, then the commit coordinator is the MS DTC that is local to that server.

In either case, the commit coordinator is the MS DTC on the node on which the transaction begins. For this reason, this node is typically referred to as the parent node.


Recommended Configurations

In the configuration shown, the client application begins the transaction (the C or C++ BEGIN TRANSACTION statement resides in the application code). Because the MS DTC client utility contains the application programming interfaces (APIs) necessary to begin an MS DTC transaction, the client utility is required on the client node. The commit coordinator for the transaction is a complete MS DTC service on a server node. The particular server-based MS DTC is specified either in the application code or in the client computer's local system registry.

In the configuration shown, the application calls a stored procedure that begins the MS DTC transaction (the Transact-SQL BEGIN DISTRIBUTED TRANSACTION statement resides in the stored procedure). The APIs necessary to begin an MS DTC transaction already reside on each node that hosts the complete MS DTC service. Therefore, the MS DTC client utility is not required on the client node. During installation on each server node, the SQL Server setup program designates the local MS DTC as the default commit coordinator for any transactions begun on that node. If the transaction is begun by a stored procedure, then the MS DTC local to the node on which the procedure was called will act as the transaction's commit coordinator.

In the configuration shown, the application is on the same node as a SQL Server. Because they share a complete MS DTC service, either the application or a SQL Server stored procedure can initiate an MS DTC transaction. If the transaction is begun by the application, then the application determines which server-based MS DTC will act as the transaction's commit coordinator. If the transaction is begun by a stored procedure, then the MS DTC local to the node on which the called procedure resides will act as the transaction's commit coordinator.


Complete MS DTC Service

An installation of the complete MS DTC service on a database server includes these components:

  • Distributed transaction coordinator service
  • Extensions to SQL Server Enterprise Manager for graphical management of the MS DTC
  • Interfaces that applications use to begin MS DTC transactions

When you install the complete MS DTC service, the MS DTC creates the log file MSDTC.LOG. This log file is used to record the outcome of all transactions in which the local MS DTC participates.

Caution You should never modify or delete the MSDTC.LOG file.


Hardware Platforms

MS DTC hardware platforms are identical to those for Microsoft SQL Server 6.5.


Hardware and Software Requirements

MS DTC hardware and software requirements are identical to those for Microsoft SQL Server 6.5, except for the following:

Network software MS DTC runs on the Windows NT 3.51 (or later) platform using TCP/IP, SPX/IX, and NetBEUI network software.


MS DTC Client Utility

An installation of the MS DTC client utility includes the interfaces that applications use to begin MS DTC transactions. The MS DTC client utility does not include the distributed transaction coordinator service or the extensions to SQL Enterprise Manager for graphical management of the MS DTC. The MS DTC client utility will not create the MSDTC.LOG file during installation.


Client Platforms

The MS DTC client utility can be installed on computers running these operating systems:

  • Microsoft Windows NT Server, version 3.51 or later.
  • Microsoft Windows NT Workstation, version 3.51 or later.
  • Microsoft Windows 95.


Client Hardware and Software Requirements

MS DTC client hardware and software requirements are identical to those for Microsoft SQL Server 6.5, except for the following:

Network software MS DTC runs on the Windows NT 3.51 (or later) and Windows 95 platforms using TCP/IP, SPX/IX, and NetBEUI network software.


MS DTC Files

The complete MS DTC components are contained in these files.

File | Description
ADME.DLL | Maintains contacts between various MS DTC components
DAC.EXE | MS DTC user interface control program
DTCCM.DLL | Connection manager DLL
DTCTRACE.EXE | MS DTC trace program
DTCTRACE.DLL | MS DTC trace DLL
DTCUIC.DLL | Client side of administrative component
DTCUIS.DLL | MS DTC administrative component DLL
DTCUTIL.DLL | MS DTC name service DLL
ENUDTC.DLL | String resource DLL
LOGMGR.DLL | Log manager DLL
MSDTC.EXE | MS DTC Windows NT service executable
MSDTCPRX.DLL | MS DTC interface proxy DLL
MSDTCTM.DLL | Transaction manager state machine DLL
UTIL.LIB | Name service/Memory management library
XOLEHLP.DLL | MS DTC helper APIs DLL

The MS DTC client utility includes the interfaces that applications use to begin MS DTC transactions. The MS DTC client utility consists of these files.

File | Description
ADME.DLL | Maintains contact between various MS DTC components
DTCCFG.CPL | Remote client configuration utility
DTCCM.DLL | Connection manager DLL
DTCHELP.LIB | Helper library
DTCUTIL.DLL | MS DTC name service DLL
ENUDTC.DLL | String resource DLL (one per national language supported)
MSDTCPRX.DLL | MS DTC interface proxy DLL
SVCSRVL.DLL | Helper for DTCCFG.CPL
UTIL.LIB | Name service/Memory management library
XOLEHLP.DLL | MS DTC helper APIs DLL


Installing the MS DTC Service

The complete MS DTC service is automatically installed on any node on which you install SQL Server.

For a more detailed discussion of installing Microsoft SQL Server, including supported hardware platforms and hardware and software requirements, see What's New in SQL Server 6.5 and Microsoft SQL Server Setup.

The setup program updates information about the MS DTC files in the Windows NT Registry.

The MS DTC Dynamic Link Libraries (DLLs) and executable files are installed in the \BINN subdirectory of the SQL root directory (C:\MSSQL). The MS DTC log file is installed in the \DATA subdirectory of the SQL root directory.

Important Because of the possible changes to the format of the MS DTC log file between releases, later versions of MS DTC may not be able to read log files created by earlier versions. Therefore, before upgrading to a later version, make sure that all in-doubt transactions are resolved on the earlier version.

After installing the MS DTC on the server, verify a successful installation by performing the following procedure:

To verify your installation
  1. Use SQL Enterprise Manager to start MS DTC as described in Starting MS DTC from the Server.
  2. Once the MS DTC has started, right-click the Distributed Transaction Coordinator icon.
  3. Choose Statistics from the displayed menu to open the MS DTC Statistics window.
  4. Click the SQL Query Tool button on the SQL Enterprise Manager toolbar.
  5. Type BEGIN DISTRIBUTED TRANSACTION in the Query window.
  6. Press Ctrl-E to execute the query.
  7. Return to the MS DTC Statistics window.

    The Current / Active counter should show one active transaction.

  8. Return to the Query window and click the Query tab.
  9. Type ROLLBACK TRANSACTION in the Query window. For information about the ROLLBACK TRANSACTION statement, see the Microsoft SQL Server Transact-SQL Reference.
  10. Press Ctrl-E to execute the query.
  11. Return to the MS DTC Statistics window.

    The Current / Active counter returns to 0.


Upgrading to SQL Server 6.5

You may find it preferable to upgrade from a Microsoft SQL Server 6.0 installation to a Microsoft SQL Server 6.5 installation rather than installing a new SQL Server 6.5 system. Upgrading preserves the databases that you built on your SQL Server 6.0 installation.

The MS DTC is automatically added to your system when you choose the Upgrade SQL Server option in the setup program. For details, including discussion of post-upgrade configuration tasks you may need to perform, see What's New in SQL Server 6.5 and Microsoft SQL Server Setup.


Starting MS DTC from the Server

You can start MS DTC from the server in several ways¾by using SQL Enterprise Manager, SQL Service Manager, the Services application in Control Panel, or from the command prompt.

In each case, MS DTC starts as a service under the Windows NT Service Control Manager by using the default startup options written to the Windows NT Registry by the setup program.

To start MS DTC from SQL Enterprise Manager
  1. From the Microsoft SQL Server 6.5 program group, start SQL Enterprise Manager.
  2. If you have not yet registered the server you want to use, from the Server menu, choose Register Server to do so.
  3. From the Server Manager window, choose the plus sign (+) beside the server group that you want to open.
  4. Click the right mouse button on the server you want to use.
  5. From the shortcut menu, choose Start.
  6. In the Server Manager window, choose the plus sign (+) beside the name of the server that hosts the MS DTC you want to start.

    The available Server services display.

  7. Right-click the Distributed Transaction Coordinator icon to display this shortcut menu:

  8. To start MS DTC either:
    • Choose Start. The Distributed Transaction Coordinator icon turns green once MS DTC has started.
    • Or
    • Choose Configure. When the MS DTC Configuration dialog box displays, choose the Start button.
To start MS DTC from SQL Service Manager
  1. From the Microsoft SQL Server 6.5 group, choose SQL Service Manager.

    The SQL Service Manager dialog box appears.

  2. If the service is a remote service, select or enter the remote server name in the Server box, and then choose the Connect button.
  3. In the Services box, select MS DTC.
  4. Double-click the Start / Continue light.
To start MS DTC from Control Panel
  1. From the Main group, choose Control Panel.
  2. From Control Panel, choose Services.
  3. From the Services dialog box, select MS DTC, and then choose Start.
  4. Choose Close.

Note From the Services dialog box, you can also set MS DTC to automatically start. For information, see your Microsoft Windows NT documentation.

To start MS DTC from the command prompt
  • Type the following from the command prompt:

    net start msdtc


Installing the MS DTC Client Utility

To install the MS DTC client utility, run the SQL Server setup program on a client computer. The MS DTC client utility includes only basic client support that provides remote access to an MS DTC server.

You do not need to install the MS DTC client utility on a computer that already has the SQL Server server components installed on it. The client utilities are automatically installed with the server components.

For a detailed discussion of installing Microsoft SQL Server client utilities, including supported hardware platforms and hardware and software requirements, see What's New in SQL Server 6.5 and Microsoft SQL Server Setup.

Note Unlike other Microsoft SQL Server client utilities, the MS DTC client utility does not run on 16-bit computers.

  • The setup program:
  • Adds the Microsoft SQL Server 6.5 program group to Program Manager.
  • Adds the MS DTC client configuration program to Control Panel.
  • Updates the Windows Registry with information about the MS DTC files.

The MS DTC client utility files are installed in the \BINN subdirectory of the MSSQL root directory.

After the MS DTC client utility is installed, you must run the MS DTC Client Configuration program on the client computer to configure the name and network protocol of the default commit coordinator. For details about using the MS DTC Client Configuration program and configuring the MS DTC client software, see Configuring the MS DTC Client Utility.

For details about how to set configuration options for other SQL Server client utilities, see What's New in SQL Server 6.5 and the Microsoft SQL Server Administrator's Companion.


Configuring the MS DTC Client Utility

Important Windows 95 users must install the Microsoft Remote Registry Service (REGSERV.EXE and related files) before configuring the MS DTC client utility.

To install this service
  1. Double click the Network icon in Control Panel.
  2. Click the Add button in the Network dialog box.
  3. Select Service in the Select Network Component Type dialog box.
  4. Click the Add button.
  5. Click the Have Disk button in the Select Network Service dialog box.
  6. Insert the SQL Server setup CD into your CD ROM drive.
  7. Click the Browse button in the Install From Disk dialog box.
  8. Select your CD ROM drive in the Open dialog box.
  9. Select the \i386\remotreg folder in the Folders dialog box and click OK.
  10. Click OK in the Install From Disk dialog box.

For more information about the Remote Registry Service, see the topic in the Windows 95 Resource Kit (WIN95RK.HLP).

After you install the MS DTC client utility on a client node, you must run the MS DTC Client Configuration program to specify a default commit coordinator. The complete MS DTC service on the computer you specify is used as the commit coordinator when:

  • The application program on the client node begins an MS DTC transaction

    and

  • The application program does not explicitly specify a commit coordinator.

Configure the MS DTC client utility by providing this information:

  • The network computer to use as the default commit coordinator

    and

  • The network protocol used to communicate with the computer you specified as the default coordinator.

Note The complete MS DTC service must be installed on the computer you specify as the default remote commit coordinator.

To configure the MS DTC client computer
  1. From the Main group, choose Control Panel.
  2. From Control Panel, choose MS DTC.
  3. From the MS DTC Client Configuration dialog box, either:
    • Type the name of the computer to use as the default coordinator in the Current Selection box.

    Or

    • Click the Select Computer button to display a list of all computers on the network. Then select the computer you want from the list.
  4. Click the arrow on the Available Network Protocols box to display a list of choices. Then select the protocol used by the network computer you specified as the default coordinator.
  5. Choose OK.

Note It is not necessary to run the MS DTC Client Configuration program when the following two conditions apply:

  • The client application resides on the same computer as a complete MS DTC service.
  • The client application does not specify a commit coordinator.

In this case, the MS DTC that is on the same computer as the client application is used as the default commit coordinator.

However, if the client application resides on the same computer as a complete MS DTC service, and the client application specifies an MS DTC on another network node as the commit coordinator, you must run the MS DTC Client Configuration program to specify the network protocol that is used by the designated MS DTC.

To do so, follow the procedure given above. You need only to specify the commit coordinator's network protocol. Because the commit coordinator is already specified by the client application, the Select Computer button on the MS Client Configuration dialog box is disabled.


Starting MS DTC from a Client

You can start the complete MS DTC service on remote servers from a client node. Doing so is useful if you want to use the client node as a central console for administrating MS DTC transactions. You must have administrative privileges for each SQL Server on which an MS DTC service you want to start resides.

To start a remote MS DTC service from a client node, use SQL Server Enterprise Manager. The procedure is the same as that described in Starting MS DTC from the Server.


Removing an MS DTC Installation

Removing MS DTC is useful, for example, as a preliminary step in converting from a server installation to a client installation, or vice versa, on a networked computer.

  • To remove a complete MS DTC installation from a server, you must run the SQL Server setup program and remove SQL Server from its host computer.
  • To remove an MS DTC client utility from a client computer, you must run the setup program from your Microsoft SQL Server CD.

For more information, see Microsoft SQL Server Setup.


Converting MS DTC Installations

Occasionally, you may want to reconfigure one or more computers on a distributed transaction system. For example, you may want to add a SQL Server database to a computer that was previously configured as a client machine.

To convert a networked computer from one installation option to the other:

  1. Remove the current MS DTC installation (see Removing an MS DTC Installation).
  2. Rerun the Microsoft SQL Server setup program and choose the installation option you want. See Installing the MS DTC Service and Installing the MS DTC Client Utility.


Chapter 3 Administration

Administration

SQL Enterprise Manager provides a graphical interface for managing and configuring Microsoft Distributed Transaction Coordinator (MS DTC). By using this interface, an administrator can start and stop MS DTC, view current MS DTC statistics and traces, force the outcomes of in-doubt transactions, and set various global MS DTC options.

The management interface consists of three windows:

  • MS DTC Transactions
  • MS DTC Trace
  • MS DTC Statistics

These windows provide information for you to monitor MS DTC performance. The MS DTC Configuration dialog box allows you to specify MS DTC view and log behavior and to start and stop MS DTC. Each interface component is described in the following sections.

Note The management interface is available to client and server computers running Windows NT. The management interface is not available to client computers running Windows 95.

To open the management interface
  1. From the Microsoft SQL Server 6.5 group, choose SQL Enterprise Manager.
  2. If you have not yet registered the server you want to use, from the Server menu, choose Register Server to do so.
  3. From the Server Manager window, choose the plus sign (+) beside the server group that you want to open.
  4. Click the right mouse button on the server you want to use.

    A shortcut menu appears.

  5. From the shortcut menu, choose Start.
  6. In the Server Manager window, click the plus sign (+) beside the name of the server that hosts the MS DTC you want to start.

    The available Server services display.

  7. Right-click the Distributed Transaction Coordinator icon to display this shortcut menu:
  8. To start MS DTC either:
    • Choose Start. The Distributed Transaction Coordinator icon turns green once MS DTC has started.
    • Or
    • Choose Configure. When the MS DTC Configuration dialog box displays, choose the Start button.
  9. Right-click the Distributed Transaction Coordinator icon.
  10. Choose the window you want to open: Transactions, Trace, Statistics, or Configure. These windows are described in the following sections.

Note You can repeat the above procedure to open, one-by-one, the management interface on several servers; that is, you can display the management interface for server 1, server 2, server 3, and so on. This allows system-wide administration of all transaction participants from a single location.

For example, a system administrator can see that a transaction is shown as committed on one participating server and in doubt on another. The administrator can diagnose the problem (perhaps a failed connection between the commit coordinator and the in-doubt server) and take the appropriate action to resolve the transaction.


The MS DTC Transactions Window

Use the MS DTC Transactions window to:

  • Monitor the status of a transaction
  • Manually resolve a transaction

The MS DTC Transactions window lists the current transactions in which a local MS DTC participates. Because the MS DTC can support thousands of concurrent transactions, the MS DTC Transactions window lists only:

  • Transactions whose status is in doubt.
  • Transactions that have remained in the same state for the period of time specified in the MS DTC Configuration dialog box (see The MS DTC Configuration Dialog Box).

Transactions that may need to be manually resolved fall into two categories:

  • In-doubt transactions (usually the result of a failed connection between participating servers).
  • Transactions that have been committed but not acknowledged by a SQL Server, usually because of a SQL Server failure that prevents the SQL Server from starting or causes a SQL Server to lose its log.

Database locks are maintained on one or more participating servers as long as a transaction remains unresolved (neither committed nor aborted). It is occasionally necessary to manually resolve a transaction to release the locks and make database resources available to other network users.


Monitoring Transaction States

Transaction states are represented by the following icons in the Large Icon view of the MS DTC Transactions window:

Active

The transaction has been started.

Aborting

The transaction is aborting. The commit coordinator is notifying all participants that the transaction must abort.

It is not possible to change the transaction outcome at this point.

Aborted

The transaction has aborted. All participants have been notified or are currently inaccessible. Once a transaction has aborted, it is immediately removed from the list of transactions in the MS DTC Transactions window.

It is not possible to change the transaction outcome at this point.

Preparing

The client application has issued a commit request. The commit coordinator is collecting prepare responses from all participants.

Prepared

All participants have responded yes to prepare.

In Doubt

The transaction is prepared, is coordinated by a different MS DTC, and the coordinating MS DTC is inaccessible. The system administrator can force the transaction to commit or abort by right-clicking in the Transactions window and choosing the Resolve/Commit or Resolve/Abort command. Once a forced outcome is executed, the transaction is designated as forced commit or forced abort.

Caution Do not manually force an in-doubt transaction until you have read Manually Resolving Transactions.

Forced Commit

The administrator forced the in-doubt transaction to commit (see In Doubt).

Forced Abort

The administrator forced the in-doubt transaction to abort (see In Doubt).

Notifying Committed

The transaction has prepared successfully and the commit coordinator is notifying participants that the transaction has been committed. The commit coordinator does not forget the transaction until all participants have acknowledged receiving (and logging) the commit request.

It is not possible to change the transaction outcome at this point.

Only Failed Remain to Notify

The commit coordinator has notified all connected participants that the transaction has committed. The only participants not notified are those that are currently inaccessible.

The system administrator can force a subordinate MS DTC to forget the transaction by right-clicking in the Transactions window and choosing the Resolve/Forget command.

Caution Do not manually force an in-doubt transaction until you have read Manually Resolving Transactions.

Committed

The transaction has committed and all participants have been notified. Once a transaction commits, it is immediately removed from the list of transactions in the MS DTC Transactions window.

It is not possible to change the transaction outcome at this point.


The View Option

You can set status icons to display in the MS DTC Transactions window in these formats:

  • Large Icon
  • Small Icon
  • Details
  • List

Small Icon and List display the most transactions at any one time. Details provides the most information about the transactions, and Large Icon displays transactions in the most readable format. The options are described in the following sections.


List

The List option displays transactions sequentially in a column.

If a text description for the transaction is provided by the application or stored procedure that begins the transaction, then that description appears next to the transaction icon. If no text description is provided, then transactions are numbered sequentially as they arrive on a given node.

Text descriptions are not necessarily unique, and a transaction's sequence number on one node will not necessarily match the sequence number of the same transaction on a different node. Therefore, to identify a specific transaction, always rely on the unit of work ID (a transaction's global unique identifier), which is displayed when the View option is set to Details.


Details

The Details option lists transactions in a single column and provides these two columns of information:

  • The network node on which the transaction was begun.
  • The unit of work ID associated with each transaction. This is the transaction's global unique identifier. It is generated by MS DTC when the transaction begins.


Large Icon

The Large Icon option displays transactions as large icons that are arranged sequentially in rows across the screen. Large icons are easiest to read, but they decrease the number of transactions that display.


Small Icon

The Small Icon option displays transactions as small icons that are arranged sequentially in rows across the screen.


Setting the View Option

To set the view option
  1. Right-click any icon in the MS DTC Transactions window.

    This menu displays:

  2. Choose View.

    This menu displays:

  3. Choose the view you want.


Manually Resolving Transactions

Occasionally, you may need to force a transaction to either commit or abort. This can be necessary, for example, when a communication line fails between two nodes on the network. Once a transaction has been manually committed or aborted, it is often necessary to also manually force a node to "forget" the transaction (that is, to delete the transaction from the local MS DTC log file).

The following example illustrates a case in which a transaction is manually committed. In this example, the following conditions are assumed:

  • The MS DTC on SQL Server node A is the commit coordinator.
  • The lines of communication along which the two-phase commit protocol is conducted proceed sequentially from node A to node D.
  • Phase 1 of the two-phase commit protocol has concluded, and the commit coordinator has written a COMMITTED record to its log.
  • Communication fails between nodes B and C during Phase 2 of the two-phase commit protocol.
  • The transaction is left in the following unresolved state:

Because the line of communication between nodes A and B is still intact, B has also committed the transaction. Both nodes, however, must retain the COMMITTED records in their log files until nodes C and D confirm that they have also committed the transaction. To resolve the transaction (and thereby release the database locks on nodes C and D), the system administrator forces node C to commit the transaction.

Because the line of communication between nodes C and D is still intact, the forced commit on node C allows the transaction to commit on node D. Node D can now release its database locks and forget the transaction. Once node D confirms to node C that it has committed and forgotten the transaction, node C can also release its locks and forget the transaction.

The transaction is now committed on all nodes; however, because node C cannot communicate its commit to node B, node B must continue to remember the transaction. Because node B has not forgotten the transaction, node A must also remember it. To complete the transaction, the system administrator forces node B to forget the transaction. Node B's forced forget allows node A to also forget the transaction. The two-phase commit protocol has been manually concluded, and the transaction is complete.

Important Because of the outgoing-incoming communication pattern of the two-phase commit protocol, manual resolves should be done on nodes immediately adjacent to the break in communications. Therefore, in the example above, the forced commit occurs on node C (not D), and the forced forget occurs on node B (not A).

You must manually resolve transactions that are either in the In Doubt or the Only Failed Remain to Notify state.

In Doubt State

The In Doubt state indicates that the transaction is on a child MS DTC and that the parent MS DTC is inaccessible. To resolve the in-doubt transaction, follow these steps:

  1. Use the MS DTC Transactions window to locate the transaction's immediate parent.
  2. Use the MS DTC Transactions window on the parent node to determine the outcome of the in-doubt transaction.
    • If the transaction is not shown in the MS DTC Transactions window, then it has been aborted, and you can manually abort the transaction on the child node.
    • If the transaction is shown on the parent node as Only Failed Remain to Notify, then it has committed, and you can manually commit the transaction on the child node.
    • If the transaction is shown as In Doubt on the parent node, use the MS DTC Transactions window on the parent node to locate the transaction's next immediate parent. Continue to follow the transaction up the commit tree until you locate the parent on which the transaction is either aborted (not shown) or committed (in the Only Failed Remain to Notify state). If the transaction is aborted on the parent node, manually force the transaction to abort on that node's immediate child. If the transaction is committed on the parent node, manually force the transaction to commit on the child node.
  3. Once you have either manually committed or aborted the transaction on the child node, manually force the immediate parent to forget the transaction.
Only Failed Remain to Notify State

The Only Failed Remain to Notify state indicates that the transaction has committed, but some subordinate MS DTCs have not been notified. Resolving transactions that are in the Only Failed Remain to Notify state is difficult because the system provides no easy method of locating the subordinate MS DTCs that have not been notified of the transaction outcome. You must do this manually by examining each system and looking for in-doubt transactions with a global identifier that matches that of the Only Failed Remain to Notify transaction. Once you have located the subordinate MS DTCs, force the transaction to commit on each one. Once you have manually committed the transaction on all subordinate MS DTCs, return to the MS DTC that shows the transaction in the Only Failed Remain to Notify state, and force that MS DTC to forget the transaction.

Caution Do not manually forget a transaction until all subordinate MS DTCs have been notified of the transaction outcome.

To manually resolve a transaction
  1. In the MS DTC Transactions window, right-click the icon of the transaction you want to resolve.

    This menu displays:

  2. Choose Resolve.

    This menu displays:

  3. Choose the command you want.


The MS DTC Trace Window

The MS DTC Trace window lists current trace messages issued by MS DTC. Tracing allows the system administrator to view the current status of various MS DTC activities, such as startup and shutdown, and to track potential problems by viewing additional debugging information.

The system administrator specifies the level of tracing that is displayed by using the Trace slider in the View group of the MS DTC Configuration dialog box. More tracing means a slower MS DTC because more trace messages have to be sent for display from within the MS DTC service process, which is generally busy with transaction coordination work.


Trace Severity Levels

MS DTC tracing supports these levels of severity:

Errors

Something has happened that requires restarting MS DTC. For example, a corrupt log file is detected.

Warnings

Something could go wrong soon.

Information

Information is provided about infrequent events, such as startup and shutdown.

Trace

Debugging information is provided about events such as new client connections or resource manager enlistments.


The Windows NT Event Log

All error, warning, and informational traces are routed to the Windows NT event log regardless of whether SQL Enterprise Manager is running and regardless of the Trace slider setting in the View group of the MS DTC Configuration dialog box.


Trace Sources

The tracer and the Windows NT event log tag each message with its source.

Source | Description
SVC | The MS DTC Service
LOG | The MS DTC log
CM | The MS DTC network connection manager


Clearing the MS DTC Trace Window

To clear all messages from the MS DTC Trace window
  1. Right-click in the MS DTC Trace window.
  2. From the View menu, choose Clear.


The MS DTC Statistics Window

Ideally, in a distributed transaction environment, transaction managers should be left running even when they are disconnected from the network. One advantage of a continuously running MS DTC is that it allows for accumulated statistics over the "lifespan" of the MS DTC operation. The system administrator can use these statistics to monitor the system's performance and make adjustments to the system when necessary.

The MS DTC Statistics window displays statistical information about the transactions in which a server participated. Some of the statistics are cumulative; others reflect current performance.

Important to remember that when you stop the MS DTC, the values of all cumulative statistics will reset to zero when you restart the MS DTC.

Important When you stop the MS DTC, the values of all cumulative statistics will reset to 0 when you restart the MS DTC.

The MS DTC Statistics window contains four groups of information:

  • Current
  • Aggregate
  • Response Times (milliseconds)
  • MS DTC Started

Each group of information is described in the following sections.


The Current Group

For information about the current MS DTC session, refer to these statistics:

  • Active¾The current number of transactions that have not yet completed the two-phase commit protocol.
  • Max. Active¾The highest number of active transactions at any time during the current MS DTC operating session.
  • Indoubt¾The current number of transactions that are unable to commit because of a communication failure between the local SQL Server and the commit coordinator.

The size of the MS DTC log file determines the maximum allowable number of concurrent transactions. Once a transaction has committed or aborted, it is deleted from the log file. However, if the log file becomes full, the MS DTC on the local server cannot accept a new transaction until space to record the new transaction becomes available.

Together, the Active and Max. Active statistics measure the transaction load on a particular MS DTC. If, for example, the number of current transactions approaches the historical maximum, the system administrator can increase the size of the log file to allow for more transactions. If the number of current transactions is well below the maximum, the system administrator can decrease the size of the log file to conserve disk resources.

The system administrator can increase or decrease the size of the log file by using the MS DTC Configuration dialog box. For details, see The MS DTC Configuration Dialog Box.


The Aggregate Group

For aggregate values, refer to these statistics:

  • Committed¾The cumulative total of committed transactions. This number does not include forced (manually resolved) commits.
  • Aborted¾The cumulative total of aborted transactions. This number does not include forced (manually resolved) aborts.
  • Forced Commit¾The cumulative total of committed transactions that were manually committed.
  • Forced Abort¾The cumulative total of aborted transactions that were manually aborted.
  • Total¾The cumulative total of all transactions.


The Response Times Group

Response time is the duration of a transaction from the point that it began to the point that it was committed by the commit coordinator (aborted transactions and transactions whose outcomes were forced are not taken into account). The Response Times group shows the minimum, average, and maximum transaction response times in milliseconds.


The MS DTC Started Group

This group shows the date and time that the current MS DTC session started.


The MS DTC Configuration Dialog Box

Use the MS DTC Configuration dialog box to:

  • Change MS DTC display parameters.
  • Reset the MS DTC log.
  • Start and stop the MS DTC.

You can change display parameters while the MS DTC is running. You must stop the MS DTC before resetting the log and timers.

To access the MS DTC Configuration dialog box
  • Click the right mouse button on the MS DTC icon in the Server Manager window and from the menu, select Configure.


The View Group

You can set the following MS DTC display parameters:

  • Display Refresh
  • Transactions Shown
  • Trace

The parameters and their supported settings are described in the following sections.


Display Refresh

Use the Display Refresh slider to control how often the transaction list, trace messages, and statistical information are sent from the MS DTC process to the graphical interface. More frequent updates increase administrative overhead on the running transactions but also provide more current information on the running MS DTC. These are the values on the slider:

  • Update the display every 20 seconds. (Shown as "Infrequently" on the slider.)
  • Update the display every 10 seconds.
  • Update the display every 5 seconds (default).
  • Update the display every 3 seconds.
  • Update the display every 1 second. (Shown as "Frequently" on the slider.)


Transactions Shown

Use the Transactions Shown slider to control how long a transaction must be active before being displayed on the graphical interface. These are the values on the slider:

  • Show 5 minute old transactions. (Shown as "Very Old" on the slider.)
  • Show 1 minute old transactions.
  • Show 30 second old transactions (default).
  • Show 10 second old transactions.
  • Show 1 second old transactions. (Shown as "New + Old" on the slider.)


Trace

Use the Trace slider to control the level of trace information sent from the MS DTC process to the graphical interface. These are the settings on the slider:

  • Send no traces.
  • Send only error traces.
  • Send error and warning traces.
  • Send error, warning, and informational traces (default).
  • Send all traces.

Sending no traces increases MS DTC's speed performance. Sending all traces decreases MS DTC's speed performance.


The Log Group

The MS DTC log file is called MSDTC.LOG.

Caution Do not reset the MS DTC log file while MS DTC has unresolved transactions. Unresolved transactions are displayed in the MS DTC Transactions window in SQL Enterprise Manager while MS DTC is running.

To change the size or location of the log file
  1. Choose the Stop button to stop the MS DTC.
  2. Wait for the Status indicator to show Stopped before making any changes.
  3. To change the log file size, use the Size slider.

    To change the log file location, use the Drive and Directory boxes.

    After changing the size or location of the log file, choose the Reset Log button.

  4. Choose the Start button to restart the MS DTC.


Remote Administration

By using the graphical management interface on a server or client node, you can manage the MS DTCs on remote server nodes. Doing so allows the system administrator to use an individual MS DTC installation as a central console for managing MS DTC transactions.

Remote administration of MS DTC requires the user of SQL Server Enterprise Manager to have permissions to the following registry key on the computers on which the MS DTCs reside:

HKEY_CLASSES_ROOT/CID

By default, Windows NT enables remote access to registry entries, so if you wish to prevent users from remotely modifying MS DTC parameters, you should change the permissions on the HKEY_CLASSES_ROOT/CID key and all of its subkeys.

To change permissions for remote access
  1. At the command prompt, type regedt32.
  2. From the Window menu, select HKEY_CLASSES_ROOT on Local Machine.
  3. From the list of keys displayed, select CID.
  4. From the Security menu, select Permissions.
  5. In the Registry Key Permissions dialog box, check the Replace Permission on Existing Subkeys check box.
  6. In the Name box, select Everyone.
  7. Click the Remove button.
  8. Click OK.
  9. Respond Yes to the message box to override permissions.

You can also assign full permissions to specific users as follows.

To assign full permissions
  1. Do steps 1-4, above.
  2. In the Registry Key Permissions dialog box, click the Add button.
  3. In the Add Users and Groups dialog box, in the Name box, type the user names of those to whom you want to assign full permissions to.
  4. In the Type of Access box, select Full Control.
  5. Click OK.
  6. In the Registry Key Permissions dialog box, click OK.
  7. Respond Yes to the message box to override permissions.


Chapter 4 Application Development

Application Development

About the Example Programs

Application Development Using Transact-SQL

Application Development Using C or C++

Advanced MS DTC Programming Techniques in C and C++

Applications that update distributed data are vulnerable to a wide variety of failures, including failure of the client application, the database servers, or the network connections between the client application and the database servers. The application must be able to detect and recover from these failures. Including distributed transactions in your application makes recovery easy.

The Microsoft Distributed Transaction Coordinator (MS DTC) is a robust, high performance, scalable, and easy-to-use distributed transaction manager for Microsoft Windows NT and Microsoft Windows 95 operating systems. Application programmers can use MS DTC to simplify the development of applications that:

  • Are written in Transact-SQL® and that make changes to SQL data contained in two or more SQL Servers.
  • Are written in C or C++ and use DB-Library™ or ODBC and that make changes to SQL data contained in two or more SQL Servers.

Applications written in Visual Basic cannot initiate and control MS DTC transactions directly. Visual Basic applications can use MS DTC transactions by calling Transact-SQL stored procedures that initiate and control MS DTC transactions.

This chapter describes how to develop applications that use MS DTC transactions to change SQL data contained in two or more SQL Servers. It first introduces the example program that is used throughout the chapter. It next describes how to develop MS DTC applications in SQL Server's Transact-SQL programming language. Finally, it describes how to develop MS DTC applications in C or C++.


About the Example Programs

The Microsoft SQL Server Programmer's Toolkit (PTK) includes sample MS DTC applications for Transact-SQL, ODBC, and DB-Library. The samples are located in the \PTK\SAMPLES\MSDTC directory on the SQL Workstation CD.

The examples use the Microsoft SQL Server pubs database that is installed by Microsoft SQL Server. To use the example programs, identical copies of the pubs database must exist on two systems. The example programs use an MS DTC distributed transaction to update the address of an author on both databases.


Application Development Using Transact-SQL

Applications that are written in Transact-SQL can use MS DTC transactions. Using MS DTC through Transact-SQL stored procedures is attractive for these reasons:

  • Application programming is easy because SQL Server's Transact SQL language provides simple interfaces for beginning, committing, and aborting distributed transactions.
  • The cost of committing a transaction can be lower when SQL Server initiates and commits the transaction. When SQL Server initiates the transaction, the MS DTC transaction manager and SQL Server are on the same system. This reduces the cost of committing the transaction, because the transaction manager on the client application's system does not need to participate in the two-phase commit protocol.
  • Setup and administration are easy because there is no need to install MS DTC on client machines.

Transact-SQL applications can initiate MS DTC transactions in two ways: They can explicitly initiate transactions by calling the Transact-SQL BEGIN DISTRIBUTED TRANSACTION statement, or they can rely on SQL Server to implicitly initiate MS DTC transactions when they are needed. Both of these techniques are illustrated in the examples that follow.

When a Transact-SQL application uses MS DTC transactions, the application can call a remote stored procedure in another SQL Server under the protection of a single distributed transaction. SQL Server and MS DTC automatically propagate the MS DTC transaction from one SQL Server to the other. If the remote stored procedure calls other remote stored procedures in other SQL Servers, these SQL Servers will also participate in the transaction. Transaction propagation occurs regardless of whether the transaction was initiated explicitly or implicitly.

If SQL Server and MS DTC encounter an error while propagating an MS DTC transaction from one system to another, the entire transaction is aborted. This might occur, for example, if the network connection between the two systems fails.

SQL Server initiates and propagates MS DTC transactions for applications written in Transact-SQL. However, Transact-SQL applications cannot directly access MS DTC transaction objects. They cannot return MS DTC transaction objects to the client application that called them. They cannot propagate MS DTC transactions objects to extended stored procedures that they call. In short, MS DTC transactions initiated by SQL Server cannot be directly manipulated by the Transact-SQL application or exported outside of SQL Server by the Transact-SQL application.


Finding Further Information Regarding Transact-SQL

For more information about developing applications in Transact-SQL, see the Microsoft SQL Server Transact-SQL Reference and What's New in SQL Server 6.5.


SQL Server Explicitly Initiated Transactions

A Transact-SQL application can explicitly initiate an MS DTC transaction by calling the Transact-SQL BEGIN DISTRIBUTED TRANSACTION statement. An explicitly initiated transaction works as follows:

  1. When the application calls the Transact-SQL BEGIN DISTRIBUTED TRANSACTION statement, SQL Server calls the MS DTC ITransactionDispenser::BeginTransaction method and obtains a transaction object that represents the transaction. The call to BEGIN DISTRIBUTED TRANSACTION can include a transaction description. The transaction description is displayed by the MS DTC management interface in the MS DTC Transactions window.

    After obtaining the transaction object, SQL Server enlists in the transaction with its local MS DTC transaction manager. This permits SQL Server to participate in the two-phase commit protocol and to receive transaction commit or abort notifications from MS DTC.

  2. All database updates, inserts, and deletes that are performed by the application are performed within the MS DTC transaction.
  3. If the application calls a remote stored procedure in another SQL Server, the originating SQL Server propagates the MS DTC transaction with the call to the remote stored procedure, and the remote SQL Server also enlists in the transaction. All changes to both SQL Servers are protected by the MS DTC transaction.
  4. When the work of the transaction is complete, the application calls the Transact-SQL COMMIT TRANSACTION statement. In response to the COMMIT TRANSACTION call, SQL Server calls the MS DTC ITransaction::Commit method. MS DTC uses the two-phase commit protocol to coordinate commitment of the transaction. Alternatively, the application could call the Transact-SQL ROLLBACK TRANSACTION statement. In this case, SQL Server would call the MS DTC ITransaction::Abort method to undo the effects of the transaction from both SQL Servers.
  5. The application can then go on to perform more transactions.

A call to BEGIN DISTRIBUTED TRANSACTION affects subsequent calls to other transaction-related Transact-SQL statements. For more information, see the BEGIN DISTRIBUTED TRANSACTION statement in What's New in SQL Server 6.5.

This example shows how an MS DTC transaction that is explicitly initiated can be used within a stored procedure to ensure that two SQL Server databases are updated consistently. The change_addr stored procedure initiates an MS DTC transaction, updates its local pubs database, calls the update_addr remote stored procedure to update the remote pubs database, and then commits the MS DTC transaction.

/*******************************************************/
/* Using BEGIN DISTRIBUTED TRANSACTION to explicitly   */
/* initiate MS DTC transactions.                       */
/*******************************************************/
CREATE PROCEDURE change_addr(@au_id varchar(11),
                             @addr varchar(40),
                             @toserver varchar(12) ) AS
declare @execstr varchar(200)

/* Start a Transaction */
BEGIN DISTRIBUTED TRANSACTION change_author_address

/* Change local author information */
update authors set address = @addr where au_id = @au_id

/* Make a string with the remote server name and       */
/* stored procedure to execute                         */
select @execstr = @toserver + '.pubs..update_addr '

/* Update remote server. (Note that these servers must */
/* be added to each other by using sp_addserver and    */
/* sp_addremotelogin.)                                 */
exec @execstr @au_id, @addr

/* Commit the MS DTC transaction */
COMMIT TRANSACTION

The following remote stored procedure is used to update the remote pubs database.

/********************************************************/
/* Stored procedure to update an author's address on    */
/* the remote server.                                   */
/********************************************************/
CREATE PROCEDURE update_addr(@au_id varchar(11),
                             @addr varchar(40)) AS
update authors set address = @addr where au_id = @au_id


SQL Server Implicitly Initiated Transactions

The Transact-SQL BEGIN DISTRIBUTED TRANSACTION statement provides an explicit way for a Transact-SQL application to begin a distributed transaction. However, you must change existing Transact-SQL applications to initiate MS DTC transactions in this way. SQL Server provides a way for you to use MS DTC transactions without any change to your existing Transact-SQL application. SQL Server implicitly initiated transactions share all of the benefits of explicitly initiated transactions but have these additional advantages:

  • Existing Transact-SQL applications can use distributed transactions with no change to the application.
  • Application programming is easy because SQL Server automatically initiates distributed transactions only when they are needed. SQL Server only initiates an MS DTC transaction when no distributed transaction is in force and a Transact-SQL application in one SQL Server calls a remote stored procedure in another SQL Server.

SQL clients and the SQL system administrator control whether SQL Server implicitly initiates MS DTC transactions. There are two SQL Server options for controlling implicit transactions:

  • The REMOTE_PROC_TRANSACTIONS option is a session-level option that the Transact-SQL application controls by using the Transact-SQL SET statement. When this session-level option is set and a Transact-SQL application calls a remote stored procedure, SQL Server automatically initiates an MS DTC transaction.
  • The REMOTE PROC TRANS option is a server configuration parameter that the system administrator controls by using the sp_configure statement. The REMOTE PROC TRANS server configuration parameter determines the default setting of the REMOTE_PROC_TRANSACTIONS session-level option. It permits the system administrator to enable implicit MS DTC transactions for an entire SQL Server system.

The REMOTE_PROC_TRANSACTIONS session-level option and the REMOTE PROC TRANS server configuration parameter have no affect on programs that initiate MS DTC transactions explicitly by using the BEGIN DISTRIBUTED TRANSACTION statement.

The first example illustrates the REMOTE_PROC_TRANSACTIONS session-level option and the second illustrates the REMOTE PROC TRANS server configuration parameter.


REMOTE_PROC_TRANSACTIONS Session Option

The REMOTE_PROC_TRANSACTIONS option is a session-level option that the Transact-SQL application controls by using the Transact-SQL SET statement. When the session-level option is ON and a Transact-SQL application calls a remote stored procedure, SQL Server implicitly initiates an MS DTC transaction. When this session-level option is OFF, no MS DTC transactions are implicitly initiated on the session. The session-level option is controlled by using the Transact-SQL SET statement as follows:

set remote_proc_transactions {ON|OFF}

For details about REMOTE_PROC_TRANSACTIONS, see What's New in SQL Server 6.5.

A SQL Server implicitly initiated transaction works as follows:

  1. When a Transact-SQL application calls the BEGIN TRANSACTION statement, SQL Server initiates a local SQL Server transaction. It does not initiate an MS DTC transaction.
  2. All changes that the Transact-SQL application makes to the local database are performed within the local transaction.
  3. If the Transact-SQL application calls a remote stored procedure in another SQL Server system, SQL Server determines if the REMOTE_PROCEDURE_TRANSACTIONS session-level option has been enabled. If so, SQL Server initiates an MS DTC transaction by calling the ITransactionDispenser::BeginTransaction method and obtaining a transaction dispenser object that represents the MS DTC transaction. SQL Server enlists in the transaction with its local MS DTC transaction manager. This permits SQL Server to participate in the two-phase commit protocol.
  4. SQL Server propagates the MS DTC transaction with the call to the remote stored procedure. All updates, inserts, and deletes (including those that the Transact-SQL application had previously made to the local database within the local transaction) will now be protected within the MS DTC transaction.
  5. When the work of the transaction is complete, the Transact-SQL application calls the COMMIT TRANSACTION statement. SQL Server determines whether a local or MS DTC transaction is in force. If an MS DTC transaction is in force, SQL Server calls the MS DTC ITransaction::Commit method. MS DTC uses the two-phase commit protocol to coordinate commitment of the transaction. Alternatively, the Transact-SQL application could call the ROLLBACK TRANSACTION statement. In this case, SQL Server calls the MS DTC ITransaction::Abort method to undo the effects of the transaction.
  6. The Transact-SQL application then can go on to perform more transactions.

    For information about the BEGIN TRANSACTION, COMMIT TRANSACTION, and ROLLBACK TRANSACTION statements, see the Microsoft SQL Server Transact-SQL Reference.

This example shows how SQL Server implicitly initiates a distributed transaction when one is needed and the REMOTE_PROC_TRANSACTIONS session-level option is ON. Note that the Transact-SQL application continues to use the BEGIN TRANSACTION statement rather than the new BEGIN DISTRIBUTED TRANSACTION statement.

/*******************************************************/
/* Using the session option for implicit SQL Server    */
/* initiated transactions.                             */
/*******************************************************/

CREATE PROCEDURE change_addr(@au_id varchar(11),
                             @addr varchar(40),
                             @toserver varchar(12) ) AS
declare @execstr varchar(200)

/* Set the REMOTE_PROC_TRANSACTIONS option to enable   */
/* MS DTC transactions                                 */
set remote_proc_transactions ON

/* Begin a local SQL Server Transaction.               */
/* This transaction will become an MS DTC distributed  */
/* transaction when the remote stored procedure is     */
/* called because the REMOTE_PROC_TRANSACTIONS option  */
/* is ON.                                              */
BEGIN TRANSACTION

/* Change local author information */
update authors set address = @addr where au_id = @au_id

/* Make a string with the remote server name and       */
/* stored procedure to execute                         */
select @execstr = @toserver + '.pubs..update_addr '

/* Update remote server. This statement causes SQL     */
/* Server to begin an MS DTC distributed transaction.  */
/* (Note that these servers must be added to each      */
/* other by using sp_addserver and sp_addremotelogin.) */
exec @execstr @au_id, @addr

/* Commit the MS DTC transaction */
COMMIT TRANSACTION

The following remote stored procedure is used to update the remote pubs database.

/********************************************************/
/* Stored procedure to update an author's address on    */
/* the remote server.                                   */
/********************************************************/
CREATE PROCEDURE update_addr(@au_id varchar(11),
                             @addr varchar(40)) AS
update authors set address = @addr where au_id = @au_id


REMOTE PROC TRANS Server Configuration Parameter

When the setting for the REMOTE_PROC_TRANSACTIONS session-level option is not specified, it is based on the value of the REMOTE PROC TRANS server configuration parameter.

REMOTE PROC TRANS | REMOTE_PROC_TRANSACTIONS
0 | OFF
1 | ON

By default, the value of the REMOTE PROC TRANS server configuration parameter is 0. This ensures compatibility with earlier SQL Server releases, which did not support distributed transactions. The value of the REMOTE PROC TRANS server configuration parameter can be changed by using the sp_configure system stored procedure. The RECONFIGURE WITH OVERRIDE statement must be entered after the parameter value is changed. You can set the value of REMOTE PROC TRANS as follows:

sp_configure 'remote proc trans', 1
reconfigure with override

Only a SQL Server system administrator can enter the RECONFIGURE WITH OVERRIDE statement.

The REMOTE PROC TRANS server configuration parameter is dynamic. For new SQL Server sessions, the REMOTE_PROC_TRANSACTIONS session-level option is set based on the current value of REMOTE PROC TRANS.

For details about REMOTE PROC TRANS, see the sp_configure in What's New in SQL Server 6.5.

The following example shows how an MS DTC distributed transaction can be used with an existing Transact-SQL application to ensure that two SQL Servers are updated consistently. SQL Server implicitly initiates the distributed transaction when the remote stored procedure is called and the REMOTE PROC TRANS server configuration parameter is ON. Note that the Transact-SQL application continues to use the BEGIN TRANSACTION statement rather than the new BEGIN DISTRIBUTED TRANSACTION statement.

The SQL Server system administrator first uses sp_configure to enable the REMOTE PROC TRANS server configuration parameter:

SP_CONFIGURE 'REMOTE PROC TRANS', 1
RECONFIGURE WITH OVERRIDE

/*******************************************************/
/* Using the server configuration parameter for        */
/* implicit SQL Server initiated transactions.         */
/*******************************************************/

CREATE PROCEDURE change_addr(@au_id varchar(11),
                             @addr varchar(40),
                             @toserver varchar(12) ) AS
declare @execstr varchar(200)

/* Begin a local SQL Server Transaction.               */
/* This transaction will become an MS DTC distributed  */
/* transaction when the remote stored procedure is     */
/* called because the REMOTE PROC TRANS server         */
/* configuration parameter is ON.                      */
BEGIN TRANSACTION

/* Change local author information */
update authors set address = @addr where au_id = @au_id

/* Make a string with the remote server name and       */
/* stored procedure to execute                         */
select @execstr = @toserver + '.pubs..update_addr '

/* Update remote server. This statement causes SQL     */
/* Server to begin an MS DTC distributed transaction.  */
/* (Note that these servers must be added to each      */
/* other by using sp_addserver and sp_addremotelogin.) */
exec @execstr @au_id, @addr

/* Commit the MS DTC transaction */
COMMIT TRANSACTION

The following remote stored procedure is used to update the remote pubs database.

/********************************************************/
/* Stored procedure to update an author's address on    */
/* the remote server.                                   */
/********************************************************/
CREATE PROCEDURE update_addr(@au_id varchar(11),
                             @addr varchar(40)) AS
update authors set address = @addr where au_id = @au_id


Application Development Using C or C++

Applications written in C or C++ can directly initiate MS DTC transactions. Using C or C++ to directly initiate MS DTC transactions is attractive for these reasons:

  • An application can use any OLE transaction-compliant resource manager. For the initial release of MS DTC, SQL Server is the only supported resource manager; in future releases, other resource managers will be supported.
  • An application can explicitly control the scope and duration of the transaction.
  • An application can be coded in any programming language that supports the OLE Transaction interfaces for initiating and controlling MS DTC transactions. For the initial release of MS DTC, only the C and C++ programming languages support these interfaces.

C and C++ applications that use MS DTC transactions can access SQL Server by using either ODBC or DB-Library. Both of these techniques are illustrated in the examples that follow.


Finding Further Information Regarding C and C++

For more information about developing applications in C and C++, see these sources.

Programming environment | Information source
C or C++ | Microsoft Visual C++ online documentation
DB-Library | What's New in SQL Server 6.5 Microsoft SQL Server Programming DB-Library for C
ODBC | What's New in SQL Server 6.5 Programming ODBC for Microsoft SQL Server ODBC 2.0 Programmer's Reference and SDK Guide by Microsoft Press® Inside ODBC by Kyle Geiger
OLE Component Object Model | OLE 2 Programmer's Reference by Microsoft Press Inside OLE, second edition, by Kraig Brockschmidt Microsoft Developer Network (MSDN) Development Library (a CD ROM subscription from Microsoft)


Required Files

These files are required for developing MS DTC applications with C or C++.

File | Description
ODBCSS.H | You must include this header file in source files that use ODBC.
XOLEHLP.H | You must include this header file in source files that use the DtcGetTransactionManager interface.
TRANSACT.H | You must include this header file in source files that use any of these MS DTC interfaces: ITransaction ITransactionDispenser ITransactionOptions ITransactionOutcomeEvents
XACTOMSG.H | This header file is automatically included by XOLEHLP.H.
XOLEHLP.LIB | You must link this library file with applications that call the DtcGetTransactionManager function.

To install these files, run the Microsoft SQL Server PTK setup program and select the MS DTC development libraries checkbox. The header files are installed in the MSDTC\INCLUDE subdirectory of the directory that you specify when you run PTK setup. The library file is installed in the MSDTC\LIB subdirectory of the directory that you specify when you run PTK setup.

C or C++ applications that initiate MS DTC transactions must be used on systems on which either the MS DTC server or the MS DTC client has been installed. For information about these installation options, see Setup.


An ODBC-based Application

This example shows the steps that a C or C++ application takes to use ODBC to update two SQL Server databases within an MS DTC transaction. It shows the OLE transaction calls for initiating and committing MS DTC transactions as well as the ODBC call to propagate an MS DTC transaction from the application to SQL Server. Note that the complete ODBC example is not shown here but it can be found in the Microsoft SQL Server Programmer's Toolkit.

These are the steps that the application performs:

  1. The application first declares variables and completes initialization. Note that it is not necessary for the application to call either CoInitialize or OleInitialize. MS DTC does not depend on these calls.
  2. The application connects to MS DTC and obtains an interface pointer to the transaction dispenser object by calling DtcGetTransactionManager.
  3. The application uses standard ODBC calls to connect to two databases under the control of different SQL Servers.
  4. The application begins an MS DTC transaction by calling the ITransactionDispenser::BeginTransaction method on the transaction dispenser object. BeginTransaction initiates a new transaction and returns a transaction object that represents the transaction.
  5. The application calls the ODBC SQLSetConnectOption function to associate the transaction with each of the ODBC database connections. All further work performed on the ODBC connections is performed within the MS DTC transaction.
  6. The application uses standard ODBC calls to associate a statement handle with each ODBC database connection. The application then updates each of the databases.
  7. The application calls ITransaction::Commit on the transaction object. MS DTC performs the two-phase commit protocol to commit the transaction. If any SQL Server database is unable to commit the transaction, the transaction is aborted, and the transaction's effects are undone from all databases that were modified. When the transaction completes, the application releases the transaction dispenser object.

    You cannot use the ODBC database connections until ITransaction::Commit completes and you call SQLSetConnectOption to enlist in a new MS DTC transaction. If you reuse the ODBC connection before doing this, an error will result.

    Note If you have used an ODBC connection with an MS DTC transaction and you want to use the same ODBC connection with a local SQL Server transaction, you must first call SQLSetConnectOption and pass a NULL transaction. By passing a NULL transaction to the ODBC SQLSetConnectOption function, you instruct SQL Server to use local SQL Server transactions.

  8. When no more transactions are needed, the application releases the transaction dispenser object and closes all ODBC connections.
    void main(int argc, char **argv)
{

ITransactionDispenser    *pTransactionDispenser;
ITransaction                *pTransaction;
HRESULT                    hr = S_OK ;
BOOL                        tf = 0 ;
TCHAR                    SqlStatement[STR_LEN*2];

// Initialize globals & validate command line arguments
InitGlobals(argc,argv);

// Obtain the ITransactionDispenser Interface pointer
// by calling DtcGetTransactionManager()
hr = DtcGetTransactionManager(
        NULL,                 // LPTSTR pszHost,
        NULL,                // LPTSTR pszTmName,
        IID_ITransactionDispenser,    // REFIID rid,
        0,                    // DWORD dwReserved1,
        0,                    // WORD wcbReserved2,
        0,                    // void FAR * pvReserved2,
        (void **)&pTransactionDispenser     // void**    ppvObject) ;
if (FAILED (hr))
{
printf("DtcGetTransactionManager failed: %x\n", hr);
       exit (1);
}

// Initialize the ODBC environment handle.
if (SQL_NULL_HENV == gHenv)
{
ProcessRC("SQLAllocEnv",0,SQLAllocEnv(&gHenv));
}

// Establish connection to database on server#1
LogonToDB(&gSrv1);

// Establish connection to database on server#2
LogonToDB(&gSrv2);

// Loop performing distributed transactions
for (INT i = 0; i < 5; i++)
{

// Initiate an MS DTC transaction
hr = pTransactionDispenser->BeginTransaction(
            NULL,                // IUnknown __RPC_FAR *punkOuter,
            ISOLATIONLEVEL_ISOLATED,    // ISOLEVEL isoLevel,
            ISOFLAG_RETAIN_DONTCARE,    // ULONG isoFlags,
            NULL,                // ITransactionOptions *pOptions
            &pTransaction        //  ITransaction **ppTransaction) ;

if (FAILED (hr))
{
printf("BeginTransaction failed: %x\n",hr);
exit(1);
}

// Enlist each of the data sources in the transaction
Enlist(&gSrv1,pTransaction);
Enlist(&gSrv2,pTransaction);

// Generate the SQL statement to execute on each
// of the databases
sprintf(SqlStatement,
  "update authors set address = '%s_%d' where au_id = '%s'",
   gNewAddress,i,gAuthorID);

// Perform updates on both of the DBs participating
// in the transaction
ExecuteStatement(&gSrv1,SqlStatement);
ExecuteStatement(&gSrv2,SqlStatement);

// Commit the transaction
hr = pTransaction->Commit(0,0,0);
if (FAILED(hr))
{
printf("pTransaction->Commit() failed: %x\n",hr);
exit(1);
}

// At end of each transaction, pTransaction-Release()
// must be called.
hr = pTransaction->Release();
if (FAILED(hr))
{
printf("pTransaction->Release() failed: %x\n",hr);
exit(1);
}

printf("Successfully committed Transaction #%d\n",i);

} // for

// release the transaction dispenser
pTransactionDispenser->Release();

// Free ODBC handles
FreeODBCHandles(&gSrv1);
FreeODBCHandles(&gSrv2);

// Free the global ODBC environment handle.
SQLFreeEnv(gHenv);
}

void LogonToDB(DBCONN *ptr)
{
RETCODE rc = 0;

rc = SQLAllocConnect(gHenv, &(ptr->hdbc) );

if (ProcessRC("SQLAllocConnect",ptr,rc))
{
rc = SQLConnect(ptr->hdbc,
(UCHAR *)(ptr->pszSrv),
SQL_NTS,
(UCHAR *)(ptr->pszUser),
SQL_NTS,
(UCHAR *)(ptr->pszPasswd),
SQL_NTS
);

ProcessRC("SQLConnect",ptr,rc);
}
}

void Enlist(DBCONN *ptr, ITransaction *pTransaction)
{
RETCODE rc = 0;

// Enlist database in the transaction
    rc = SQLSetConnectOption
(ptr->hdbc,
SQL_COPT_SS_ENLIST_IN_DTC,
(UDWORD)pTransaction);

ProcessRC("SQLSetConnectOption",ptr,rc);
}

void ExecuteStatement(DBCONN *ptr, LPTSTR pszBuf)
{
RETCODE rc = 0;

// Allocate a statement handle for use with SQLExecDirect
rc = SQLAllocStmt(ptr->hdbc,&(ptr->hstmt));

ProcessRC("SQLAllocStmt",ptr,rc);

// Execute the passed string as a SQL statement
    rc = SQLExecDirect(ptr->hstmt,(UCHAR *)pszBuf,SQL_NTS);

ProcessRC("SQLExecDirect",ptr,rc);

// Free the statement handle
rc = SQLFreeStmt(ptr->hstmt, SQL_DROP);
ptr->hstmt = SQL_NULL_HSTMT;

ProcessRC("SQLFreeStmt",ptr,rc);

}

void FreeODBCHandles(DBCONN *ptr)
{
SQLDisconnect(ptr->hdbc);

SQLFreeConnect(ptr->hdbc);

ptr->hdbc   = SQL_NULL_HDBC;
ptr->hstmt  = SQL_NULL_HSTMT;
}


A DB-Library-based Application

This example shows the steps that a C or C++ application takes to use DB-Library to update two SQL Servers within an MS DTC transaction. It shows the OLE transaction calls for initiating and committing MS DTC transactions as well as the DB-Library call to propagate an MS DTC transaction from the application to SQL Server. Note that the complete DB-Library example is not shown here but it can be found in the Microsoft SQL Server Programmer's Toolkit.

These are the steps that the application performs:

  1. The application first declares variables and completes initialization. Note that it is not necessary for the application to call either CoInitialize or OleInitialize. MS DTC does not depend on these calls.
  2. The application connects to MS DTC and obtains an interface pointer to the transaction dispenser object by calling DtcGetTransactionManager.
  3. The application uses standard DB-Library calls to connect to two databases under the control of different SQL Servers.
  4. The application begins an MS DTC transaction by calling the ITransactionDispenser::BeginTransaction method on the transaction dispenser object. BeginTransaction initiates a new transaction and returns a transaction object that represents the transaction.
  5. The application calls the DB-Library dbenlisttrans function to associate the transaction with each of the DB-Library database connections. All further work performed on the DB-Library connections is performed within the MS DTC transaction.

    The application passes two parameters to dbenlisttrans. The first parameter is the database process structure (DBPROC), which identifies the SQL Server connection. The second parameter is a pointer to the MS DTC transaction object. To learn more about dbenlisttrans, see What's New in SQL Server 6.5.

  6. The application uses standard DB-Library calls to associate a statement handle with each DB-Library database connection. The application then updates each of the databases.
  7. The application calls ITransaction::Commit on the transaction object. MS DTC performs the two-phase commit protocol to commit the transaction. If any SQL Server database is unable to commit the transaction, the transaction is aborted, and the transaction's effects are undone from all databases that were modified. When the transaction completes, the application releases the transaction dispenser object.

    You cannot use the DB-Library database connections until ITransaction::Commit completes and you call dbenlisttrans to enlist in a new MS DTC transaction. If you reuse the DB-Library connection before doing this, an error will result.

    Note If you have used a DB-Library connection with an MS DTC transaction and you want to use the same DB-Library connection with a local SQL Server transaction, you must first call dbenlisttrans and pass a NULL transaction. By passing a NULL transaction to the DB-Library dbenlisttrans function, you instruct SQL Server to use local SQL Server transactions.

  8. When no more transactions are needed, the application releases the transaction dispenser object and closes all DB-Library connections.
    void main(int argc, char **argv)
{

ITransactionDispenser    *pTransactionDispenser;
ITransaction                *pTransaction;
HRESULT                    hr = S_OK ;
TCHAR                    SqlStatement[STR_LEN*2];

// Initialize globals & validate command line arguments
InitGlobals(argc,argv);

// set error/msg handlers for this program
dbmsghandle((DBMSGHANDLE_PROC)msg_handler);
dberrhandle((DBERRHANDLE_PROC)err_handler);

// initialize LOGINREC structure
login = dblogin();

// Obtain the ITransactionDispenser Interface pointer
// by calling DtcGetTransactionManager()
hr = DtcGetTransactionManager(
        NULL,                 // LPTSTR pszHost,
        NULL,                // LPTSTR pszTmName,
        IID_ITransactionDispenser,    // REFIID rid,
        0,                    // DWORD dwReserved1,
        0,                    // WORD wcbReserved2,
        0,                    // void FAR * pvReserved2,
        (void **)&pTransactionDispenser     // void**    ppvObject) ;
if (FAILED (hr))
{
printf("DtcGetTransactionManager failed: %x\n", hr);
       exit (1);
}

// Establish connection to database on server#1
LogonToDB(&dbproc_server1,&gSrv1);

// Establish connection to database on server#2
LogonToDB(&dbproc_server2,&gSrv2);

// Loop performing distributed transactions
for (INT i = 0; i < 5; i++)
{

// Initiate an MS DTC transaction
hr = pTransactionDispenser->BeginTransaction(
            NULL,                // IUnknown __RPC_FAR *punkOuter,
            ISOLATIONLEVEL_ISOLATED,    // ISOLEVEL isoLevel,
            ISOFLAG_RETAIN_DONTCARE,    // ULONG isoFlags,
            NULL,                // ITransactionOptions *pOptions
            &pTransaction        //  ITransaction **ppTransaction) ;

if (FAILED (hr))
{
printf("BeginTransaction failed: %x\n",hr);
exit(1);
}

// Enlist each of the data sources on the transaction
Enlist(&gSrv1,dbproc_server1,pTransaction);
Enlist(&gSrv2,dbproc_server2,pTransaction);

// Generate the SQL statement to execute on each
// of the databases
sprintf(SqlStatement,
  "update authors set address = '%s_%d' where au_id = '%s'",
  gNewAddress,i,gAuthorID);

// Perform updates on both of the DBs participating
// in the transaction
ExecuteStatement(&gSrv1,dbproc_server1,SqlStatement);
ExecuteStatement(&gSrv2,dbproc_server2,SqlStatement);

// Commit the transaction
hr = pTransaction->Commit(0,0,0);
if (FAILED(hr))
{
printf("pTransaction->Commit() failed: %x\n",hr);
exit(1);
}

// At end of each transaction, pTransaction-Release()
// must be called.
hr = pTransaction->Release();
if (FAILED(hr))
{
printf("pTransaction->Release() failed: %x\n",hr);
exit(1);
}

printf("Successfully committed Transaction #%d\n",i);

} // for

// release the transaction dispenser
pTransactionDispenser->Release();

// release DBLib resources and exit
dbexit();
}

void LogonToDB(DBPROCESS **dbp, DBCONN *ptr)
{

DBSETLUSER(login, ptr->pszUser);
DBSETLPWD(login, ptr->pszPasswd);
DBSETLAPP(login, "example");

*dbp = dbopen (login, ptr->pszSrv);
if (*dbp == NULL)
{
printf ("\nLogin to server: %s failed, exiting!\n",ptr->pszSrv);
exit (ERREXIT);
}

/* Use the "pubs" database. */
dbuse(*dbp, "pubs");
}

void Enlist(DBCONN *ptr, DBPROCESS *dbp, ITransaction *pTransaction)
{
RETCODE rc = 0;

rc = dbenlisttrans (dbp, pTransaction);

if (FAIL == rc)
{
printf("\ndbenlisttrans() failed: %x\n",rc);
exit(1);
}

}

void ExecuteStatement(DBCONN *ptr, DBPROCESS *dbp, char *pszBuf)
{
RETCODE rc = 0;

dbcmd(dbp,pszBuf);

rc = dbsqlexec(dbp);
if (FAIL == rc)
{
printf("dbsqlexec() failed\n");
exit(1);
}

rc = dbresults(dbp);
if (rc != SUCCEED)
{
printf("dbresults() failed: %x\n",rc);
exit(1);
}
}


Advanced MS DTC Programming Techniques in C and C++

Selecting the Transaction Coordinator

Transaction Options

Asynchronous Transaction Commit and Abort

Transaction Outcome Events


Selecting the Transaction Coordinator

An application can specify the name of the system that will serve as the transaction coordinator by calling DtcGetTransactionManager and passing a server host name in the pszHost parameter. All transactions that are initiated by using the ITransactionDispenser::BeginTransaction method that DtcGetTransactionManager returns are started and coordinated on the specified computer on the network. If no server host name is specified, these rules determine where transactions are started and coordinated:

  1. If the application is located on a system on which the complete MS DTC service has been installed, then the local MS DTC coordinator serves as the transaction coordinator.
  2. If the application is located on a Windows 95 computer or a Windows NT computer on which only the MS DTC client utilities were installed, then the default MS DTC coordinator serves as the transaction coordinator. The default MS DTC coordinator is specified with the DTCCFG control panel application, which then records it in the system registry. For more information about DTCCFG, see Configuring the MS DTC Client Utility in Chapter 2, "Setup."


Transaction Options

Transaction options objects, are used to associate attributes with transactions. The application calls ITransactionDispenser::GetOptionsObject to create a transaction options object. The application then assigns transaction attributes to the transaction options object by calling the ITransactionOptions::SetOptions method. The transaction options object can then be passed as an argument to ITransactionDispenser::BeginTransaction. The transaction attributes from the transaction options object will be inherited by the newly created transaction object.

A transaction options object can provide a textual description for a transaction. The description is displayed in the SQL Enterprise Manager MS DTC Transactions window (see Chapter 3, "Administration"). The description is for the MS DTC system administrator only; it is not processed or interpreted by MS DTC.

Transaction options objects also can specify a time-out value (in milliseconds) for a given transaction.

The time-out value limits the duration of the transaction and therefore bounds the amount of time locks are held on database records and system resources. If the time-out period expires before the transaction commits, MS DTC automatically aborts the transaction. A time-out value of zero specifies an infinite time-out period and places no limit on how long database resources can be locked.

For more information about transaction options, see ITransactionOptions.


Asynchronous Transaction Commit and Abort

Usually, ITransaction::Commit or Abort calls are performed synchronously. When an application calls ITransaction::Commit, the calling thread in the application blocks until the end of phase one of the two-phase commit protocol. When an application calls ITransaction::Abort, the calling thread in the application blocks only briefly. Control is returned to the application as soon as the commit coordinator is notified that the transaction should be aborted.

To entirely avoid blocking the calling thread, use asynchronous Commit or Abort calls. To call Commit asynchronously, specify XACTTC_ASYNC for the grfTC parameter. To call Abort asynchronously, specify TRUE for the fAsync parameter.

For more information about asynchronous Commit and Abort calls, see ITransaction in Chapter 5, "MS DTC Programmer's Reference."


Transaction Outcome Events

Applications can use the ITransactionOutcomeEvents interface to receive an asynchronous notice of a transaction's outcome. The application implements the methods in the ITransactionOutcomeEvents interface and registers the interface with the connection point mechanism. When MS DTC determines the outcome of a transaction, it calls the appropriate method in the ITransactionOutcomeEvents interface to inform the application of the outcome.

The ITransactionOutcomeEvents interface has the following methods.

Method | Description
ITransactionOutcomeEvents ::Committed | Raised for committed transactions.
ITransactionOutcomeEvents ::Aborted | Raised for aborted transactions.
ITransactionOutcomeEvents ::HeuristicDecision | Raised when one of the participants in the transaction makes an heuristic decision to commit or abort the transaction. Heuristic decisions are not supported in the current release.
ITransactionOutcomeEvents ::InDoubt | Raised when the application calls either Commit or Abort and then loses communication with the commit coordinator before completion of phase one of the two-phase commit protocol.

To use transaction outcome events, follow these steps
  1. Implement the methods in the ITransactionOutcomeEvents interface.
  2. Each time you initiate a new transaction, call the QueryInterface method on the transaction object with an riid of IID_IConnectionPointContainer to obtain the IConnectionPointContainer interface.
  3. Call the IConnectionPointContainer::FindConnectionPoint method with an riid of IID_ITransactionOutcomeEvents to obtain the IConnectionPoint that supports the ITransactionOutcomeEvents sink.
  4. Call the Release method on the IConnectionPointContainer interface.
  5. Call the Advise method on the IConnectionPoint interface and pass the pointer to the ITransactionOutcomeEvents interface that you implemented. Advise will return a Connection Key.
  6. When the transaction commits or aborts, MS DTC will call the appropriate ITransactionOutcomeEvents method to report the transaction's outcome.
  7. Call the Unadvise method on the IConnectionPoint interface and pass the Connection Key that was returned from Advise.
  8. Call the Release method on the IConnectionPoint interface.
  9. Call the Release method on the transaction object.

You must repeat steps 2 through 9 for each transaction for which you require transaction outcome notification.

For more information about:

  • The ITransactionOutcomeEvents interface and its methods, see Chapter 5, "MS DTC Programmer's Reference."
  • The OLE events architecture, see IConnectionPoint in the Microsoft Developer Network (MSDN) Development Library.


XA Transaction Processing

For information about installing, configuring, programming, and administering your XA transaction processing monitor, refer to the documentation provided with your transaction processing monitor. This section provides information about making your XA-compliant transaction processing monitor work with SQL Server and MS DTC.


Open and Close Strings

Most XA-compliant transaction processing monitors provide a way to pass startup information (referred to as the open string) to the database resource manager when opening it. Similarly, most TP monitors provide a way to pass shutdown information (referred to as the close string) to the database resource manager when closing it. SQL Server expects to receive both an open and a close string from the TP monitor. SQL Server’s open and close strings are identical. The open and close strings take the form:

Tm=TPMonitorName, RmRecoveryGuid=RecoveryGUID

where

TPMonitorName
Is the name of the transaction processing monitor. The name can be up to 40 characters in length. Typical values for TPMonitorName are:

TUXEDO

TOPEND

ENCINA

RecoveryGUID
Is a global unique identifier in registry format but without braces. To obtain a RecoveryGUID, run the guidgen utility program. A unique RecoveryGUID must be specified for each XA program on a system. If you run multiple instances of a program on a system, each instance of the program must have a unique RecoveryGUID.

Example

Here is a sample open or close string:

Tm=ENCINA, RmRecoveryGuid=AC0BE353-3046-11CF-B48D-00AA00A2FA25

Each XA-compliant transaction processing monitor has its own mechanism for specifying the open and close strings. For Tuxedo, the open and close strings are specified in the “GROUPS Section” of the UBBCONFIG file. For TOP END, the open and close strings are specified in the RMSWITCH.C file, which is used to produce the RMSWITCH.DLL file. For Encina, the open and close strings are specified by the system administrator through the Encina Enconsole facility.


XA Switch for Microsoft SQL Server

The object file containing the XA switch is XASWITCH.OBJ. Typically, this file is linked with each XA program that calls XA functions. For the procedures for linking the XA switch file with your XA application, see your TP monitor documentation.

The variable name that represents the XA switch is msqlsrvxa1.

The descriptive name for the XA switch is “MS SQL Server XA_1”.


Chapter 5 MS DTC Programmer's Reference

MS DTC Programmer's Reference

This chapter describes the OLE Transaction interfaces for developing MS DTC applications with C or C++.

This chapter first describes the DtcGetTransactionManager function. It then describes the following interfaces:

ITransaction
ITransactionDispenser
ITransactionOptions
ITransactionOutcomeEvents

Applications that are written in C and C++ will also make use of functions and interfaces not described here. For information about other functions and interfaces, see the following sources:

  • Applications that use ODBC must use the SQL_COPT_SS_ENLIST_IN_DTC driver-specific connection option of the SQLSetConnectionOption statement. This connection option is described in Programming ODBC for Microsoft SQL Server.
  • Applications that use DB-Library must use the dbenlisttrans or dbenlistxatrans function. These functions are described in Part 7, "What's New for DB-Library for C," in What's New in SQL Server 6.5.
  • Applications that use ITransactionOutcomeEvents must use the connection point mechanism. For information about connection points, see the Microsoft Developer Network (MSDN) Development Library.
  • Applications can call stored procedures that are written in Transact-SQL and that use MS DTC transactions. For information about the Transact-SQL BEGIN DISTRIBUTED TRANSACTION statement, see Part 4, "What's New for Transact-SQL," in What's New in SQL Server 6.5.


DtcGetTransactionManager

DtcGetTransactionManager is usually the first MS DTC procedure that you call when you use MS DTC. It establishes the initial connection and obtains an interface to MS DTC. It is not necessary to call CoInitialize or OleInitialize before calling DtcGetTransactionManager.

Calls to DtcGetTransactionManager can specify a host name in the pszHost parameter. This allows transactions to be started and coordinated on a specific computer on the network. If the pszHost parameter is NULL, these rules determine where transactions are started and coordinated:

  1. If the application that calls DtcGetTransactionManager is located on a system on which the complete MS DTC service has been installed, then the local MS DTC starts and coordinates the transactions.
  2. If the application that calls DtcGetTransactionManager is located on a Windows 95 system or on a Windows NT system on which only the MS DTC client utilities were installed, then the default MS DTC starts and coordinates the transactions. The default MS DTC is specified by using the MS DTC Client Configuration program in Control Panel and is recorded in the system registry. For information about the MS DTC Client Configuration program, see Configuring the MS DTC Client Utility in Chapter 2, "Setup."

Syntax

HRESULT DtcGetTransactionManager (
LPTSTR pszHost,
LPTSTR pszTmName,
REFIID riid,
DWORD dwReserved1,
WORD wcbVarLenReserved2,
void* pvVarDataReserved2,
void** ppv );

where

pszHost
[in] Is the name of the host system that will serve as the transaction commit coordinator.
pszTmName
[in] Is the string name of the transaction manager that will serve as the transaction commit coordinator. Must be NULL.
riid
[in] Is the IID of the requested interface. Usually this is IID_ITransactionDispenser.
dwReserved1
[in] Is reserved. Must be zero.
wcbVarLenReserved2
[in] Is reserved. Must be zero.
pvVarDataReserved2
[in] Is reserved. Must be NULL.
ppv
[out] Is the pointer to the pointer to the requested interface.

Returns

S_OK
Indicates succeeded.
E_NOINTERFACE
Indicates unable to provide the requested interface.
E_UNEXPECTED
Indicates an unexpected error has occurred.
E_INVALIDARG
Indicates one or more arguments are invalid.
E_FAIL
Indicates failed.


ITransaction

You can use this interface to commit and abort transactions and to obtain status information about transactions.


How to Obtain ITransaction

You can obtain this interface by calling the ITransactionDispenser::BeginTransaction method.


ITransaction::Commit

Commits the transaction.

Syntax

HRESULT Commit (
BOOL fRetaining,
DWORD grfTC,
DWORD grfRM )

where

fRetaining
[in] Is FALSE.
grfTC
[in] Is the set of values from the enumeration XACTTC that is described below.
grfRM
[in] Is zero.

Returns

S_OK
Indicates succeeded.
XACT_S_ASYNC
Indicates an asynchronous commit was specified. The commit operation has begun, but its outcome is not yet known. The application can use the ITransactionOutcomeEvents interface to receive notice of the outcome of the transaction.
XACT_E_NOTRANSACTION
Indicates unable to commit the transaction, because it had already been committed or aborted. The call was ignored.
XACT_E_ALREADYINPROGRESS
Indicates a commit or abort operation was already in progress. The call was ignored.
XACT_E_NOTSUPPORTED
Indicates an invalid combination of commit flags was specified. The call was ignored.
XACT_E_CANTRETAIN
Indicates retaining commit is not supported. The call was ignored.
E_FAIL
Indicates the transaction failed to commit for an unknown reason. The transaction was aborted.
XACT_E_INDOUBT
Indicates the transaction status is unknown. A communication failure has occurred or a transaction manager or resource manager has failed.
E_UNEXPECTED
Indicates an unexpected error has occurred. The transaction status is unknown.
XACT_E_ABORTED
Indicates the transaction was aborted before ITransaction::Commit was called.
XACT_E_CONNECTION_DOWN
Indicates no longer able to communicate with the transaction manager, because the connection to the transaction manager failed. The transaction was aborted.

Remarks

These flags are supported for the grfTC parameter.

Flag | Meaning
XACTTC_ASYNC | When this flag is specified, an asynchronous commit is performed. The call to ITransaction::Commit returns as soon as the two-phase commit protocol is initiated. The application can use the ITransactionOutcomeEvents interface to determine the outcome of the transaction. This flag cannot be specified when the XACTTC_SYNCPHASEONE flag is specified. If neither XACTTC_ASYNC nor XACTTC_SYNCPHASEONE is specified, a synchronous commit is performed.
XACTTC_SYNCPHASEONE | When this flag is specified, a synchronous commit is performed. The call to ITransaction::Commit returns after phase one of the two-phase commit protocol. This flag cannot be specified when the XACTTC_ASYNC flag is specified. If neither XACTTC_ASYNC nor XACTTC_SYNCPHASEONE is specified, a synchronous commit is performed.


ITransaction::Abort

Aborts the transaction. You can call ITransaction::Abort on a transaction repeatedly. XACT_S_ABORTING will be returned on each call following the first call to Abort.

Syntax

HRESULT Abort (
BOID* pboidReason,
BOOL fRetaining,
BOOL fAsync )

where

pboidReason
[in] Is an optional BOID that indicates why the transaction is being aborted. Must be NULL.
fRetaining
[in] Is FALSE.
fAsync
[in] Is TRUE or FALSE. When fAsync is TRUE, an asynchronous abort is performed and the call to ITransaction::Abort returns immediately. The application can use the ITransactionOutcomeEvents interface to receive notice that the transaction abort is underway. The ITransactionOutcomeEvents interface is described later in this chapter.

By default, fAsync is FALSE.

Returns

S_OK
Indicates succeeded.
XACT_S_ASYNC
Indicates that an asynchronous Abort was specified and the call to ITransaction::Abort returned immediately. The application can use the ITransactionOutcomeEvents interface to receive notice that the transaction abort is underway. The ITransactionOutcomeEvents interface is described later in this chapter.
XACT_E_NOTRANSACTION
Indicates unable to abort the transaction, because it had already been committed or aborted. The call was ignored.
XACT_E_ALREADYINPROGRESS
Indicates a commit operation was already in progress. The call was ignored.
XACT_E_CANTRETAIN
Indicates retaining abort is not supported. The call was ignored.
E_FAIL
Indicates the transaction failed to abort for an unspecified reason.
E_UNEXPECTED
Indicates an unexpected error has occurred. The transaction status is unknown.
XACT_S_ABORTING
Indicates an abort operation was already in progress. The call was ignored.
XACT_E_INDOUBT
Indicates the transaction status is unknown. A communication failure has occurred or a transaction manager or resource manager has failed.
XACT_E_CONNECTION_DOWN
Indicates no longer able to communicate with the transaction manager because the connection to the transaction manager failed. The transaction state is unknown.


ITransaction::GetTransactionInfo

Returns information about a transaction.

Syntax

HRESULT GetTransactionInfo ( XACTTRANSINFO* pinfo )

where

pinfo
[out] Is the pointer to the XACTTRANSINFO structure that was allocated by the caller. This structure will receive information about the transaction. Must not be NULL.

The XACTTRANSINFO structure is defined as follows:

typedef struct XACTTRANSINFO
{
XACTUOW uow;
ISOLEVEL isoLevel;
ULONG isoFlags;
DWORD grfTCSupported;
DWORD grfRMSupported;
DWORD grfTCSupportedRetaining;
DWORD grfRMSupportedRetaining;
}    XACTTRANSINFO;

The XACTTRANSINFO members are described below.
Member | Description
uow | Is the unit of work that is associated with this transaction.
isoLevel | Is the isolation level that is associated with this transaction object. ISOLATIONLEVEL_UNSPECIFIED indicates that no isolation level was specified.
isoFlags | Will be set to zero (0).
grfTCSupported | This bit mask indicates which grfTC flags are supported by the current version of MS DTC. The application can set one or more of these grfTC flags when calling ITransaction::Commit.
grfRMSupported | Will be set to zero (0).
grfTCSupportedRetaining | Will be set to zero (0).
grfRMSupportedRetaining | Will be set to zero (0).

Returns

S_OK
Indicates succeeded.
XACT_E_NOTRANSACTION
Indicates unable to retrieve information for the transaction, because it was already complete. No information is returned.
E_UNEXPECTED
Indicates an unexpected error has occurred. No information is returned.
E_INVALIDARG
Indicates the value of pinfo was NULL. No information is returned.


ITransactionDispenser

The ITransactionDispenser interface contains two methods. The ITransactionDispenser::BeginTransaction method initiates a new transaction and returns a new transaction object that represents the transaction. The ITransactionDispenser::GetOptionsObject method creates new transaction options objects.


How to Obtain ITransactionDispenser

You can obtain this interface by calling DtcGetTransactionManager with an riid of IID_ITransactionDispenser. Clients that obtained the IUnknown interface from DtcGetTransactionManager can call QueryInterface on the IUnknown interface with an riid of IID_ITransactionDispenser to obtain the ITransactionDispenser interface.


ITransactionDispenser::GetOptionsObject

Creates a transaction options object. The transaction options object is obtained from the GetOptionsObject call and can be assigned transaction attributes by calling the ITransactionOptions::SetOptions method. The transaction options object can then be passed to ITransactionDispenser::BeginTransaction. The transaction attributes from the transaction options object will be inherited by the newly created transaction.

A process can create many transaction options objects.

Two or more threads can simultaneously call the BeginTransaction method and pass the same transaction options object as a parameter. However, the attributes of the transaction options object must not be changed while the object is being used by the BeginTransaction method.

Syntax

HRESULT GetOptionsObject (
ITransactionOptions** ppOptions )

where

ppOptions
[out] Is the pointer to the pointer to the ITransactionOptions interface on the transaction options object. Must not be NULL.

Returns

S_OK
Indicates succeeded.
E_OUTOFMEMORY
Indicates unable to allocate memory.
E_INVALIDARG
Indicates the value of ppOptions is NULL.


ITransactionDispenser::BeginTransaction

Initiates a new transaction and returns a new transaction object that represents the transaction.

Syntax

HRESULT BeginTransaction (
IUnknown punkOuter,
ISOLEVEL isoLevel,
ULONG isoFlags,
ITransactionOptions* pOptions,
ITransaction** ppTransaction )

where

punkOuter
[in] Is NULL.
isoLevel
[in] Is the isolation level that is used for this transaction. This value is ignored by MS DTC and passed to the resource managers.
isoFlags
[in] Is zero.
pOptions
[in] Is a pointer to a transaction options object. This value can be NULL.

If pOptions is NULL the time-out value for the transaction is infinite and the transaction will not have a description.

The transaction options object must not be changed while the ITransactionDispenser::BeginTransaction method call is outstanding.

ppTransaction
[out] Is a pointer to the pointer to the ITransaction interface on the new transaction object.

Returns

S_OK
Indicates succeeded.
CLASS_E_NOAGGREGATION
Indicates punkOuter was not NULL.
XACT_E_LOGFULL
Indicates unable to begin a new transaction because the log file is full.
XACT_E_NOTIMEOUT
Indicates a time out was specified, but time outs are not supported.
E_OUTOFMEMORY
Indicates unable to allocate memory.
E_FAIL
Indicates an unknown error occurred.
E_UNEXPECTED
Indicates an unexpected error has occurred.
E_INVALIDARG
Indicates ppTransaction was NULL.
XACT_E_CONNECTION_DOWN
Indicates no longer able to communicate with the transaction manager, because the connection to the transaction manager failed.
XACT_E_TMNOTAVAILABLE
Indicates unable to connect to the transaction manager, or the transaction manager is unavailable.
XACT_E_CONNECTION_DENIED
Indicates the transaction manager did not accept a connection request.


ITransactionOptions

You can use this interface to read and alter attributes within a transaction options object. The transaction options object can be passed as a parameter to the ITransactionDispenser::BeginTransaction method. The attributes of the transaction options object are inherited by the newly initiated transaction. This allows the caller of the BeginTransaction method to control the attributes of a transaction such as its time-out period and transaction description.


How to Obtain ITransactionOptions

You can obtain this interface by calling the ITransactionDispenser::GetOptionsObject method.


ITransactionOptions::SetOptions

Changes transaction attributes in a transaction options object. After changing the options, you can pass the transaction options object to the ITransactionDispenser::BeginTransaction method. The attributes of the transaction options object are inherited by the newly initiated transaction.

Transaction attributes are specified by using the XACTOPT structure that is defined below.

ITransactionOptions::SetOptions must not be called on a transaction options object that is currently being used by the ITransactionDispenser::BeginTransaction method.

Syntax

HRESULT SetOptions ( XACTOPT* pOptions )

where

pOptions
[in] Is the pointer to the XACTOPT structure that is allocated by the caller. This structure contains attribute information for a transaction option object.

The XACTOPT structure is defined as follows:

typedef struct XACTOPT
{
ULONG ulTimeout;
unsigned char szDescription[ MAX_TRAN_DESC ];
}   XACTOPT;

The XACTOPT structure members are described below.
Member Description
ulTimeOut Is the time, in milliseconds, before the transaction is automatically aborted. Zero indicates an infinite time out.

The time out limits the duration of the transaction and therefore bounds the amount of time locks are held on database records and system resources. If the time-out period expires before the transaction commits, MS DTC automatically aborts the transaction.
szDescription Is a textual description for a transaction. The transaction description is displayed by the MS DTC management interface in the MS DTC Transactions window. The transaction description is for the MS DTC administrator only; it is not processed or interpreted by MS DTC itself.

The transaction description cannot be longer than MAX_TRAN_DESC bytes in length.

Returns

S_OK
Indicates succeeded.
E_OUTOFMEMORY
Indicates unable to allocate memory.
E_INVALIDARG
Indicates the value of pOptions is NULL.


ITransactionOptions::GetOptions

Returns transaction attributes from a transaction options object.

Syntax

HRESULT GetOptions ( XACTOPT* pOptions )

where

pOptions

[out] Is the pointer to the XACTOPT structure that is allocated by the caller. This structure is used to return attribute information from a transaction options object. The XACTOPT structure is described with the ITransactionOptions::SetOptions method earlier.

Returns

S_OK
Indicates succeeded.
E_OUTOFMEMORY
Indicates unable to allocate memory.
E_INVALIDARG
Indicates the value of pOptions is NULL.


ITransactionOutcomeEvents

Your OLE object can implement this interface to receive asynchronous notice of transaction outcomes.


How to Implement ITransactionOutcomeEvents Events

To receive asynchronous ITransaction events, your OLE object must implement the ITransactionOutcomeEvents interface and all its methods. Your application then registers the ITransactionOutcomeEvents interface by using the connection point mechanism. MS DTC calls the appropriate method on the ITransactionOutcomeEvents interface to inform the application of the transaction outcome.

For more information about implementing an OLE object to receive ITransaction events, see Transaction Outcome Events in Chapter 4, "Application Development."


ITransactionOutcomeEvents::Committed

Raised when the transaction commits. The Committed event is raised at the end of phase one on the root transaction manager's system and at the beginning of phase two on subordinate transaction manager's systems.

Syntax

HRESULT Committed (
BOOL fRetaining,
XACTUOW* pNewUOW,
HRESULT hr )

where

fRetaining
[in] Is always FALSE.
pNewUOW
[in] Is always NULL.
hr
[in] Is always S_OK.

Returns

S_OK
Indicates the transaction committed.


ITransactionOutcomeEvents::Aborted

Raised when the transaction aborts.

MS DTC raises the Aborted event as soon as the transaction manager decides to abort the transaction. When the Aborted event is raised, there is no guarantee that the resource managers will have received the abort request or undone the effects of the aborted transaction.

A transaction can abort for any of the following reasons:

  • The application that initiated the transaction aborted the transaction by calling ITransaction::Abort.
  • The application that initiated the transaction called ITransaction::Commit for the transaction, but the attempt to commit the transaction was unsuccessful.
  • The application that initiated the transaction failed due to a process fault or system failure before it called ITransaction::Commit.
  • The application that initiated the transaction lost communication with the transaction manager before calling ITransaction::Commit.
  • An enlisted resource manager failed due to a process fault or system failure before completion of phase one of the two-phase commit protocol.
  • A communication failure occurred between a transaction manager and an enlisted resource manager before completion of phase one of the two-phase commit protocol.
  • An enlisted resource manager called IUnknown::Release to release the transaction object before completion of phase one of the two-phase commit protocol.
  • An enlisted resource manager replied "abort" when asked to prepare at phase one of the two-phase commit protocol.
  • An enlisted transaction manager failed due to a process fault or system failure before the completion of phase one of the two-phase commit protocol.
  • A communication failure occurred between two enlisted transaction managers before the completion of phase one of the two-phase commit protocol.
  • The transaction failed to commit within the timeout that was specified when the transaction was initiated. The transaction was aborted by the transaction manager.
  • A transaction manager detected that a new transaction manager or resource manager tried to join the transaction while the transaction was being committed. The transaction manager aborted the transaction.
  • The system administrator resolved an in-doubt transaction by manually aborting it.

Syntax

HRESULT Aborted (
BOID* pboidReason,
BOOL fRetaining,
XACTUOW* pNewUOW,
HRESULT hr )

where

pboidReason
[in] Is always NULL.
fRetaining
[in] Is always FALSE.
pNewUOW
[in] Is always NULL.
hr
[in] Is always S_OK

Returns

S_OK
Indicates the transaction aborted.


ITransactionOutcomeEvents::HeuristicDecision

Raised when one of the participants in the transaction makes an heuristic decision to commit or abort the transaction.

Syntax

HRESULT HeuristicDecision (
DWORD dwDecision,
BOID* pboidReason,
HRESULT hr )

where

dwDecision
[in] Is the set of values from the enumeration XACTHEURISTIC.
pboidReason
[in] Is always NULL.
hr
[in] Is always S_OK.

Returns

S_OK
Indicates the transaction had an heuristic outcome.

Note Heuristic decisions are not supported in the current release.


ITransactionOutcomeEvents::InDoubt

Raised when the application calls either Commit or Abort and then loses communication with the commit coordinator before the completion of phase one of the two-phase commit protocol. In this case, MS DTC cannot inform the application about the transaction outcome. Any of the following errors will cause the InDoubt event to be raised:

  • The communication path between the application and the commit coordinator fails.
  • The commit coordinator process fails due to a process fault or system failure.
  • A transaction manager delegates commit coordinator responsibility to a subordinate transaction manager or resource manager and the communication path to that transaction manager or resource manager fails.
  • A transaction manager delegates commit coordinator responsibility to a subordinate transaction manager or resource manager and that transaction manager or resource manager process fails due to a process fault or system failure.

Syntax

HRESULT InDoubt (void)

Returns

S_OK
Indicates succeeded.


Before You Begin

The programming components in Microsoft® SQL Server™ 6.5 enable you to develop sophisticated client/server applications that tap the power of Microsoft SQL Server from workstations running the Microsoft® Windows NT™, Microsoft® Windows® 95 and Microsoft® Windows® operating systems.

The Microsoft Open Database Connectivity (ODBC) interface enables you to create applications that are interoperable with multiple database systems. The ODBC SQL Server driver enables you to create ODBC client/server applications that take maximum advantage of Microsoft SQL Server.


About Programming ODBC for Microsoft SQL Server

Programming ODBC for Microsoft SQL Server describes how the ODBC SQL Server driver uses various Microsoft SQL Server features. It provides installation information, gives details on creating and configuring SQL Server data sources, summarizes the ODBC API in a step-by-step programming guide, and provides information on how the ODBC functions and SQL grammar map to SQL Server features.

This book is written for developers who are writing ODBC client/server applications that connect to Microsoft SQL Server using the ODBC SQL Server driver. It assumes that you are familiar with SQL Server and with the ODBC application programming interface (API). For information about the ODBC API, see the Microsoft ODBC API Reference or the Microsoft ODBC 2.0 Programmer's Reference and SDK Guide.

This book also assumes that you are familiar with Transact-SQL, the enhanced version of SQL (structured query language). For information about Transact-SQL, see the Microsoft SQL Server Transact-SQL Reference.


Finding Further Information

This book contains reference information to help you use the ODBC SQL Server driver. Information about SQL Server is available from the following sources, as well as from the Microsoft® Development Library and Microsoft® TechNet.

The Microsoft Developer Network provides in-depth information for developers. With Level 1 of the Developer Network, you get four quarterly releases of the Development Library, packed with inside information on programming for Microsoft Windows and Windows NT, plus other program benefits. With Level 2 of the Developer Network, you'll receive all the Level 1 benefits plus quarterly releases of the Development Platform, containing the latest Windows and Windows NT Workstation operating systems and API-level SDKs and DDKs from Microsoft. For ordering information, call (800) 759-5474.

Microsoft TechNet is the front-line resource for fast complete answers to technical questions on Microsoft desktop and system products. Through two monthly CDs, you get everything from crucial data on client/server and workgroup computing, systems platforms, and database products to the latest applications support for Microsoft Windows and the Apple® Macintosh®. For ordering information, call your reseller or (800) 344-2121.


SQL Server Documentation

The documentation for SQL Server 6.5 is available online as part of the Microsoft® Development Library and as Microsoft SQL Server Books Online, which is part of Microsoft SQL Server and Microsoft® SQL Workstation.

Important SQL Server Books Online contains the most up-to-date information about SQL Server 6.5, including information that changed or was unavailable when the SQL Server 6.5 books were printed.

Microsoft SQL Server Setup
Provides instructions for installing SQL Server 6.0 servers and clients.
Microsoft SQL Server System Administrator's Companion
Incorporates configuration, administration, and troubleshooting topics. Describes server and client configuration. Explains system administration tasks, such as managing devices and databases, backing up and recovering data, performing replication, scheduling tasks, managing security, and monitoring performance. Describes error conditions and gives troubleshooting procedures.
Microsoft SQL Server Database Developer's Companion
Provides an overview of Transact-SQL, which is an enhanced version of SQL (structured query language). Discusses managing data and database objects, such as tables, views, indexes, stored procedures, defaults, rules, constraints, and user-defined datatypes.
Microsoft SQL Server Transact-SQL Reference
Explains how to use Transact-SQL statements and other features to access databases, and provides syntax and descriptions for Transact-SQL statements, system procedures, utility programs, and system tables.
Microsoft SQL Server Programming SQL Distributed Management Objects
Provides syntax and reference information for the SQL Distributed Management Objects, which are 32-bit OLE Automation objects for the Microsoft® Windows® 95 and Windows NT operating systems. These objects, properties, methods, and collections are used to write scripts and programs that can administer multiple SQL Servers distributed across a network.
Microsoft SQL Server Programming DB-Library for C
Provides syntax and reference information for the DB-Library application programming interface (API), which is used to write C/C++ client programs for the Windows, Windows 95, Windows NT, and MS-DOS operating systems.
Microsoft SQL Server Programming DB-Library for Visual Basic
Provides syntax and reference information for the DB-Library API, which is used to write Microsoft® Visual Basic® programming system–based client programs for the Windows operating system.


Chapter 1 Overview

Overview

Microsoft® SQL Server™ is a multiuser relational database management system (DBMS) that runs on the Microsoft Windows NT™ operating system. Structured Query Language (SQL) is used to access data in a SQL Server database. Client workstations communicate with SQL Server across a network, such as a Windows NT Server, Novell® NetWare®, Banyan® VINES®, or TCP/IP network.

The SQL Server driver enables applications to access data in Microsoft SQL Server databases through the Open Database Connectivity (ODBC) interface.

Both 16- and 32-bit versions of the ODBC SQL Server driver are available.

Note that the 32-bit ODBC SQL Server driver is thread safe. The driver will serialize shared access by multiple threads to shared hstmt, hdbc, and henv objects. However, the ODBC program is still responsible for keeping operations within statement and connection spaces in the proper sequence, even when the program uses multiple threads.

This is the application/driver architecture for 16-bit environments:

Note Thunking means intercepting a function call, doing some special processing to translate between 16-bit and 32-bit code, and then transferring control to a target function.

Application (16-bit) Application (32-bit in Win32s)
| |
32-bit Thunking Driver Manager
(ODBC32.DLL)
| |
ODBC Universal Thunking DLL
(ODBC16UT.DLL)
| |
ODBC Driver Manager
(ODBC.DLL)
|
ODBC Cursor Library (optional)
(ODBCCURS.DLL)
|
SQL Server Driver (16-bit)
(SQLSRVR.DLL)
|
Net-Library
(DBNMP3.DLL, DBMSSPX3.DLL, etc.)
|
Network Software
(Windows NT, Windows for Workgroups, Novell NetWare, etc.)
|
Microsoft SQL Server

This is the application/driver architecture for 32-bit environments:

Application (16-bit) Application (32-bit)
| |
ODBC Driver Manager ODBC Driver Manager
(ODBC.DLL) (ODBC32.DLL)
| |
ODBC Cursor Library (optional) ODBC Cursor Library (optional)
(ODBCCURS.DLL) (ODBCCR32.DLL)
| |
16-Bit ODBC Generic Thunking DLL
(ODBC16GT.DLL)
| |
32-Bit ODBC Generic Thunking DLL
(ODBC32GT.DLL)
| |
SQL Server Driver (32-bit)
(SQLSRV32.DLL)
|
Net-Library
(DBNMPNTW.DLL, DBMSSPXN.DLL, etc.)
|
Network Software
(Windows NT, Windows for Workgroups, Novell NetWare, etc.)
|
Microsoft SQL Server


Chapter 2 Installation

Installation

This chapter outlines the requirements for a system to run the ODBC SQL Server driver. Installation instructions and steps for upgrading catalog stored procedures are also included.


System Requirements

To access SQL Server data, you must have the following software:

  • The ODBC SQL Server driver.
  • Microsoft SQL Server.
  • Network software on the computers on which the driver and SQL Server reside (not required when connecting to a local (non-network) desktop SQL Server).

The hardware and software requirements of each of these components follows.


ODBC SQL Server Driver

Hardware requirements:

  • An Industry Standard Architecture (ISA) computer, such as the IBM® PC/AT® or compatible,

    Or

    A Micro Channel® Architecture (MCA) computer, such as an IBM PS/2® or compatible,

    Or

    An Extended Industry Standard Architecture (EISA) computer with an 80286, 80386, 80486, or Pentium microprocessor,

    Or

    An Alpha AXP™, a MIPS®, or a Power PC microprocessor.

  • At least 2 MB of RAM; 4 MB is recommended.
  • A hard disk drive with approximately 300K of hard disk space for the SQL Server driver and ODBC Driver Manager.

Operating system software requirements:

  • 16-bit driver—Microsoft Windows® version 3.1 or later
  • 32-bit driver—Microsoft Windows 95 or Windows NT version 3.5 or later

For information about the hardware and software required for SQL Server clients, see What's New in SQL Server 6.5 and Microsoft SQL Server Setup.


SQL Server

To use the SQL Server driver to access data in Microsoft SQL Server databases, you must have Microsoft SQL Server 4.21a or later. The catalog stored procedures must be installed on your SQL Server. You may need to install the catalog stored procedures shipped with this driver when you use version 4.21a or 6.0 of Microsoft SQL Server (see the Upgrading the Catalog Stored Procedures topic). For information about the hardware and software required by SQL Server, see Microsoft SQL Server Setup.


Network Software

Network software is required to connect the computers on which the SQL Server driver and SQL Server reside. To connect to a SQL Server, you can use Microsoft Windows NT, Microsoft Windows for Workgroups, or a compatible network such as IBM LAN Server, DEC™ PATHWORKS™, Novell NetWare, or Banyan VINES. For information about the hardware and software required by each network, see your network documentation.

The SQL Server driver communicates with network software through the SQL Server Net-Library interface, which requires a Net-Library dynamic-link library (DLL). For more information about supported network configurations and Net-Library files, see Microsoft SQL Server Setup.


Installing the SQL Server Driver

The ODBC SQL Server driver is installed automatically when you install the SQL Server 6.5 client software on a computer running Windows NT, Windows 95, or Windows 3.11. For more information about installing SQL Server 6.5 client software, see Microsoft SQL Server Setup.

If you need to reinstall just the ODBC SQL Server driver, you can run the ODBC setup program from the ODBC subdirectory of the appropriate client install directory.

To use the SQL Server driver, you usually add a data source for each installation of SQL Server in which you want to access data (see Connecting to a SQL Server Data Source.)

If you are using Microsoft SQL Server 4.21a or 6.0, the INSTCAT.SQL file included with this driver includes minor fixes to the catalog stored procedures. For information about installing the updated catalog stored procedures, see the following section.


Upgrading the Catalog Stored Procedures

The SQL Server driver uses a set of system stored procedures, known as catalog stored procedures, to obtain information from the SQL Server system catalog. Microsoft SQL Server installs the catalog stored procedures automatically when you install or upgrade SQL Server. The INSTCAT.SQL file included with this driver includes minor updates to the catalog stored procedures. Having the SQL Server system administrator upgrade the catalog stored procedures on a server running Microsoft SQL Server 4.21a or 6.0 is required.

To upgrade the catalog stored procedures, the system administrator runs a script using the isql utility (see the instructions below). Before making any changes to the master database, the system administrator should back it up. To run isql, your computer must be installed as a client workstation for Microsoft SQL Server.

To upgrade the catalog stored procedures
  • At the command prompt, use the isql utility to run the INSTCAT.SQL script. For example:

    C:> ISQL /Usa /P sa_password /S server_name /i location\INSTCAT.SQL

    where

sa_password
Is the system administrator's password.
server_name
Is the name of the server on which SQL Server resides.
location
Is the full path of the location of INSTCAT.SQL. You can use INSTCAT.SQL from an installed SQL Server 6.5 (the default location is C:\MSSQL\INSTALL) or from the SQL Server 6.5 CD (the default location is D:\platform where D is the CD drive letter and platform is the appropriate server platform directory, such as I386).

The INSTCAT.SQL script generates messages. Ignore these.

The INSTCAT.SQL script fails when there is not enough space available in the master database to store the catalog stored procedures or to log the changes to existing procedures. If the INSTCAT.SQL script fails, contact your system administrator.

The SQL Server driver uses the following catalog stored procedures.

Stored procedure | Returns
sp_column_privileges | Information about column privileges for the specified table(s)
sp_columns | Information about columns for the specified table(s)
sp_databases | A list of databases
sp_datatype_info | Information about the supported datatypes
sp_fkeys | Information about logical foreign keys
sp_pkeys | Information about primary keys
sp_server_info | A list of attribute names and matching values for the server
sp_special_columns | Information for a single table about columns in the table that have special attributes
sp_sproc_columns | Column information for a stored procedure
sp_statistics | A list of indexes for a single table
sp_stored_procedures | A list of stored procedures
sp_table_privileges | Information about table privileges for the specified table(s)
sp_tables | A list of objects that can be queried

For additional information about the catalog stored procedures, see What's New in SQL Server 6.5 and the Microsoft SQL Server Transact-SQL Reference.


Chapter 3 Data Source Setup and Connection

Data Source Setup and Connection

This chapter discusses creating and configuring SQL Server data sources. Once a SQL Server data source is created, an ODBC application can connect to SQL Server using the data source.

ODBC SQL Server Setup

Connecting to a SQL Server Data Source

Driver-specific Connection Options

Deleting a Data Source

Data Source

A data source includes the data a user wants to access and the information needed to access that data. For the ODBC SQL Server driver, a data source is a Microsoft SQL Server database, the server on which it resides, and the network that is used to access that server.


ODBC SQL Server Setup

To access the ODBC SQL Server Setup dialog box
  1. From Control Panel, double-click the ODBC icon.

    Note When using 16-bit drivers on Microsoft Windows NT or Windows 95, in the Program Manager window, open the Microsoft ODBC group and double-click the Microsoft ODBC Administrator icon.

    The Data Sources dialog box appears.

  2. Choose the Add button.

    The Add Data Source dialog box appears.

  3. From the Installed ODBC Drivers list, select SQL Server, and then choose OK.

    The ODBC SQL Server Setup dialog box appears.

The ODBC SQL Server Setup dialog box has the following options:

Data Source Name
The name of the data source. For example, "Personnel Data."
Description
A description of the data in the data source. For example, "Hire date, salary history, and current review of all employees."
Server
The name of a SQL Server on your network. You can select a server from the list or enter the server name. If the specified server name has already been configured (by another data source or by the SQL Client Configuration Utility), the Network Address and Network Library fields will automatically display the existing network information.

You can enter "(local)" as the server on a Microsoft Windows NT computer. The user can then use a local copy of SQL Server (that listens on named pipes), even when running a non-networked version of SQL Server. Note that when the 16-bit SQL Server driver is using "(local)" without a network, the Microsoft Loopback Adapter must be installed.

For more information about server names for different types of networks, see Microsoft SQL Server Setup.

Network Address
The address of the SQL Server database management system (DBMS) from which the driver retrieves data. For Microsoft SQL Server, you can usually leave this value set to (Default).
Network Library
The name of the SQL Server Net-Library DLL that the SQL Server driver uses to communicate with the network software. If the value of this option is (Default), then the SQL Server driver uses the client computer's default Net Library, which is specified in the SQL Server Client Configuration Utility dialog box.

If you create a data source using a Network Library other than (Default) and optionally a Network Address, ODBC SQL Server setup will create a server name entry that you can see in the Advanced tab in the SQL Server Client Configuration Utility dialog box. These server name entries can also be used by DB-Library™ applications.

Use Trusted Connection
Specifies whether the ODBC SQL Server driver requests a secure or trusted connection to SQL Server. This means that SQL Server will use integrated login security to establish connections that are made using this data source, regardless of the current login security mode at the server. Any login ID or password that is supplied is ignored.

To access the following fields, choose the Options button.

Database Name
The name of the SQL Server database.
Language Name
The national language used by SQL Server.
Generate Stored Procedure for Prepared Statement
When selected, creates stored procedures for prepared statements (the default). The SQL Server driver prepares a statement by placing it in a procedure and compiling that procedure.

To disable the creation of stored procedures for prepared statements, clear this check box. In this case, a prepared statement is stored and run at execution time.

Translation
The description of the current translator. To select a different translator, choose the Select button and in the Select Translator dialog box that appears, select a translator from the list.
Convert OEM to ANSI Characters
When selected, converts extended characters that are stored in the database to ANSI (for use by Windows-based applications). Select this option if the SQL Server client computer and SQL Server are using the same non-ANSI character set. For example, if SQL Server uses code page 850 and the client computer uses code page 850 for the OEM code page.

When this check box is clear and the SQL Server client computer and SQL Server are using different character sets, you must specify a character set translator.

The following profiling settings are available by choosing the Options button, and then choosing the Profiling button to display the Profiling Options dialog box.

Save Long Running Queries

Logs any query that takes longer than the Query Logging Threshold value. Click the Query File button to specify the long-running query log file.

Query Logging Threshold (milliseconds)

Specifies a threshold value, in milliseconds, for long-running query logging. Any query that takes longer than this number of milliseconds to run is logged.

Log Driver Statistics

Logs driver statistics. Click the Log File button to specify the driver statistics log file.

For information about connection options, see Driver-specific Connection Options.


Connecting to a SQL Server Data Source

When an application connects to SQL Server using SQLDriverConnect, the application may generate a prompt for data source information. This prompt can be in the form of a Data Source query or a dialog box. For a Data Source query, enter the name of the data source. For a dialog box, complete the dialog box as follows:

  1. Enter or select the data source name.
  2. In the Login ID entry field, type your SQL Server login ID.
  3. In the Password entry field, type your SQL Server password.
  4. Choose OK.

For information about the SQL Server login security mode and secure connections, see the Microsoft SQL Server Administrator's Companion.

To enter optional connection information, such as the database to access and the language for SQL Server to use, choose the Options button.

  1. From the Database list box, select the database you want to access. Setting the default database and the language for the login ID in SQL Server is more efficient than specifying them as DSN options.

    When you open the list box, the user's default database is selected.

  2. From the Language box, select the language you want SQL Server to use. Setting the default database and the language for the login ID in SQL Server is more efficient than specifying them as DSN options.

    When you open the list box, the user's default language is selected.

  3. If the application name that is displayed is incorrect, enter the correct application name.

    The application name is the name of the application that is calling the SQL Server driver.

  4. If the workstation ID that is displayed is incorrect, enter the correct workstation ID.

    Typically, this is the network name of the computer on which the application resides.

  5. Choose OK.


Using odbcping to Verify a Connection

You can use the odbcping utility to check whether ODBC is properly installed by connecting to a server using the ODBC SQL Server driver. This utility is a 32-bit application that is stored in the \MSSQL\BINN directory. To verify ODBC connectivity, from a command prompt, type:

odbcping /S servername /U login_id /P password

where

servername
Is the name of a server you will connect to.
login_id
Is a valid login ID for that server.
password
Is the password for that login ID.

If the ODBC connection is established, this message is displayed:

CONNECTED TO SQL SERVER

If the ODBC connection cannot be established, this message is displayed:

COULD NOT CONNECT TO SQL SERVER

the following func

For more information about connecting to a data source, see Chapter 8, Functions:

SQLBrowseConnect

SQLConnect

SQLDriverConnect


Driver-specific Connection Options

The ODBC SQL Server driver supports the following driver-specific connection options for SQLSetConnectOption and SQLGetConnectOption.

Option | Description
SQL_COPT_SS_ANSI_OEM SQL_AO_OFF. ANSI to OEM and OEM to ANSI translation is not performed. (Default.)

SQL_AO_ON. ANSI to OEM and OEM to ANSI translation is performed.

(Similar to dbsetopt and dbclropt using DBANSItoOEM | DBOEMtoANSI.)
SQL_COPT_SS_CONNECTION
_DEAD
(SQLGetConnectOption only) 		SQL_CD_TRUE. The connection has been broken and is dead.

SQL_CD_FALSE. The connection is active and available.

(Similar to dbdead.)
SQL_COPT_SS_ENLIST_IN_DTC The MS DTC OLE transaction object that specifies the transaction to export to SQL Server. The client calls the MS DTC OLE ITransactionDispenser::BeginTransaction method to begin an MS DTC transaction and create an MS DTC transaction object that represents the transaction. The application then calls the SQLSetConnectOption function with the SQL_COPT_SS_ENLIST_IN_DTC option to associate the transaction object with the ODBC connection. All related database activity will be performed under the protection of the MS DTC transaction.

SQL_DTC_DONE. Ends an MS DTC association with an ODBC connection. The application can then use the same ODBC connection for a local SQL Server transaction.

(For more information, see the Guide to Microsoft Distributed Transaction Coordinator.)
SQL_COPT_SS_ENLIST_IN_XA To begin an XA transaction with an XA-compliant Transaction Processor (TP), the client calls the X/Open tx_begin function. The application then calls the SQLSetConnectOption function with a SQL_COPT_SS_ENLIST_IN_XA parameter of TRUE to associate the XA transaction with the ODBC connection. All related database activity will be performed under the protection of the XA transaction.

To end an XA association with an ODBC connection, the client must call the SQLSetConnectOption function with a SQL_COPT_SS_ENLIST_IN_XA parameter of FALSE. The application can then use the same ODBC connection for a local SQL Server transaction.

(For more information, see the Guide to Microsoft Distributed Transaction Coordinator.)
SQL_COPT_SS_PERF_DATA
(SQLGetConnectOption only) 		The address of a pointer to a SQLPERF structure. The SQL Server driver will return a pointer to a SQLPERF structure that contains current performance data. If NULL returned, logging of performance data is not enabled.
SQL_COPT_SS_PERF_DATA
(SQLSetConnectOption only) 		SQL_PERF_START. Start logging performance data.

SQL_PERF_STOP. Stop logging performance data.
SQL_COPT_SS_PERF_DATA_LOG | Full path and filename of the performance data log file.
SQL_COPT_SS_PERF_DATA_LOG
_NOW
(SQLSetConnectOption only) 		Writes a tab-delimited record of performance data to the specified log file. The vParam parameter can point to a null-terminated character string that contains a comment for this log record.
SQL_COPT_SS_PERF_QUERY
(SQLGetConnectOption only) 		If NULL is returned, logging of long-running queries is not enabled. Otherwise, logging of long-running queries is enabled.
SQL_COPT_SS_PERF_QUERY
(SQLSetConnectOption only) 		SQL_PERF_START. Start logging long-running queries.

SQL_PERF_STOP. Stop logging long-running queries.
SQL_COPT_SS_PERF_QUERY
_INTERVAL 		The threshold value in milliseconds for logging of long-running queries. A query that takes longer than this number of milliseconds to run is logged.
SQL_COPT_SS_PERF_QUERY_LOG | Full path and filename of the log file for long-running queries.
SQL_COPT_SS_USER_DATA Sets or gets the user data pointer.

If not set, SQLGetConnectOption returns SQL_UD_NOTSET.

(Similar to dbsetuserdata and dbgetuserdata.)
SQL_FALLBACK_CONNECT SQL_FALLBACK_CONNECT_OFF. Fallback server support is disabled. (Default)

SQL_FALLBACK_CONNECT_ON. When successfully connected to the primary server, the ODBC SQL Server driver automatically determines the current fallback server and verifies that fallback information is stored in the registry. If an attempt to connect to a primary server fails (the connection timeout must be greater than 0 for this to occur), the ODBC SQL Server driver will attempt to connect to the fallback server. This option must be set before calling SQLConnect, SQLDriverConnect, or SQLBrowseConnect.
SQL_INTEGRATED_SECURITY SQL_IS_OFF. Request a normal connection to SQL Server. A trusted connection using SQL Server integrated security is not requested. (Default)

SQL_IS_ON. Request a trusted connection to SQL Server regardless of the security mode of the server.

For information about the SQL Server login security mode and trusted connections, see the Microsoft SQL Server Administrator's Companion.
SQL_PRESERVE_CURSORS SQL_PC_OFF. All cursors are closed on SQLTransact. (Default)

SQL_PC_ON. Server cursors remain open on SQLTransact.
SQL_USE_PROCEDURE
_FOR_PREPARE 		SQL_UP_ON. Temporary stored procedures are generated for SQLPrepare. (Default)

SQL_UP_OFF. Temporary stored procedures are not generated for SQLPrepare. The statement is stored, compiled, and run at execution time. All syntax error checking is delayed until execution time.

SQL_UP_ON_DROP. Temporary stored procedures are explicitly dropped on a subsequent call to SQLPrepare or when an hstmt is freed.


Driver-specific Option #Defines

The SQL Server driver-specific defines can be found in the ODBCSS.H header file.


Deleting a Data Source

To delete a data source, you can use the Data Sources dialog box.

To use the Data Sources dialog box
  1. Select the data source you want to delete from the Data Sources list.
  2. Choose the Delete button, and then choose the Yes button to confirm the deletion.

You may be asked if you want to remove the data source name and its associated information from the WIN.INI file or Registry. Other applications that call SQL Server may use this information to connect to SQL Server data sources.

Choose the Yes button if you are certain that no other applications use the information about the data source; otherwise, choose the No button.


Data Source

You can call the SQLConfigDataSource function to add, modify, or delete a data source dynamically. This function uses keywords to set connection options that are normally set through the ODBC SQL Server Setup dialog box. Use this function when you want to add, modify, or delete a data source without displaying the ODBC SQL Server Setup dialog box.


Chapter 4 Programming ODBC

Programming ODBC

This chapter contains step-by-step procedures for programming ODBC for Microsoft SQL Server.

This chapter discusses using data-at-execution parameters and data-at-execution columns to handle text and image data. Note that they can be used for data of any type and length.


Using ODBC

To use ODBC
  1. Call SQLAllocEnv to initialize ODBC and allocate an environment handle.
  2. Use connections. For more information, see Using Connections.
  3. Call SQLFreeEnv to free the environment handle.


Using Connections

To use a connection
  1. Call SQLAllocConnect to allocate a connection handle.
  2. Optionally, call SQLSetConnectOption to set connection options or SQLGetConnectOption to get connection options.
  3. Call SQLConnect to use an existing data source to connect to SQL Server.

    Or

    Call SQLDriverConnect to use a connection string to connect to SQL Server.

    A minimum complete SQL Server connection string has one of two forms:

    DSN=dsnname;UID=loginid;PWD=password;

    DRIVER={SQL Server};SERVER=server;UID=loginid;PWD=password;

    If the connection string is not complete, SQLDriverConnect can prompt for the required information.

    Or

    Call SQLBrowseConnect multiple times in an iterative fashion to build the connection string and connect to SQL Server.

  4. Optionally, call SQLGetInfo to get driver attributes and behavior for the SQL Server data source.
  5. Use statements. For more information, see Using Statements.
  6. Call SQLDisconnect to disconnect from SQL Server and make the connection handle available for a new connection.
  7. Call SQLFreeConnect to free the connection handle.


Using Statements

To use a statement
  1. Call SQLAllocStmt to allocate a statement handle.
  2. Optionally, call SQLSetStmtOption to set statement options or SQLGetStmtOption to get statement options.

    To use server cursors, you must set cursor options to values other than their defaults. For more information, see Setting Cursor Options.

  3. Execute a statement directly. For more information, see Executing Statements Directly .

    Or

    Prepare a statement once, then execute it multiple times. For more information, see Preparing and Executing Statements.

    Or

    Call a catalog function, which returns results.

  4. Process the results of a statement one row at a time. For more information, see Processing Results.

    Or

    Process the results of a statement using a scrollable cursor. For more information, see Using Scrollable Cursors.

    Or

    Call SQLRowCount to determine the number of rows affected by an insert, update, or delete statement.

  5. If results are returned, call SQLFreeStmt with an fOption of SQL_CLOSE to clear any pending results and make the statement handle available for a new cursor.

    To reuse the statement handle, go to step 2.

  6. Call SQLFreeStmt with an fOption of SQL_DROP to free the statement handle.


Setting Cursor Options

To set cursor options
  1. Call SQLSetStmtOption to set or SQLGetStmtOption to get the statement options that control cursor behavior.
fOption | Specifies
SQL_CURSOR_TYPE | A cursor type of forward-only, static, dynamic, or keyset
SQL_CONCURRENCY | A concurrency control option of read-only, locking, optimistic using timestamps, or optimistic using values
SQL_ROWSET_SIZE | The number of rows in the rowset

The default values for these options (forward-only, read-only, rowset size of 1) do not use server cursors. To use server cursors, at least one of these options must be set to a value other than the default, and the statement being executed must be a single SELECT statement or a stored procedure that contains a single SELECT statement.


Executing Statements Directly

To execute a statement directly and one time only
  1. If the statement has parameter markers, for each parameter
    1. Call SQLBindParameter to bind a program buffer to the statement parameter.

      If the parameter is a data-at-execution text or image parameter, set it up. For more information, see Using Data-at-Execution Parameters.

    2. Put the data values into the bound program buffer.
  2. Call SQLExecDirect to execute the statement.
  3. If data-at-execution text or image parameters are used, handle them. For more information, see Using Data-at-Execution Parameters.
To execute a statement directly using multiple sets of parameters
  1. Call SQLParamOptions to set the number of sets (S) of parameters.
  2. For each parameter marker
    1. Allocate an array of S parameter buffers to store data values.
    2. Allocate an array of S parameter buffers to store data lengths.
    3. Call SQLBindParameter to bind the parameter's data value and data length arrays to the statement parameter.

      If the parameter is a data-at-execution text or image parameter, set it up. For more information, see Using Data-at-Execution Parameters.

    4. Put the S data values and S data lengths into the bound parameter arrays.
  3. Call SQLExecDirect to execute the statement multiple times. This will efficiently execute the statement S times, once for each set of parameters.
  4. If data-at-execution text or image parameters are used, handle them. For more information, see Using Data-at-Execution Parameters.


Preparing and Executing Statements

To prepare a statement once, then execute it multiple times
  1. Call SQLPrepare to prepare the statement.
  2. Optionally, call SQLNumParams to determine the number of parameters in the prepared statement.
  3. Optionally, for each parameter in the prepared statement
    • Call SQLDescribeParam to get parameter information.
  4. Optionally, get result set information. For more information, see Getting Result Set Information.
  5. If the statement has parameter markers, for each parameter
    • Call SQLBindParameter to bind a program buffer to the statement parameter.

      If the parameter is a data-at-execution text or image parameter, set it up. For more information, see Using Data-at-Execution Parameters.

  6. For each execution of a prepared statement
    1. If the statement has parameter markers, put the data values into the bound program buffer.
    2. Call SQLExecute to execute the prepared statement.
    3. If data-at-execution text or image parameters are used, handle them. For more information, see Using Data-at-Execution Parameters.
  7. Call SQLFreeStmt with an fOption of SQL_RESET_PARAMS to release all the bound parameter buffers.


Processing Results

To get results
  1. Get result set information. For more information, see Getting Result Set Information.
  2. If bound columns are used, for each column you want to bind to
    • Call SQLBindCol to bind a program buffer to the column.
  3. For each row in the result set
    1. Call SQLFetch to get the next row.
    2. If bound columns are used, use the data now available in the bound column buffers.
    3. If unbound columns are used, call SQLGetData one or more times to get the data for unbound columns after the last bound column. Calls to SQLGetData should be in increasing order of column number.

      Call SQLGetData multiple times to get data from a text or image column.

  4. Call SQLMoreResults to determine if another result set is available.

    If it returns SQL_SUCCESS, another result set is available.

    If it returns SQL_NO_DATA_FOUND, no more result sets are available.

    If it returns SQL_SUCCESS_WITH_INFO or SQL_ERROR, call SQLError to determine if the output from a PRINT or RAISEERROR statement is available.

    If bound statement parameters are used for output parameters or the return value of a stored procedure, use the data now available in the bound parameter buffers.

    Note that when a result set contains compute rows, each compute row is made available as a separate result set. These compute result sets are interspersed within the normal rows and break up the normal rows into multiple result sets.

  5. Call SQLFreeStmt with an fOption of SQL_UNBIND to release all the bound column buffers.
  6. If another result set is available, go to step 1.


Getting Result Set Information

To get information about the columns in the result set
  1. Call SQLNumResultCols to get the number of columns in the result set.
  2. For each column in the result set
    • Call SQLDescribeCol to get information about the result column.

      Or

    • Call SQLColAttributes to get specific descriptor information about the result column.


Using Scrollable Cursors

To use cursors
  1. Call SQLNumResultCols to get the number of columns (C) in the rowset.
  2. Call SQLSetStmtOption with an fOption of SQL_ROWSET_SIZE to set the number of rows (R) in the rowset.
  3. Optionally, call SQLSetCursorName to set the cursor name or SQLGetCursorName to get the cursor name.
  4. Use column-wise binding.

    Or

    Use row-wise binding. For more information, see Using Rowset Binding.

  5. Fetch rowsets from the cursor as desired. For more information, see Fetching and Updating Rowsets.
  6. Call SQLMoreResults to determine if another result set is available.

    If it returns SQL_SUCCESS, another result set is available.

    If it returns SQL_NO_DATA_FOUND, no more result sets are available.

    If it returns SQL_SUCCESS_WITH_INFO or SQL_ERROR, call SQLError to determine if the output from a PRINT or RAISEERROR statement is available.

    If bound statement parameters are used for output parameters or the return value of a stored procedure, use the data now available in the bound parameter buffers.

    Note that when a result set contains compute rows, each compute row is made available as a separate result set. These compute result sets are interspersed within the normal rows and break up the normal rows into multiple result sets.

  7. Call SQLFreeStmt with an fOption of SQL_UNBIND to release all the bound column buffers.
  8. If another result set is available, go to step 1.


Using Rowset Binding

To use column-wise binding
  1. For each bound column
    1. Allocate an array of R (or more) column buffers to store data values.
    2. Allocate an array of R (or more) column buffers to store data lengths.
    3. Call SQLBindCol to bind the column's data value and data length arrays to the column of the rowset.
  2. Call SQLSetStmtOption with an fOption of SQL_BIND_TYPE and a vParam of SQL_BIND_BY_COLUMN to use column-wise binding.
To use row-wise binding
  1. Allocate an array of R (or more) row buffers. Each row buffer should contain C data value buffers and C data length elements.
  2. For each bound column
    • Call SQLBindCol to bind the column's data value and data length buffers (within the array of row buffers) to the column of the rowset.
  3. Call SQLSetStmtOption with an fOption of SQL_BIND_TYPE and a vParam of the size of a single row element to use row-wise binding.


Fetching and Updating Rowsets

To fetch and update rowsets from a cursor
  1. Optionally, call SQLSetStmtOption with an fOption of SQL_ROWSET_SIZE to change the number of rows (R) in the rowset.
  2. Call SQLExtendedFetch to get a rowset.
  3. If bound columns are used, use the data values and data lengths now available in the bound column buffers for the rowset.
  4. If unbound columns are used, after calling SQLSetPos to set the cursor position, for each unbound column:
    • Call SQLGetData one or more times to get the data for unbound columns after the last bound column of the rowset. Calls to SQLGetData should be in increasing order of column number.
    • Call SQLGetData multiple times to get data from a text or image column.
  5. If data-at-execution text or image columns are used, set them up. For more information, see Using Data-at-Execution Columns.
  6. Call SQLSetPos to set the cursor position, refresh, update, delete, or add row(s) within the rowset.

    If data-at-execution text or image columns are used for an update or add operation, handle them. For more information, see Using Data-at-Execution Columns.

  7. Optionally, execute a positioned UPDATE or DELETE statement, specifying the cursor name (available from SQLGetCursorName) and using a different statement handle on the same connection.


Using Data-at-Execution Parameters

To handle data-at-execution text or image parameters
  1. When calling SQLBindParameter to bind a program buffer to the statement parameter:
    • Use a pcbValue of SQL_LEN_DATA_AT_EXEC(length) where length is the total length of the text or image parameter data.
    • Use an rgbValue of a program-defined parameter identifier.
  2. Calling SQLExecDirect or SQLExecute returns SQL_NEED_DATA, which indicates that data-at-execution parameters are ready for processing.
  3. For each data-at-execution parameter
    1. Call SQLParamData to get the program-defined parameter ID. It will return SQL_NEED_DATA if there is another data-at-execution parameter.
    2. Call SQLPutData one or more times to send the parameter data, until length is sent.
  4. Call SQLParamData to indicate that all the data for the final data-at-execution parameter has been sent. It will not return SQL_NEED_DATA.


Using Data-at-Execution Columns

To handle data-at-execution text or image columns
  1. For each data-at-execution column:
    • Put special values into the buffers previously bound by SQLBindCol.

      Into the pcbValue data value buffer, put SQL_LEN_DATA_AT_EXEC(length) where length is the total length of the text or image column data.

      Into the rgbValue data length buffer, put a program-defined column identifier.

  2. Calling SQLSetPos returns SQL_NEED_DATA, which indicates that data-at-execution columns are ready for processing.
  3. For each data-at-execution column:
    1. Call SQLParamData to get the program-defined column ID. It will return SQL_NEED_DATA if there is another data-at-execution column.
    2. Call SQLPutData one or more times to send the column data, until length is sent.
  4. Call SQLParamData to indicate that all the data for the final data-at-execution column has been sent. It will not return SQL_NEED_DATA.


Chapter 5 Implementation

Implementation

This chapter first discusses the following implementation features; then it covers other implementation issues:

  • Full Level-2 compliance
  • Server cursors
  • Decimal and numeric datatypes
  • Batched RPCs
  • Prepare/execute statements
  • Use of SQL Server features
  • Identity attribute
  • Text/image processing
  • Performance improvements
  • Integrated security
  • SQLExtendedFetch for Microsoft SQL Server 4.21a
  • DSN
  • DayOfWeek
  • Literal parameters in procedures
  • SQLGetInfo changes
  • INSTCAT.SQL
  • DBCS
  • Arithmetic errors
  • ODBC SDK


Version 2.5 Features

The following features of the ODBC SQL Server driver are available in version 2.5 and later.


Full Level-2 Compliance

The SQL Server driver supports all Level-2 ODBC APIs. Support for the following APIs is new in version 2.5:

SQLParamOptions
SQLDescribeParam
SQLSetPos
SQLExtendFetch

For details on these APIs, see Chapter 8, Functions, and the ODBC API Reference.


Server Cursors

The ODBC SQL Server driver automatically uses the server cursors (static, keyset, and dynamic) that were implemented in SQL Server 6.0. This results in improved performance, cleaner cursor semantics (compared to the cursor library in earlier versions), and more efficient memory usage at the client. Server cursors are not used in the following cases:

  • The user sets ODBC_CURSORS to SQL_CUR_USE_ODBC.
  • The user declares the cursor to be forward-only, read-only, rowset = 1.
  • The user declares the cursor to be static and updatable.

One key benefit of using server cursors is that you can have multiple active statements (several open cursors) on the same connection. For more information about using server cursors with ODBC functions, see Chapter 7, ODBC Cursors.


Decimal and Numeric Datatypes

The driver supports full usage of decimal and numeric datatypes and provides the appropriate convert functions to and from other datatypes.

The following ODBC functions return datatype information:

SQLGetInfo | SQLDescribeCol
SQLGetTypeInfo | SQLProcedureColumns
SQLColumns | SQLSpecialColumns

The following ODBC functions may involve conversions between the ODBC SQL and the ODBC C datatypes:

SQLBindCol | SQLGetData
SQLBindParameter | SQLPutData


Batched RPCs

The driver automatically batches remote stored procedure (RPC) requests to the server when appropriate. This could drastically reduce the number of trips to the server and result in an order of magnitude performance gain in many cases. The driver batches RPC requests when the user issues a batch of canonical stored procedure invocations or uses SQLParamOptions in conjunction with SQLPrepare/SQLExecute or a canonical procedure invocation.


Prepare/Execute Statements

The driver creates temporary stored procedures (as opposed to regular stored procedures in earlier versions) on a SQLPrepare. These procedures are automatically deleted when the connection is abnormally terminated. Previously, stored procedures created on a SQLPrepare were orphaned at the server when the connection was abnormally terminated. In addition, the driver provides users with a driver-specific connection option (SQL_USE_PROCEDURE_FOR_PREPARE) that governs when these temporary stored procedures are deleted. By default, they are deleted when the connection is freed. When you are issuing several prepare/execute statements in a connection and need to conserve usage of tempDB, you can have the driver delete these procedures when an hstmt is closed.


Use of SQL Server Features

The driver takes advantage of the following new features in SQL Server:

  • The driver uses the SET TRANSACTION ISOLATION LEVEL statement to
    • Expose the READ UNCOMMITTED isolation level
    • Enforce strict serializability

    In earlier versions, the driver "manually" inserted a HOLDLOCK in the FROM clause of SELECT statements when the user had requested the serializable option.

  • The driver uses the SET FMTONLY statement to implement the SQLDescribeCol and SQLColAttributes APIs. Previously, these APIs were implemented by issuing a "dummy" query that did not return results.
  • The driver enforces the use of ANSI Quoted Identifiers and issues the SET QUOTED_IDENTIFIER ON statement during the startup sequence.
  • The driver exposes SQL Server's IEF using the SQLPrimaryKeys and SQLForeignKeys APIs.
  • The driver uses the SET ANSI_NULL_DFLT_ON statement to enforce ANSI compliant default nullability for columns. In earlier versions, the driver "manually" inserted the NULL keyword after column specifications.
  • The driver allows text and image parameters in stored procedures. Invocation of these stored procedures is handled as an RPC request, as opposed to a language event as in previous versions.
  • The driver automatically uses the default packet size set at the server if one is not specified using the ODBC SQLSetConnectOption.


Identity Attribute

The driver exposes the SQL Server Identity Attribute using the SQL_COLUMN_AUTO_INCREMENT descriptor in SQLColAttributes and the AUTO_INCREMENT column in the SQLGetTypeInfo results set. SQL Server treats identity as an attribute, whereas ODBC treats it as a datatype. To resolve this mismatch, SQLGetTypeInfo returns the following new datatypes:

  • int identity
  • smallint identity
  • tinyint identity
  • decimal identity
  • numeric identity


Text/Image Processing

The driver has several enhancements to the processing of text and image data:

  • When connected to SQL Server, the driver uses the UPDATETEXT function in the server to support updating the text and image columns of all rows when the UPDATE statement affects multiple rows.

    When connected to SQL Server 4.2x, only the text and image columns of the first row (of a multirow UPDATE) will be updated.

  • The driver exposes a driver-specific statement option (SQL_TEXTPTR_LOGGING) to disable the logging of text and image column operations.
  • When using server cursors, the driver does not retrieve text and image data for unbound columns unless the user explicitly issues the SQLGetData call.
  • When connected to SQL Server, SQLExecDirect and SQLExecute do not require SQL_LEN_DATA_AT_EXEC, but using it is more efficient.


Performance Improvements

The driver has the following new performance-related features:

  • Improved Connect Time—The driver batches informational queries to the server when making a connection that reduces the number of trips to the server. The fast connect option is no longer needed or supported.
  • The driver makes better use of memory (eliminating copies) for faster processing of results.
  • 64-bit Arithmetic—The 32-bit driver uses 64-bit arithmetic for data conversions to and from money, decimal, and numeric datatypes.


Integrated Security

The driver provides a driver-specific option (SQL_INTEGRATED_SECURITY) to request a secure connection from SQL Server.


SQLExtendedFetch for 4.21a SQL Server

The driver supports the SQLExtendedFetch API (forward-only, read-only cursors) for SQL Server 4.21a.


DSN

When you install the 32-bit driver, you have the option to convert existing 16-bit DSNs to 32-bit DSNs so they can be used by 32-bit applications. In addition, the driver uses the OEMtoANSI setting from the SQL Server Client Configuration Utility dialog box as the default when a new DSN is defined.


DayOfWeek

The driver supports the DAYOFWEEK canonical function defined in ODBC.


Literal Parameters in Procedures

The driver executes canonical procedure invocations that have literal parameters as RPC requests. In earlier versions, unless the invocation had all parameter markers, the request was issued as a language event.


SQLGetInfo Changes

For more information, see the SQLGetInfo function.


INSTCAT.SQL

The new INSTCAT.SQL catalog provides new functionality and improved performance over previous versions.


DBCS

The ODBC SQL Server driver version 2.5 is DBCS enabled.

Note that the canonical LENGTH function maps to the SQL Server DATALENGTH function, which returns the length of a data value in bytes. Therefore, if a character string contains any DBCS characters, the canonical LENGTH function will return the number of bytes in the character string and not the number of characters in the character string.


Arithmetic Errors

The ODBC SQL Server driver version 2.5 uses SET ARITHABORT ON to enhance ODBC semantics.


ODBC SDK

The ODBC SDK is included as part of the Microsoft SQL Workstation version 6.5.


Active hstmt

The SQL Server driver can have only one active hstmt unless the driver is used with server cursors. The driver returns this information through SQLGetInfo with the SQL_ACTIVE_STATEMENTS option. An hstmt is defined as active if it has results pending. In this context, results are any information returned by SQL Server, such as a results set or a count of the rows that are affected by an UPDATE statement.

Note An hstmt's activity is not related to its state. For example, if a SELECT statement is executed and it does not return any rows, the statement is not active, because no results are pending. However, before the statement can be executed again, the cursor associated with it must be closed with SQLFreeStmt.

When connected to SQL Server 6.x, the SQL Server driver supports multiple active statements on a single connection when server cursors are used.

When connected to SQL Server 4.2x, the SQL Server driver supports only one active statement per connection. The cursor library (shipped with the SQL Server driver) allows applications to use multiple active statements on a connection.


Cursor Library

The cursor library (shipped with the SQL Server driver) allows applications to use multiple active statements on a connection, as well as scrollable, updateable cursors. The cursor library (ODBCCURS.DLL (16-bit) or ODBCCR32.DLL (32-bit)) must be loaded to support this functionality. Use SQLSetConnectOption to specify how the cursor library should be used and SQLSetStmtOption to specify the cursor type, concurrency, and rowset size.


Arithmetic Errors

If an arithmetic error such as divide-by-zero or a numeric overflow occurs during execution of an SQL statement, the statement is aborted. Partial results may have already been sent to the client and may be delivered to the application before the application is notified of the error.

The driver sets ARITHABORT to ON.

For more information, see SET ARITHABORT and SET ARITHIGNORE in the SET Statement section in the Microsoft SQL Server Transact-SQL Reference.


Manual-commit Mode Transactions

When the SQL Server driver is in manual-commit mode, it initiates a transaction with a BEGIN TRANSACTION statement in the following situations:

  • An SQL statement is pending.
  • There is no current transaction.
  • It is not a restricted Data Definition Language (DDL) statement.

    For more information about restricted DDL statements, see the section on Transactions in the Microsoft SQL Server Transact-SQL Reference documentation for the list of statements that cannot be in a transaction.

To commit or roll back a transaction in manual-commit mode, the application must call SQLTransact. The SQL Server driver sends a COMMIT TRANSACTION statement to commit a transaction; it sends a ROLLBACK TRANSACTION statement to roll back a transaction.

A restricted DDL statement can be executed only in manual-commit mode under one of the following circumstances:

  • After manual commit mode has been set and before a non-restricted DDL or a Data Manipulation Language (DML) statement has been executed,

Or

  • After a transaction has been committed or rolled back and before a non-restricted DDL or a DML statement has been executed.

For more information about manual-commit mode, see SQLSetConnectOption in the Microsoft ODBC SDK Programmer's Reference.

The following ODBC catalog functions cannot be called inside a transaction because they use catalog stored procedures that create temporary tables:

SQLColumnPrivileges
SQLForeignKeys
SQLPrimaryKeys (limited for SQL Server 4.2x only)
SQLStatistics
SQLTablePrivileges


Remote Procedure Calls

The SQL Server driver uses the RPC facility in SQL Server to run procedures rather than pass procedures to SQL Server in an SQL statement. A procedure can be:

  • A prepared statement (which is a statement that is stored as a procedure)
  • A procedure that is called with the ODBC procedure syntax
  • A stored procedure that the SQL Server driver uses to implement a catalog function

RPCs have the following advantages over procedures passed in an SQL statement:

  • RPCs are faster than procedures passed in an SQL statement.
  • RPCs can have output parameters (however, see "Limitations," below); procedures passed in an SQL statement cannot. (A procedure can return a value in either case.)
To run a statement as an RPC, an application
  1. Constructs an SQL statement.
  2. Calls SQLBindParameter for each parameter in the statement.
  3. Prepares the statement with SQLPrepare. (Note that the SQL_USE_PROCEDURE_FOR_PREPARE connection option must be set to SQL_UP_ON.)
  4. Executes the statement with SQLExecute.
To run a procedure as an RPC, an application
  1. Constructs an SQL statement that uses the ODBC procedure syntax. The statement uses parameter markers for each input, input/output, and output parameter, and for the procedure return value (if any).
  2. Calls SQLBindParameter for each input, input/output, and output parameter, and for the procedure return value (if any).
  3. Executes the statement with SQLExecDirect.

Note If an application submits a procedure using the SQL Server syntax (as opposed to the ODBC procedure syntax), the SQL Server driver passes the procedure call to SQL Server as an SQL statement rather than as an RPC.


Limitations

RPCs are executed as language events (EXEC Procname Params) if any parameter is bound to using SQL_DATA_AT_EXEC.

When an RPC is executed as a language event, no output parameter values are returned.

Output parameters of a stored procedure are also input parameters, although the stored procedure may not use the input value. However, a valid input value must be provided to prevent conversion errors.

For input/output parameters and output parameters, the length/precision (cbColDef) and scale (ibScale) that are set by using SQLBindParameter limit the maximums that the output value can contain.


Using Microsoft Distributed Transaction Coordinator

The SQL Server driver supports Microsoft Distributed Transaction Coordinator (MS DTC) and MS DTC transactions.

To update two or more SQL Servers using MS DTC
  1. Connect to MS DTC using the MS DTC OLE DtcSelectTransactionManager function. For information about MS DTC, see the Guide to Microsoft Distributed Transaction Coordinator.
  2. Call SQLDriverConnect once for each SQL Server connection you want to establish.
  3. Call the MS DTC OLE ITransactionDispenser::BeginTransaction function to begin an MS DTC transaction and obtain a Transaction object that represents the transaction.
  4. Call SQLSetConnectOption one or more times for each ODBC connection you want to enlist in the MS DTC transaction. SQLSetConnectOption must be called with an fOption of SQL_COPT_SS_ENLIST_IN_DTC and a vParam of the Transaction object (obtained in step 3).
  5. Call SQLExecDirect once for each SQL Server you want to update.
  6. Call the MS DTC OLE ITransaction::Commit function to commit the MS DTC transaction. The Transaction object is no longer valid.

To perform a series of MS DTC transactions, repeat steps 3 through 6.

To release the reference to the Transaction object, call the MS DTC OLE ITransaction::Return function.

To use an ODBC connection with an MS DTC transaction, and then use the same connection with a local SQL Server transaction, call SQLSetConnectOption with a vParam of SQL_DTC_DONE.

Note You can also call SQLSetConnectOption and SQLExecDirect in turn for each SQL Server instead of calling them as suggested in steps 4 and 5 above.


Logging Performance Data

In SQL Server 6.5, the ODBC SQL Server driver supports logging performance data.

To log ODBC performance data
  1. Optionally, call SQLSetConnectOption with fOption set to SQL_COPT_SS_PERF_DATA_LOG and vParam set to the full path and filename of the performance data log file. For example:
    C:\\ODBCPERF.LOG
  2. Call SQLSetConnectOption with fOption set to SQL_COPT_SS_PERF_DATA and vParam set to SQL_PERF_START to start logging performance data.
  3. Call SQLGetConnectOption with fOption set to SQL_COPT_SS_PERF_DATA and pvParam set to the address of a pointer to a SQLPERF structure. This will set the pointer to point to a valid SQLPERF structure that contains current performance data.
  4. Optionally, call SQLSetConnectOption with fOption set to SQL_COPT_SS_LOG_NOW and vParam set to NULL to write a tab-delimited record of performance data to the performance data log file.
  5. Call SQLSetConnectOption with fOption set to SQL_COPT_SS_PERF_DATA and vParam set to SQL_PERF_STOP to stop logging performance data.

The SQLPERF structure is defined as follows:

typedef struct sqlperf
{
    // Application Profile Statistics
    DWORD TimerResolution;
    DWORD SQLidu;
    DWORD SQLiduRows;
    DWORD SQLSelects;
    DWORD SQLSelectRows;
    DWORD Transactions;
    DWORD SQLPrepares;
    DWORD ExecDirects;
    DWORD SQLExecutes;
    DWORD CursorOpens;
    DWORD CursorSize;
    DWORD CursorUsed;
    LDOUBLE PercentCursorUsed;
    LDOUBLE AvgFetchTime;
    LDOUBLE AvgCursorSize;
    LDOUBLE AvgCursorUsed;
    DWORD SQLFetchTime;
    DWORD SQLFetchCount;
    DWORD CurrentStmtCount;
    DWORD MaxOpenStmt;
    DWORD SumOpenStmt;

    // Connection Statistics
    DWORD CurrentConnectionCount;
    DWORD MaxConnectionsOpened;
    DWORD SumConnectionsOpened;
    DWORD SumConnectionTime;
    LDOUBLE AvgTimeOpened;

    // Network Statistics
    DWORD ServerRndTrips;
    DWORD BuffersSent;
    DWORD BuffersRec;
    DWORD BytesSent;
    DWORD BytesRec;

    // Time Statistics;
    DWORD msExecutionTime;
    DWORD msNetworkServerTime;

}     SQLPERF;


Additional ODBC SQL Server Driver Information

When connected to Microsoft SQL Server 6.5:

  • The USER keyword is part of the supported ODBC SQL grammar.
  • Static server side cursors can be used on ODBC catalog functions.
  • The DEFAULT keyword is supported in canonical procedure invocations. Use the DEFAULT keyword to specify a default procedure parameter.
  • Default procedure parameters can be used anywhere. When connected to SQL Server version 6.0 or earlier, all default procedure parameters must be after all non-default procedure parameters.
  • Canonical procedure invocations that include a NULL literal parameter are executed as an RPC request. When connected to SQL Server version 6.0 or earlier, the request is issued as a language event.
  • SQLTablePrivileges supports search patterns for the table owner and table name parameters. (All servers.)
  • SQLTablePrivileges and SQLColumnPrivileges return information in the GRANTOR column of the results set to reflect grants that are used with the WITH GRANT clause.
  • The following ODBC catalog functions can be called inside a transaction:
SQLColumnPrivileges | SQLStatistics
SQLForeignKeys | SQLTablePrivileges
SQLPrimaryKeys |

  • Because the SQLSetStmtOption SQL_MAX_ROWS option maps to the SET ROWCOUNT statement (when connected to any version of SQL Server), setting this option causes all Transact-SQL® statements to stop processing when they have each affected the specified number of rows. This includes triggers and data modification statements, such as INSERT, UPDATE, and DELETE, as well as the filling of a Keyset cursor at the specified number of rows. This option should be used with caution and primarily with the SELECT statement.
  • The following fDescType attribute parameters of SQLColAttributes are supported only when server side cursors are used:

    SQL_COLUMN_TABLE_NAME

    SQL_COLUMN_OWNER_NAME

    SQL_COLUMN_QUALIFIER_NAME

  • Parameters to an ODBC canonical procedure call that are only output parameters can contain non-valid input data.
  • The ODBC like escape clause is supported.
  • All ODBC outer join extensions can be used without restrictions.
  • When storing data in character or binary datatypes, any non-blank (for character) or non-zero (for binary) data truncation will cause SQL_ERROR to be returned. A subsequent call to SQLError will return an szSqlState of "22001."
  • SQLSetPos has the following performance enhancements:
    • SQLSetPos supports asynchronous execution.
    • Calling SQLSetPos with an fOption of SQL_DELETE and an irow of 0 is a single server operation.
    • Calling SQLSetPos with an fOption of SQL_UPDATE or SQL_ADD and an irow of 0 uses a batch of multiple RPCs.
  • When not in auto-commit mode, the ODBC SQL Server driver uses SET IMPLICIT_TRANSACTION ON to increase performance.

When connected to SQL Server 6.0 and later, bookmarks are supported for Static and Keyset cursors.


Chapter 6 SQL Grammar

SQL Grammar

The ODBC SQL Server driver fully supports the core SQL grammar. The SQL Server driver also supports almost all SQL statements in the extended ODBC grammar. When connected to SQL Server 6.5, the only extended ODBC grammar not supported is the DROP COLUMN clause of the ALTER TABLE statement, and the CASCADE and RESTRICT clauses of the DROP VIEW, DROP TABLE, and REVOKE statements. In accordance with the design of ODBC, the SQL Server driver will pass native SQL grammar to SQL Server.

This chapter provides information regarding supported and non-supported grammar. It includes the following sections:

  • SQL Grammar Limitations
  • Data-at-Execution Parameter Limitations
  • Procedure Invocation Limitations
  • Non-Supported ODBC SQL Grammar
  • Nullability Resolution


SQL Grammar Limitations

The SQL Server driver and SQL Server impose the following programming limitations on the ODBC SQL grammar.

ODBC SQL grammar | SQL Server/SQL Server driver limitation
Data-at-execution parameter limitations | Data-at-execution parameters that are used to send a lot of data for a SQL_LONGVARCHAR or SQL_LONGVARBINARY column are subject to a number of restrictions. For details, see the Data-at-Execution Parameter Limitations topic.
OUTER JOIN | When connected to SQL Server version 6.0 or earlier, the search condition for an outer join must be an equals condition (=). The ODBC outer join extension must appear last in the table reference list. SQL Server versions 6.0 and earlier do not support both nested outer joins and inner joins nested within an outer join. A table cannot be the inner table in an outer join and still participate in an inner join. A table cannot be the inner table in an outer join and the outer table in another outer join. A table can, however, participate in an inner join and be the outer table in an outer join.
Procedures | A procedure must be invoked as the first statement in a prepared batch of statements, or it must be invoked with the EXECUTE statement or by using the ODBC canonical procedure innovation. For details, see the Procedure Invocation Limitations topic.


Data-at-Execution Parameter Limitations

If you use a data-at-execution parameter to send more than 65,535 bytes of data (for SQL Server 4.21a) or 250K of data (for SQL Server version 6.0 and later) for a SQL_LONGVARCHAR (text) or SQL_LONGVARBINARY (image) column, the parameter is subject to the following restrictions:

  • It can be used only as an insert_value in an INSERT statement.
  • It can be used only as an expression in the SET clause of an UPDATE statement.
  • It cannot be used in a statement with data-at-execution parameters that have a datatype other than SQL_LONGVARCHAR or SQL_LONGVARBINARY.
  • It can be used in a statement with non-data-at-execution parameters of any datatype.
  • If its value is NULL, the cbColDef argument in SQLBindParameter and the cbValueMax argument in SQLPutData must be SQL_NULL_DATA.
  • Canceling the operation (a call to SQLPutData for a column after SQLParamData returns SQL_NEED_DATA) before completion will cause a partial update. The text or image column you were processing when you canceled will be set to an intermediate "place holder" value, and any unprocessed text or image columns will remain unchanged.


Procedure Invocation Limitations

For maximum interoperability, procedures should be invoked using the ODBC {call procedure} extension to the SQL language. If you prepare a procedure without using the {call} syntax, use the EXECUTE in front of each stored procedure. This is because the SQL Server driver surrounds a statement it is preparing with other SQL statements. Thus, the statement being prepared is no longer the first in the batch.

With the SQL Server driver, there is no advantage to preparing a statement that invokes a procedure (instead of executing it directly). When the Generate Stored Procedures for Prepared Statements option is selected, the SQL Server driver prepares a statement by placing it in a procedure and compiling that procedure. Preparing a statement by placing it in a procedure and compiling it can be disabled, however. To ensure that stored procedures are never used to implement SQLPrepare, clear the Generate Stored Procedures check box in the SQL Server Setup dialog box, or set the SQL_USE_PROCEDURE_FOR_PREPARE option in SQLSetConnectOption to SQL_UP_OFF. This ensures that a prepared statement will be stored and executed at run time. Then stored procedures will not be used to implement SQLPrepare. In addition, all syntax error checking will be delayed until execution time.

When a SET NOCOUNT ON statement is executed, multiple statements embedded in a stored procedure do not create multiple results as they should. The driver ignores row counts that are generated by SQL statements inside of a stored procedure.


Cursors Using Stored Procedures

Server cursors can only be opened on a stored procedure that contains a single SELECT statement. Using a stored procedure that contains no SELECT statement, more than one SELECT statement, or any statement other than a SELECT statement will generate an error. Because of this restriction, server cursors cannot be used with the ODBC catalog functions when connected to SQL Server 6.0 or earlier.


Non-Supported ODBC SQL Grammar

The SQL Server driver fully supports all core and extended ODBC SQL grammar with the following exceptions.

Non-supported grammar | Description
DAYOFWEEK | The scalar function DAYOFWEEK is not supported when connected to SQL Server 4.2x. The function is supported when connected to SQL Server 6.x.
DELETE | The WHERE CURRENT OF cursor_name clause (positioned delete statement) is not supported when connected to SQL Server 4.2x. The clause is supported when connected to SQL Server 6.x.
DROP INDEX | table_name and index_name must be used instead of just index_name.
IEF | None of the clauses in the Integrity Enhancement Facility (IEF) are supported when connected to SQL Server 4.2x. All of the clauses are supported when connected to SQL Server 6.x except the CASCADE and RESTRICT clauses.
MAX, MIN | The DISTINCT keyword is not supported for these set functions.
SELECT | The FOR UPDATE OF clause of the SELECT statement is not supported when connected to SQL Server 4.2x. The clause is supported when connected to SQL Server 6.x.
UPDATE | The WHERE CURRENT OF cursor_name clause (positioned UPDATE statement) is not supported when connected to SQL Server 4.2x. The clause is supported when connected to SQL Server 6.x.
USER | When connected to SQL Server version 6.0 and earlier, the USER keyword is not supported, except in the DEFAULT clause of the IEF.


Nullability Resolution

In the ODBC grammar, columns for which nullability is not specified are assumed to be nullable. In the SQL Server grammar, columns for which nullability is not specified are assumed to be not nullable.

When connected to SQL Server 6.x, the SQL Server driver resolves this situation by setting SET ANSI_NULL_DEFAULT_ON. This causes the server to use a default of NULL for columns where nullability is not specified except for bit columns or user-defined datatypes.

When connected to SQL Server 4.2x, the SQL Server driver adds a NULL specification to each column definition in a CREATE TABLE statement that does not specify whether the column is nullable (except for bit columns, which are not nullable). It adds a NULL specification to each column definition in an ALTER TABLE statement (except for bit columns, which are not nullable).


Chapter 7 ODBC Cursors

ODBC Cursors

After discussion about using ODBC cursors and server cursors, this chapter provides information about creating, retrieving data from, updating, and closing cursors.

Using ODBC Cursors


Using ODBC Cursors

SQL Server 6.x provides support for engine-based cursors, and version 2.5 and later of the SQL Server driver makes use of that powerful feature. This section provides a brief overview on how to use server cursors through the ODBC API.


ODBC Cursor Model

ODBC supports a cursor model that allows several types of cursors, scrolling within a cursor, several concurrency options, and single-row as well as bulk fetches. Unlike SQL Server 6.x, ODBC does not have explicit APIs to declare, open, and close cursors. Cursors are automatically created for you when you issue a SQLExecDirect or a SQLPrepare plus SQLExecute that is based on the specified statement options.


Type A and Type B Statements

The SQL Server driver uses two types of statements — Type A and Type B.

A Type A statement is defined as any statement that uses the default setting for each of the following three statement options.

Option | Default
SQL_CONCURRENCY | SQL_CONCUR_READ_ONLY
SQL_CURSOR_TYPE | SQL_CURSOR_FORWARD_ONLY
SQL_ROWSET_SIZE | 1

Type A statements do not make use of server cursors. Instead the query is executed at the server and results sets are passed back to the application. The SQL Server driver allows you to perform SQLFetch and SQLExtendedFetch (you can change the rowset size after the cursor is open and perform block fetches) on this data, but the connection between the client and the server remains busy until all the data has been fetched (you have reached the end of the cursor) or the cursor is closed. This option is fast if you are going to retrieve all rows sequentially and you do not need to perform any updates. Because server cursors are not used, you cannot do positioned operations (using WHERE CURRENT OF) on Type A statements.

A Type B statement is defined as any statement that does not use the default settings for the above three statement options. Type B statements cause the driver to use server cursors in most cases (see the restrictions noted in "Creating Cursors," later in this chapter).


Using Server Cursors

There are several advantages to using server cursors, which are implemented in SQL Server 6.x.

  • Performance — If you are going to access a small fraction of the data in the cursor (typical of many browsing applications), using server based cursors will give you an optimal performance because only required data (and not the entire results set) is sent over the network.
  • Additional cursor types — Keyset and dynamic cursor types are only available if you use server cursors. In addition, the cursor library only supports forward only with read-only concurrency and static with read-only and optimistic concurrency. With server based cursors, you can use the full range of concurrency values with the different cursor types.
  • Cleaner semantics — The cursor library simulates cursor updates by generating a SQL searched update statement. This can sometimes lead to unintended updates.
  • Memory usage — When using server based cursors, the client does not need to cache large amounts of data or maintain information about the cursor position; the server provides that functionality.
  • Multiple open cursors — When using server based cursors, the connection between the client and the server does not remain busy between cursor operations. This allows you to have multiple cursor hstmts active at the same time. The ODBC specification still restricts you to one cursor per hstmt. To get around the one active hstmt limitation associated with Type A statements, change the statement options so you get server cursors associated with Type B statements.


Creating Cursors

For the purposes of ODBC cursors, the cursor definition is essentially the SQL statement passed as an argument to SQLExecuteDirect or SQLPrepare/SQLExecute. The following rules apply when creating cursors through the SQL Server driver:

  • Server cursors are created only for statements that begin with a SELECT, EXEC[ute] procedure_name, or {call procedure_name} clause. Otherwise, the statement is treated as a Type A statement. Server cursors are not created for an SQL batch. SQL batches are treated as Type A statements.
  • When connected to SQL Server version 6.0 and earlier, if you ask for a Dynamic or Keyset cursor and there is not a unique index for every table referenced in the cursor definition, the server creates a static cursor and the driver returns a SQL_SUCCESS_WITH_INFO status.
  • SQL Server allows you to create cursors on base tables as well as on views. In addition, cursors can be opened on a query involving joins between multiple tables and/or aggregate operators. You cannot, however, use the keywords COMPUTE, COMPUTE BY, FOR BROWSE, and INTO in the cursor definition.
  • If the cursor definition involves a UNION, UNION ALL, outer join, GROUP BY with/without HAVING, or DISTINCT, a static cursor is always created irrespective of what was requested and the driver returns a SQL_SUCCESS_WITH_INFO status.
  • When connected to SQL Server version 6.0 and earlier, if you ask for a Dynamic cursor and the cursor definition contains an ORDER BY clause that does not match a unique index or a subquery, the server creates a Keyset cursor and the driver returns a SQL_SUCCESS_WITH_INFO status.
  • If you ask for a concurrency of row versioning and there is not a timestamp column for every table in the cursor definition, the server uses a concurrency based on values and the driver returns a SQL_SUCCESS_WITH_INFO status.
  • You will get a cursor on SQLExecDirect (EXEC[ute] procedure_name or {call procedure_name}) only if the procedure contains one SELECT statement and nothing else. Otherwise, SQL Server generates an error message.
  • You will automatically get the cursor behavior associated with Type A statements when executing a batch that contains multiple SELECT statements (except if the first statement is a SELECT, EXECUTE, or ODBC canonical procedure invocation, in which case, SQL Server driver generates an error message).

Keyset cursors could also be populated asynchronously (please refer to the SQL Server documentation about sp_configure). Asynchronous keyset population does not affect the cursor-related ODBC APIs except for SQLRowCount.

The following ODBC functions are relevant for creating cursors:

SQLSetStmtOption SQLGetCursorName
SQLSetScrollOptions SQLGetStmtOption
SQLSetConnectOption SQLGetInfo
SQLSetCursorName


Retrieving Data Through Cursors

There are two ways to retrieve data through cursors:

  • You can bind columns of the results set to storage locations by using SQLBindCol, and then use SQLFetch to move to the next row in the results set. For bulk fetches, you could bind columns to an array and use SQLExtendedFetch. The SQL Server driver supports row-wise as well as column-wise binding. Keep in mind that when using server cursors, each SQLFetch or SQLExtendedFetch operation involves a round trip to the server and the connection remains free between these operations. The server tracks all required state information (for example, current cursor position). Also, cursor operations do not have to be sequential. The server allows you to traverse the cursor in the forward or backward directions relative to the current position. You can also directly set the position to an absolute row number (except for Dynamic cursors) in the results set.
  • You can retrieve data for unbound columns (columns for which storage has not been allocated). Use SQLFetch or SQLExtendedFetch to position the cursor on the next row, and call SQLGetData to retrieve data for specific unbound columns. You can call SQLGetData multiple times on the same column to incrementally retrieve data. This is useful if you are retrieving large amounts of data from a text or image column. Keep in mind, however, that the connection is busy until you read all the data associated with the column. If you issue an SQLSetPos with the Position option, the SQL Server driver flushes the remaining data and frees up the connection, thereby allowing you to use it for processing on another hstmt.

You can retrieve data from both bound and unbound columns in the same row.

When retrieving rows involving potentially large text and image columns, if you do not want to access the text data column in the row, do not bind that column. When you do an SQLExtendedFetch, the retrieved row will only contain the text pointer for the unbound column as opposed to the previous behavior of returning the complete row including the text data.

The following ODBC functions are relevant:

SQLFetch | SQLRowCount
SQLExtendedFetch |


Updating Cursors

Data is usually modified one row at a time (there is an option in SQLSetPos to affect the entire rowset) by first positioning to the desired row. To position the cursor on a particular row, you can:

  • Call SQLFetch one or more times.
  • Call SQLExtendedFetch one or more times.
  • Call SQLSetPos with the SQL_POSITION option.

There are two ways of modifying data in the results set:

  • You can issue an UPDATE WHERE CURRENT OF cursor_name or DELETE WHERE CURRENT OF cursor_name to update or delete the row currently pointed to by the cursor. The positioned UPDATE or DELETE statement must be issued on a separate hstmt on the same connection, and it requires the cursor name (which you can explicitly set using the SQLSetCursorName function). This allows you to work with several cursors simultaneously.
  • You can use the SQLSetPos function to add, delete, and update rows of data. The SQLSetPos API provides options to specify the desired operation, the target row number, and how to lock the row. SQLSetPos can only be used on row sets that are fetched with SQLExtendedFetch.

The following ODBC functions are relevant:

SQLSetPos

SQLRowCount


Closing Cursors

Cursors are automatically closed if you commit or roll back the transaction. The SQL Server driver provides a driver-specific connection option, SQL_PRESERVE_CURSORS, to override this behavior for server cursors. If this option is set to SQL_PC_ON, cursors remain open and the cursor state is preserved across transaction commits or rollbacks.

The following ODBC functions are relevant:

SQLFreeStmt

SQLTransact


Chapter 8 Functions

Functions

This chapter describes how the ODBC SQL Server driver implements certain ODBC functions.

ODBC API Function Implementation


ODBC API Function Implementation

The SQL Server driver supports translation DLLs as well as the functions listed in the following table. For an explanation of how each supported function is implemented, see the following sections.

Function | Description
SQLBrowseConnect SQLBrowseConnect uses three levels of keywords:

1. DSN, DRIVER

2. SERVER, UID, PWD, APP, WSID

3. DATABASE, LANGUAGE
SQLConnect | SQLConnect supports DATABASE and LANGUAGE defaults.
SQLDriverConnect | SQLDriverConnect uses the DSN, DRIVER, SERVER, UID, PWD, APP, WSID, DATABASE, and LANGUAGE keywords.
SQLColAttributes, SQLDescribeCol, and SQLNumResultCols | If any of these functions are called after a SELECT statement has been prepared and before it has been executed, the SQL Server driver uses SET FMTONLY to cause SQL Server to generate the necessary information about the results set.
SQLConfigDataSource | SQLConfigDataSource adds, modifies, or deletes a data source dynamically by using keywords to set connect options.
SQLPrepare | SQL Server does not directly support the Prepare/Execute model of ODBC. To prepare an SQL statement, the SQL Server driver creates a temporary procedure, which compiles the statement for later execution. Note that generation of stored procedures for SQLPrepare can be disabled in either the ODBC SQL Server Driver Setup dialog box or by using the SQLSetConnectOption function. If disabled, the SQL statement is stored and then sent to the server each time it is executed.
SQLParamOptions | The SQLParamOptions function allows an application to specify an array of multiple values for the parameters assigned by SQLBindParameter. By calling SQLParamOptions with a crow greater than 1, the driver generates an SQL statement batch or a stored procedure batch to execute multiple SQL statements.
SQLDescribeParam | The SQLDescribeParam function returns the description of a parameter marker associated with a prepared SQL statement.
SQLRowCount | If this function is called after a "cursor open" and the cursor is of type keyset or static, the function returns the number of rows in the results set. For dynamic cursors, SQLRowCount always returns –1. If the keyset is being populated asynchronously, SQLRowCount will return –1 until the keyset is fully populated.
SQLTables | The driver does not support search patterns for the szTableQualifier parameter.


SQLBrowseConnect

SQLBrowseConnect uses keywords that can be categorized into three levels of connection information. For each keyword, the following table indicates whether a list of valid values is returned and whether the keyword is optional.

Level 1

Keyword | List returned? | Optional? | Description
DSN | N/A | No | The name of the data source as it is returned by SQLDataSources. The DSN keyword is not used if the DRIVER keyword is used.
DRIVER | N/A | No | The SQL Server driver name is {SQL Server}. (For a 16-bit program, the 32-bit driver name is {SQL Server (32 bit)}.)

Level 2

Keyword | List of valid values returned? | Optional? | Description
SERVER | Yes | No | The name of the server on the network on which the data source resides. When running on Microsoft Windows NT, "(local)" can be entered as the server, in which case, a local copy of SQL Server can be used, even when this is a non-networked version. Note that when the 16-bit SQL Server driver is using "(local)" without a network, the "MS Loopback Adapter" must be installed.
UID | No | Yes | The user login ID.
PWD | No | Yes (depends on the user) | The user-specified password.
APP | No | Yes | The name of the application calling SQLBrowseConnect.
WSID | No | Yes | The workstation ID. Typically, this is the network name of the computer on which the application resides.

Level 3

Keyword | List of valid values returned? | Optional? | Description
DATABASE | Yes | Yes | The name of the SQL Server database.
LANGUAGE | Yes | Yes | The national language to be used by SQL Server.

SQLBrowseConnect ignores the values of the DATABASE and LANGUAGE keywords that are stored in the ODBC data source definitions. If the database or that is language specified in the connection string passed to SQLBrowseConnect is invalid, SQLBrowseConnect returns SQL_NEED_DATA and the level 3 connection attributes.

SQLBrowseConnect doesn't check user access to all the databases listed with the DATABASE keyword. If the user doesn't have access to the chosen database, SQLBrowseConnect returns SQL_NEED_DATA and the level 3 connection attributes.


SQLConnect

The SQLConnect function uses the following parameters.

Parameter | Description
szDSN | The name of the data source as returned by SQLDataSources.
szUID | The user login ID.
szAuthStr | The user-specified authentication string (typically the password).

SQLConnect retrieves the value of the LANGUAGE keyword from the ODBC data source definition. If the SQL Server driver is unable to use the specified language, it uses the default language for the specified user ID, and SQLConnect returns SQL_SUCCESS_WITH_INFO. If SQL Server is unable to use the default language for the specified user ID, SQLConnect returns SQL_ERROR.

SQLConnect retrieves the value of the DATABASE keyword from the ODBC data source definition. If the SQL Server driver is unable to use the specified database, it uses the default database for the specified user ID, and SQLConnect returns SQL_SUCCESS_WITH_INFO. If SQL Server is unable to use the default database for the specified user ID, SQLConnect returns SQL_ERROR.


SQLDriverConnect

The SQLDriverConnect connection string uses the following keywords.

Keyword | Description
DSN | The name of the data source as it is returned by SQLDataSources. The DSN keyword is not used if the DRIVER keyword is used.
DRIVER | The name of the driver as returned by SQLDrivers. The DRIVER keyword is not used if the DSN keyword is used. The SQL Server driver name is {SQL Server}. (For a 16-bit program, the 32-bit driver name is {SQL Server (32 bit)}.)
SERVER | The name of the server on the network on which the data source resides. When running on Microsoft Windows NT, "(local)" can be entered as the server, in which case, a local copy of SQL Server can be used, even when this is a non-networked version. Note that when the 16-bit SQL Server driver is using "(local)" without a network, the "MS Loopback Adapter" must be installed.
UID | The user login ID.
PWD | The user-specified password.
APP | The name of the application calling SQLDriverConnect (optional).
WSID | The workstation ID. Typically, this is the network name of the computer on which the application resides (optional).
DATABASE | The name of the SQL Server database (optional).
LANGUAGE | The national language to be used by SQL Server (optional).

SQLDriverConnect uses keyword values from the dialog box (if one is displayed). If a keyword value is not set in the dialog box, SQLDriverConnect uses the value from the connection string. If the value is not set in the connection string, it uses the value from the ODBC.INI file.

If the fDriverCompletion argument is SQL_DRIVER_NOPROMPT or SQL_DRIVER_COMPLETE_REQUIRED, the language or database comes from the connection string, and if the language or database is invalid, SQLDriverConnect returns SQL_ERROR.

If the fDriverCompletion argument is SQL_DRIVER_NOPROMPT or SQL_DRIVER_COMPLETE_REQUIRED, the language or database comes from the ODBC data source definitions, and if the language or database is invalid, SQLDriverConnect uses the default language or database for the specified user ID and returns SQL_SUCCESS_WITH_INFO.

If the fDriverCompletion argument is SQL_DRIVER_COMPLETE or SQL_DRIVER_PROMPT and if the language or database is invalid, SQLDriverConnect redisplays the dialog box.

Examples

For example, to connect to the Human Resources data source on the server HRSERVER using the login ID Smith and the password Sesame, you would use the following connection string:

DSN=Human Resources;UID=Smith;PWD=Sesame

To specify the Payroll database on the same server, you would use the following connection string:

DSN=Human Resources;UID=Smith;PWD=Sesame;DATABASE=Payroll

To specify the SQL Server driver (the driver name is {SQL Server}) and server name directly (without using a DSN), you would use the following connection string:

DRIVER={SQL Server};SERVER=hrserver;UID=Smith;PWD=Sesame;
    DATABASE=Payroll


SQLColAttributes, SQLDescribeCol, and SQLNumResultCols

SQL Server returns information about a results set before it returns the data in the results set. The SQL Server driver returns this information to an application through the SQLColAttributes, SQLDescribeCol, and SQLNumResultCols functions.

When connected to SQL Server 6.x, the SQL Server driver uses the SET FMTONLY statement to retrieve the appropriate information about a results set.

When connected to SQL Server 4.2x, if an application calls any of these functions after a SELECT statement has been prepared and before it has been executed, the SQL Server driver submits the SELECT statement with the clause WHERE 1=2. This forces SQL Server to generate a results set without any rows but with the information about the results set.

Note When connected to SQL Server 4.2x, SQLColAttributes, SQLDescribeCol, and SQLNumResultCols cannot return information about a results set that is generated by a procedure if that procedure has been prepared but not executed. If the SELECT statement is the first statement in a batched statement and SQL Server native grammar is used (no semicolons between statements), the results of these functions are unpredictable. Note also that the word "SELECT" must be the first token in the buffer. If anything precedes the word "SELECT" in the statement to be prepared, "WHERE 1=2" will not be added to the SELECT statement and the information about the results set will not be returned.

In SQL Server 6.5, the ODBC SQL Server driver supports the following driver-specific column attributes in SQLColAttributes.

fDescType parameter | pfDesc values
SQL_CA_SS_COLUMN_SSTYPE | SQLTEXT SQLVARBINARY SQLINTN SQLVARCHAR SQLBINARY SQLIMAGE SQLCHAR SQLINT1 SQLBIT SQLINT2 SQLINT4 SQLMONEY SQLDATETIME SQLFLT8 SQLFLTN SQLMONEYN SQLDATETIMN SQLFLT4 SQLMONEY4 SQLDATETIM4 SQLDECIMAL SQLDECIMALN SQLNUMERIC SQLNUMERICN (Similar to dbcoltype or dbalttype.)
SQL_CA_SS_COLUMN_UTYPE | SQLudtTEXT SQLudtVARBINARY SQLudtINTN SQLudtVARCHAR SQLudtBINARY SQLudtIMAGE SQLudtCHAR SQLudtINT1 SQLudtBIT SQLudtINT2 SQLudtINT4 SQLudtMONEY SQLudtDATETIME SQLudtFLT8 SQLudtFLTN SQLudtMONEYN SQLudtDATETIMN SQLudtSYSNAME SQLudtTIMESTAMP SQLudtFLT4 SQLudtMONEY4 SQLudtDATETIM4 SQLudtDECML SQLudtDECMLN SQLudtNUM SQLudtNUMN (Similar to dbcolutype or dbaltutype.)
SQL_CA_SS_NUM_ORDERS | The number of columns in the SQL statement's ORDER BY clause. (Similar to dbnumorders.)
SQL_CA_SS_COLUMN_ORDER | The SELECT list column ID of a column that appears in the SQL statement's ORDER BY clause. (Similar to dbordercol.)
SQL_CA_SS_COLUMN_VARYLEN | TRUE if the column's data can vary in length, otherwise FALSE. (Similar to dbvarylen.)
SQL_CA_SS_NUM_COMPUTES | The number of compute clauses in the current results set. (Similar to dbnumcompute.)
SQL_CA_SS_COMPUTE_ID | The compute ID of a compute row. (Similar to dbnextrow compute ID return value.)
SQL_CA_SS_COMPUTE_BYLIST | The bylist for a compute row. (Similar to dbbylist.)
SQL_CA_SS_COLUMN_ID | The SELECT list column ID for a compute column. (Similar to dbaltcolid.)
SQL_CA_SS_COLUMN_OP | SQLAOPCNT SQLAOPSUM SQLAOPAVG SQLAOPMIN SQLAOPMAX SQLAOPANY SQLAOPNOOP (Similar to dbaltop.)


SQLConfigDataSource

The SQLConfigDataSource function is used to add, modify, or delete a data source dynamically. It uses the keywords in the following table. Note that only the SERVER keyword is required for this function; all other keywords are optional.

Keyword | Description
ADDRESS | The network address of the SQL Server database management system from which the driver retrieves data.
DATABASE | The name of the SQL Server database.
DESCRIPTION | A description of the data in the data source.
LANGUAGE | The national language to be used by SQL Server.
NETWORK | The network library that connects the platforms on which SQL Server and the SQL Server driver reside.
OEMTOANSI | Enables conversion of the OEM character set to the ANSI character set if the SQL Server client machine and SQL Server are using the same non-ANSI character set. Valid values are YES for on (conversion is enabled) and NO for off. The default value is set by using the SQL Client Configuration Utility.
SERVER | The name of the network computer on which the data source resides.
TRANSLATIONDLL | The name of the DLL that translates data passing between an application and a data source.
TRANSLATIONNAME | The name of the translator that translates data passing between an application and a data source.
TRANSLATIONOPTION | Enables translation of data passing between an application and a data source.
USEPROCFORPREPARE | Disables generation of stored procedures for SQLPrepare. Valid values are NO for off (generation is disabled) and YES for on. The default value (set in the Setup dialog box) is YES.

Note that keyword pairs in SQLConfigDataSource strings are null-byte (\0) terminated, and the string itself is also null-byte (\0) terminated. For example:

DSN=Human Resources\0SERVER=hrserver\0ADDRESS=hrnetaddr\0
    NETWORK=DBMSSOCN\0DATABASE=payroll\0\0


SQLPrepare

SQL Server does not directly support the Prepare/Execute model of ODBC.

First, a temporary stored procedure is created from the statement, because stored procedures are an efficient way to execute a statement more than once. The procedure is named #odbc#useridentifier, where user is up to 6 characters of the username and identifier is up to 8 digits and identifies the statement. The procedure is created at prepare time if all parameters have been set, or at execute time if all parameters were not set at prepare time or if any parameter has been reset since the procedure was created. Because of this, SQLExecute can return any errors that SQLPrepare can return.

If CREATE PROCEDURE returns an error, SQLPrepare submits the statement to SQL Server with the SET NOEXEC or SET PARSEONLY option enabled (depending on the statement type). SQL Server checks the syntax of the statement and returns any errors.

If a user cannot create a stored procedure for any reason (such as lack of permission), the SQL Server driver does not use a stored procedure but, instead, submits the SQL statement each time SQLExecute is called.

You can disable a generation of stored procedures for SQLPrepare. If disabled, the statement will be stored and re-executed at execution time. You can disable generation of stored procedures in either of two ways:

  • Clear the Generate Stored Procedures for Prepared Statements check box in the ODBC SQL Server Driver Setup dialog box.
  • Set the SQL_USE_PROCEDURE_FOR_PREPARE option of the SQLSetConnectOption function to SQL_UP_OFF.

When generation of stored procedures is disabled and the statement is stored and executed at run time, all syntax error checking is delayed until run time.

Note that if SET NOCOUNT ON has been executed, multiple statements embedded in a stored procedure do not create multiple results sets as they should. Row counts that are generated by SQL statements inside a stored procedure are ignored by the driver.


SQLParamOptions

The SQLParamOptions function allows an application to specify an array of multiple values for the parameters that are assigned by SQLBindParameter. By calling SQLParamOptions with a crow greater than 1, the driver generates an SQL statement batch or a stored procedure batch to execute multiple SQL statements.

SQLParamOptions is usually used with DML. Any DDL statements that are used with SQLParamOptions will have the same result as executing the statement serially crow times. For statements that do not contain parameter markers, the statement will still be executed crow times.

A stored procedure batch is used for SQLPrepare/SQLExecute and for canonical procedure invocations that do not use any data-at-execution parameters. Stored procedure output parameters are returned.

An SQL batch (also called a language event) is used for SQL commands and for canonical procedure invocations that use data-at-execution parameters. Any stored procedure output parameters are not returned. If a SELECT statement is used, multiple results sets will be returned, and the application must use SQLMoreResults to process them. After SQLParamData, SQLExecDirect, or SQLExecute returns success, the value returned in pirow is initially set to 1, and SQLMoreResults increments this value as you process each results set.

SQLRowCount will return the total of all rows that are affected by all statements in the SQL or stored procedure batch that contains no SELECT statements. The value returned by SQLRowCount is undefined if one or more SELECT statements are included. Also, when the original SQL contains multiple statements, the value returned in pirow can be incorrect.

While processing a batch, SQL Server may return an error. In some cases, SQL Server cancels the current command only, and the remainder of the batch is processed. For these errors, one or more executions will fail, and SQLExecDirect, SQLExecute, or SQLParamData will return SQL_ERROR. The value returned in pirow will be set to crow because all parameter rows were processed. SQLError will return the errors that occurred, but there is no way to determine which parameter row(s) caused the error. Because all parameter rows were processed, rebinding and continuing execution is not necessary.

In other cases, an error causes SQL Server to cancel the entire batch. For these errors, the value returned in pirow will contain the affected parameter row. You must rebind and continue execution to process the remaining parameter rows.

When data truncation occurs for a parameter, processing continues for the remaining parameters. SQL_SUCCESS_WITH_INFO is returned, along with a warning message. However, when an error (such as a conversion error) occurs on the client for one of the parameters, the entire batch execution is stopped and no execution is done for any row.

While SQLParamData returns SQL_NEED_DATA, it updates the value of pirow as it processes data-at-exec parameters, and the final SQLParamData updates the value of pirow based on any errors that are encountered during execution. Therefore, if an error is encountered with a row during execution, the value in pirow may be larger during the data-at-exec parameter processing than it is after the execution has completed.

When connected to SQL Server 4.2x, SQLParamOptions is limited as follows:

  • SQL Server 4.2x is limited to approximately 128,000 bytes for a single language event. If using SQLParamOptions causes this limit to be exceeded, the driver will return the SQL Server error message.
  • SQL Server 4.2x does not support stored procedure batches. Therefore, any stored procedure output parameters are not returned.

Note When you pass a non-null value for pirow, the driver will continue to place the current row number in that memory address, even if SQLParamOptions is effectively "turned off" by passing a crow of 1. Therefore, if the pirow address supplied by the application becomes an invalid address (for example, a local variable-leaving scope) it is possible that the driver might fail.


SQLDescribeParam

The SQLDescribeParam function returns the description of a parameter marker that is associated with a prepared SQL statement.

Parameter markers must appear in the correct ODBC locations, as specified in the Microsoft ODBC 2.0 Programmer's Reference and SDK Guide. Also, the driver does not support the following items:

  • Calling SQLDescribeParam after execution.
  • The Transact-SQL FROM clause extension to UPDATE and DELETE statements.
  • Parameter markers in a subquery.
  • Parameter markers in both expressions of a comparison, like, or quantified predicate.


SQLSetStmtOption

The SQLSetStmtOption function allows the caller to set various options at the statement level. The following cursor related options are supported.

Option | Value
SQL_CONCURRENCY | SQL_CONCUR_READ_ONLY SQL_CONCUR_LOCKING SQL_CONCUR_ROWVER SQL_CONCUR_VALUES
SQL_CURSOR_TYPE | SQL_CURSOR_FORWARD_ONLY SQL_CURSOR_STATIC SQL_CURSOR_KEYSET_DRIVEN SQL_CURSOR_DYNAMIC
SQL_ROWSET_SIZE | Integer value that specifies the number of rows in the rowset, that is the number of rows that are returned by each call to SQLExtendedFetch. The default value is 1.
SQL_BIND_TYPE | Integer value that sets the binding orientation to be used when SQLExtendedFetch is called on the associated hstmt. Both column and row bindings are supported.

SQL Server supports read-only static cursors, and these are exposed through the SQL Server driver. Applications that require updatable static cursors should choose the Cursor Library implementation by setting SQL_ODBC_CURSORS to SQL_CUR_USE_ODBC. Cursors that are provided by the Cursor Library are implemented at the client. All the data is cached, and updates and deletes are issued by constructing a WHERE clause that uses the cached values.

Cursors that are implemented at the server (Forward Only, Keyset, Dynamic, Read-only, and Static) can be specified with a concurrency control option of read-only, lock, row version, or row values. Cursors that are implemented by the cursor library can be read-only or row values.

Mixed cursors are not supported. The SQL_KEYSET_SIZE value is automatically converted to zero (0) if a non-zero value is specified.

In SQL Server 6.5, the ODBC SQL Server driver supports the following driver-specific statement options in SQLSetStmtOption and SQLGetStmtOption.

fOption option | vParam descriptions
SQL_SOPT_SS_CURRENT_COMMAND (SQLGetStmtOption only) | The current SQL command number in the batch. (Similar to dbcurcmd.)
SQL_SOPT_SS_TEXTPTR_LOGGING | SQL_TL_OFF. Text and image operations are not logged. SQL_TL_ON. Text and image operations are logged. (Default.)


SQLSetScrollOptions

The SQLSetScrollOptions function allows the caller to set options that control cursor behavior. In ODBC 2.0, these options have been superseded by the corresponding options in the SQLSetStmtOption function and are only supported for backward compatibility. The options fall into three categories as follows.

Option | Value
Concurrency control | SQL_CONCUR_READ_ONLY SQL_CONCUR_LOCK SQL_CONCUR_ROWVER SQL_CONCUR_VALUES
Sensitivity | SQL_CURSOR_FORWARD_ONLY SQL_CURSOR_STATIC SQL_CURSOR_KEYSET_DRIVEN SQL_CURSOR_DYNAMIC
Rowset size | Integer value


SQLSetConnectOption

The SQLSetConnectOption function allows the caller to set options that govern aspects of the connection.

The following cursor related options are supported.

Option | Value
SQL_ODBC_CURSORS | SQL_CUR_USE_IF_NEEDED SQL_CUR_USE_ODBC SQL_CUR_USE_DRIVER
SQL_TXN_ISOLATION | SQL_TXN_READ_UNCOMMITTED SQL_TXN_READ_COMMITTED SQL_TXN_REPEATABLE_READ SQL_TXN_SERIALIZABLE The SQL_TXN_VERSIONING option is not supported. (In SQL Server, repeatable read is treated as serializable.)
Driver specific option | SQL_PRESERVE_CURSORS allows you to choose between closing or preserving the cursor state across transaction commits/rollbacks. The default is to close cursors on a transaction commit/rollback.


SQLSetCursorName

The SQLSetCursorName function associates a cursor name with an active hstmt. A cursor name is automatically created if one is not specified.


SQLGetCursorName

The SQLGetCursorName function returns the cursor name that is associated with a specified hstmt. The cursor name can be user specified or system generated. This function can only be called if SQLSetCursorName has been previously called or after the cursor has been opened (by issuing an ExecuteDirect, Execute, or Catalog operation). The cursor name is valid for the lifetime of the hstmt, that is, if the cursor is closed and another one is opened, the driver reuses the previous name. Cursor names are required for issuing positioned updates and deletes.


SQLGetStmtOption

The SQLGetStmtOption function returns the current setting of options that are specified in SQLSetStmtOption plus a couple of additional flags. SQL_ROW_NUMBER specifies the number of the current row in the entire results set. This option is supported for Keyset and Static cursors; otherwise, 0 is returned.


SQLGetInfo

The SQLGetInfo function returns information about a specific driver and data source. For values that are provided by the SQL Server driver, see the Driver Attributes topic.


SQLFetch

The SQLFetch function fetches one row of data from the results set. It cannot be mixed with SQLExtendedFetch for the same cursor. Also, SQLFetch is forward only.


SQLExtendedFetch

The SQLExtendedFetch function returns one row set (set in SQLSetStmtOption) of data to the application. It takes as input the statement handle, the fetch type, and the number of the row to fetch. It returns the number of rows actually fetched and, optionally, an array that contains status values for each row.

The following fetch types are supported:

SQL_FETCH_ABSOLUTE
SQL_FETCH_FIRST
SQL_FETCH_LAST
SQL_FETCH_NEXT
SQL_FETCH_PRIOR
SQL_FETCH_RELATIVE
SQL_FETCH_BOOKMARK

SQL_FETCH_NEXT is required when the cursor type is SQL_CURSOR_FORWARD_ONLY. SQL_FETCH_ABSOLUTE is not supported for Dynamic cursors. SQL_FETCH_BOOKMARK is supported for Static and Keyset cursors only.


SQLRowCount

If this function is called after the cursor has been opened and the cursor is of type Keyset or Static, the SQLRowCount function returns the number of rows in the results set. For Dynamic cursors, SQLRowCount always returns –1. If the keyset is being populated asynchronously (please refer to the SQL Server documentation on sp_configure) SQLRowCount will return –1 until the keyset is fully populated.

The SQLRowCount function returns the number of rows that are affected by an UPDATE, INSERT, or DELETE statement or by the SQL_UPDATE, SQL_ADD, or SQL_DELETE operations in SQLSetPos. SQLRowCount can be called after a database update has been performed.


SQLSetPos

The SQLSetPos function allows an application to set the cursor position in a row set and perform an operation based on that position. The function takes as input the statement handle, the position of the row in the row set (on which the operation is to be performed), the operation type, and an additional parameter that describes how to lock the row after performing the operation.

The irow argument specifies the number of the row (in the row set) on which to perform the operation. If irow is 0, the operation applies to the entire row set.

The following operations are supported:

SQL_ADD
SQL_DELETE
SQL_POSITION
SQL_REFRESH
SQL_UPDATE

The following lock type is supported:

SQL_LOCK_NO_CHANGE

Note that if a row is marked as deleted (SQL_ROW_DELETED), and later a row is inserted with the same key value(s) as the old row, an SQL_REFRESH operation will show the new row (SQL_ROW_SUCCESS) in the old position.


SQLFreeStmt

The SQLFreeStmt function stops processing that is associated with a specific statement, closes any open cursors, discards pending results, and, optionally, frees all resources that are associated with the statement handle.

The following cursor related options are supported:

SQL_CLOSE
SQL_DROP


SQLTransact

The SQLTransact function requests a commit or rollback operation for all active operations on all statements that are associated with the connection. All open server cursors remain open after this operation if SQL_PRESERVE_CURSORS has been set to SQL_PC_ON. By default, cursors are closed on commit or rollback.


Appendix A Driver Attributes

Driver Attributes

The following table lists the C language #defines for the fInfoType argument and the corresponding values that are returned by SQLGetInfo when connected to SQL Server 6.x. An application retrieves this information by passing the listed C language #defines to SQLGetInfo in the fInfoType argument.

fInfoType argument (#define) | Value returned by SQLGetInfo
SQL_ACCESSIBLE_PROCEDURES | Y
SQL_ACCESSIBLE_TABLES | Y
SQL_ACTIVE_CONNECTIONS | 0 (The number of active connections is determined by the number of network connections available on the client computer and the number of connections allowed by the server DBMS.)
SQL_ACTIVE_STATEMENTS | 1 (Even though this value is 1, the driver supports multiple active statements on a connection if server cursors are being used. For more information, see Using ODBC Cursors.)
SQL_ALTER_TABLE | SQL_AT_ADD_COLUMN
SQL_BOOKMARK_PERSISTENCE | 0
SQL_COLUMN_ALIAS | Y
SQL_CONCAT_NULL_BEHAVIOR | SQL_CB_NON_NULL
SQL_CONVERT_FUNCTIONS | SQL_FN_CVT_CONVERT
SQL_CONVERT_type where type is the SQL datatype, such as CHAR | For more information, see the Datatype Mapping_and_Usage topic.
SQL_CORRELATION_NAME | SQL_CN_ANY
SQL_CURSOR_COMMIT_BEHAVIOR | SQL_CB_CLOSE (This is the ANSI-specified behavior. Because many applications need to preserve server cursor currency across commits/rollbacks, the driver provides a driver-specific option, SQL_PRESERVE_CURSORS, to override the ANSI default.)
SQL_CURSOR_ROLLBACK _BEHAVIOR | SQL_CB_CLOSE (This is the ANSI-specified behavior. Recognizing the need for many applications to preserve server cursor currency across commits/rollbacks, the driver provides a driver-specific option, SQL_PRESERVE_CURSORS, to override the ANSI default.)
SQL_DBMS_NAME | Microsoft SQL Server
SQL_DEFAULT_TXN_ISOLATION | SQL_TXN_READ_COMMITTED
SQL_DRIVER_NAME | SQLSRVR.DLL (16-bit) SQLSRV32.DLL (32-bit)
SQL_DRIVER_ODBC_VER | 02.50
SQL_DRIVER_VER | 02.65.nnnn (where nnnn specifies the build number)
SQL_EXPRESSIONS_IN_ORDERBY | Y
SQL_FETCH_DIRECTION | SQL_FD_FETCH_NEXT SQL_FD_FETCH_FIRST SQL_FD_FETCH_LAST SQL_FD_FETCH_PRIOR SQL_FD_FETCH_ABSOLUTE SQL_FD_FETCH_RELATIVE SQL_FD_FETCH_BOOKMARK
SQL_FILE_USAGE | SQL_FILE_NOT_SUPPORTED
SQL_GETDATA_EXTENSIONS | SQL_GD_BLOCK
SQL_GROUP_BY | SQL_GB_GROUP_BY_CONTAINS _SELECT
SQL_IDENTIFIER_CASE | (Depends on whether SQL Server was installed as case-sensitive or case-insensitive.)
SQL_IDENTIFIER_QUOTE_CHAR | " (Double quote)
SQL_KEYWORDS | BREAK BROWSE BULK CHECKPOINT CLUSTERED COMMITTED COMPUTE CONFIRM CONTROLROW DATABASE DBCC DISK DUMMY DUMP ERRLVL ERROREXIT EXIT EXPIREDATE FILE FILLFACTOR FLOPPY GETDEFAULT HOLDLOCK IDENTITY_INSERT IDENTITYCOL IF KILL LINENO LOAD MIRROREXIT NONCLUSTERED OFF OFFSETS ONCE OVER PERM PERMANENT PLAN PRINT PROC PROCESSEXIT PUBLIC RAISERROR READ READTEXT RECONFIGURE REPEATABLE RETAINDATE RETURN ROWCOUNT RULE SAVE SERIALIZABLE SETUSER SHUTDOWN STATISTICS TAPE TEMP TEXTSIZE TRAN TRIGGER TRUNCATE TSEQUEL UNCOMMITTED UPDATETEXT USE VOLUME WAITFOR WHILE WRITETEXT
SQL_LIKE_ESCAPE_CLAUSE | Y
SQL_LOCK_TYPES | SQL_LCK_NO_CHANGE
SQL_MAX_BINARY_LITERAL_LEN | 131072
SQL_MAX_CHAR_LITERAL_LEN | 131072
SQL_MAX_COLUMN_NAME_LEN | 30
SQL_MAX_COLUMNS_IN_GROUP _BY | 16
SQL_MAX_COLUMNS_IN_INDEX | 16
SQL_MAX_COLUMNS_IN_ORDER _BY | 16
SQL_MAX_COLUMNS_IN_SELECT | 4000
SQL_MAX_COLUMNS_IN_TABLE | 250
SQL_MAX_CURSOR_NAME_LEN | 30
SQL_MAX_INDEX_SIZE | 900
SQL_MAX_OWNER_NAME_LEN | 30
SQL_MAX_PROCEDURE_NAME _LEN | 36 (1 to 30 characters followed by a semicolon [;] and one to five digits)
SQL_MAX_QUALIFIER_NAME_LEN | 30
SQL_MAX_ROW_SIZE | 1962
SQL_MAX_ROW_SIZE_INCLUDES _LONG | N
SQL_MAX_STATEMENT_LEN | 131072
SQL_MAX_TABLE_NAME_LEN | 30
SQL_MAX_TABLES_IN_SELECT | 16
SQL_MAX_USER_NAME_LEN | 30
SQL_MULT_RESULT_SETS | Y
SQL_MULTIPLE_ACTIVE_TXN | Y
SQL_NEED_LONG_DATA_LEN | Y
SQL_NON_NULLABLE_COLUMNS | SQL_NNC_NON_NULL
SQL_NULL_COLLATION | SQL_NC_LOW
SQL_NUMERIC_FUNCTIONS | SQL_FN_NUM_ABS SQL_FN_NUM_ACOS SQL_FN_NUM_ASIN SQL_FN_NUM_ATAN SQL_FN_NUM_ATAN2 SQL_FN_NUM_CEILING SQL_FN_NUM_COS SQL_FN_NUM_COT SQL_FN_NUM_DEGREES SQL_FN_NUM_EXP SQL_FN_NUM_FLOOR SQL_FN_NUM_LOG SQL_FN_NUM_LOG10 SQL_FN_NUM_MOD SQL_FN_NUM_PI SQL_FN_NUM_POWER SQL_FN_NUM_RADIANS SQL_FN_NUM_RAND SQL_FN_NUM_ROUND SQL_FN_NUM_SIGN SQL_FN_NUM_SIN SQL_FN_NUM_SQRT SQL_FN_NUM_TAN
SQL_ODBC_API_CONFORMANCE | SQL_OAC_LEVEL2
SQL_ODBC_SAG_CLI _CONFORMANCE | SQL_OSCC_NOT_COMPLIANT
SQL_ODBC_SQL_CONFORMANCE | SQL_OSC_CORE
SQL_ODBC_SQL_OPT_IEF | Y
SQL_ORDER_BY_COLUMNS_IN _SELECT | N
SQL_OJ_CAPABILITIES | SQL_OJ_LEFT SQL_OJ_RIGHT SQL_OJ_FULL SQL_OJ_NESTED SQL_OJ_NOT_ORDERED SQL_OJ_INNER SQL_OJ_ALL_COMPARISON_OPS
SQL_OUTER_JOINS | Y
SQL_OWNER_TERM | owner
SQL_OWNER_USAGE | SQL_OU_DML_STATEMENTS SQL_OU_PROCEDURE_INVOCATION SQL_OU_TABLE_DEFINITION SQL_OU_INDEX_DEFINITION SQL_OU_PRIVILEGE_DEFINITION
SQL_POS_OPERATIONS | SQL_POS_ADD SQL_POS_DELETE SQL_POS_POSITION SQL_POS_REFRESH SQL_POS_UPDATE
SQL_POSITIONED_STATEMENTS | SQL_PS_POSITIONED_DELETE SQL_PS_POSITIONED_UPDATE SQL_PS_SELECT_FOR_UPDATE
SQL_PROCEDURE_TERM | stored procedure
SQL_PROCEDURES | Y
SQL_QUALIFIER_LOCATION | SQL_QL_START
SQL_QUALIFIER_NAME _SEPARATOR | . (period)
SQL_QUALIFIER_TERM | database
SQL_QUALIFIER_USAGE | SQL_QU_DML_STATEMENTS SQL_QU_PROCEDURE_INVOCATION SQL_QU_TABLE_DEFINITION
SQL_QUOTED_IDENTIFIER_CASE | (Depends on whether SQL Server was installed as case-sensitive or case-insensitive.)
SQL_ROW_UPDATES | N
SQL_SCROLL_CONCURRENCY | SQL_SCCO_LOCK SQL_SCCO_OPT_ROWVER SQL_SCCO_OPT_VALUES SQL_SCCO_READ_ONLY
SQL_SCROLL_OPTIONS | SQL_SO_DYNAMIC SQL_SO_FORWARD_ONLY SQL_SO_KEYSET_DRIVEN SQL_SO_STATIC
SQL_SEARCH_PATTERN_ESCAPE | \ (backslash)
SQL_SPECIAL_CHARACTERS | #$ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔ ÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïð ñòóôõöøùúûüýþÿ
SQL_STATIC_SENSITIVITY | SQL_SS_ADDITIONS SQL_SS_UPDATES
SQL_STRING_FUNCTIONS | SQL_FN_STR_ASCII SQL_FN_STR_CHAR SQL_FN_STR_CONCAT SQL_FN_STR_DIFFERENCE SQL_FN_STR_INSERT SQL_FN_STR_LCASE SQL_FN_STR_LEFT SQL_FN_STR_LENGTH SQL_FN_STR_LOCATE_2 SQL_FN_STR_LTRIM SQL_FN_STR_REPEAT SQL_FN_STR_RIGHT SQL_FN_STR_RTRIM SQL_FN_STR_SOUNDEX SQL_FN_STR_SPACE SQL_FN_STR_SUBSTRING SQL_FN_STR_UCASE
SQL_SUBQUERIES | SQL_SQ_COMPARISON SQL_SQ_EXISTS SQL_SQ_IN SQL_SQ_QUANTIFIED SQL_SQ_CORRELATED _SUBQUERIES
SQL_SYSTEM_FUNCTIONS | SQL_FN_SYS_DBNAME SQL_FN_SYS_IFNULL SQL_FN_SYS_USERNAME
SQL_TABLE_TERM | table
SQL_TIMEDATE_ADD_INTERVALS | SQL_FN_TSI_FRAC_SECOND SQL_FN_TSI_SECOND SQL_FN_TSI_MINUTE SQL_FN_TSI_HOUR SQL_FN_TSI_DAY SQL_FN_TSI_WEEK SQL_FN_TSI_MONTH SQL_FN_TSI_QUARTER SQL_FN_TSI_YEAR
SQL_TIMEDATE_DIFF_INTERVALS | SQL_FN_TSI_FRAC_SECOND SQL_FN_TSI_SECOND SQL_FN_TSI_MINUTE SQL_FN_TSI_HOUR SQL_FN_TSI_DAY SQL_FN_TSI_WEEK SQL_FN_TSI_MONTH SQL_FN_TSI_QUARTER SQL_FN_TSI_YEAR
SQL_TIMEDATE_FUNCTIONS | SQL_FN_TD_NOW SQL_FN_TD_CURDATE SQL_FN_TD_DAYOFMONTH SQL_FN_TD_DAYOFWEEK SQL_FN_TD_DAYOFYEAR SQL_FN_TD_DAYNAME SQL_FN_TD_MONTH SQL_FN_TD_MONTHNAME SQL_FN_TD_QUARTER SQL_FN_TD_WEEK SQL_FN_TD_YEAR SQL_FN_TD_CURTIME SQL_FN_TD_HOUR SQL_FN_TD_MINUTE SQL_FN_TD_SECOND SQL_FN_TD_TIMESTAMPADD SQL_FN_TD_TIMESTAMPDIFF
SQL_TXN_CAPABLE | SQL_TC_ALL
SQL_TXN_ISOLATION_OPTION | SQL_TXN_READ_COMMITTED SQL_TXN_READ_UNCOMMITTED SQL_TXN_REPEATABLE_READ SQL_TXN_SERIALIZABLE
SQL_UNION | SQL_U_UNION SQL_U_UNION_ALL

The ODBC SQL Server driver supports the following new driver-specific SQLGetInfo value:

fInfoType parameter | rgbInfoValue returned
SQL_INFO_SS_NETLIB_NAME | The name of the Net-Library DLL that is used to connect to SQL Server. (Similar to dbprocinfo.)


Appendix B Datatype Mapping and Usage

Datatype Mapping and Usage

This appendix describes how SQL Server SQL datatypes are mapped to ODBC SQL data types, and discusses certain datatype usage conditions.

Datatype Mapping

Datatype Usage


Datatype Mapping

The SQL Server driver maps SQL Server SQL datatypes to ODBC SQL data types. The following table lists SQL Server SQL datatypes and shows the ODBC SQL data types to which they are mapped.

SQL Server SQL datatype | ODBC SQL data type
binary | SQL_BINARY
bit | SQL_BIT
char character | SQL_CHAR
datetime | SQL_TIMESTAMP
decimal (SQL Server 6.x) dec (SQL Server 6.x) | SQL_DECIMAL
float double precision, float(n) where n = 24 – 53 | SQL_FLOAT
image | SQL_LONGVARBINARY
int integer | SQL_INTEGER
money | SQL_DECIMAL
numeric (SQL Server 6.x) | SQL_NUMERIC
real float(n) where n = 1 – 23 | SQL_REAL
smalldatetime | SQL_TIMESTAMP
smallint | SQL_SMALLINT
smallmoney | SQL_DECIMAL
sysname | SQL_VARCHAR
text | SQL_LONGVARCHAR
timestamp* | SQL_BINARY (SQL Server 6.x) SQL_VARBINARY (SQL Server 4.2x)
tinyint | SQL_TINYINT
varbinary binary varying | SQL_VARBINARY
varchar character varying char varying | SQL_VARCHAR
* The timestamp datatype is converted to the SQL_VARBINARY or SQL_BINARY ODBC data type, because values in timestamp columns are not datetime datatypes but varbinary(8) or binary(8) data that indicates the sequence of SQL Server activity on the row.

Note The ODBC SQL Server driver does not convert ODBC SQL data of types SQL_CHAR, SQL_VARCHAR, or SQL_LONGVARCHAR to C data of types SQL_C_DATE or SQL_C_TIME. All other conversions are supported for the ODBC SQL data types listed. For information on supported conversions, see Appendix D of the Microsoft ODBC SDK Programmer's Reference.


Datatype Usage

The SQL Server driver and SQL Server impose the following usage of data types.

Datatype | Limitation
Date literals | Date literals, when stored in an SQL_TIMESTAMP column (SQL Server datatypes of datetime or smalldatetime), have a time value of 12:00:00.000 a.m. (midnight).
money and smallmoney | Only the integer parts of the money and the smallmoney datatypes are significant. If the decimal part of SQL money data is truncated during datatype conversion, the SQL Server driver returns a warning, not an error.
SQL_BINARY (nullable) | When connected to SQL Server version 6.0 and earlier, if an SQL_BINARY column is nullable, the data that is stored in the data source is not padded with zeroes. When data from such a column is retrieved, the SQL Server driver pads it with zeroes on the right. However, data that is created in operations performed by SQL Server, such as concatenation, does not have such padding.
SQL_CHAR (truncation) | When connected to SQL Server version 6.0 and earlier, and data is placed into a SQL_CHAR column, SQL Server truncates it on the right without warning if the data is too long to fit into the column.
SQL_CHAR (nullable) | When connected to SQL Server version 6.0 and earlier, if a SQL_CHAR column is nullable, the data that is stored in the data source is not padded with blanks. When data from such a column is retrieved, the SQL Server driver pads it with blanks on the right. However, data that is created in operations performed by SQL Server, such as concatenation, does not have such padding.
SQL_LONGVAR BINARY, SQL_LONGVAR CHAR | Updates of columns with SQL_LONGVARBINARY or SQL_LONGVARCHAR data types (using a WHERE clause) that affect multiple rows are fully supported when connected to SQL Server 6.x. When connected to SQL Server 4.2x, an S1000 error "Partial insert/update. The insert/update of a text or image column(s) did not succeed" is returned if the update affects more than one row.
String function parameters | string_exp parameters to the string functions must be of data type SQL_CHAR or SQL_VARCHAR. SQL_LONG_VARCHAR data types are not supported in the string functions. The count parameter must be less than or equal to 255, because the SQL_CHAR and SQL_VARCHAR data types are limited to a maximum length of 255 characters.
Time literals | Time literals, when stored in an SQL_TIMESTAMP column (SQL Server datatypes of datetime or smalldatetime), have a date value of January 1, 1900.
timestamp | Only a NULL value can be manually inserted into a timestamp column. However, because timestamp columns are automatically updated by SQL Server, a NULL value is overwritten.
tinyint | The SQL Server tinyint datatype is unsigned. A tinyint column is bound to a variable of data type SQL_C_UTINYINT by default.
User-defined data types | When connected to SQL Server 4.2x, the SQL Server driver adds NULL to a column definition that does not explicitly declare a column's nullability. Therefore, the nullability that is stored in the definition of a user-defined datatype is ignored. When connected to SQL Server 4.2x, columns with a user-defined datatype that has a base datatype of char or binary and for which no nullability is declared are created as datatype varchar or varbinary. SQLColAttributes, SQLColumns, and SQLDescribeCol return SQL_VARCHAR or SQL_VARBINARY as the data type for these columns. Data that is retrieved from these columns is not padded.
LONG data types | SQL_LONGVARBINARY data must be passed to SQLPutData as raw binary data, not as binary data that is converted to character data. Also, data-at-execution parameters are restricted for both the SQL_LONGVARBINARY and the SQL_LONGVARCHAR data types.

For details, see the Data-at-Execution Parameter Limitations topic.


Appendix C Errors

Errors

When an error occurs, the SQL Server driver returns the native error number, the SQLSTATE (an ODBC error code), and an error message. The driver gets this information from errors that are detected by the driver and from errors that are returned by SQL Server.


Native Error Numbers

For errors that occur in the data source (returned by SQL Server), the SQL Server driver returns the native error number that is returned to it by SQL Server. For errors that are detected by the driver, the SQL Server driver returns a native error number of 0. For a list of native error numbers, see the error column of the sysmessages system table in the master database in SQL Server.

For errors returned by the Net-Library, the native error number is from the underlying network software.


SQLSTATE (ODBC Error Codes)

For errors that occur in the data source that are detected and returned by SQL Server, the SQL Server driver maps the returned native error number to the appropriate SQLSTATE. If a native error number does not have an ODBC error code to map to, the SQL Server driver returns SQLSTATE 37000 (Syntax error or access violation). For errors that are detected by the driver, the SQL Server driver generates the appropriate SQLSTATE.


Error Messages

For errors that occur in the data source and that are detected and returned by SQL Server, the SQL Server driver returns an error message that is based on the message that is returned by SQL Server. For errors that occur in the SQL Server driver or the Driver Manager, the SQL Server driver returns an error message that is based on the text that is associated with the SQLSTATE. For a list of error messages that can be returned by SQL Server (but not by the SQL Server driver), see the description column of the sysmessages system table in the master database in SQL Server.


Syntax

Error messages have the following format:

  • [vendor][ODBC_component][data_source]error_message

where the prefixes in brackets ([ ]) identify the source of the error as defined in the following table.

Note When an error occurs in the data source, the [vendor] and [ODBC_component] prefixes identify the vendor and the name of the ODBC component that received the error from the data source (not the data source itself).

Data source Prefix Value
Driver manager [vendor]
[ODBC_component]
[data_source] 		[Microsoft]
[ODBC Driver Manager]
N/A
Cursor library [vendor]
[ODBC_component]
[data_source] 		[Microsoft]
[ODBC Cursor Library]
N/A
SQL Server driver [vendor]
[ODBC_component]
[data_source] 		[Microsoft]
[ODBC SQL Server Driver]
N/A
SQL Server [vendor]
[ODBC_component]
[data_source] 		[Microsoft]
[ODBC SQL Server Driver]
[SQL Server]
SQL Server Net-Library [vendor]
[ODBC_component]
[data_source] 		[Microsoft]
[ODBC SQL Server Driver]
[net_library]


Before You Begin

The programming components in Microsoft® SQL Server™ 6.0 enable you to develop sophisticated client/server applications that tap the power of Microsoft SQL Server from workstations running the Microsoft® Windows NT™, Microsoft® Windows 95, Microsoft® Windows®, and MS-DOS® operating systems.

Microsoft® DB-Library™ is used to create client applications for SQL Server.

Note This book contains background information about Microsoft SQL Server and provides some information specific to SQL Server 6.0. For information about changes and enhancements specific to SQL Server 6.5, see the supplementary "What's New in SQL Server 6.5."


About Programming DB-Library for C

This book describes the Microsoft DB-Library for C application programming interface (API), a set of C functions used to create client applications that interact with Microsoft SQL Server.

This book describes DB-Library and provides details about building applications for the Windows NT operating system and about porting Windows-based applications to Windows NT system. It also provides a directory of all DB-Library for C functions and includes sample code.

The documentation is written for programmers who are using the C programming language to develop applications for SQL Server. To use this documentation effectively, you should already be familiar with Transact-SQL®, the enhanced version of SQL (structured query language). For information about Transact-SQL, see the Microsoft SQL Server Transact-SQL Reference.


Document Conventions

This documentation uses the following conventions to distinguish elements of text:

Convention | Purpose
UPPERCASE | Represents statement and clause names, structure names, datatypes, return values, filenames, and paths.
SMALL CAPITALS | Represent key names, such as ctrl.
bold | Represents functions, configuration-file entries, and syntax.
italic | Represents database names, table names, column names, index names, binding types, and variables that appear in text.
monospace | Represents examples and sample program code.


Finding Further Information

This documentation contains reference information to help you write DB-Library for C-based applications for Microsoft SQL Server. Information about DB-Library for C and SQL Server 6.0 is available from the following sources, as well as from the Microsoft® Development Library and Microsoft® TechNet.

The Microsoft Developer Network provides in-depth information for developers. With Level 1 of the Developer Network, you get four quarterly releases of the Development Library, packed with inside information on programming for Microsoft Windows and Windows NT, plus other program benefits. With Level 2 of the Developer Network, you'll receive all the Level 1 benefits plus quarterly releases of the Development Platform, containing the latest Windows and Windows NT Workstation operating systems and API-level SDKs and DDKs from Microsoft. For ordering information, call (800) 759-5474.

Microsoft TechNet is the front-line resource for fast complete answers to technical questions on Microsoft desktop and system products. Through two monthly CDs, you get everything from crucial data on client/server and workgroup computing, systems platforms, and database products to the latest applications support for Microsoft Windows and the Apple® Macintosh®. For ordering information, call your reseller or (800) 344-2121.

DB-Library Online Help

To access online Help while using DB-Library, choose the Help file icon from within Program Manager.

SQL Server Documentation

The documentation for SQL Server 6.0 is available online as part of the Microsoft® Development Library and as Microsoft SQL Server Books Online, which is part of Microsoft SQL Server and Microsoft® SQL Workstation.

Important SQL Server Books Online contains the most up-to-date information about SQL Server 6.0, including information that changed or was unavailable when the SQL Server 6.0 books were printed.

Microsoft SQL Server Setup
Provides instructions for installing SQL Server 6.0 servers and clients.
Microsoft SQL Server Administrator's Companion
Incorporates configuration, administration, and troubleshooting topics. Describes server and client configuration. Explains system administration tasks, such as managing devices and databases, backing up and recovering data, performing replication, scheduling tasks, managing security, and monitoring performance. Describes error conditions and gives troubleshooting procedures.
Microsoft SQL Server Database Developer's Companion
Provides an overview of Transact-SQL, which is an enhanced version of SQL (structured query language). Discusses managing data and database objects, such as tables, views, indexes, stored procedures, defaults, rules, constraints, and user-defined datatypes.
Microsoft SQL Server Transact-SQL Reference
Explains how to use Transact-SQL statements and other features to access databases, and provides syntax and descriptions for Transact-SQL statements, system procedures, utility programs, and system tables.
Microsoft SQL Server Programming SQL Distributed Management Objects
Provides syntax and reference information for the SQL Distributed Management Objects, which are 32-bit OLE Automation objects for the Microsoft® Windows® 95 and Windows NT operating systems. These objects, properties, methods, and collections are used to write scripts and programs that can administer multiple SQL Servers distributed across a network.
Microsoft SQL Server Programming DB-Library for C
The Online version of this book, provides syntax and reference information for the DB-Library application programming interface (API), which is used to write C/C++ client programs for the Windows, Windows 95, Windows NT, and MS-DOS operating systems.
Microsoft SQL Server Programming DB-Library for Visual Basic
Provides syntax and reference information for the DB-Library API, which is used to write Microsoft® Visual Basic® programming system-based client programs for the Windows operating system.
Microsoft SQL Server Programming Open Data Services
Provides syntax and reference information for Open Data Services, used to write server applications for client/server systems.


Obtaining Technical Support

Microsoft offers a variety of support options to help you get the most from Microsoft SQL Server. For information about these options, see the service and support card that came in the Microsoft SQL Server and Microsoft SQL Workstation packages, and the online support information in the Microsoft Development Library.

In addition, you can get technical support information from the Microsoft® Knowledge Base (KB), which can help you resolve problems. Information about the Knowledge Base (including how to get KB articles, how to get the KB on CD, and how to contribute to the KB) is available in the Help file KB_MSL.HLP, located in the \SQL60\INSTALL directory.


Chapter 1 Getting Started

Getting Started

Microsoft SQL Server is a powerful structured query language (SQL) database server. With local area network (LAN) software, SQL Server allows clients running the Windows NT, Windows, Windows 95, or MS-DOS operating-systems to access its services. Developers can write applications for SQL Server by programming with DB-Library for C, the C-language version of the communication library for SQL Server or with DB-Library for Visual Basic, the Visual Basic version of the communication library for SQL Server. For more information about DB-Library for Visual Basic, see Microsoft SQL Server Programming DB-Library for Visual Basic.

DB-Library for C is an application programming interface (API) that consists of C functions and macros that allow an application to interact with SQL Server. Included are functions that send Transact-SQL statements to SQL Server and functions that process the results of those statements. Other functions handle errors and convert data.

DB-Library for C offers a rich set of functions for:

  • Opening connections.
  • Formatting queries.
  • Sending query batches to the server and retrieving the resulting data.
  • Using scrollable cursors.
  • Bulk-copying data from files or program variables to and from the server.
  • Controlling two-phase commit operations between several participating SQL Servers.
  • Executing stored procedures or remote stored procedures.

These functions allow the application developer extremely fine-grained control of data flow back and forth between the client and the server. DB-Library supports multiple environments. C programmers can choose from among:

  • A multithreaded dynamic-link library (DLL) for the Windows NT operating system
  • Medium and large model static-link libraries for MS-DOS for both Microsoft and Borland® compilers
  • A DLL for the Windows operating system


System Requirements

To develop applications using DB-Library for C, you must meet the Microsoft SQL Server client system requirements for the operating system that you are using. For information about the system requirements for SQL Server, see Microsoft SQL Server Setup.


Windows NT

To create Win32 DB-Library applications for Windows NT, you need the files provided with this release, as well as the following software:

  • Microsoft Windows NT Workstation version 3.5 or later (version 3.51 or later is recommended)

    Or

    Microsoft Windows NT Server version 3.5 or later (version 3.51 or later is recommended)

  • Microsoft® Visual C++® version 2.0 or later, or 100% compatible compiler and linker

DB-Library for Windows NT is available for computers with the following microprocessor architectures:

  • Alpha AXP™
  • Intel® 32-bit x86-based
  • MIPS®


Windows 95

To create Win32 DB-Library applications for Windows 95, you need the same DB-Library files you use for Windows NT, as well as the following software:

  • Microsoft Windows 95
  • Microsoft Visual C++ version 2.0 or later, or 100% compatible compiler and linker


Windows

To create Win16 DB-Library applications for Windows, you need the files provided with this release, as well as the following software:

  • Microsoft Windows version 3.11 or later

    Or

    Microsoft Windows for Workgroups version 3.11 or later

  • Microsoft Visual C++ for Windows version 1.0 or later

    Or

    Borland C++ version 3.1 or later


MS-DOS

To create 16-bit DB-Library applications for MS-DOS, you need the files provided with this release, as well as the following software:

  • MS-DOS version 5.0 or later
  • Microsoft Visual C++ for Windows version 1.0 or later

    Or

    Borland C++ version 3.1 or later


DB-Library for C Files

The setup program installs the following groups of files:

In C:\SQL60\DBLIB\INCLUDE

File | Description
SQLDB.H | DB-Library function prototypes.
SQLFRONT.H | DB-Library type and macro definitions.

In C:\SQL60\DBLIB\LIB

File | Description
BLDBLIB.LIB | Borland large-model DB-Library static library for MS-DOS.
BMDBLIB.LIB | Borland medium-model DB-Library static library for MS-DOS.
MSDBLIB3.LIB | DB-Library import library for Windows.
NTWDBLIB.LIB | DB-Library import library for Win32.
RLDBLIB.LIB | Large-model DB-Library static library for MS-DOS.
RMDBLIB.LIB | Medium-model DB-Library static library for MS-DOS.
W3DBLIB.LIB | Old DB-Library import library for Windows. (Use MSDBLIB3.LIB, not this file.)

In C:\SQL60\DBLIB\SAMPLES

File | Description
README.TXT | Summary of sample programs available in each directory.

In C:\SQL60\HELP

File | Description
DBLIBC.HLP | DB-Library function reference Help.


Determining DB-Library Version

Determining DB-Library for C Version

For Windows and Windows NT, run the SQL Client Configuration Utility to determine which version of DB-Library is installed on your computer. This utility searches the path for the appropriate DLL to load (the path begins with the current directory). Run the utility from the same working directory as your application.

For MS-DOS, include a call to dbinit in your DB-Library for C application to determine which version of DB-Library for C is installed. This function returns the version number of DB-Library for C. It is a good idea to display this information in all your DB-Library applications.


Programming for SQL Server

There are several methods of programming SQL Server applications. The following sections describe different approaches you can use.


Transact-SQL

Transact-SQL is the SQL Server - enhanced version of the SQL database language. Client applications use Transact-SQL to communicate with SQL Server. Transact-SQL provides statements for creating and manipulating database objects, and for inserting, updating, and selecting data. The Transact-SQL enhancements include data integrity features and stored procedures. Stored procedures (compiled static SQL statements) allow much of an application's processing logic to be shifted from the front-end application to SQL Server. Stored procedures can contain most Transact-SQL statements, including Transact-SQL control-of-flow statements. Furthermore, stored procedures are precompiled, so the statements don't have to be parsed each time the procedure is executed.


DB-Library for C Applications

DB-Library for C enables the database to become an integral part of an application. Transact-SQL statements can be incorporated into the application, allowing the application to retrieve and update values from a database. Through DB-Library for C, values from the database can be placed in program variables for manipulation by the application. Conversely, values in program variables can be inserted into the database.

Although DB-Library for C contains many functions, giving the application much control over its interaction with SQL Server, most applications require only a few functions. The actual process of connecting with SQL Server, sending Transact-SQL statements to SQL Server, and manipulating the resulting data is straightforward.


DB-Library for C Compared to Embedded SQL

DB-Library differs distinctly from the Embedded SQL type of language interface:

  • The DB-Library interface does not require a language precompiler.
  • DB-Library consists of C functions that are not preprocessed into an intermediate form.

Avoiding preprocessing can make database applications more straightforward to write and to debug. However, for programmers new to developing SQL Server applications or who are familiar with other database platforms, Embedded SQL offers a simpler programming interface. Tools for building Embedded SQL applications are available separately from Microsoft.


DB-Library for C Compared to Microsoft ODBC

In addition to DB-Library, SQL Server supports the Microsoft Open Database Connectivity (ODBC) call-level API. ODBC enables applications for Windows, Windows NT, and Windows 95 to access multiple data sources, including a wide range of relational databases and local indexed sequential access method (ISAM) data. In most cases, DB-Library and ODBC are equally capable of creating SQL Server client applications. ODBC enables applications to access more data sources. DB-Library provides equivalent functionality in multiple client environments, including MS-DOS. In addition, DB-Library provides specialized support for SQL Server, such as bulk copy, two-phase commit, and text operations.

Tools for developing ODBC applications are available in the Microsoft ODBC Software Development Kit, which is part of the Microsoft Developer Network Level II. The ODBC drivers for SQL Server and the ODBC drivers for Open Data Services gateways are included with Microsoft SQL Server.


Communicating with SQL Server

DB-Library functions communicate with SQL Server through the DBPROCESS structure. The dbopen function allocates and initializes a DBPROCESS when it logs on to SQL Server. DBPROCESS serves as the connection between the application and SQL Server. Most DB-Library functions require DBPROCESS as the first parameter. An application can have more than one DBPROCESS if, for instance, it needs to update a database while still processing the results of a previous query. Each DBPROCESS is completely independent of any other.

Another structure, LOGINREC, allocated by dblogin, is the login record that contains information the dbopen function uses to log on to SQL Server. It contains typical login information, such as the username and password. This information is also specified through DB-Library for C functions.

Note With the Windows NT and Windows 95 operating systems, each connection is a separate execution thread that is spawned when the connection to SQL Server is established with dbopen and terminated when the connection is closed using dbclose.


DB-Library for C and Net-Library Interaction

When a call is made to open a connection to SQL Server (dbopen), DB-Library determines which client-side Net-Library should be loaded to communicate with SQL Server.

Net-Libraries are linked dynamically at run time. With the Windows, Windows 95, and Windows NT operating systems, Net-Libraries are implemented as dynamic-link libraries (DLLs), and multiple Net-Libraries can be loaded simultaneously. With the MS-DOS operating system, Net-Libraries are implemented as terminate-and-stay-resident (TSR), and only one can be loaded at any given time.


Net-Library Architecture

Microsoft SQL Server Net-Library architecture for client/server applications is based on the Net-Library concept that abstracts the client and server applications from the underlying network protocols being used.

Tabular Data Stream (TDS) is the data stream protocol used by Microsoft SQL Server to transfer requests and responses between the client and the server. TDS is a logical data stream protocol and must be supported by a physical network interprocess communication mechanism (IPC). The Net-Library architecture provides a method of sending TDS across a physical network connection, and it provides a transparent interface to DB-Library for C.


Using Examples with pubs

Throughout this documentation, examples that use the pubs database are based on the U.S. English version of pubs. Your system must have access to the pubs database to run the sample programs. If you have a localized version of SQL Server and want to try the examples, drop the localized version of pubs and install the U.S. English version by running INSTPUBS.SQL. The syntax is as follows:

isql /Usa /P password /S server -i\sql\install\instpubs.sql

The pubs database is installed in the \SQL60\DATA subdirectory.


Chapter 2 Programming with DB-Library for C

Programming with DB-Library for C

This chapter gives an overview of programming with DB-Library for C. It groups functions into categories, and gives a quick reference to the bulk copy and two-phase commit service special libraries.

Programming with DB-Library for C typically involves the following steps:

  1. Connect to SQL Server.
  2. Put Transact-SQL statements into a buffer and send them to SQL Server.
  3. Process the results, if any, returned from SQL Server, one statement at a time and one row at a time. You can put the results into program variables, where the application can manipulate them.
  4. Handle DB-Library errors and SQL Server messages.
  5. Disconnect from SQL Server.

The following example shows the basic framework of many DB-Library for C applications. The program connects to SQL Server, sends a Transact-SQL SELECT statement to SQL Server, and processes the set of rows resulting from the SELECT.

For information about defining the target operating system prior to compiling your application, see Building Applications.

#define DBNTWIN32
#include <stdio.h>
#include <windows.h>
#include <sqlfront.h>
#include <sqldb.h>
// Forward declarations of the error handler and message handler.
int err_handler(PDBPROCESS, INT, INT, INT, LPCSTR, LPCSTR);
int msg_handler(PDBPROCESS, DBINT, INT, INT, LPCSTR, LPCSTR,
                LPCSTR, DBUSMALLINT);
main()
{
    PDBPROCESS  dbproc;    // The connection with SQL Server.
    PLOGINREC   login;     // The login information.
    DBCHAR      name[100];
    DBCHAR      city[100];

    // Install user-supplied error- and message-handling functions.
    dberrhandle (err_handler);
    dbmsghandle (msg_handler);

    // Initialize DB-Library.
    dbinit ();

    // Get a LOGINREC.
    login = dblogin ();
    DBSETLUSER (login, "my_login");
    DBSETLPWD (login, "my_password");
    DBSETLAPP (login, "example");

    // Get a DBPROCESS structure for communication with SQL Server.
    dbproc = dbopen (login, "my_server");

    // Retrieve some columns from the "authors" table in the
    // "pubs" database.

    // First, put the command into the command buffer.
    dbcmd (dbproc, "select au_lname, city from pubs..authors");
    dbcmd (dbproc, " where state = 'CA' ");

    // Send the command to SQL Server and start execution.
    dbsqlexec (dbproc);

    // Process the results.
    if (dbresults (dbproc) == SUCCEED)
    {
        // Bind column to program variables.
        dbbind (dbproc, 1, NTBSTRINGBIND, 0, name);
        dbbind (dbproc, 2, NTBSTRINGBIND, 0, city);

        // Retrieve and print the result rows.
        while (dbnextrow (dbproc) != NO_MORE_ROWS)
        {
            printf ("%s from %s\n", name, city);
        }
    }

    // Close the connection to SQL Server.
    dbexit ();

    return (0);
}

int err_handler (PDBPROCESS dbproc, INT severity,
    INT dberr, INT oserr, LPCSTR dberrstr, LPCSTR oserrstr)
{
    printf ("DB-Library Error %i: %s\n", dberr, dberrstr);
    if (oserr != DBNOERR)
    {
        printf ("Operating System Error %i: %s\n", oserr, oserrstr);
    }
    return (INT_CANCEL);
}

int msg_handler (PDBPROCESS dbproc, DBINT msgno, INT msgstate,
    INT severity, LPCSTR msgtext, LPCSTR server,
    LPCSTR procedure, DBUSMALLINT line)
{
    printf ("SQL Server Message %ld: %s\n", msgno, msgtext);
    return (0);
}

This example illustrates features common to most DB-Library for C applications, including:

header files
All source files that contain calls to DB-Library functions require two header files, SQLFRONT.H and SQLDB.H.

Before including the SQLFRONT.H and SQLDB.H files, define the target operating system with #define:

  • DBMSDOS (for MS-DOS)
  • DBMSWIN (for 16-bit Windows)
  • DBNTWIN32 (for 32-bit Windows 95 and Windows NT)

Or put DBMSDOS, DBMSWIN, or DBNTWIN32 on the compilation command lines. For more information, see the examples in "Include Files," in Building Applications.

For Windows, Windows 95, and Windows NT, you must include WINDOWS.H before including the SQLFRONT.H and SQLDB.H files.

Include SQLFRONT.H before SQLDB.H. SQLFRONT.H defines symbolic constants, such as function return values and the exit values STDEXIT and ERREXIT. These exit values can be used as the parameter for the C standard library function exit. The exit values are defined appropriately for the operating system running the program. The SQLFRONT.H file also includes type definitions for datatypes that can be used in program variable declarations. These datatypes are described in Appendix B: DB-Library Datatypes.

The SQLDB.H file contains additional type definitions and DB-Library function prototypes, most of which are meant to be used only by the DB-Library functions. They should not be accessed directly by the program. To ensure compatibility with future releases of DB-Library, use the contents of SQLDB.H only as documented in this documentation.

dberrhandle and dbmsghandle
The first of these DB-Library functions, dberrhandle, installs a user-supplied error-handling function, which is called automatically whenever the application encounters a DB-Library error. Similarly, dbmsghandle installs a message-handling function, which is called in response to informational or error messages returned from SQL Server. The error- and message-handling functions are user-supplied. It is strongly recommended that users supply error-processing functions.
dblogin
Supplies a LOGINREC structure, which DB-Library uses to log in to SQL Server. Two functions set entries in the LOGINREC. DBSETLPWD sets the password that DB-Library uses when logging in. DBSETLAPP sets the name of the application, which appears in the SQL Server sysprocess table. Certain functions set other aspects of the LOGINREC, which contains defaults for each value they set.
dbopen
Opens a connection between the application and SQL Server. It uses the LOGINREC supplied by dblogin to log in to the server. It returns a DBPROCESS structure, which serves as the conduit for information between the application and the server. After this function has been called, the application is connected with SQL Server and can send Transact-SQL statements to SQL Server and process the results. Simultaneous transactions must each have a distinct DBPROCESS. Serial transactions can use the same DBPROCESS.
dbcmd
Fills the command buffer with Transact-SQL statements, which can then be sent to SQL Server. Each call, after the first, to dbcmd adds the supplied text to the end of any text already in the buffer. The programmer must supply necessary blanks between words, such as the space between the quotation mark and the word where in the second dbcmd call in the example:
dbcmd(dbproc, " where state = 'CA' ");

Although multiple statements can be included in the buffer, this example only shows how to send and process a single statement. DB-Library allows an application to send multiple statements (called a command batch) to SQL Server and process each statement's set of results separately.

dbsqlexec
Executes the command buffer; that is, it sends the contents of the buffer to SQL Server, which parses and executes the commands. This function causes DB-Library to wait until SQL Server has completed execution of the query. To avoid this delay, you can call dbsettime to set the DB-Library timeout, or you can use dbsqlsend, dbdataready, and dbsqlok (instead of dbsqlexec) to retain control while SQL Server is busy.
dbresults
Gets the results of the current Transact-SQL statement ready for processing. After dbresults returns SUCCEED, column metadata for the current results set is available. Your program should call dbresults until it returns no_more_results. If your program fails to do this, the DB-Library error message 10038 "Results Pending" occurs the next time that DBPROCESS is used.
dbbind
Binds result columns to program variables. In the example, the first call to dbbind binds the first result column to the name variable. In other words, when the program reads a result row by calling dbnextrow, the contents of the first column in the result row are placed in the name variable. The datatype of the binding is NTBSTRINGBIND, one of several binding types available for character data. The second call binds the second result column to the city variable.
dbnextrow
Reads a row and places the results in the program variables specified by the earlier dbbind calls. Each successive call to dbnextrow reads another result row until the last row has been read and NO_MORE_ROWS is returned. Processing of the results must take place inside the dbnextrow loop. This is because each call to dbnextrow overwrites the previous values in the bound program variables.
dbexit
Closes all SQL Server connections and frees all DBPROCESS structures created because of the application. It is usually the last DB-Library function in the program.


DB-Library Datatypes

DB-Library defines datatype tokens for SQL Server data. These datatype constants begin with "SQL" (for example, SQLINT4, SQLCHAR, SQLMONEY). DB-Library also provides type definitions for use in program variable declarations. These type definitions begin with the prefix "DB" (for example, DBINT, DBCHAR, DBMONEY). By using them, you ensure that your program variables will be compatible with SQL Server datatypes. For a list of SQL Server datatypes and the DB-Library program variable types, see Appendix B: DB-Library Datatypes.

The dbconvert function provides a way to convert data from one SQL Server datatype to another. It supports conversion between most datatypes. Since the SQL Server datatypes correspond directly to the DB-Library datatypes, you can use dbconvert widely within your application.

The functions that bind SQL Server result columns to program variables ¾ dbbind and dbaltbind ¾ also provide type conversion.

When the operators SUM and AVG are applied to any column with a small datatype (such as smalldatetime, real, smallmoney, smallint, or tinyint), the server returns results in the larger datatype. For example, suppose that the table sales has a column named price, which is made from the datatype smallmoney, and the following query is executed on this table:

select price from sales

compute sum(price), avg(price), min(price), max(price)

The returned values price, MIN(price), and MAX(price) are of the datatype smallmoney; AVG(price), and SUM(price) are of the datatype money.


Finding SQL Servers on the Network

You can use the dbserverenum function to obtain the names of SQL Servers either locally or over the network. For network searches, the Net-Library DLL used must support the dbserverenum function.


Resolving Server Names

DB-Library resolves server names differently depending on the client platform. The following sections describe how DB-Library resolves server names for each of the available client platforms. It is recommended that you use the SQL Client Configuration Utility to configure server name and Net-Library connection information.


Windows NT - based Clients

For Windows NT - based clients, when dbopen is called with the name of a SQL Server to connect to, DB-Library uses the configuration information in the following subtree of the Windows NT Registry:

HKEY_LOCAL_MACHINE\
SOFTWARE\
Microsoft\
MSSQLServer\
Client\
ConnectTo

The entries of the Registry are values in the following format:

value:REG_SZ:Net-Library_Name[,network_specific_ parameters]


Windows-based Clients

For Windows-based clients, when dbopen is called with the name of a SQL Server to connect to, DB-Library uses the configuration information in the [SQLSERVER] section of the WIN.INI file. The entries of the [SQLSERVER] section of WIN.INI have the following format:

logical_name = Net-Library_Name[,network_specific_ parameters]


MS-DOS - based Clients

With MS-DOS, only one Net-Library TSR can be loaded, so there is no .INI configuration. Instead, MS-DOS environment variables are used to specify any network-specific connection information. Environment variables have the following format:

logical_name = network_specific_ parameters

Before loading the Net-Library TSR, the environment variables containing connection information must be set. If the servername parameter passed from dbopen corresponds to a currently set environment variable, the Net-Library uses the information in the environment string to determine server location and network-specific information parameters, if present. If no environment variable matches the servername passed from dbopen, the Net-Library uses the servername parameter passed from dbopen.


Results Processing

When dbsqlexec or dbsqlok returns SUCCEED, it indicates that SQL Server has successfully executed a command batch. At that point, the application must process any results. The SELECT statement and EXECUTE statements that contain SELECT statements both return result rows. INSERT statements and most other Transact-SQL statements also return data needed by DB-Library.

The following list describes the two types of result rows:

  • Regular rows are generated from columns in a SELECT statement's select list.
  • Compute rows are generated from columns in a SELECT statement's COMPUTE clause.

Since these two types of rows contain different data, the application must process them separately.

The result for each statement in a batch is returned to the application separately. Within each statement's set of results, the result rows are processed one at a time.

The results for each statement in the batch must be set up separately with dbresults.


Getting Result Data

The simplest way to get result data is to bind result columns to program variables with dbbind and dbaltbind. Then, when a result row is accessed, DB-Library automatically places copies of the columns' data into the program variables to which they are bound.

You also can access a result column's data directly with dbdata and dbadata, which return pointers to the data. These functions are frequently used with dbdatlen and dbadlen, which return the length of the data. The dbdata and dbadata functions have the advantage of providing access to the actual data, not a copy of the data.

Binding of columns to variables must take place after the call to dbresults but before the first call to dbnextrow. No such preliminary step is needed when results will be directly accessed with dbdata or dbadata.


Accessing Result Rows

Once dbresults has returned SUCCEED and any binding of columns to variables has been specified, the application is ready to process the results. The first step is to make the result rows available to the application. The dbnextrow function accomplishes this. Each call to dbnextrow reads the next row returned from SQL Server. The row is read directly from the network. As an alternative, you can do the same thing through cursors, often more simply and with more power. For details, see Bulk-Copy Functions.

Once a row has been read in by dbnextrow, the application can perform any processing desired on the data in the row. If the result columns have been bound to program variables, the data in the row will have been automatically copied into the variables. Alternatively, the data is accessible through dbdata or dbadata.

Rows read in by dbnextrow can be automatically saved in a row buffer, if desired. This is accomplished by setting the DBBUFFER option. Without row buffering, each row must be processed as it is read in by dbnextrow because the next call to dbnextrow will overwrite the previously read row. If row buffering has been turned on, the rows are added to a row buffer as they are read in by dbnextrow. Row buffering allows the application to skip around in the buffer and return to previously read rows.

After all result rows have been returned, the final call to dbnextrow returns the NO_MORE_ROWS indication. You must continue calling dbnextrow until it returns NO_MORE_ROWS, even if you know that the query produces only one result row.

Also available are functions that print result rows in a default format. They are often used for debugging. (These are not available with the Windows operating system.)

DB-Library processes results one statement at a time, although multiple statements can be sent. When all the results for one statement have been read, dbresults must be called again to set up the results for the next statement in the command buffer and one final time to return no_more_results.

Information covering several areas, including regular result columns, compute result columns, row buffers, and the command state, can be retrieved from the DBPROCESS structure. Regular result columns correspond to columns in the SELECT statement's select list, and compute result columns correspond to columns in the SELECT statement's optional COMPUTE clause.


Regular Result Column Information

These functions can be called after dbresults returns SUCCEED.

Function | Description
dbcollen | Returns the maximum length of a regular column's data.
dbcolname | Returns the name of a regular result column.
dbcoltype | Returns the SQL Server datatype for a regular result column.
dbcolutype | Returns the user-defined datatype for a regular result column.
dbdatlen | Returns the actual length of a regular column's data. This function is often used together with dbdata. The value returned by dbdatlen can differ for each regular row read by dbnextrow.
dbnumcols | Determines the number of columns in the current results set.


Compute Result Column Information

These functions can be called after dbnextrow or dbgetrow returns a compute ID.

Function | Description
dbadlen | Returns the actual length of a compute column's data. This function is often used together with dbadata. The value returned by dbadlen can differ for each compute row read by dbnextrow.
dbaltcolid | Returns the column ID for a compute column.
dbaltlen | Returns the maximum length for a compute column's data.
dbaltop | Returns the type of aggregate operator for a compute column.
dbalttype | Returns the datatype for a compute column.
dbaltutype | Returns the user-defined datatype for a compute column.
dbbylist | Returns the bylist for a compute row.
dbnumalts | Returns the number of columns in a compute row.
dbnumcompute | Returns the number of COMPUTE clauses in the current set of results.


Error and Message Handling

DB-Library for C applications deal with errors and messages: messages generated by DB-Library for C functions are called errors and those from SQL Server are known as messages. SQL Server can return both informational and error messages to the application. In addition, DB-Library for C has its own set of possible warnings and errors. A list of SQL Server messages appears in the sysmessages table. For a list of DB-Library for C errors, see Error Messages.

DB-Library for C easily centralizes error and message handling. With dbmsghandle and dberrhandle, you can install your own message- and error-handling functions. When a message or error occurs, DB-Library for C automatically calls the appropriate user-supplied function, providing information to that function on the nature of the message or error, thus the error- and message-handling logic can be assigned to two functions in your application.


Browse Mode

By creating temporary tables, browse mode lets you scan database rows and update their values one row at a time. This feature uses optimistic concurrency control, which holds no locks while you are accessing data. Browse mode requires several steps because it transfers each row from the database into program variables before browsing and updating it.

Since a row being browsed is just a copy residing in program variables, rather than the actual row in the database, the application must ensure that changes to the variables' values reliably update the original database row. In particular, in multiuser situations, the application must ensure that updates to the database made by one user do not overwrite updates made by another. This becomes an issue whether the application selects one row or several rows at a time from the database. A timestamp column in database tables that can be browsed lets you regulate this type of multiuser updating.

Browse mode functions also allow an application to update ad hoc queries, that is, queries made while an application is running. Several of these functions return information that an application can use to examine the structure of a complicated ad hoc query to update the underlying database tables.

Conceptually, browse mode does the following:

  1. Issues a SELECT statement.
  2. Fetches rows.
  3. If any changes must be made, constructs an UPDATE statement and issues it.

In an application, implement these three steps as follows:

  1. Execute a SELECT statement, generating result rows containing result columns. The SELECT statement must include the FOR BROWSE option.
  2. Bind the result column values into program variables, one row at a time.
  3. If appropriate, change the variables' values (possibly in response to user input).
  4. If appropriate, construct and execute an UPDATE statement that updates the database row corresponding to the current result row. To handle multiuser updates, the WHERE clause of the UPDATE statement must reference the timestamp column. An appropriate WHERE clause can be constructed with the dbqual function.
  5. Repeat steps 2 through 4 for each result row.

To use browse mode, the following conditions must be true:

  • The SELECT statement must end with the keywords FOR BROWSE.
  • The table(s) to be updated must have a unique index (or primary key) and a timestamp column.
  • The result columns to be used in the updates must be derived from tables that can be browsed and cannot be the result of compute columns, such as "MAX(colname)". In other words, there must be a valid correspondence between the result column and the database column to be updated.

In addition, browse mode requires two DBPROCESS structures: one for selecting the data and another for updating based on the selected data.


Chapter 3 Building Applications

Building Applications

This chapter describes how to build DB-Library applications for the Windows NT, Windows 95, Windows, and MS-DOS operating systems.

The following table shows the DB-Library include files used for all operating systems:

Include file | Contains
SQLFRONT.H | Type definitions, error codes and severity levels, miscellaneous definitions.
SQLDB.H | Function prototypes for all DB-Library functions.


Changes to DB-Library for C

DB-Library for C version 6.0 has been changed and improved since version 4.2x, and your program can be revised to take advantage of these changes. However, no changes to your application or program source code are required. Existing applications should continue to run properly with DB-Library 6.0, and existing programs should build properly with DB-Library 6.0.


MSDBLIB3 Replaces W3DBLIB

The DB-Library files for Windows have been renamed. The new files are named MSDBLIB3.DLL and MSDBLIB3.LIB. New DB-Library applications for Windows should use these files. The W3DBLIB.DLL and W3DBLIB.LIB files are still provided for backward compatibility with existing applications.


Header Files SQLFRONT.H and SQLDB.H Changed

The DB-Library for C header files SQLFRONT.H and SQLDB.H have been changed. They now use standard Win32™ API portable datatypes. The new PDBPROCESS, PLOGINREC, and PDBCURSOR portable macros can be used instead of the platform-specific pointers.

Use | Instead of
PDBPROCESS | DBPROCESS * DBPROCESS NEAR * DBPROCESS FAR *
PLOGINREC | LOGINREC * LOGINREC NEAR * LOGINREC FAR *
PDBCURSOR | DBCURSOR * DBCURSOR NEAR * DBCURSOR FAR *

Also, the new PDBHANDLE macro indicates that either a PDBPROCESS, PLOGINREG, or PDBCURSOR may be valid.


Building Win32 DB-Library Applications

This section describes issues relevant to building DB-Library applications using the Win32 API, the 32-bit application programming interface for Windows NT and Windows 95.


DB-Library Architecture

For the Win32-based versions of the DB-Library dynamic-link library (DLL), a separate operating-system thread may be spawned for each connection that DB-Library makes with SQL Server (depending on the Net-Library in use). Each instance of the DB-Library DLL loaded by a calling process gets a private data area, while sharing code.

Win32-based DB-Library architecture differs from the implementation with the Windows operating system. In Windows, MSDBLIB3.DLL maintains DB-Library connections as a linked list of connections in a single data segment. This architecture is required because in the Windows operating system, dynamic-link libraries have a single data segment that is shared among all calling processes. This necessitates the initialization and clean up of the DB-Library DLL data structures through calls to the dbinit and dbwinexit functions. Because dbinit initializes private DB-Library structures and to maintain compatibility with future versions of DB-Library, you should call dbinit for all environments.


Libraries

The DB-Library functions for the Win32 API are stored in a dynamic-link library, NTWDBLIB.DLL. Net-Libraries for Windows NT and Windows 95 are also implemented as DLLs. For example, DBNMPNTW.DLL connects to SQL Server over named pipes. Set the PATH environment variable to include the directory in which the libraries reside.

The NTWDBLIB.LIB file is an import library containing function definitions that your applications use.


Include Files

You can append the path to the INCLUDE environment variable to include the directory where the DB-Library SQLFRONT.H and SQLDB.H include files reside. Or you can use the /I compile line switch to point to the include file directory.

Because your Win32-based applications must always include the WINDOWS.H, SQLFRONT.H, and SQLDB.H files, you don't need to define the DB-Library functions you use. These functions and their proper declarations are already defined in the include file. However, you must define an application's operating system before including the DB-Library include files. Include the following statements at the beginning of all DB-Library applications designed for the Win32 API:

#define DBNTWIN32
#include <windows.h>
#include <sqlfront.h>
#include <sqldb.h>

You can also define the operating system by using the /D compile line switch (for example, /DDBNTWIN32 instead of a #define declaration).


Compiling and Linking

See your documentation for Visual C++ for details about compiling and linking a Win32 application for Windows NT or Windows 95. The DB-Library sample programs include sample build files.


Porting DB-Library Applications

All DB-Library functions are completely portable between the Windows and Windows NT platforms. You should not need to modify any of your DB-Library calls. You simply need to define the application's operating system at compile time (for example, #define DBNTWIN32 for the Win32 API).

Two DB-Library functions, dbprhead and dbprrow, not supported in Windows because they send output to STDIO, are supported in the Win32 API and can be used when developing applications for the CONSOLE subsystem. The dbprhead and dbprrow functions provide a convenient way to display the results of a query to the default output device.

If you have existing Win16 DB-Library applications for Windows that you want to port to Win32 and run with Windows NT or Windows 95, you can take two approaches to porting:

  • Change your application source code so that it can be compiled for the Win32 or Windows platform. If your DB-Library application is under development or is evolving to meet changing user needs, and you want to run the application with Windows and Windows NT or Windows 95, make small changes to the source code to build 16-bit (Windows-based) and 32-bit (Win32-based) versions of your application from the same source.
  • Port your application source code entirely to the Win32 platform. If you decide to modify your application to run only as a 32-bit (Win32-based) application (for example, you require Win32-specific features such as threads or preemptive multitasking), you can port your application to the Win32 API, removing redundant Windows calls and dependencies.


Porting to Maintain DB-Library Compatibility with Windows

This section explains how to port a Win16 DB-Library application for the Windows operating system to the Win32 API for Windows NT or Windows 95 operating systems while retaining compatibility with applications for Windows.

API Calls for Windows and C Run Time

In general, you can change your source code to easily build 16-bit or 32-bit versions. For an in-depth discussion of writing applications for the Win32 API that retain compatibility with the Windows operating system, see the Microsoft Win32 API Programmer's Reference (available separately).

Follow these guidelines when developing applications for the Win32 API:

  • Function definitions and prototypes. Be sure that your function definitions and function prototypes use portable datatypes.
  • Windows message parameter packing. The widening of handles to 32-bits means that the packing of handles and other values in wParam and lParam has changed. Verify whether or not you need to change the decoding of wParam and lParam in your application.

DB-Library Functions

All DB-Library functions are completely portable between operating systems. You simply need to define the target operating system at compile time.

Many DB-Library functions return values of type int. Note that the int datatype is a 16-bit value in Windows and a 32-bit value in the Win32 API. Therefore, verify that your application uses the correct type of variable to receive return values from DB-Library functions that return an int datatype. For example, a variable defined as the datatype short receives a correct int value from DB-Library in Windows but receives an incorrect value in the Win32 API.

Apart from verifying that variables receiving return values from DB-Library are of the correct type, no changes are needed to DB-Library functions.


Additional Porting Considerations

If you port a Windows-based application to the Windows NT or Windows 95 operating system and do not need to maintain compatibility with Windows, you can change your DB-Library code to remove redundant or unnecessary Windows functions.

Redundant Windows-specific DB-Library Functions

The dbwinexit function is Windows-specific and unnecessary in DB-Library for the Win32 API.

Error/Message Handler Registration

The following changes apply to the registration of error and message handlers for the Win32 API:

  • No need to export callback functions. You don't need to export the DB-Library error and message handler callback functions in a .DEF file.
  • No need to call MakeProcInstance. You don't need to call MakeProcInstance to obtain a pointer to pass to the dberrhandle and dbmsghandle functions. Simply call dberrhandle and dbmsghandle, passing the function address. The following examples show the differences in calling the dberrhandle and dbmsghandle functions in Windows and in the Win32 API:

    For Windows

    // Define variables
static FARPROC lpdbMsgHandler;
static FARPROC lpdbErrHandler;

// Get Procedure Instances
lpdbMsgHandler = MakeProcInstance((FARPROC)dbMsgHandler, hInst);
lpdbErrHandler = MakeProcInstance((FARPROC)dbErrHandler, hInst);

// Install the instances into dblib
dbmsghandle(lpdbMessageHandler);
dberrhandle(lpdbErrorHandler);

    For the Win32 API

    // Install the instances into dblib
dbmsghandle(dbMsgHandler);
dberrhandle(dbErrHandler);

Preemptive Multitasking (Win32) vs. Cooperative Multitasking (Windows)

To support asynchronous processing in the cooperative multitasking environment in Windows, each application must behave well and yield to the CPU at regular intervals. Therefore, when you process SQL Server queries in Windows, you need to use Windows timers or the PeekMessage function in combination with the DB-Library function calls for asynchronous processing (dbsqlsend, dbdataready, and dbsqlok).

Support for preemptive multitasking in the Win32 API simplifies the implementation of asynchronous query processing. The preemptive multitasking nature of the Windows NT and Windows 95 operating systems ensures that other processes always obtain CPU cycles regardless of any processing that another application is doing. Within a single process, asynchronous processing can be implemented using Win32 threads or by using the DB-Library functions that support asynchronous processing in conjunction with the PostMessage Windows function. For more information about asynchronous processing, see Taking Advantage of Win32 API Features in DB-Library Applications.


Taking Advantage of Win32 API Features in DB-Library Applications

This section describes how to take advantage of the unique features of the Win32 API.

Asynchronous Query Processing

Memory Management in the Win32 API

Threads in the Win32 API

Reentrancy and DB-Library


Asynchronous Query Processing

Preemptive multitasking in the Win32 API makes it easy to implement asynchronous query processing. Use one of the following ways to implement asynchronous query processing, depending on whether you want your application to exhibit asynchronous behavior between processes or within a single process.

  • Switch tasks between processes. Use the standard dbsqlexec call to send a query to SQL Server.

    Although dbsqlexec is synchronous from the calling thread's perspective (dbsqlexec returns only when SQL Server processes the query and is ready to return results), the preemptive nature of the Win32 API allows other applications or threads of the same application to continue to work and process user input while the query is executing.

  • Implement asynchronous processing within a single process.

    Use threads. The easiest way to implement asynchronous processing within a process is to use Win32 threads. You can spawn a thread that calls dbsqlexec and continue to do other work or continue to receive user input while the query is being processed.

    Single-thread approach. If you require a single-thread process to implement asynchronous query processing, use the asynchronous DB-Library functions dbsqlsend, dbdataready, and dbsqlok in combination with the PostMessage function, as shown in this example:

    case WM_SENDQUERY:
    dbsqlsend(dbproc);
    PostMessage(hWnd,WM_CHECKQUERY,0,0L);
    break;

case WM_CHECKQUERY:
    if (dbdataready(dbproc))
    {
        dbsqlok(dbproc);
        PostMessage(hWnd,WM_GETRESULTS,0,0L);
    }
    else
    {
        PostMessage(hWnd,WM_CHECKQUERY,0,0L);
    }
    break;


Memory Management in the Win32 API

The 32-bit linear virtual memory address space available to processes in the Win32 API makes memory management simpler and cleaner. (This applies to DB-Library programming as well as to all other programming for the Win32 API.)

Although the memory management functions (GlobalAlloc, LocalAlloc, and so on) in the Windows operating system are supported in the Win32 API, consider using the C run-time functions malloc and free to perform dynamic memory management when you develop applications to run with the Win32 API. In addition to the standard memory management functions (Global and Local, C run-time support), the Win32 API also provides heap and virtual memory management functions for applications that require specialized memory management.

Two specific areas of DB-Library programming can take advantage of the ability to address greater than 64K of data:

  • Processing of text and image data. There are many uses for SQL Server text and image datatypes. All require manipulation of text and image data, and the ability to transfer data between the application and SQL Server. The ability to address large chunks of memory can make this easier. Because it is possible to address up to 2 gigabytes (GB) of user memory in an application for the Win32 API, you can develop text/image handling functions that transfer text/image data in a single operation instead of transferring data chunks less than 64K. (Note, however, that waiting for 2 GB of data to transfer can take considerable time.)
  • Row buffering. In DB-Library for MS-DOS and Windows, you are constrained because DB-Library cannot handle more that 64K of data at a time, including memory allocated for row buffering. This value is further reduced by overhead taken up by data structures, variables, and so on. In the Win32 API, it is possible to use DBSETOPT(DBBUFFER,...) to enable row buffering for data sets greater than 64K.


Threads in the Win32 API

The multithreaded process structure of the Win32 API opens up powerful and elegant solutions to high-end applications. Each thread within a process has its own stack and machine state. On multiprocessor systems with the Windows NT operating system, multiple threads can execute at the same time but on different processors. Applications that need to perform intensive processing, I/O, and so on, can do this in the background using threads and still offer a responsive user interface.


Reentrancy and DB-Library

In applications where each thread uses a separate DBPROCESS connection, you don't need to serialize the DB-Library calls. However, you must use dbprocerrhandle (instead of dberrhandle) and dbprocmsghandle (instead of dbmsghandle) to establish connection-specific (instead of global) error and message handlers for your application. You should pass a LOGINREC to dbprocerrhandle and dbprocmsghandle before calling dbopen using that LOGINREC. If you follow these steps, DB-Library is completely reentrant and thread-safe.

DB-Library functions and routines that access a shared DBPROCESS are not reentrant across multiple threads. Therefore, be sure that you serialize all DB-Library calls that access the same DBPROCESS in multithreaded applications you develop.


Building Windows-based Applications

This section describes how to build DB-Library applications for the Windows operating system.

Libraries

Include Files

Compiling and Linking


Libraries

The DB-Library functions are stored in a dynamic-link library, MSDBLIB3.DLL. Windows Net-Libraries are also implemented as DLLs. For example, DBNMP3.DLL connects to SQL Server over named pipes. Set the PATH environment variable to include the directory in which the libraries reside.

Another file, called MSDBLIB3.LIB, contains the import definitions that your application will use. Set the LIB environment variable to include the directory where MSDBLIB3.LIB resides.


Include Files

You can set the INCLUDE environment variable to point to the directory that contains the DB-Library SQLFRONT.H and SQLDB.H include files. Alternatively, you can use the /I compile line switch to point to the include file directory.

Since your application must always include the WINDOWS.H, SQLFRONT.H, and SQLDB.H files, you don't need to define the DB-Library functions you use. These functions and their proper declarations are already defined in the include file.

You must define an application's target operating system before including the DB-Library header files. Use the following statements at the beginning of all SQL Server applications that will run with the Windows operating system:

#define DBMSWIN
#include <windows.h>
#include <sqlfront.h>
#include <sqldb.h>


Compiling and Linking

See your documentation for Visual C++ for details about compiling and linking a Win16 application for Windows. The DB-Library sample programs include sample build files.


Special DB-Library Functions for Windows

A special DB-Library option, DBANSItoOEM, set with dbsetopt, initiates automatic calls to the Windows-based functions ANSItoOEM and OEMtoANSI to translate characters. For more information on DB-Library options, see DB-Library Options.

Write your Windows-based application to call dbinit, once and only once, before any other DB-Library function.

The function dbwinexit has been added to the Windows operating system version of DB-Library. Your application should call this function immediately before exiting to tell DB-Library that the application will no longer be using DB-Library.


Special Considerations

The Windows operating system requires error and message handling for DB-Library to be installed as exported callback functions.

When the Windows operating system executes a callback function, the data segment register is not set to the application's data segment, even though the error handler is part of the application. Declare the error and message handlers using
_ _export (or declare the functions as EXPORT in the .DEF file) to cause Windows to set up the data segment register correctly so that your handlers can access the application's data.

To create an error handler or message handler, first make the function into a procedure instance. To do this, call MakeProcInstance in your initialization code or in the application's message loop. The following example shows the call in the application's message loop:

long FAR PASCAL MySqlWndProc(hWnd, message, wParam, lParam)
HWND hWnd;          // window handle
unsigned message;   // type of message
WORD wParam;        // additional information
LONG lParam;        // additional information
{
        .
        .
        .

    static FARPROC lpMyMessageHandler;  // pointer to message handler
    static FARPROC lpMyErrorHandler;    // pointer to error handler
    int cdecl FAR MyMessageHandler(DBPROCESS *,DBINT, DBSMALLINT,
        DBSMALLINT, LPSTR, LPSTR, LPSTR, DBUSMALLINT);
    int cdecl FAR MyErrorHandler(DBPROCESS *, int, int, int, LPSTR,
        LPSTR);

    switch (message) {
        .
        .
        .

    case WM_CREATE:    // message: window being created
        // Make the message and error handler instances.
        lpMyMessageHandler =
            MakeProcInstance((FARPROC)MyMessageHandler, hInst);
        lpMyErrorHandler =
            MakeProcInstance((FARPROC)MyErrorHandler, hInst);

        // Install the instances into DBLIB.
        dbmsghandle(lpMyMessageHandler);
        dberrhandle(lpMyErrorHandler);
        .
        .
        .

Making the FARPROC variables static allows you to free them during WM_DESTROY message processing:

.
    .
    .
case WM_DESTROY:         // message: window being destroyed
    FreeProcInstance(lpMyMessageHandler);   // release handlers
    FreeProcInstance(lpMyErrorHandler);
    PostQuitMessage(0);
    dbwinexit();
    break;
    .
    .
    .

Note that callback functions in the Windows operating system are normally declared FAR PASCAL, but not with these two callback functions for DB-Library (MyErrorHandler and MyMessageHandler). DB-Library expects all function calls to be cdecl FAR. Consequently, your handlers must also be cdecl FAR, as shown in the following example:

int cdecl FAR MyErrorHandler(dbproc, severity, errno,
    oserr, dberrstr, oserrstr);

Because this function declaration type is contrary to the FARPROC declaration type in MakeProcInstance, you must cast the function name as FARPROC.

Also, you must pass the FARPROC pointers returned from MakeProcInstance to dberrhandle and dbmsghandle to install the handlers properly. Passing the addresses of the handler functions instead of the procedure instances causes unpredictable results.

Finally, you must export the functions so that the Windows environment will correctly fix the segment references. In your .DEF file, add the following lines to the EXPORTS section:

_MyMessageHandler x      ; message handler
_MyErrorHandler y    ; error handler

Note that the function names begin with an underscore ( _ ); this is because with cdecl, the compiler automatically adds the underscore to the function name. The x and y are replaced with numbers for the number of your exported functions. See the sample Windows-based application for examples of installing error and message handlers.


Multitasking with Windows

The Windows operating system is a cooperative, nonpreemptive multitasking system. In a Windows-based program, use either of the following background processing techniques to complete a long task, such as processing a query. The first technique uses a PeekMessage loop instead of a GetMessage loop in the WinMain function, and requires the creation of a function to do a small piece of the background task each time it is called. The second technique uses the Windows timer. Both techniques use the dbsqlsend, dbdataready, and dbsqlok functions to allow background processing of a query.

The following example WinMain function shows how to create a PeekMessage loop for background processing. The benefits of this technique include:

  • All input messages are processed before performing background processing, providing quick response to user input.
  • Background processing is accomplished in small parts, and control is yielded to the Windows operating system after each small part is finished, keeping the application from monopolizing the system.
  • When no background processing needs to be done, control is yielded to the Windows operating system via WaitMessage, allowing the Windows system to idle.
//////////////////////////////////////////////////////////////////////
//
//  FUNCTION: WinMain
//
//  PURPOSE: Calls initialization function, processes message loop
//
//  COMMENTS:  Uses a PeekMessage loop for background processing
//  Note that this is a modified version of the Windows-based GENERIC
//  sample application.
//
//////////////////////////////////////////////////////////////////////

int PASCAL WinMain(
    HANDLE hInstance,
    HANDLE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow)
{
    MSG msg;    // message

    if (!hPrevInstance)
        if (!InitApplication(hInstance))  // Initialize shared things
            return (FALSE);

    // Perform initializations that apply to a specific instance
    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    while (TRUE)
    {
        if (PeekMessage(&msg,
            NULL,
            0,
            0,
            PM_REMOVE))
        {
            // PeekMessage has found a message--process it
            if (msg.message != WM_QUIT)
            {
                TranslateMessage(&msg); // Translate virt. key codes
                DispatchMessage(&msg);  // Dispatch msg. to window
            }
            else
            {
                // WM_QUIT message found, so break out of the
                // message loop

                break;
            }
        }
        else
        {
            // PeekMessage has not found a message, so call
            // DoBackgroundPart to do a portion of the background
            // processing. DoBackgroundPart returns TRUE if
            // it has more background work to do, or FALSE when all
            // background work is completed.

            if (!DoBackgroundPart())
            {
                // All background processing is now finished, so call
                // WaitMessage to yield control to Windows.

                WaitMessage();
            }
        }
    }

    return (msg.wParam);    // Returns the value from PostQuitMessage
}

The preceding example calls a user-defined function DoBackgroundPart that does a small portion of the background processing each time it is called. In a DB-Library program, this function should do background query processing. A sample DoBackgroundPart function is shown below. This function returns true when it needs to continue processing the query, and false when the query processing is complete.

///////////////////////////////////////////////////////////////////
//
//  FUNCTION:   DoBackgroundPart()
//
//  PURPOSE:    Does a small part of the background processing each
//              time it is called.
//
//  COMMENTS:   This function assumes two global variables.
//
//                  DBPROCESS//pDbproc;
//                  BOOL bQueryPending;
//
//              bQueryPending is TRUE only after another
//              part of the program has sent a query to
//              SQL Server using the dbsqlsend function.
//
//  RETURNS:    TRUE when there is more background work to do
//              FALSE when no background work is pending.
//
///////////////////////////////////////////////////////////////////

BOOL DoBackgroundPart(void)
{
    BOOL bContinue = FALSE;

    // bQueryPending is a global flag indicating if query
    // processing is pending

    if (bQueryPending)
    {
        if (dbdataready(pDbproc))
        {
            dbsqlok(pDbproc);
            ProcessQuery();
            bQueryPending = FALSE;
            bContinue = FALSE;
        }
        else
        {
            bContinue = TRUE;
        }
    }
    else
    {
        bContinue = FALSE;
    }
    return (bContinue);
}

The second background processing technique uses a Windows timer and does not require a PeekMessage loop. The following example illustrates the timer technique, and should be placed in the main window procedure. The SetTimer function creates a timer that sends a WM_TIMER message to your application every 1000 milliseconds. Have your application check dbdataready after each WM_TIMER message.

case WM_SENDQUERY:
    dbsqlsend (pDbproc);
    SetTimer (hWnd, 1, 1000, 0);
    break;

case WM_TIMER:
    if (dbdataready(pDbproc))
    {
        dbsqlok (pDbproc);
        KillTimer (hWnd, 1);
        ProcessQuery();
    }
    break;

For further information about programming for Microsoft Windows, see your documentation for Windows.


Building MS-DOS - based Applications

This section describes how to build DB-Library applications for MS-DOS.

Terminate-and-Stay-Resident Utility

Libriaries

Include Files

Required System Libraries

Compiling and Linking

Building MS-DOS - based Applications with the Borland C++ Compiler


Terminate-and-Stay-Resident Utility

In MS-DOS, before you can communicate with SQL Server, you must load a Net-Library terminate-and-stay-resident utility (TSR). The most common Net-Library, used for accessing SQL Server over named pipes protocols is DBNMPIPE. To load and execute the named pipes Net-Library TSR just before you run your SQL Server application, type the following:

dbnmpipe

If the directory in which the TSR resides is not named in your PATH variable, you must type in the exact path to the TSR.

Whether you load the TSR through AUTOEXEC.BAT or from the command line, you can unload it and recover the memory that it uses with the ENDDBLIB.EXE program. To do this, type:

enddblib

This program checks to make sure that the Net-Library TSR is loaded and then unloads it. If the Net-Library was not the last TSR loaded, the program does not unload it properly, causing unpredictable problems. ENDDBLIB will ask if you want to remove it anyway. You can suppress prompting and force ENDDBLIB to unload the TSR by using the /q (quiet) command line switch as follows:

enddblib /q

Caution Do not unload a TSR if it was not the last one loaded.


Libraries

DB-Library supports two memory models: medium and large. The following table shows the libraries for each model:

Memory model | Library file
Large | RLDBLIB.LIB BLDBLIB.LIB (Borland)
Medium | RMDBLIB.LIB BMDBLIB.LIB (Borland)

When linking the application, append to the LIB environment variable the path where the library files reside.


Include Files

At compile time, you can set the INCLUDE environment variable to include the directory where the include files reside. Alternatively, you can use the /I compile line switch to point to the include file directory.

Since your SQL Server application must always contain the SQLFRONT.H and SQLDB.H files, defining the DB-Library functions you use is unnecessary. These functions and their proper declarations are already defined in the include file.

You must define an application's target operating system before including the DB-Library header files. Use the following statements at the beginning of all SQL Server applications that use MS-DOS:

#define DBMSDOS
#include <sqlfront.h>
#include <sqldb.h>


Required System Libraries

DB-Library does not require any special system libraries, except the standard C run-time libraries; the TSR handles all network communication for the application. Load any special libraries your application needs, including any that provide direct access to the network.


Compiling and Linking

See your documentation for Visual C++ for details about compiling and linking an application for MS-DOS. The DB-Library sample programs include sample build files. The following command illustrates a typical compilation with automatic linkage:

cl /AL app.c rldblib.lib

The name APP.C is the name of your application. The large model (/AL) is used. Notice that the large model library, RLDBLIB.LIB, is specified.


Building MS-DOS - based Applications with the Borland C++ Compiler

You can build DB-Library applications for MS-DOS with the Borland C++ Compiler version 3.1 or later. To compile and link DB-Library programs for MS-DOS, keep the following points in mind:

  • The BMDBLIB.LIB (medium model) library is used in place of RMDBLIB.LIB; the BLDBLIB.LIB (large model) library is used in place of RLDBLIB.LIB.
  • The stack size must be set to 8192 or greater. For example:
    extern unsigned _stklen = 8192;
  • To run a program within the Borland IDE or to use the debugger, you must first load an appropriate Net-Library (for example, DBNMPIPE.EXE).
  • The following command illustrates a typical compilation with automatic linkage:
    bcc -ml -v -Ic:\sql\dblib\include -Lc:\sql\dblib\lib app.c bldblib.lib

    APP.C is the name of your application. Notice that the large model library, BLDBLIB.LIB, is specified.


Chapter 4 Core Functions

Core Functions

dbadata

dbadlen

dbaltbind

dbaltcolid

dbaltlen

dbaltop

dbalttype

dbaltutype

dbanullbind

dbbind

dbbylist

dbcancel

dbcanquery

dbchange

dbclose

dbclrbuf

dbclropt

dbcmd

dbcmdrow

dbcolinfo

dbcollen

dbcolname

dbcoltype

dbcolutype

dbconvert

dbcount

dbcurcmd

dbcurrow

dbdata

dbdataready

dbdatecrack

dbdatlen

dbdead

dberrhandle

dbexit

dbfcmd

dbfirstrow

dbfreebuf

dbfreelogin

dbfreequal

dbgetchar

dbgetmaxprocs

dbgetoff

dbgetpacket

dbgetrow

dbgettime

dbgetuserdata

dbinit

dbisavail

dbiscount

dbisopt

dblastrow

dblogin

dbmorecmds

dbmsghandle

dbname

dbnextrow

dbnullbind

dbnumalts

dbnumcols

dbnumcompute

dbnumorders

dbopen

dbordercol

dbprhead

dbprocerrhandle

dbprocinfo

dbprocmsghandle

dbprrow

dbprtype

dbresults

dbrows

dbrowtype

dbserverenum

dbsetavail

DBSETLAPP

DBSETLHOST

DBSETLNATLANG

dbsetlogintime

DBSETLPACKET

DBSETLPWD

DBSETLSECURE

DBSETLTIME

DBSETLUSER

DBSETLVERSION

dbsetmaxprocs

dbsetnull

dbsetopt

dbsettime

dbsetuserdata

dbsqlexec

dbsqlok

dbsqlsend

dbstrcpy

dbstrlen

dbuse

dbvarylen

dbwillconvert

dbwinexit


dbadata

Returns a pointer to the data for a compute column.

Syntax

LPCBYTE dbadata (
PDBPROCESS dbproc,
INT computeid,
INT column );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
computeid
Is the ID that identifies the COMPUTE clause. A SELECT statement can have multiple COMPUTE clauses, which can have varying numbers of aggregate operators and aggregate targets. The computeid is returned by dbnextrow or dbgetrow.
column
Is the number of the column. The first column returned is number 1.

Returns

A BYTE pointer to the data for a particular column in a compute. A null BYTE pointer is returned if there is no such column or compute or if the data has a null value. The data space pointed to is allocated and freed by DB-Library. Be careful not to overwrite the space.

Remarks

After each call to dbnextrow that returns a value greater than 0, use dbadata to obtain a pointer to the data for a particular column in a compute. The data is not null-terminated. Use dbadlen to get the length of the data.

When a column of integer data is summed or averaged, SQL Server always returns a four-byte integer, regardless of the size of the column. Therefore, be sure that the variable that is to contain the result from such a compute is declared as DBINT.

Example

The following program fragment shows how to use dbadata:

DBPROCESS    *dbproc;
int            rowinfo;
DBINT        sum;

// First, put the commands into the command buffer.
dbcmd(dbproc, "select db_name(dbid), dbid, size from sysusages");
dbcmd(dbproc, " order by dbid");
dbcmd(dbproc, " compute sum(size) by dbid");
// Send the commands to SQL Server and start execution.
dbsqlexec(dbproc);
// Process the command.
dbresults(dbproc);
// Examine the results of the COMPUTE clause.
while((rowinfo = dbnextrow(dbproc)) != NO_MORE_ROWS)
{
    if (rowinfo == REG_ROW)
        printf("regular row returned.\n");
    else
    {
        // This row is the result of a COMPUTE clause,
        // and "rowinfo" is the computeid of this COMPUTE
        // clause.

        sum = *(DBINT *)(dbadata(dbproc, rowinfo, 1));
        printf("sum = %ld\n", sum);
    }
}

The dbaltbind function automatically binds data to your program variables. It is somewhat easier to use than dbadata and dbadlen but is less efficient because it copies the data into your variable.

See Also

dbadlen, dbaltbind, dbaltlen, dbalttype, dbgetrow, dbnextrow, dbnumalts


dbadlen

Returns the actual length of the data for a compute column.

Syntax

DBINT dbadlen (
PDBPROCESS dbproc,
INT computeid,
INT column );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
computeid
Is the ID that identifies the COMPUTE clause. A SELECT statement can have multiple COMPUTE clauses, which can have varying numbers of aggregate operators and aggregate targets. The computeid is returned by dbnextrow or dbgetrow.
column
Is the number of the column. The first column is number 1.

Returns

The length, in bytes, of the data for a compute column. When no such column or COMPUTE clause exists, -1 is returned. When the data has a null value, 0 is returned.

Remarks

This dbadlen returns the length of the data for a compute column. You can get a pointer to the actual data by using dbadata. Calling dbadata after dbnextrow or dbgetrow returns a computeid.

Example

The following program fragment shows how to use dbadlen:

DBPROCESS    *dbproc;
char            biggest_name[MAXNAME+1];
DBINT        namelen;
STATUS        rowinfo;

// Put the command into the command buffer.
dbcmd(dbproc, "select name from sysobjects");
dbcmd(dbproc, " order by name");
dbcmd(dbproc, " compute max(name)");

// Send the command to SQL Server and start execution.
dbsqlexec(dbproc);

// Process the command.
dbresults(dbproc);

// Examine each row returned by the command.
while ((rowinfo = dbnextrow(dbproc)) != NO_MORE_ROWS)
{
    if (rowinfo == REG_ROW)
        printf("regular row returned.\n");
    else
    {
        // This row is the result of a COMPUTE clause,
        // and "rowinfo" is the computeid of this COMPUTE
        // clause.

        namelen = dbadlen(dbproc, rowinfo, 1);
        strncpy(biggest_name,(char *)dbadata(dbproc, rowinfo, 1),
            (int)namelen);

        // Data pointed to by dbadata() is not null-terminated.
        biggest_name[namelen] = '\0';

        printf("biggest name = %s\n", biggest_name);
    }
}

See Also

dbadata, dbaltlen, dbalttype, dbgetrow, dbnextrow, dbnumalts


dbaltbind

Binds a compute column (column of results from a COMPUTE clause) to a program variable.

Syntax

RETCODE dbaltbind (
PDBPROCESS dbproc,
INT computeid,
INT column,
INT vartype,
DBINT varlen,
LPCBYTE varaddr );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
computeid
Is the ID of the COMPUTE clause to which the dbaltbind function refers. Since a SELECT statement can have more than one COMPUTE clause, the computeid is necessary to distinguish between them. The computeid is returned by dbnextrow or dbgetrow.
column
Is the column number of the compute data that is to be copied to a program variable. The first column is number 1.
vartype
Is a description of the binding's datatype. It corresponds to the datatype of the program variable that receives the copy of the data from the DBPROCESS.

The dbaltbind function supports a wide range of type conversions, so the binding's datatype can be different from the type returned by the SQL query. For instance, a SQLMONEY result can be bound to a DBFLT8 program variable, using FLT8BIND, and the appropriate data conversion happens automatically.

For a list of the data conversions provided by DB-Library, see dbwillconvert. For a list of the type definitions used by DB-Library, see DB-Library Datatypes. The following table lists the legal vartypes recognized by dbaltbind and the program variable and SQL Server types that each refers to.

vartype 		Program variable
type
SQL Server type
CHARBIND | DBCHAR | SQLCHAR
STRINGBIND | DBCHAR | SQLCHAR
NTBSTRINGBIND | DBCHAR | SQLCHAR
VARYCHARBIND | DBVARYCHAR | SQLCHAR
BINARYBIND | DBBINARY | SQLBINARY
VARYBINBIND | DBVARYBIN | SQLBINARY
TINYBIND | DBTINYINT | SQLINT1
SMALLBIND | DBSMALLINT | SQLINT2
INTBIND | DBINT | SQLINT4
FLT8BIND | DBFLT8 | SQLFLT8
BITBIND | DBBIT | SQLBIT
DATETIMEBIND | DBDATETIME | SQLDATETIME
MONEYBIND | DBMONEY | SQLMONEY
SMALLMONEYBIND | DBMONEY4 | SQLMONEY4
SMALLDATETIBIND | DBDATETIM4 | SQLDATETIM4
FLT4BIND | DBFLT4 | SQLFLT4
DECIMALBIND | DBDECIMAL | SQLDECIMAL
NUMERICBIND | DBNUMERIC | SQLNUMERIC
SRCDECIMALBIND | DBDECIMAL | SQLDECIMAL
SRCNUMERICBIND | DBNUMERIC | SQLNUMERIC

Because SQLTEXT and SQLIMAGE data are never returned through a compute row (a row of results generated by a COMPUTE clause), these datatypes are not included in the preceding table. The SQL Server type is listed for your reference. The vartype you specify does not necessarily have to correspond to a particular SQL Server type because, as mentioned earlier, dbaltbind converts SQL Server data into the specified vartype.

The following table lists the four representations for character data. They differ according to whether the data is padded with blanks or is null-terminated:
vartype | Program type | Padding | Terminator
CHARBIND | DBCHAR | blanks | none
STRINGBIND | DBCHAR | blanks | \0
NTBSTRINGBIND | DBCHAR | none | \0
VARYCHARBIND | DBVARYCHAR | none | none

Note that "\0" is the null terminator character. Similarly, binary data can be stored in two different ways:
vartype | Program type | Padding
BINARYBIND | DBBINARY | nulls
VARYBINBIND | DBVARBINARY | none

When a column of integer data is summed or averaged, SQL Server always returns a four-byte integer, regardless of the size of the column. Therefore, be sure that the variable that is to contain the result from such a compute is declared as DBINT and that the vartype of the binding is INTBIND.

When the source column specified by the column parameter has a type of SQLDECIMAL or SQLNUMERIC, you can keep the same precision and scale in your bound C variable by using SRCDECIMALBIND or SRCNUMERICBIND.

varlen
Is the length of the program variable in bytes. For fixed-length vartypes, such as MONEYBIND or FLT8BIND, this length is ignored. For character and binary types, varlen must describe the total length of the available destination buffer space, including any space required for special terminating bytes, such as a null terminator. If varlen is 0, the total number of bytes available is copied into the program variable. (For char and binary SQL Server data, the total number of bytes available is equal to the defined length of the database column, including any blank padding. For varchar and varbinary data, the total number of bytes available is equal to the actual data contained in the column.) Therefore, if you are sure that your program variable is large enough to handle the results, set varlen to 0. The varlen is ignored for VARYCHARBIND and VARYBINBIND data.
varaddr
Is the address of the program variable to which the data is copied. Calling dbaltbind with a null var address parameter breaks previously set bindings.

When binding using DECIMALBIND or NUMERICBIND, the varaddr parameter must be a pointer to a DBNUMERIC or DBDECIMAL C variable, respectively, with the precision and scale fields of the structure already set to the desired values. You can use DEFAULTPRECISION to specify a default precision and DEFAULTSCALE to specify a default scale.

Returns

SUCCEED or FAIL. The dbaltbind function returns FAIL if vartype isn't compatible with the SQL Server type being returned, or if varaddr is null.

Remarks

This function directs DB-Library to copy compute column data returned by SQL Server into a program variable. (A compute column is a column of results from a COMPUTE clause in a Transact-SQL SELECT statement.) When each new row containing computed data is read by dbnextrow or dbgetrow, the data from the designated column in that compute row is copied into the program variable with the address varaddr. (A compute row is a row of results from a COMPUTE clause in a Transact-SQL SELECT statement.) There must be a separate dbaltbind call for each compute column to be copied. It is not necessary to bind every compute column to a program variable.

SQL Server can return two types of rows: regular rows containing data from columns designated by a SELECT statement's select list, and compute rows resulting from the COMPUTE clause. The dbaltbind function binds data from compute rows. Use dbbind for binding data from regular rows.

The calls to dbaltbind must be made after a call to dbresults and before the first call to dbnextrow.

Using dbaltbind causes some overhead because it always copies the row data into the designated program variable. To avoid this copying, the returned data can be accessed more directly with dbadlen and dbadata.

Since null values can be returned from SQL Server, there is a set of default values, one for each datatype, that is substituted when binding null values. You can explicitly set your own values to be substituted for the default null values with the dbsetnull function. (For a list of the default substitution values, see dbsetnull.)

Example

This example shows the typical sequence of calls:

DBCHAR    name[20];
DBINT    namecount;

// Read the query into the command buffer.
dbcmd(dbproc, "select name from employee compute count(name)");
// Send the query to SQL Server.
dbsqlexec(dbproc);
// Get ready to process the results of the query.
dbresults(dbproc);
// Bind the regular row data - name.
dbbind(dbproc, 1, STRINGBIND, (DBINT) 0, name);
// Bind the compute column data - count of name.
dbaltbind(dbproc, 1, 1, INTBIND, (DBINT) 0, (BYTE *) &namecount);
// Now process each row.
while (dbnextrow(dbproc) != NO_MORE_ROWS)
{
    //C-code to print or process row data
}

See Also

dbadata, dbadlen, dbanullbind, dbbind, dbconvert, dbgetrow, dbnextrow, dbresults, dbsetnull, dbwillconvert; DB-Library Datatypes


dbaltcolid

Returns the operand column ID for a compute column.

Syntax

INT dbaltcolid (
PDBPROCESS dbproc,
INT computeid,
INT column );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
computeid
Is the ID that identifies the COMPUTE clause. A SELECT statement can have multiple COMPUTE clauses, which can have varying numbers of aggregate operators and aggregate targets. The computeid is returned by dbnextrow or dbgetrow.
column
Is the number of the compute column. The first column is number 1.

Returns

The column ID that the aggregate in the compute applies to. The first column is number 1. If either computeid or column is invalid, -1 is returned. Call this function after dbnextrow or dbgetrow returns a computeid.

Example

When issued after the following SELECT statement, dbaltcolid(dbproc, 1, 1) returns 2, because the COMPUTE COUNT clause in the SELECT statement refers to the second column in the select list:

select dept, name from employee
order by dept, name
compute count(name) by dept

See Also

dbadata, dbadlen, dbaltlen, dbgetrow, dbnextrow, dbnumalts, dbprtype


dbaltlen

Returns the maximum length of the data for a compute column.

Syntax

DBINT dbaltlen (
PDBPROCESS dbproc,
INT computeid,
INT column );

where

dbproc
The DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
computeid
The ID that identifies the COMPUTE clause. A SELECT statement can have multiple COMPUTE clauses, which can have varying numbers of aggregate operators and aggregate targets. The computeid is returned by dbnextrow or dbgetrow.
column
The number of the column. The first column is number 1.

Returns

The maximum number of bytes that the data can be for a particular column in a compute. When no such column or compute exists, -1 is returned.

Remarks

dbaltlen returns the maximum length, in bytes, for a particular column in a compute row. For variable length data, this is not necessarily the actual length of the data, but rather the maximum length. Calling dbaltlen only after dbnextrow or dbgetrow returns a computeid. For the actual data length, use dbadlen.

Example

After the following SELECT, calling dbaltlen(dbproc, 1, 1) returns 4, because counts are of SQLINT4 type, which is 4 bytes long:

select dept, name from employee
order by dept, name
compute count(name) by dept

See Also

dbadata, dbadlen, dbalttype, dbgetrow, dbnextrow, dbnumalts


dbaltop

Returns the type of aggregate function for a compute column.

Syntax

INT dbaltop (
PDBPROCESS dbproc,
INT computeid,
INT column );

where

dbproc
The DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
computeid
The ID that identifies the COMPUTE clause. A SELECT statement can have multiple COMPUTE clauses, which can have varying numbers of aggregate operators and aggregate targets. The computeid is returned by dbnextrow or dbgetrow.
column
The number of the column. The first column is number 1.

Returns

The type of aggregate operator for the particular column in the compute. The types are defined as follows:

Type | Aggregate operator
SQLAOPSUM | SUM
SQLAOPAVG | AVG
SQLAOPCNT | COUNT
SQLAOPMIN | MIN
SQLAOPMAX | MAX

Call dbaltop only after dbnextrow or dbgetrow returns a computeid.

If computeid or column is not valid, -1 is returned.

Example

After the following SELECT, calling dbaltop(dbproc, 1, 1) returns the type for COUNT since the first aggregate operator in the first COMPUTE clause is COUNT:

select dept, name from employee
order by dept, name
compute count(name) by dept

To convert the type to a readable string, use dbprtype.

See Also

dbadata, dbadlen, dbaltlen, dbgetrow, dbnextrow, dbnumalts, dbprtype


dbalttype

Returns the datatype for a compute column.

Syntax

INT dbalttype (
PDBPROCESS dbproc,
INT computeid,
INT column );

where

dbproc
The DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
computeid
The ID that identifies the COMPUTE clause. A SELECT statement can have multiple COMPUTE clauses, which can have varying numbers of aggregate operators and aggregate targets. The computeid is returned by dbnextrow or dbgetrow.
column
The number of the column. The first column is number 1.

Returns

The type of the data for the particular column in the compute. The types are defined as follows:

Column datatype | Returned constant
char | SQLCHAR
varchar | SQLCHAR
binary | SQLBINARY
varbinary | SQLBINARY
tinyint | SQLINT1
smallint | SQLINT2
int | SQLINT4
real | SQLFLT4
float | SQLFLT8
smallmoney | SQLMONEY4
money | SQLMONEY
decimal | SQLDECIMAL
numeric | SQLNUMERIC
smalldatetime | SQLDATETIM4
datetime | SQLDATETIME
image | SQLIMAGE
text | SQLTEXT

Call dbalttype only after dbnextrow or dbgetrow returns a computeid.

If either the computeid or column is invalid, -1 is returned.

Example

In the following SELECT, calling dbalttype(dbproc, 1, 1) returns the type for SQLINT4 since counts are of SQLINT4 type.

select dept, name from employee
order by dept, name
compute count(name) by dept

To convert the type to a readable string, use dbprtype.

See Also

dbadata, dbadlen, dbaltlen, dbgetrow, dbnextrow, dbnumalts, dbprtype; DB-Library Datatypes


dbaltutype

Returns the user-defined datatype for a compute column.

Syntax

DBINT dbaltutype (
PDBPROCESS dbproc,
INT computeid,
INT column );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
computeid
Is the ID that identifies the COMPUTE clause. A SELECT statement can have multiple COMPUTE clauses, which can have varying numbers of aggregate operators and aggregate targets. The computeid is returned by dbnextrow or dbgetrow.
column
Is the number of the column. The first column is number 1.

Returns

The user-defined datatype of the specified compute column on success and -1 on error.

Remarks

For a description of how to add user-defined datatypes to SQL Server databases or server-library programs, see Microsoft SQL Server Transact-SQL Reference.

This function is defined as type DBINT, because both the DB-Library datatype DBINT and user-defined datatypes are 32 bits long. Call dbaltutype only after dbnextrow or dbgetrow returns a computeid.

See Also

dbalttype, dbcolutype


dbanullbind

Associates an indicator variable with a compute-row column.

Syntax

RETCODE dbanullbind (
PDBPROCESS dbproc,
INT computeid,
INT column,
LPCDBINT indicator );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
computeid
Is the ID that identifies the COMPUTE clause. A SELECT statement can have multiple COMPUTE clauses, which can have varying numbers of aggregate operators and aggregate targets. The computeid is returned by dbnextrow or dbgetrow. A value of 1 is the computeid corresponding to the first compute clause in a SELECT statement.
column
Is the number of the column to be associated with the indicator variable.
indicator
Is a pointer to the indicator variable.

Note The indicator parameter is just the pointer to the indicator variable. The variable itself is set.

Returns

SUCCEED or FAIL. The dbanullbind function returns FAIL if computeid or column
is invalid.

Remarks

The indicator variable reveals whether a particular compute-row column has been converted and copied to a program variable successfully or unsuccessfully, or whether it is null. Call dbanullbind only after dbnextrow or dbgetrow returns a computeid.

The indicator variable is set when compute rows are processed through dbnextrow. The possible values are:

  • -1 if the column is null.
  • The full length of the column's data. This value is in bytes if the column was bound to a program variable through dbaltbind, the binding did not specify
    any data conversions, and the bound data was truncated because the program variable was too small to hold the column's data.
  • 0 if the column was successfully bound and copied to a program variable.

Note Detection of character string truncation is implemented only for CHARBIND and VARYCHARBIND.

See Also

dbadata, dbadlen, dbaltbind, dbnextrow, dbnullbind


dbbind

Binds a regular result column (a column of results from a SELECT statement's select list) to a program variable.

Syntax

RETCODE dbbind (
PDBPROCESS dbproc,
INT column,
INT vartype,
DBINT varlen,
LPBYTE varaddr );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
column
Is the column number of the row data to be copied to a program variable. The first column is number 1.
vartype
Is a description of the binding's datatype. It corresponds to the datatype of the program variable that receives the copy of the data from the DBPROCESS. The dbbind function supports a wide range of type conversions, so vartype can be different from the type returned by the SQL query. For instance, a SQLMONEY result can be bound to a DBFLT8 program variable, using FLT8BIND, and the appropriate data conversion happens automatically. For a list of the data conversions provided by DB-Library, see dbwillconvert. For a list of the type definitions used by DB-Library, see DB-Library Datatypes.

The following table lists legal vartypes recognized by dbbind and the program variable and SQL Server type tokens that each refers to:
vartype | varaddr | SQL Server type of column
CHARBIND | DBCHAR | SQLCHAR, SQLVARCHAR, or SQLTEXT
STRINGBIND | DBCHAR | SQLCHAR, SQLVARCHAR, or SQLTEXT
NTBSTRINGBIND | DBCHAR | SQLCHAR, SQLVARCHAR, or SQLTEXT
VARYCHARBIND | DBVARYCHAR | SQLCHAR, SQLVARCHAR, or SQLTEXT
BINARYBIND | DBBINARY | SQLBINARY, SQLVARBINARY, or SQLIMAGE
VARYBINBIND | DBVARYBIN | SQLBINARY, SQLVARBINARY, or SQLIMAGE
TINYBIND | DBTINYINT | SQLINT1 or SQLINTN
SMALLBIND | DBSMALLINT | SQLINT2 or SQLINTN
INTBIND | DBINT | SQLINT4 or SQLINTN
FLT4BIND | DBFLT4 | SQLFLT4 or SQLFLTN
FLT8BIND | DBFLT8 | SQLFLT8 or SQLFLTN
BITBIND | DBBIT | SQLBIT
SMALLMONEYBIND | DBMONEY4 | SQLMONEY4 or SQLMONEYN
MONEYBIND | DBMONEY | SQLMONEY or SQLMONEYN
DECIMALBIND | DBDECIMAL | SQLDECIMAL
NUMERICBIND | DBNUMERIC | SQLNUMERIC
SRCDECIMALBIND | DBDECIMAL | SQLDECIMAL
SRCNUMERICBIND | DBNUMERIC | SQLNUMERIC
SMALLDATETIBIND | DBDATETIM4 | SQLDATETIM4 or SQLDATETIMN
DATETIMEBIND | DBDATETIME | SQLDATETIME or SQLDATETIMN

Note that the SQL Server type in the preceding table is listed merely for your information. The vartype you specify does not necessarily have to correspond to a particular SQL Server type because dbbind converts SQL Server data into the specified vartype.

The following table lists the four representations for character and text data. They differ according to whether the data is blank-padded or null-terminated:
vartype | varaddr | Padding | Terminator
CHARBIND | DBCHAR | blanks | none
STRINGBIND | DBCHAR | blanks | \0
NTBSTRINGBIND | DBCHAR | none | \0
VARYCHARBIND | DBVARYCHAR | none | none

Note that '\0' is the null terminator character. Similarly, binary and image data can be stored in two different ways:
vartype | varaddr | Padding
BINARYBIND | DBBINARY | nulls
VARYBINBIND | DBVARBINARY | none

When the source column specified by the column parameter has a type of SQLDECIMAL or SQLNUMERIC, you can keep the same precision and scale in your bound C variable by using SRCDECIMALBIND or SRCNUMERICBIND.

varlen
Is the length of the varaddr program variable in bytes. For fixed-length vartypes, such as MONEYBIND or FLT8BIND, this length is ignored. For character, text, binary, and image types, varlen must describe the total length of the available destination buffer space, including any space that can be required for special terminating bytes, such as a null terminator. If varlen is 0, the number of bytes available is copied into the program variable. (For char and binary SQL Server data, the number of bytes available is equal to the defined length of the database column, including any blank padding. For varchar, varbinary, text, and image data, the number of bytes available is equal to the actual data contained in the column.) Therefore, if you are sure that your program variable is large enough to handle the results, you can set varlen to 0.

In some cases, DB-Library issues a message indicating that data conversion resulted in an overflow. This is usually caused by a varlen specification being too small for the data being received from SQL Server. For example, if varlen is set to 5, vartype is set to VARYCHARBIND, and the SQL Server column being bound is of type VARCHAR with a length of 20. When the bind occurs (using dbnextrow), the overflow message is issued. Note however that five bytes of data will be bound. Other types of binds also can cause the overflow message to be issued. For information about datatype conversions, see "dbconvert."

varaddr
Is the address of the program variable to which the data is copied. Calling dbbind with a null varaddr parameter breaks a previously set binding.

When binding using DECIMALBIND or NUMERICBIND, the varaddr parameter must be a pointer to a DBNUMERIC or DBDECIMAL C variable, respectively, with the precision and scale fields of the structure already set to the desired values. You can use DEFAULTPRECISION to specify a default precision and DEFAULTSCALE to specify a default scale.

Returns

SUCCEED or FAIL. The dbbind function returns FAIL if the column number given isn't valid, if the vartype isn't compatible with the SQL Server type being returned, or if varaddr is null.

Remarks

Data comes back from SQL Server one row at a time. This function directs DB-Library to copy the data for a regular column (designated in a SELECT statement's select list) into a program variable. When each new row containing regular (not compute) data is read using dbnextrow or dbgetrow, the data from the designated column in that row is copied into the program variable with the address varaddr. There must be a separate dbbind call for each regular column to be copied. It is not necessary to bind every column to a program variable. A result column can be bound to only one program variable.

SQL Server can return two types of rows: regular rows and compute rows resulting from the COMPUTE clause of a SELECT statement. The dbbind function binds data from regular rows. Use dbaltbind for binding data from compute rows.

Calls to dbbind must be made after a call to dbresults and before the first call to dbnextrow.

Using dbbind causes some overhead because it copies the row data into the designated program variable. To avoid this copying, the returned data can be accessed more directly with dbdatlen and dbdata.

Since null values can be returned from SQL Server, there is a set of default values, one for each datatype, that will be substituted when binding null values. You can explicitly set your own values to be substituted for the default null value with the dbsetnull function. (For a list of the default substitution values, see dbsetnull.)

For the Windows operating system, DB-Library retrieves information about date, time, numeric, and currency formatting from the SQLCOMMN.LOC file. The location of SQLCOMMN.LOC is pointed to by the SQLLocalizationFile key in the Windows initialization file (WIN.INI) under the [SQLSERVER] application heading. For example:

[SQLSERVER]
SQLLocalizationFile=C:\SQL60\BIN\SQLCOMMN.LOC

For the Windows NT operating system, you set the date, time, numeric, and currency formatting using the International application in the Control Panel. Use the SQL Client Configuration Utility's Use International Settings option to activate this for DB-Library.

Example

This example shows the typical sequence of calls:

DBINT    xvariable;
DBCHAR    yvariable[10];

// Read the query into the command buffer.
dbcmd(dbproc, "select x = 100, y = 'hello'");
// Send the query to SQL Server.
dbsqlexec(dbproc);
// Get ready to process the results of the query.
dbresults(dbproc);
// Bind column data to program variables.
dbbind(dbproc, 1, INTBIND, (DBINT) 0, (BYTE *) &xvariable);
dbbind(dbproc, 2, STRINGBIND, (DBINT) 0, yvariable);

// Now process each row.
while (dbnextrow(dbproc) != NO_MORE_ROWS)
{
    // C-code to print or process row data
}

See Also

dbaltbind, dbanullbind, dbconvert, dbdata, dbdatlen, dbgetrow, dbnextrow, dbresults, dbsetnull, dbwillconvert; DB-Library Datatypes


dbbylist

Returns the bylist for a compute row.

Syntax

LPCBYTE dbbylist (
PDBPROCESS dbproc,
INT computeid,
LPINT size );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
computeid
Is the ID that identifies the COMPUTE clause. A SELECT statement can have multiple COMPUTE clauses, which can have varying numbers of aggregate operators and targets. The computeid is returned by dbnextrow or dbgetrow.
size
Is a pointer to an integer which dbbylist sets to the number of elements in the bylist.

Returns

A pointer to an array of BYTES containing the numbers of the columns that compose the bylist for the specified compute. The names of the columns are available by calling dbcolname. If the computeid is out of range, null is returned.

The size of the array is returned in the size parameter. A size of 0 indicates that either this particular compute has no bylist or the computeid is out of range.

Remarks

A SELECT statement's COMPUTE clause can contain the keyword BY, followed by a list of columns. This list, known as the bylist, divides the results into subgroups based on changing values in the specified columns. The COMPUTE clause's row aggregate is applied to each subgroup, generating a compute row for each subgroup.

Call this function after dbresults has returned SUCCEED.

Example

Assume the following command has been executed:

select dept, name, year, sales from employee
order by dept, name, year
compute count(name) by dept,name

The call dbbylist(dbproc, 1, &size) sets size to 2 because there are two items in the bylist. It returns a pointer to an array of 2 BYTES, which contain the values 1 and 2, indicating that the bylist is composed of columns 1 and 2 from the select list.

See Also

dbadata, dbadlen, dbaltlen, dbalttype, dbcolname, dbgetrow, dbnextrow, dbresults


dbcancel

Cancels the current command batch and flushes any pending results.

Syntax

RETCODE dbcancel ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

SUCCEED or FAIL.

Remarks

You can call this function after calling dbsqlexec, dbsqlsend, dbsqlok, dbresults, or dbnextrow to cancel the execution of the current command batch that SQL Server is processing and eliminate any pending results. When dbcancel is called, SQL Server is interrupted and stops executing the command batch associated with the dbproc. Any pending results are read and discarded. Note that dbcancel cancels all the commands in the current command batch. Don't try to use it to cancel only the current command in a multiple-command batch; use dbcanquery instead.

If you receive the DB-Library error 10038 "Results Pending," you can call dbcancel to clear the pending results. If dbcancel returns FAIL, the server may not be able to respond to the cancel request. Either continue to call dbcancel until it returns SUCCEED, or close the DBPROCESS connection and open a new one.

See Also

dbcanquery, dbnextrow, dbresults, dbsqlexec, dbsqlok, dbsqlsend


dbcanquery

Cancels any rows pending from the most recently executed query.

Syntax

RETCODE dbcanquery ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

SUCCEED or FAIL.

Remarks

This function is an efficient way to throw away any unread rows that result from the most recently executed SQL query. Calling dbcanquery is similar to calling dbnextrow until it returns no_more_rows. Binds are broken before rows are read.

The dbresults function must return SUCCEED before an application can call dbcanquery.

If you want to ignore all of the results from all of the commands in the current command batch, call dbcancel.

See Also

dbcancel, dbnextrow, dbresults, dbsqlexec


dbchange

Determines whether a command batch has changed the current database to another database.

Syntax

LPCSTR dbchange ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

A pointer to the null-terminated name of the new database, if any. If the database has not changed, null is returned.

Remarks

The dbchange function informs the program of a switch from one database to another by catching any instance of the Transact-SQL USE statement.

When connected to SQL Server 4.2, a USE statement does not take effect until the end of the batch. The dbchange function is therefore useful only in determining whether the current command batch has changed to another database for subsequent command batches. The simplest way to keep track of database switches is to call dbchange when dbresults returns NO_MORE_RESULTS at the end of each command batch.

When connected to SQL Server 6.0, a USE statement takes effect immediately.

Alternatively, you can always get the name of the current database by calling dbname.

See Also

dbname, dbresults, dbsqlexec, dbsqlsend, dbuse


dbclose

Closes and frees a single DBPROCESS structure.

Syntax

RETCODE dbclose ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

SUCCEED or FAIL

Remarks

The dbclose function is the inverse of dbopen. It cleans up any activity associated with a single DBPROCESS structure and frees the memory. It also closes the corresponding network connection and any open cursors.

To close all open DBPROCESS structures, use dbexit.

Calling dbclose with a parameter not returned by dbopen causes an error.

See Also

dbexit, dbopen


dbclrbuf

Clears rows from the row buffer.

Syntax

void dbclrbuf (
PDBPROCESS dbproc,
DBINT n );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
n
Is the number of rows you want cleared from the row buffer. If n is equal to
or greater than the number of rows in the buffer, all but the newest row are
removed. If n is less than 1, the call is ignored. Rows are cleared on a first-in/first-out basis.

Remarks

You can turn row buffering on by calling dbsetopt (dbproc, DBBUFFER, n), where n is the number of rows you would like DB-Library to buffer. DB-Library for C can buffer rows as they are returned from SQL Server. If buffering is on, you can refer to buffered rows that have been read from SQL Server using dbgetrow.

The row buffer can become full if SQL Server returns more than the n rows that you said you wanted buffered. The row buffer is full when dbnextrow returns buf_full. Once the row buffer is full, dbnextrow continues to return buf_full until at least one row is freed by calling dbclrbuf. The dbclrbuf function frees the oldest n rows in the buffer.

See Also

dbgetrow, dbnextrow, dbsetopt; Bulk-Copy Functions and DB-Library Options


dbclropt

Clears an option set by dbsetopt.

Syntax

RETCODE dbclropt (
PDBPROCESS dbproc,
INT option,
LPCSTR param );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server. If dbproc is null, the option is set for all active and future DBPROCESS structures.
option
Is the option to be turned off.
param
Is the option parameter. Certain options take parameters. If an option does not take a parameter, param is ignored. If an option does take a parameter, param is ignored for all options except DBOFFSET and DBSTAT.

The DBOFFSET and DBSTAT options can have several settings, each with a different parameter. In these cases, dbclropt needs a valid param to determine which option parameter to clear.

For a list of options that take parameters, see DB-Library Options.

If an invalid parameter is specified for one of the SQL Server options, it will not be discovered until the command is sent to SQL Server. The dbsqlexec or dbsqlsend calls will fail and DB-Library will invoke the user-installed message handler. If an invalid parameter is specified for one of the DB-Library options (DBBUFFER or DBTEXTLIMIT) dbclropt itself will fail.

Returns

SUCCEED or FAIL.

Remarks

This function clears SQL Server and DB-Library options that have been set with dbsetopt. Although SQL Server options can be set and cleared directly through SQL, use dbsetopt and dbclropt in an application to set and clear options. This provides a uniform interface for setting both SQL Server and DB-Library options. It also allows the application to use dbisopt to check the status of an option.

The dbclropt function does not immediately clear the options specified. With the exception of DBBUFFER and DBNOAUTOFREE, options are not cleared until the command buffer is sent to SQL Server (by invoking the dbsqlexec function). An additional result is returned by using dbresults. (For information about results returned, see "dbresults.")

Note that the command string generated by this function is not immediately sent to SQL Server. Instead, it is buffered within DB-Library and sent the next time dbsqlexec is invoked. Therefore, any options requested by this function do not go into effect until then. Also, the results of the command generated by this function are not returned until the command is transferred to SQL Server. The application should be expecting the results returned from the command string generated by this function.

For a complete list of options, see DB-Library Options

See Also

dbisopt, dbsetopt; Bulk-Copy Functions and DB-Library Options


dbcmd

Adds text to the DBPROCESS command buffer.

Syntax

RETCODE dbcmd (
PDBPROCESS dbproc,
LPCSTR cmdstring );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
cmdstring
Is a null-terminated character string to be copied into the command buffer.

Returns

SUCCEED or FAIL.

Remarks

This function adds text to the command buffer in the DBPROCESS structure. It adds to the existing command buffer; it doesn't delete or overwrite the current contents except after the buffer has been sent to SQL Server. The user can call dbcmd repeatedly. Note that sequential calls are concatenated; the application must include any necessary blanks between the end of one line and the beginning of the next.

After a call to dbsqlexec or dbsqlsend, the first call to either dbcmd or dbfcmd automatically clears the command buffer before the new text is entered. If this situation is undesirable, set the DBNOAUTOFREE option. When DBNOAUTOFREE is set, the command buffer is cleared only by a call to dbfreebuf.

The dbfcmd function is a related function. Unlike dbcmd, dbfcmd takes additional parameters and interprets cmdstring as a format string that is passed to sprintf along with any additional parameters.

Example

This example shows how to use dbcmd to build up a multiple-line SQL statement:

DBPROCESS    *dbproc;

dbcmd(dbproc, "Select name from sysobjects");
dbcmd(dbproc, " where id < 5");
dbcmd(dbproc, " and type='S'");

Note the leading spaces in the second and third calls to dbcmd. Leading spaces are needed to properly concatenate the entire command string.

See Also

dbfcmd, dbfreebuf, dbsqlexec, dbsetopt, dbsqlsend; Bulk-Copy Functions and DB-Library Options


dbcmdrow

Determines whether the current command can return rows.

Syntax

RETCODE dbcmdrow ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

SUCCEED to indicate that the statement can return rows.

FAIL to indicate that the statement can't return rows.

Remarks

dbcmdrow determines whether the current command is a Transact-SQL SELECT statement or an EXECUTE statement on a stored procedure containing a SELECT statement. Call dbcmdrow after dbresults returns SUCCEED.

Even if dbcmdrow returns SUCCEED, the statement will not return any rows if none have qualified. To determine whether any rows are actually being returned, use dbrows.

Even if dbcmdrow returns FAIL, you must still process the results by calling dbnextrow until it returns NO_MORE_ROWS.

See Also

dbnextrow, dbresults, dbrows, dbrowtype


dbcolinfo

Returns information about a regular column or a compute column in a result set, or a column in a cursor.

Syntax

RETCODE dbcolinfo (
PDBHANDLE pdbhandle,
INT type,
DBINT column,
DBINT computeid,
LPDBCOL lpdbcol );

where

pdbhandle
Is a DBPROCESS pointer or a cursor handle. If type is CI_REGULAR or CI_ALTERNATE, this is a DBPROCESS pointer. If type is CI_CURSOR, this is a DBCURSOR handle.
type
Is the type of column information to return. The following table describes the different type values:
type | Description
CI_REGULAR | Return information about a regular column in the current result set.
CI_ALTERNATE | Returns information about a compute column in the current result set.
CI_CURSOR | Returns information about a column in the open cursor.

column
Is the number of the column. The first column is number 1.
computeid
If type is CI_ALTERNATE, this is the ID that identifies the compute (the result of a COMPUTE clause) value. The computeid is returned by dbnextrow or dbgetrow. If type is not CI_ALTERNATE, specify 0.
lpdbcol
Is a pointer to a DBCOL structure that DB-Library will fill with detailed information about the specified column.

The DBCOL structure is defined as follows:

typedef struct
{
    DBINT SizeOfStruct;
    CHAR  Name[MAXCOLNAMELEN+1]
    CHAR  ActualName[MAXCOLNAMELEN+1]
    CHAR  TableName[MAXTABLENAME+1]
    SHORT Type;
    DBINT UserType;
    DBINT MaxLength;
    BYTE  Precision;
    BYTE  Scale;
    BOOL  VarLength;
    BYTE  Null;
    BYTE  CaseSensitive;
    BYTE  Updatable;
    BOOL  Identity;
} DBCOL, PTR LPDBCOL;

The DBCOL fields (and the equivalent DB-Library functions, if any) are described below:
Field | Description
SizeOfStruct | Before calling dbcolinfo, set this field equal to the value returned by the C sizeof function for the DBCOL structure.
Name | Is the name of the returned column (dbcolname).
ActualName | Is the actual name of the column in TableName if type is CI_CURSOR; otherwise, this is the same as Name.
TableName | Is the table that contains the column if type is CI_CURSOR; otherwise, NULL.
Type | Is the datatype of the column (dbcoltype, dbalttype).
UserType | Is the user-defined datatype of the column (dbcolutype, dbaltutype).
MaxLength | Is the maximum length, in bytes, of the column (dbcollen, dbaltlen).
Precision | The precision if Type is SQLDECIMAL or SQLNUMERIC; otherwise, - 1.
Scale | The scale if Type is SQLDECIMAL or SQLNUMERIC; otherwise, - 1.
VarLength Is one of the following (dbvarylen):

TRUE if the column is variable-length.

FALSE if the column is fixed-length.
Null Is one of the following:

TRUE if the column allows nulls.

FALSE if the column does not allow nulls.

DBUNKNOWN if nullability is unknown.
CaseSensitive Is one of the following:

TRUE if the column is case sensitive.

FALSE if the column is case insensitive.

DBUNKNOWN if case sensitivity is unknown.
Updatable Is one of the following:

TRUE if the column can be changed.

FALSE if the column is read-only and cannot be changed.

DBUNKNOWN if updatability is unknown.
Identity Is one of the following:

TRUE if the column is an identity column.

FALSE if the column is not an identity column.

Returns

SUCCEED or FAIL.

Remarks

Before calling dbcolinfo, set the SizeOfStruct field equal to the value returned by the C sizeof function for the DBCOL structure. The dbcolinfo function fills the supplied DBCOL structure with information about the specified column.

Call this function after dbresults returns SUCCEED, or after dbcursoropen returns a cursor handle.

See Also

dbaltlen, dbalttype, dbaltutype, dbcollen, dbcolname, dbcoltype, dbcolutype, dbvarylen


dbcollen

Returns the maximum length, in bytes, of the data for a column.

Syntax

DBINT dbcollen (
PDBPROCESS dbproc,
INT column );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
column
Is the number of the column. The first column is number 1. For further information, see "dbadata."

Returns

The maximum length of the data for the particular column. If the column number is not in range, -1 is returned.

Remarks

In the case of variable length data, the maximum length is not necessarily the actual length of the data, but rather the maximum length that the data can be. For the actual data length, use dbdatlen. Call dbcollen after dbresults returns SUCCEED.

Example

The following example shows how to use dbcollen:

DBPROCESS    *dbproc;
int            colnum;
DBINT        column_length;

// Put the command into the command buffer.
dbcmd(dbproc, "select name, id, type from sysobjects");

// Send the command to SQL Server and begin execution.
dbsqlexec(dbproc);

// Process the command results.
dbresults(dbproc);

// Examine the column lengths.
for (colnum = 1; colnum < 4; colnum+)
{
    column_length = dbcollen(dbproc, colnum);
    printf("column %d, length is %ld.\n", colnum, column_length);
}

See Also

dbcolname, dbcoltype, dbdata, dbdatlen, dbnumcols


dbcolname

Returns a pointer to the null-terminated name of a particular result column.

Syntax

LPCSTR dbcolname (
PDBPROCESS dbproc,
INT column );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
column
Is the number of the column. The first column is number 1. For further information, see "dbadata."

Returns

A char pointer to the null-terminated name of the particular column. If the column number is not in range or if the column is the result of an expression with no name assigned, dbcolname returns null. If the column number is out of range, dbcolname also calls the error handler with an error of 10011 (SQLECNOR).

Example

The following example shows how to use dbcolname:

DBPROCESS    *dbproc;

// Put the command into the command buffer.
dbcmd(dbproc, "select name, id, type from sysobjects");

// Send the command to SQL Server and begin execution.
dbsqlexec(dbproc);

// Process the command results.
dbresults(dbproc);

// Examine the column names.
printf("first column name is %s\n", dbcolname(dbproc, 1));
printf("second column name is %s\n", dbcolname(dbproc, 2));
printf("third column name is %s\n", dbcolname(dbproc, 3));

See Also

dbcollen, dbcoltype, dbdata, dbdatlen, dbnumcols


dbcoltype

Returns the datatype for a regular result column.

Syntax

INT dbcoltype (
PDBPROCESS dbproc,
INT column );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
column
Is the number of the column. The first column is number 1. For further information, see "dbadata."

Returns

A value for the datatype for the particular column. If the column is not in range,
-1 is returned.

Column datatype | Returned constant
char | SQLCHAR
varchar | SQLCHAR
binary | SQLBINARY
varbinary | SQLBINARY
tinyint | SQLINT1
smallint | SQLINT2
int | SQLINT4
real | SQLFLT4
float | SQLFLT8
smallmoney | SQLMONEY4
money | SQLMONEY
decimal | SQLDECIMAL
numeric | SQLNUMERIC
smalldatetime | SQLDATETIM4
datetime | SQLDATETIME
image | SQLIMAGE
text | SQLTEXT

Remarks

The dbcoltype function returns an integer value for the type. Use dbprtype to convert the type value into a readable string. For a list of SQL Server types, see DB-Library Datatypes. Call dbcoltype after dbresults returns SUCCEED.

This function cannot determine whether a column can take null values.

Example

This example shows how to use dbcoltype and dbprtype:

DBPROCESS    *dbproc;
int            colnum;
int            coltype;

// Put the command into the command buffer.
dbcmd(dbproc, "select name, id, type from sysobjects");

// Send the command to SQL Server and begin execution.
dbsqlexec(dbproc);

// Process the command results.
dbresults(dbproc);
// Examine the column types.
for (colnum = 1; colnum < 4; colnum+)
{
    coltype = dbcoltype(dbproc, colnum);
    printf("column %d, type is %s.\n", colnum, dbprtype(coltype));
}

See Also

dbcollen, dbcolname, dbdata, dbdatlen, dbnumcols, dbprtype; DB-Library Datatypes


dbcolutype

Returns the user-defined datatype for a regular result column.

Syntax

DBINT dbcolutype (
PDBPROCESS dbproc,
INT column );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
column
Is the number of the column. The first column is number 1. For further information, see "dbadata."

Returns

The column parameter's user-defined datatype on success and -1 on error.

Remarks

For a description of how to add user-defined datatypes to SQL Server databases, see the Microsoft SQL Server Transact-SQL Reference.

This function is defined as datatype DBINT to accommodate the size of user-defined datatypes. Both DBINT and user-defined datatypes are 32 bits long. Call dbcolutype after dbresults returns SUCCEED.

Example

This example shows how to use dbcolutype:

DBPROCESS    *dbproc;
int            colnum;
int            numcols;

// Put the command into the command buffer.
dbcmd (dbproc, "select * from mytable");

// Send the command to the SQL Server and begin execution.
dbsqlexec(dbproc);

// Process the command results.
dbresults(dbproc);
// Examine the user-defined column types.
numcols = dbnumcols(dbproc);
for (colnum = 1; colnum < numcols; colnum+)
{
     printf
     ("column %d, user-defined type is %ld.\n",
     colnum, dbcolutype(dbproc, colnum));
}

See Also

dbaltutype, dbcoltype


dbconvert

Converts data from one datatype to another.

Syntax

INT dbconvert (
PDBPROCESS dbproc,
INT srctype,
LPCBYTE src,
DBINT srclen,
INT desttype,
LPBYTE dest,
DBINT destlen );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

In dbconvert, the DBPROCESS is used only to supply any custom null values that the program specified through dbsetnull. If dbproc is null, dbconvert uses the default values for null value data conversions.

srctype
Is the datatype of the source data to be converted. This parameter can be any of the SQL Server datatype tokens. You can use dbcoltype to get the SQL Server datatype token for a particular column.
src
Is a pointer to the source data to be converted. If this pointer is null, dbconvert puts an appropriate null value in the destination variable. You can use dbdata to get a pointer to data from a SQL Server column.

When srctype is SQLDECIMAL or SQLNUMERIC, the src parameter must be a pointer to a valid DBNUMERIC or DBDECIMAL C variable, respectively.

srclen
Is the length, in bytes, of the source data to be converted. This length is used for the following srctype datatype tokens:
  • SQLCHAR, SQLVARCHAR, SQLTEXT
  • SQLBINARY, SQLVARBINARY, SQLIMAGE
  • SQLINTN, SQLFLTN, SQLMONEYN, SQLDATETIMN

This length is ignored for all fixed-length, non-NULL datatypes. If srclen is 0, the source data is assumed to be null, and dbconvert places an appropriate null value in the destination variable. You can use dbdatlen to get the length of SQL Server data.

When src points to a DBCHAR string, a srclen of -1 indicates that the string is null-terminated.

desttype
Is the destination datatype that the source data is to be converted into. This parameter can be any of the SQL Server datatype tokens.
dest
Is a pointer to the destination variable that will receive the converted data. If this pointer is null, dbconvert calls the user-supplied error handler (if any) and returns -1.

When desttype is SQLDECIMAL or SQLNUMERIC, the dest parameter must be a pointer to a DBNUMERIC or DBDECIMAL C variable, respectively, with the precision and scale fields of the structure already set to the desired values. You can use DEFAULTPRECISION to specify a default precision and DEFAULTSCALE to specify a default scale.

destlen
Is the length, in bytes, of the destination variable. This length is used for the following desttype datatype tokens:
  • SQLCHAR, SQLVARCHAR, SQLTEXT
  • SQLBINARY, SQLVARBINARY, SQLIMAGE
  • SQLINTN, SQLFLTN, SQLMONEYN, SQLDATETIMN

The destlen is ignored for all fixed-length, non-NULL datatypes.

When dest points to a DBCHAR string or a DBBINARY array, the value of destlen must be the total length of the destination buffer space, or -1 to indicate that there is sufficient space available. Note that when dest points to a DBCHAR string, a destlen of -1 causes the character string to be given a terminating null.

Returns

The length of the converted data, in bytes, if the datatype conversion succeeds. If the conversion fails, -1 is returned. If dbconvert fails, it first calls a user-supplied error handler (if any). This routine may fail for one of these reasons:

  • The requested conversion was unavailable.
  • The conversion resulted in truncation, overflow, or loss of precision in the destination variable.
  • A syntax error occurred while converting a character string to some numeric type.

Remarks

This function allows the application to convert data from one representation to another. To determine whether a particular conversion is permitted, the program can call dbwillconvert before attempting a conversion.

The dbconvert function can convert data stored in any of the SQL Server datatypes (although not all conversions are legal). The following table shows the program variable type (src or dest parameters) you must provide for each non-NULL SQL Server datatype (srctype or desttype parameters):

Datatype (srctype, desttype) | Program variable type (src, dest)
SQLCHAR | DBCHAR
SQLVARCHAR | DBCHAR
SQLTEXT | DBCHAR
SQLBINARY | DBBINARY
SQLVARBINARY | DBBINARY
SQLIMAGE | DBBINARY
SQLINT1 | DBTINYINT
SQLINT2 | DBSMALLINT
SQLINT4 | DBINT
SQLFLT4 | DBFLT4
SQLFLT8 | DBFLT8
SQLBIT | DBBIT
SQLMONEY4 | DBMONEY4
SQLMONEY | DBMONEY
SQLDATETIM4 | DBDATETIM4
SQLDATETIME | DBDATETIME
SQLDECIMAL | DBDECIMAL
SQLNUMERIC | DBNUMERIC

The following table shows the program variable type (src or dest parameters) you must provide for each fixed-length SQL Server datatype (srctype or desttype parameters) that allows NULL values and valid byte length (srclen or destlen parameters):

srctype, desttype | srclen, destlen | src, dest
SQLINTN | 1 | DBTINYINT
SQLINTN | 2 | DBSMALLINT
SQLINTN | 4 | DBINT
SQLFLTN | 4 | DBFLT4
SQLFLTN | 8 | DBFLT8
SQLMONEYN | 4 | DBMONEY4
SQLMONEYN | 8 | DBMONEY
SQLDATIMETIMN | 4 | DBDATETIM4
SQLDATIMETIMN | 8 | DBDATETIME

Conversion to and from all SQL Server datatypes is supported, except for conversion from SQLDATETIME or SQLDATETIM4 to the following datatypes, and from the following datatypes to SQLDATETIME or SQLDATETIM4:

  • SQLINT1, SQLINT2, SQLINT4
  • SQLFLT4, SQLFLT8
  • SQLBIT
  • SQLMONEY, SQLMONEY4
  • SQLDECIMAL, SQLNUMERIC

A conversion to or from the datatypes SQLBINARY and SQLIMAGE is a straight bit-copy unless the conversion involves SQLCHAR or SQLTEXT. When converting SQLCHAR or SQLTEXT data to SQLBINARY or SQLIMAGE, dbconvert interprets the SQLCHAR or SQLTEXT string as hexadecimal digits, whether or not the string contains a leading "0x". When converting SQLBINARY or SQLIMAGE data to SQLCHAR or SQLTEXT, dbconvert creates a string of hexadecimal digits without a leading "0x".

Converting to the approximate numeric datatypes SQLFLT4 or SQLFLT8 can result in some loss of precision. Converting from the approximate numeric datatypes SQLFLT4 or SQLFLT8 to SQLCHAR or SQLTEXT can also result in some loss of precision.

Converting to SQLFLTx, SQLINTx, SQLMONEY, SQLMONEY4, SQLDECIMAL, or SQLNUMERIC can result in overflow if the number is larger than the destination's maximum value, or in underflow if the number is smaller than the destination's minimum value. If overflow occurs when converting to SQLCHAR or SQLTEXT, the first character of the resulting value contains an asterisk (*) to indicate the error.

When binding data to variables rather than accessing the data directly, use dbbind to convert instead of dbconvert.

For the Windows operating system, DB-Library retrieves information about date, time, numeric, and currency formatting from the SQLCOMMN.LOC file. The location of SQLCOMMN.LOC is pointed to by the SQLLocalizationFile key in the Windows initialization file (WIN.INI) under the [SQLSERVER] application heading. For example:

[SQLSERVER]
SQLLocalizationFile=C:\SQL60\BIN\SQLCOMMN.LOC

For the Windows NT operating system, you set the date, time, numeric, and currency formatting using the International application in the Control Panel. Use the SQL Client Configuration Utility's Use International Settings option to activate this for DB-Library.

Example

This example converts SQL Server data obtained with dbdata:

DBCHAR    title[81];
DBCHAR    price[9];

// Read the query into the command buffer.
dbcmd(dbproc, "select title, price, royalty from pubs..titles");

// Send the query to SQL Server.
dbsqlexec(dbproc);

// Get ready to process the results of the query.
dbresults(dbproc);

// Process each row.
while (dbnextrow(dbproc) != NO_MORE_ROWS)
{
    // The first dbconvert() adds a null terminator to the string.
    dbconvert(dbproc, SQLCHAR, (dbdata(dbproc,1)), (dbdatlen(dbproc,1)),
    SQLCHAR, title, (DBINT)-1);
    // The second dbconvert() converts money to string.
    dbconvert(dbproc, SQLMONEY, (dbdata(dbproc,2)), (DBINT)-1, SQLCHAR,
        price, (DBINT)-1);

    if (dbdatlen(dbproc,3) != 0)
        printf ("%s\n $%s    %ld\n", title, price,
            *((DBINT *)dbdata(dbproc,3)));
}

See Also

dbaltbind, dbbind, dbcoltype, dbdata, dbdatlen, dberrhandle, dbsetnull, dbwillconvert; Cursor Functions, DB-Library Datatypes, and Error Messages


dbcount

Returns the number of rows affected by a Transact-SQL statement.

Syntax

DBINT dbcount ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

The number of rows affected by the current statement. Call dbiscount to determine if this count is correct.

Remarks

Once the results of a statement have been processed, you can call dbcount to find out how many rows were affected by the statement. For example, if a SELECT statement was sent to SQL Server and you have read all the rows by calling dbnextrow until it returned NO_MORE_ROWS, you can call DBCOUNT to find out how many rows were retrieved.

If the current statement doesn't immediately return rows (for example, a DELETE statement), you can call dbcount after dbresults.

If the current statement executes a stored procedure, for example an EXEC or a call to a remote stored procedure, dbcount reports the number of rows returned by the last SELECT statement executed by the stored procedure. Note that a stored procedure without a SELECT statement can execute a SELECT anyway simply by calling another stored procedure with a SELECT.

See Also

dbnextrow, dbresults; DB-Library Options


dbcurcmd

Returns the number of the current command within a command batch.

Syntax

INT dbcurcmd ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

The number of the command whose results are currently being processed. The first command in a batch is number 1.

Remarks

The command number is incremented every time dbresults returns SUCCEED or FAIL. Unsuccessful commands are counted. The command number is reset by each call to dbsqlexec or dbsqlsend.

See Also

dbcmdrow, dbmorecmds, dbresults, dbrows, dbsqlexec, dbsqlsend


dbcurrow

Returns the number of the row currently being read.

Syntax

DBINT dbcurrow ( PDBPROCESS dproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

The number of the current row.

Remarks

dbcurrow returns the number of the row most recently read by dbgetrow or dbnextrow. When you do not turn on row buffering, dbfirstrow, dbcurrow, and dblastrow always return the same value (the number of the current row).

Use dbgetrow to read rows from the row buffer.

The first row returned from SQL Server is number 1. The row number is changed every time dbnextrow or dbgetrow returns SUCCEED. The row number is reset to 0 by each new call to dbresults.

See Also

dbclrbuf, dbfirstrow, dbgetrow, dblastrow, dbnextrow, dbresults, dbsetopt; DB-Library Options


dbdata

Returns a pointer to the data for a result column.

Syntax

LPCBYTE dbdata (
PDBPROCESS dproc,
INT column );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
column
Is the number of the column. The first column is number 1. For further information, see "dbadata."

Returns

A BYTE pointer to the data for the column. A NULL BYTE pointer is returned if there is no such column or if the data has a null value. To make sure that the data is really a null value, check for a return of 0 from dbdatlen.

Remarks

The data is not null-terminated. To get the length of the data, use dbdatlen.

The dbbind function automatically binds data to your program variables. It is often easier to use than dbdata, but it makes a copy of the data. Call dbdata only after dbnextrow or dbgetrow has returned reg_row.

Example

The following example shows how to use dbdata:

DBPROCESS    *dbproc;
DBINT        row_number = 0;
DBINT        object_id;

// Put the command into the command buffer.
dbcmd(dbproc, "select id from sysobjects");

// Send the command to SQL Server and begin execution.
dbsqlexec(dbproc);

// Process the command results.
dbresults(dbproc);
// Examine the data in each row.
while (dbnextrow(dbproc) != NO_MORE_ROWS)
{
    row_number+;
    object_id = *((DBINT *)dbdata(dbproc, 1));
    printf("row %ld, object id is %ld.\n", row_number, object_id);
}

See Also

dbbind, dbcollen, dbcolname, dbcoltype, dbdatlen, dbnumcols


dbdataready

Determines whether database command processing sent data back to the client is ready to be processed.

Syntax

BOOL dbdataready ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

TRUE if data is available to be read; FALSE otherwise.

Remarks

This function allows an application to continue processing while SQL Server is actually performing the database operation.

The dbdataready function is ordinarily used after a call to dbsqlsend and before a call to dbsqlok. After dbsqlsend, SQL Server begins executing the commands in the command buffer. When dbsqlok is called, Microsoft DB-Library for C waits for SQL Server to finish processing before returning control to the application.

The dbdataready function provides a way to determine when data is available for processing. It should be called repeatedly until it returns a nonzero value. At that point, the application can call dbsqlok, dbresults, dbnextrow.

Important It is possible for dbdataready to return FALSE forever if another process has a conflicting lock or if the connection is broken. The calling program should contain a timeout mechanism.

See Also

dbresults, dbsettime, dbsqlok, dbsqlsend; Building Applications


dbdatecrack

Converts a machine-readable DBDATETIME value into user-accessible format.

Syntax

RETCODE dbdatecrack (
PDBPROCESS dbproc,
LPDBDATEREC dateinfo,
LPCDBDATETIME datetime );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
dateinfo
Is a pointer to the DBDATEREC structure to contain the parts of datetime. DBDATEREC is defined as follows:
typedef struct dbdaterec
{
    int year;            // 1753 - 9999
    int quarter;         // 1 - 4
    int month;           // 1 - 12
    int dayofyear;       // 1 - 366
    int day;             // 1 - 31
    int week;            // 1 - 54 (for leap years)
    int weekday;         // 1 - 7 (Mon. - Sun.)
    int hour;            // 0 - 23
    int minute;          // 0 - 59
    int second;          // 0 - 59
    int millisecond;     // 0 - 999
} DBDATEREC;
datetime
Is a pointer to the DBDATETIME value of interest.

Returns

SUCCEED or FAIL.

Remarks

dbdatecrack converts a DBDATETIME value into its integer components and puts them into a DBDATEREC structure.

DBDATETIME structures store date and time values in an internal format. For example, a time value is stored as the number of 300ths of a second since midnight, and a date value is stored as the number of days since January 1, 1900. The dbdatecrack function converts the internal value to something easily usable by an application.

Example

The following code fragment shows how to use dbdatecrack:

dbcmd(dbproc, "select name, crdate from master..sysdatabases");
dbsqlexec(dbproc);
dbresults(dbproc);

while (dbnextrow(dbproc) != NO_MORE_ROWS)
{
    // Print the database name and its date info
    dbconvert(dbproc,
        dbcoltype(dbproc, 2), dbdata(dbproc, 2),
        dbdatlen(dbproc, 2), SQLCHAR, datestring, -1);
    printf("%s: %s\n", (char *) (dbdata(dbproc, 1)), datestring);

    // Break up the creation date into its constituent parts
    dbdatecrack(dbproc, &dateinfo, (DBDATETIME *) (dbdata(dbproc, 2)));

    // Print the parts of the creation date
    printf("\tYear = &d.\n", dateinfo.year);
    printf("\tMonth = &d.\n", dateinfo.month);
    printf("\tDay of month = &d.\n", dateinfo.day);
    printf("\tDay of year = &d.\n", dateinfo.dayofyear);
    printf("\tDay of week = &d.\n", dateinfo.weekday);
    printf("\tHour = &d.\n", dateinfo.hour);
    printf("\tMinute = &d.\n", dateinfo.minute);
    printf("\tSecond = &d.\n", dateinfo.second);
    printf("\tMillisecond = &d.\n", dateinfo.millisecond);
}

See Also

dbconvert, dbdata


dbdatlen

Returns the actual length, in bytes, of the data for a column.

Syntax

DBINT dbdatlen (
PDBPROCESS dbproc,
INT column );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
column
Is the number of the column. The first column is number 1. For further information, see "dbadata."

Returns

The actual length of the data for the particular column. If the data has a null value, 0 is returned. If the column number is not in range, -1 is returned.

Remarks

The dbcollen function determines the maximum possible length for the data. The data itself is available by calling dbdata. Calling dbdatlen after dbnextrow or dbgetrow returns reg_row.

Example

The following example shows how to use dbdatlen:

DBPROCESS    *dbproc;
DBINT        row_number = 0;
DBINT        data_length;

// Put the command into the command buffer.
dbcmd(dbproc, "select name from sysobjects");

// Send the command to SQL Server and begin execution.
dbsqlexec(dbproc);

// Process the command results.
dbresults(dbproc);

// Examine the data lengths of each row.
while (dbnextrow(dbproc) != NO_MORE_ROWS)
{
    row_number+;
    data_length = dbdatlen(dbproc, 1);
    printf("row %ld, data length is %ld.\n", row_number, data_length);
}

See Also

dbcollen, dbcolname, dbcoltype, dbdata, dbnumcols


dbdead

Determines whether a particular DBPROCESS is inactive.

Syntax

BOOL dbdead ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

TRUE or FALSE.

Remarks

dbdead is particularly useful in user-supplied error handlers.

If a DBPROCESS is inactive, almost every DB-Library function that receives it as a parameter immediately fails, calling the user-supplied error handler. You must close an inactive DBPROCESS connection with dbclose and open a new connection with dbopen.

dbdead usually returns true when a network connection is broken. Note any other errors or messages that you receive.

See Also

dberrhandle; Error Messages


dberrhandle

Supplies a user function to handle DB-Library errors.

Syntax

DBERRHANDLE_PROC dberrhandle ( DBERRHANDLE_PROC handler );

where

handler
Is a pointer to the user function that is called whenever DB-Library determines that an error has occurred. DB-Library calls this function with six parameters:
dbproc
Is the affected DBPROCESS. If there is no DBPROCESS associated with this error, this parameter is NULL.
severity
Is the severity of the error (datatype int). Error severities are defined in SQLFRONT.H.
dberr
Is the identifying number of the error (datatype int). Error numbers are defined in SQLFRONT.H.
oserr
Is the error number that describes the cause of the error (datatype int) and is specific to the operating system or network. If there is no relevant operating system error, the value is DBNOERR.
dberrstr
Is a printable description of dberr (datatype char *).
oserrstr
Is a printable description of oserr (datatype char *).

The error handler must return one of the following three values, directing DB-Library to perform particular actions:

Value | Action
INT_EXIT | Prints an error message and exits the application. DB-Library also returns an error to the operating system. With the Windows operating system, this value is considered an error and is treated as an INT_CANCEL.
INT_CANCEL | Returns FAIL from the DB-Library function that caused the error. For timeout errors (SQLETIME) only, DB-Library will call dbcancel in an attempt to cancel the current command batch and flush any pending results. If this dbcancel attempt also times out, the connection is broken.
INT_CONTINUE | Continues to wait for one additional timeout period, and then calls the error handler again. This return value is meaningful only for timeout errors (SQLETIME). In any other case, this value is considered an error and is treated as an INT_CANCEL.

If the error handler returns any value besides these three, the program continues.

The following example shows a typical error-handling routine:

#include    <sqlfront.h>
#include    <sqldb.h>

int err_handler(dbproc, severity, dberr, oserr, dberrstr, oserrstr)
DBPROCESS    *dbproc;
int            severity;
int            dberr;
int            oserr;
char            *dberrstr;
char            *oserrstr;

{
    printf("DB-Library error:\n\t%s\n", dberrstr);

    if (severity == EXCOMM && (oserr != DBNOERR || oserrstr))
        printf(Net-Lib error %d:  %s\n"' oserr, oserrstr);

    if (oserr != DBNOERR)
        printf("Operating-system error:\n\t%s\n", oserrstr);

    if (dbproc == NULL) || (DBDEAD(dbproc))
        return(INT_EXIT);
    else
        return(INT_CANCEL);
}

Important Do not call any DB-Library functions from within the error handler, because infinite recursive calls to the error handler can result.

Returns

A pointer to the previously installed error handler. This can be NULL.

Remarks

When a DB-Library error occurs, DB-Library immediately calls this error handler. You must install an error handler to handle DB-Library errors properly.

Since the error handler is a call-back function, special consideration is required when compiling these functions for the Windows operating system. For more information, see Building Applications. The user-supplied error handler completely determines the response of DB-Library to any error that occurs. It must tell DB-Library which action to take:

  • Cancel the application.
  • Return an error code.
  • Keep trying (in the case of a timeout error).

If the user does not supply an error handler (or passes a null pointer to dberrhandle), DB-Library exhibits its default error-handling behavior: it returns FAIL from the DB-Library function that caused the error and program execution continues.

Another function, dbmsghandle, installs a message handler that DB-Library calls in response to SQL Server messages. If an application causes messages to occur from DB-Library and SQL Server simultaneously, DB-Library calls the SQL Server message handler before it calls the DB-Library error handler.

The error-handling function should not call any DB-Library functions. Since calls to DB-Library functions can themselves generate errors, calls from within an error handler could result in infinite recursion. If your error handler must call a DB-Library function, it should set the error-handler to a null value, and then restore it when it exits.

The following code fragment shows this technique:

int    err_handler (dbproc, . . .
{
// Set the error handler to NULL to prevent infinite recursion.
dberrhandle(NULL);
// Call other DB_Library functions as necessary.
    .
    .
    .
// Reset the error handler to this function.
dberrhandle(err_handler);
return(. . .
}

See Also

dbmsghandle; Error Messages


dbexit

Closes and frees all DBPROCESS structures created as a result of your application.

Syntax

void dbexit ( void );

Remarks

The dbexit function calls dbclose repeatedly for all open DBPROCESS structures. The dbclose function cleans up any activity associated with a DBPROCESS structure and frees the space.

You can use dbclose directly to close just a single DBPROCESS structure.

See Also

dbclose, dbinit, dbopen


dbfcmd

Adds text to the DBPROCESS command buffer using C run-time library sprintf-type formatting.

Syntax

RETCODE dbfcmd (
PDBPROCESS dbproc,
LPCSTR cmdstring,
... params );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
cmdstring
Is a format string of the form used by the sprintf function.
params
Are optional parameters to dbfcmd. The number of parameters required depends on the number indicated in the cmdstring parameter. The parameters are passed directly to the sprintf function.

Returns

SUCCEED or FAIL.

Remarks

This function adds text to the command buffer in the DBPROCESS structure. The dbfcmd function works just like the C language standard I/O library sprintf function. If you don't need any of the formatting capability of sprintf, use dbcmd instead.

The following table lists the conversions supported by dbfcmd:

Conversion | Program variable type
%c | char
%s | null-terminated string
%d | int
%f | double
%g | double
%e | double
%% | none
%c | char
%x | unsigned hexadecimal integer string
%u | unsigned decimal

The datatype SQLDATETIME must be converted into a character string and passed, using %s. SQLMONEY can be converted to a character string and passed, using %s, or it can be converted to float and passed, using %f.

To include a percent character (%) in the command string, encode it as two percent characters (%%) because dbfcmd calls sprintf, which treats the % character as a format specification. In addition, don't use variables containing strings with apostrophes or single quotation marks because they conflict with the SQL statement syntax if there is any. If you don't need any of the formatting capability of sprintf, you can use dbcmd.

The dbfcmd function manages the space allocation for the command buffer. It adds to the existing command buffer; it doesn't delete or overwrite the current contents except after the buffer has been sent to SQL Server. You can call dbfcmd repeatedly. Note that sequential calls are concatenated: the application must make sure that any necessary blanks appear between the end of one line and the beginning of the next.

After a call to dbsqlexec or dbsqlsend, the first call to either dbcmd or dbfcmd automatically clears the command buffer before the new text is entered. If this situation is undesirable, set the DBNOAUTOFREE option. When DBNOAUTOFREE is set, the command buffer is cleared only by a call to dbfreebuf.

Do not pass dbfcmd null pointers contained in variables.

An application can intermingle calls to dbcmd and dbfcmd.

At any time, an application can access the contents of the command buffer through calls to dbgetchar, dbstrlen, and dbstrcpy.

Available memory is the only constraint on the size of the DBPROCESS command buffer created by calls to dbcmd and dbfcmd.

This function does not support the C datatype long double.

Example

The following example shows how to use dbfcmd to build up a multiple-line SQL command. Please note the leading spaces.

char            *column_name;
DBPROCESS    *dbproc;
int            low_id;
char            *object_type;
char            *tablename;

dbfcmd(dbproc, "Select %s from %s", column_name, tablename);
dbfcmd(dbproc, " where id > %d", low_id);
dbfcmd(dbproc, " and type='%s'", object_type);

Limitations

This function allocates its working buffer dynamically. The size it picks to allocate space is the maximum of a defined constant (1024) and the string length of cmdstring * 2. If the arguments are very big in comparison to the size of cmdstring, DB-Library might not be able to allocate enough space.

See Also

dbcmd, dbfreebuf; Bulk-Copy Functions, and DB-Library Options


dbfirstrow

Returns the number of the first row in the row buffer.

Syntax

DBINT dbfirstrow ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

The number of the first row in the row buffer. The first row returned from SQL Server is number 1. Use this return value when making a call to dbgetrow.

Remarks

If you are not buffering rows, dbfirstrow, dbcurrow, and dblastrow always have the same value: the current row number in the current batch. If you enable buffering by setting the DBBUFFER option, dbfirstrow returns the number of the row that is the first row in the row buffer. For example, if a query returns 100 result rows and you read 20 rows into the buffer using dbnextrow, dbfirstrow returns 1, regardless of which row is current. As the application processes and clears rows from the buffer using dbclrbuf and more data is read from the server using dbnextrow, dbfirstrow returns the number of the result row stored in the lowest (oldest) buffer location.

dblastrow returns the number of the result row stored in the highest (newest) buffer location.

See Also

dbclrbuf, dbcurrow, dbgetrow, dblastrow, dbnextrow, dbsetopt; Bulk-Copy Functions, and DB-Library Options


dbfreebuf

Clears the command buffer.

Syntax

void dbfreebuf ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Remarks

This function frees any space allocated to the command buffer of the DBPROCESS structure. The command buffer is then set to NULL. Commands for SQL Server are added to the command buffer with the dbcmd or dbfcmd function.

After a call to dbsqlexec or dbsqlsend, the first call to either dbcmd or dbfcmd automatically calls dbfreebuf to clear the command buffer before the new text is entered. If this situation is undesirable, set the DBNOAUTOFREE option. When DBNOAUTOFREE is set, the command buffer is cleared only by a call to dbfreebuf.

The contents of the command buffer can be accessed through the dbgetchar, dbstrlen, and dbstrcpy functions.

See Also

dbcmd, dbfcmd, dbgetchar, dbsqlexec, dbsqlsend, dbstrcpy, dbstrlen; Bulk-Copy Functions, and DB-Library Options


dbfreelogin

Frees a login record.

Syntax

void dbfreelogin ( PLOGINREC login );

where

login
Is the pointer to a LOGINREC structure returned from the dblogin function.

Remarks

This function frees the memory allocated by the dblogin function. It can be called immediately after a call to dbopen; however, you can use the same login record for multiple calls to dbopen. Call dbfreelogin when you are completely finished with the login record.

Example

The following example shows how to use dbfreelogin:

DBPROCESS    *dbproc;
LOGINREC    *loginrec;

loginrec = dblogin();
DBSETLUSER(login, "user");
DBSETLPWD(loginrec, "my_password");
DBSETLAPP(loginrec, "my_program");
dbproc = dbopen(loginrec, "my_server");
dbfreelogin (loginrec);

See Also

dblogin, dbopen


dbfreequal

Frees memory allocated by the dbqual function.

Syntax

void dbfreequal ( LPCSTR ptr );

where

ptr
Is a pointer to the memory allocated by the dbqual function.

Remarks

Whenever a successful call to dbqual has been issued, a buffer is dynamically allocated by dbqual. The buffer remains allocated to the application. When the application is finished using the buffer, call dbfreequal to free it.

See Also

dbqual


dbgetchar

Returns a pointer to a character in the command buffer.

Syntax

LPSTR dbgetchar (
PDBPROCESS dbproc,
INT n );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
n
Is the character to find in the command buffer. The first character is the 0th character.

Returns

A pointer to the nth character in the command buffer. If n is not in range, NULL is returned.

Remarks

The dbgetchar function can be used to find a particular character in the command buffer. It returns a pointer to the nth character in the command buffer.

Internally, the command buffer is a linked list of non-null-terminated text strings. Parts of the command buffer can be located and copied using the dbgetchar, dbstrcpy, and dbstrlen functions.

Since the command buffer is not just one large text string, but rather a linked list of text strings, you must use dbgetchar to index through the buffer. If you just get a pointer using dbgetchar and then increment it yourself, it will probably fall off the end of a string.

See Also

dbcmd, dbfcmd, dbfreebuf, dbstrcpy, dbstrlen


dbgetmaxprocs

Determines the current maximum number of simultaneously open DBPROCESS structures.

Syntax

SHORT dbgetmaxprocs ( void );

Returns

An integer representing the current limit on the number of simultaneously open DBPROCESS structures.

Remarks

A DB-Library for C program has a maximum number of simultaneously open DBPROCESS structures. By default, this number is 25. The application program can change this limit by calling dbsetmaxprocs.

See Also

dbopen, dbsetmaxprocs


dbgetoff

Checks for the existence of Transact-SQL statements in the command buffer.

Syntax

INT dbgetoff (
PDBPROCESS dbproc,
DBUSMALLINT offtype,
INT startfrom );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
offtype
Is the type of offset you want to find. The types (defined in the header file SQLFRONT.H) are: OFF_SELECT, OFF_FROM, OFF_ORDER, OFF_COMPUTE, OFF_TABLE, OFF_PROCEDURE, OFF_STATEMENT, OFF_PARAM, and OFF_EXEC

For details, see DB-Library Options.

startfrom
Is the point in the buffer from which to start looking. The command buffer begins at 0.

Returns

The character offset into the command buffer for the specified offset. If the offset is not found, -1 is returned.

Remarks

If the DBOFFSET option has been set (see DB-Library Options), dbgetoff can check for the location of certain Transact-SQL statements in the command buffer.

Examples

In this example, assume that the program doesn't know the contents of the command buffer but needs to know where the SQL keyword SELECT appears:

int        select_offset[10];
int        last_offset;
int        i;

// Set the offset option.
dbsetopt(dbproc, DBOFFSET, "select");

dbsqlexec(dbproc);        // Execute the option on the server  while(dbresults(dbproc)!=NO_MORE_RESULTS); // Read returned results
// Assume the command buffer contains the following SELECTs:
dbcmd(dbproc, "select x = 100 select y = 5");

// Send the query to SQL Server.
dbsqlexec(dbproc);

// Get all the offsets to the SELECT keyword.
for (i = 0, last_offset = 0; last_offset != -1; i+)
if ((last_offset = dbgetoff(dbproc, OFF_SELECT, last_offset))!= -1)
    select_offset[i] = last_offset+;

    dbresults(dbproc);

In this example, select_offset[0] = 0 and select_offset[1] = 15.

The function dbgetoff does not recognize SELECT statements in a subquery. So, if the command buffer contains the following, the second SELECT statement goes unrecognized:

select pub_name
from publishers
where pub_id not in
(select pub_id
from titles
where type = "business")

See Also

dbcmd, dbgetchar, dbsetopt, dbstrcpy, dbstrlen; Bulk-Copy Functions, and DB-Library Options


dbgetpacket

Returns the tabular data stream (TDS) packet size currently in use.

Syntax

UINT dbgetpacket ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

The TDS packet size currently in use.

Remarks

To determine the TDS packet size in use, an application should call dbgetpacket after dbopen.

You can change the TDS packet size by using DBSETLPACKET, which sets the packet size field in the LOGINREC structure.

If the call to dbgetpacket fails (for example, when dbproc is null), dbgetpacket returns 0. Other than the failure case of 0, however, the call should never return less than 512 bytes.

See Also

DBSETLPACKET


dbgetrow

Reads the specified row in the row buffer.

Syntax

STATUS dbgetrow (
PDBPROCESS dbproc,
DBINT row );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
row
Is the number of the row to read. The first row returned from SQL Server is number 1.

Returns

One of four different types of values:

  • If the current row is a regular row, REG_ROW is returned.
  • If the current row is a compute row, the computeid of the row is returned. (For information on the computeid, see "dbaltbind.")
  • If the row is not in the row buffer, NO_MORE_ROWS is returned.
  • If the function was unsuccessful, FAIL is returned.

Remarks

The dbgetrow function sets the current row to a specific row and reads it. This function only works if the DBBUFFER option is on. Any specified binding of row data to program variables takes effect.

When buffering is not turned on, normally each row is processed, in turn, by repeatedly calling dbnextrow until it returns NO_MORE_ROWS. When buffering is turned on, dbgetrow allows the user to jump to any row that has already been read using dbnextrow and is still in the row buffer. Calls to dbnextrow after a dbgetrow call return rows in order, following the row read by dbgetrow.

See Also

dbaltbind, dbbind, dbclrbuf, dbnextrow, Bulk-Copy Functions, and DB-Library Options


dbgettime

Returns the number of seconds that DB-Library waits for SQL Server to respond to a Transact-SQL statement.

Syntax

INT dbgettime ( void );

Returns

The timeout value ¾ the number of seconds that DB-Library waits for a SQL Server response before timing out. A timeout value of 0, the default, represents an infinite timeout period.

Remarks

dbgettime returns the length of time in seconds that DB-Library waits for a SQL Server response during calls to dbsqlexec, dbsqlok, dbresults, and dbnextrow.

The program can call dbsettime to change the timeout value.

See Also

dbnextrow, dbresults, dbsettime, dbsqlexec, dbsqlok


dbgetuserdata

Returns a pointer to user-allocated data from a DBPROCESS structure.

Syntax

LPVOID dbgetuserdata ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

A generic BYTE pointer to the user's private data space. This pointer must have been previously saved with the dbsetuserdata function.

Remarks

The functions dbgetuserdata and dbsetuserdata allow the application to associate user data with a particular DBPROCESS, without using global variables. One use for these functions is to handle deadlock. See the example under dbsetuserdata. That example reruns the transaction when the application's message handler detects deadlock.

This function is particularly useful when the application has more than one DBPROCESS.

See Also

dbsetuserdata


dbinit

Initializes DB-Library.

Syntax

LPCSTR dbinit ( void );

Returns

A null-terminated string containing the version of DB-Library, or null if initialization is unsuccessful.

Remarks

The application should call dbinit once and only once, before calling any other DB-Library functions.

The dbinit function enables dbconvert to use the international settings specified in SQLCOMMN.LOC for Windows or in the Windows NT Registry.

For the Windows operating system, DB-Library retrieves information about date, time, numeric, and currency formatting from the SQLCOMMN.LOC file. The location of SQLCOMMN.LOC is pointed to by the SQLLocalizationFile key in the Windows initialization file (WIN.INI) under the [SQLSERVER] application heading. For example:

[SQLSERVER]
SQLLocalizationFile=C:\SQL60\BIN\SQLCOMMN.LOC

For the Windows NT operating system, you set the date, time, numeric, and currency formatting using the International application in the Control Panel.

Under MS-DOS, dbinit detects the presence of the Net-Library TSR used by DB-Library to communicate over the network. If the TSR is not detected, dbinit returns null and DB-Library functions cannot be used. When running with the Windows environment, DB-Library maintains information about each application that has referenced it. DB-Library creates the information when a library application calls dbinit; it does this to prevent conflicts between applications that use DB-Library concurrently. In order for DB-Library to release this information, the application must call dbwinexit just before it exits.

See Also

dbconvert, dbwinexit


dbisavail

Determines whether a DBPROCESS is available for general use.

Syntax

BOOL dbisavail ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

TRUE if the DBPROCESS is available for general use; FALSE otherwise.

Remarks

dbisavail indicates whether the specified DBPROCESS is available for general use. When a DBPROCESS is first opened, it is marked as being available until it is used. Many DB-Library functions automatically set the DBPROCESS to "not available," but only dbsetavail resets it to "available." This facility is useful when several parts of an application are trying to share a single DBPROCESS.

See Also

dbsetavail


dbiscount

Indicates whether or not the count returned by dbcount is real.

Syntax

BOOL dbiscount ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server. Unlike the functions dbsetopt and dbclropt, dbproc cannot be NULL here.

Returns

TRUE if the count returned by dbcount is real or FALSE if the count returned by dbcount is not real.

Remarks

You can have commands that return or affect 0 or more rows and commands that do not affect rows. In both cases dbcount returns 0.

Calling dbiscount after dbcount determines whether the count is real.

See Also

DBCOUNT


dbisopt

Checks the status of a SQL Server or DB-Library option.

Syntax

BOOL dbisopt (
PDBPROCESS dbproc,
INT option,
LPCSTR param );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server. Unlike the functions dbsetopt and dbclropt, dbproc cannot be NULL here.
option
Is the option to be checked.
param
Is the option parameter. Certain options take parameters. If an option does not take a parameter, param is ignored. If an option does take a parameter, param is ignored for all options except DBOFFSET and DBSTAT.

The DBOFFSET and DBSTAT options can have several settings, each with a different parameter. In these cases, dbisopt needs a valid param to determine which option parameter to check.

For a list of options that take parameters, see DB-Library Options.

Returns

TRUE or FALSE.

Remarks

Although SQL Server options can be set and cleared directly through SQL, the application should use dbsetopt and dbclropt to set and clear options. This provides a uniform interface for setting both SQL Server and DB-Library options. It also allows the application to use the dbisopt function to check the status of an option.

For a list of each option and its default status, see DB-Library Options.

See Also

dbclropt, dbsetopt; Bulk-Copy Functions, and DB-Library Options


dblastrow

Returns the number of the last row in the row buffer.

Syntax

DBINT dblastrow ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

The number of the last row in the row buffer. The first row returned from SQL Server is number 1.

Remarks

If you aren't buffering rows, dbfirstrow, dbcurrow, and dblastrow always have the same value. If you have enabled buffering by setting the DBBUFFER option, dblastrow returns the number of the last row in the row buffer, which might not be the last row available from the server. Use this return value with a call to dbgetrow. For example, if a query returns 100 result rows and you read 20 rows into the buffer using dbnextrow, dblastrow returns 20 regardless of which row is current. As the application processes and clears rows from the buffer using dbclrbuf and more data is read from the server using dbnextrow, dblastrow returns the number of the result row stored in the highest (newest) buffer location.

See Also

dbclrbuf, dbcurrow, dbfirstrow, dbgetrow, dbnextrow, dbsetopt; Bulk-Copy Functions, and DB-Library Options


dblogin

Allocates a LOGINREC structure for use in dbopen.

Syntax

PLOGINREC dblogin ( void );

Returns

A pointer to a LOGINREC structure. NULL is returned if the structure cannot be allocated.

Remarks

DB-Library contains various functions that supply components of the LOGINREC:

Function | Component supplied
DBSTLUSER | Login ID
DBSETLPWD | Password
DBSETLHOST | Workstation name
DBSETLAPP | Application name
DBSETLNATLANG | National language
DBSETLPACKET | TDS packet size
DBSETLSECURE | Secure connection request
DBSETLTIME | Connection-specific timeout
DBSETLVERSION | DB-Library 6.0 behavior
BCP_SETL | Enables bulk copy operations

Generally, it is necessary for the program to supply only the username and password. All components in the LOGINREC are initially set to NULL.

See Also

BCP_SETL, dbfreelogin, dbopen, DBSETLAPP, DBSETLHOST, DBSETLNATLANG, DBSETLPACKET, DBSETLPWD, DBSETLSECURE, DBSETLTIME, DBSETLUSER, DBSETLVERSION


dbmorecmds

Indicates whether there are more commands to be processed.

Syntax

RETCODE dbmorecmds ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

SUCCEED to indicate more results in the command batch; otherwise, FAIL.

Remarks

It should be called after dbnextrow returns NO_MORE_ROWS. If you know that the current command is returning no rows, you can call dbmorecmds after dbresults returns SUCCEED.

You can get the same information by calling dbresults until it returns NO_MORE_RESULTS.

See Also

dbcmdrow, dbnextrow, dbresults, dbrows, dbrowtype


dbmsghandle

Installs a user function to handle SQL Server messages.

Syntax

DBMSGHANDLE_PROC dbmsghandle (DBMSGHANDLE_PROC handler );

where

handler
Is a pointer to the user function that is called whenever DB-Library receives an error or informational message from SQL Server. DB-Library calls this function with these parameters:
dbproc
Is the affected DBPROCESS.
msgno
Is the online message number (datatype DBINT). These numbers are documented in the Microsoft SQL Server Administrator's Companion. They are stored online in the sysmessages table, from which they can be selected.
msgstate
Is the message error state number (datatype int). These numbers provide information about the context of the error.
severity
Is the message information class or error severity (datatype int). These numbers are documented in the Microsoft SQL Server Administrator's Companion.
msgtext
Is the message null-terminated text (datatype char *).
srvname
Is the null-terminated name of the server that generated the message (datatype char *). A server name is stored in the srvname column of its sysservers system table. srvname is optional.
procname
Is the null-terminated name of the stored procedure that generated the message (datatype char *). If the message was not generated by a stored procedure, procname is set to a length of 0. procname is optional.
line
Is the number of the command batch or stored procedure line that generated the message (datatype DBUSMALLINT). Line numbers start at 1.

The line number pertains to the nesting level at which the message was generated. For instance, if a command batch executes stored procedure A, which then calls stored procedure B, and a message is generated at line 3 of B, then the value of line becomes 3.

If no line number is associated with the message, line becomes 0. Circumstances that can generate messages without line numbers include a login error or a call to a remote procedure (through dbrpcsend) to a stored procedure that doesn't exist.

line is optional.

The message handler must return a value of 0 to DB-Library.

Returns

A pointer to the previously installed message handler. This can be NULL.

Remarks

This function installs a message-handling function that you supply. When DB-Library receives a SQL Server error or informational message, it immediately calls this message handler. You must install a message handler to handle SQL Server messages.

Since the message handler is a call-back function, special considerations are required when compiling these functions under the Windows operating system. For more information, see Building Applications.

Note The srvname, procname, and line parameters are optional, and compatibility with previous versions of SQL Server is maintained through the cdecl parameter declaration convention.

Example

The following example shows a typical message-handling function:

#include    <sqlfront.h>
#include    <sqldb.h>

int msg_handler(dbproc, msgno, msgstate, severity, msgtext,
    srvname, procname, line)
DBPROCESS    *dbproc;
DBINT        msgno;
int            msgstate;
int            severity;
char            *msgtext;
char            *srvname;
char            *procname;
DBUSMALLINT    line;

{
    printf("SQL Server message %ld, state %d, "
        "severity %d:\n\t%s\n", msgno, msgstate, severity, msgtext);
    if (strlen(srvname)==0)
        printf ("Server '%s', ", srvname);
    if (strlen(procname)==0)
        printf ("Procedure '%s', ", procname);
    if (line==0)
        printf ("Line %d", line);

 printf("\n\t%s\n", msgtext);
    return(0);
}

See Also

dberrhandle


dbname

Returns the name of the current database.

Syntax

LPCSTR dbname ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

A pointer to the null-terminated name of the current database.

Remarks

If you need to keep track of when the database changes, use dbchange.

See Also

dbchange, dbuse


dbnextrow

Reads in the next row.

Syntax

STATUS dbnextrow ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

One of five different types of values:

  • If a regular row is read, REG_ROW is returned. Regular rows contain data from columns designated by a SELECT statement.
  • If a compute row is read, the computeid of the row is returned. (For information about computeid, see "dbaltbind.")
  • If there are no more rows to be read, if the statement didn't return any rows, or if the server was unable to return more rows (for example, when a deadlock occurs), NO_MORE_ROWS is returned.
  • If buffering is turned on and reading the next row would cause the buffer to be exceeded, BUF_FULL is returned. In this case, no row has been read. To read more rows, first clear at least one row from the top of the row buffer. To clear the row buffer, call dbclrbuf.
  • If the function was unsuccessful, FAIL is returned.

Remarks

The dbnextrow function causes the next data row to be made available through the dbproc. If the DBBUFFER option is turned on and rows have been read out of order by calling dbgetrow, the next data row is read from the buffered rows. Any specified binding of row data to program variables takes effect.

The dbresults function must be called and must have returned SUCCEED before you make any calls to dbnextrow.

Even if dbrows or dbcmdrow returns FAIL (indicating that no rows were returned), you must process the results by calling dbnextrow until it returns NO_MORE_ROWS.

Normally, each row is processed in turn by repeatedly calling dbnextrow. If row buffering is enabled and the row buffer has been cleared by the dbclrbuf function, the discarded rows are no longer available (even if dbgetrow tries to position to a discarded row). When row buffering is disabled, the last row is cleared when dbnextrow returns no_more_rows.

SQL Server can return two types of rows:

  • Regular rows containing data from columns designated by a SELECT statement's select list.
  • Compute rows resulting from the COMPUTE clause.

To help process data rows from SQL Server, dbnextrow returns different values according to the type of row. For details, see the previous section, "Returns."

If you want data returned from SQL Server to be displayed on the default output device, use dbprrow instead of dbnextrow (except with the Windows operating system).

Note This function is one of the four that do not return control to the application until the server sends the required response. The application can be blocked for a considerable time if the server is waiting for a lock or is processing a large sort. If this is unacceptable, always call dbdataready before dbnextrow and set the DB-Library timeout to regain control periodically.

Example

The typical sequence of calls is:

DBINT    xvariable;
DBCHAR    yvariable[10];

// Read the query into the command buffer.
dbcmd(dbproc, "select x = 100, y = 'hello'");

// Send the query to SQL Server.
dbsqlexec(dbproc);

// Get ready to process the results of the query.
dbresults(dbproc);

// Bind column data to program variables.
dbbind(dbproc, 1, INTBIND, (DBINT) 0, (BYTE *)&xvariable);
dbbind(dbproc, 2, STRINGBIND, (DBINT) 0, yvariable);

// Now process each row.
while (dbnextrow(dbproc) != NO_MORE_ROWS)
{
    //    C-code to print or process row data
}

Note that if you are not using row buffering, you must continue calling dbnextrow until it returns NO_MORE_ROWS. This is true even if you are sure that your query only generates one results row. The while loop in the preceding example illustrates the correct way to use dbnextrow.

See Also

dbaltbind, dbbind, dbclrbuf, dbgetrow, dbprrow, dbresults; Bulk-Copy Functions, and DB-Library Options


dbnullbind

Associates an indicator variable with a regular result row column.

Syntax

RETCODE dbnullbind (
PDBPROCESS dbproc,
INT column,
LPCDBINT indicator );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
column
Is the number of the column to be associated with the indicator variable.
indicator
Is a pointer to the indicator variable.

Returns

SUCCEED or FAIL. The function dbnullbind returns FAIL if column is invalid.

Remarks

The indicator variable reveals whether a column in a particular regular result row has been converted and copied to a program variable successfully or unsuccessfully, or whether it is NULL. Call dbnullbind after dbresults has returned SUCCEED and after calling dbbind for column.

The indicator variable is set when regular result rows are processed through dbnextrow. The possible values include:

  • -1 if the column is NULL.
  • The full length of column's data, in bytes, if column was bound to a program variable through dbbind, the binding did not specify any data conversions, and the bound data was truncated because the program variable was too small to hold data for column.
  • 0 if column was bound and copied to a program variable successfully.

Note Only CHARBIND and VARYCHARBIND can detect truncation of character strings.

See Also

dbanullbind, dbbind, dbdata, dbdatlen, dbnextrow


dbnumalts

Returns the number of columns in a compute row.

Syntax

INT dbnumalts (
PDBPROCESS dbproc,
INT computeid );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
computeid
Is the ID that identifies the COMPUTE clause. A SELECT statement can have multiple COMPUTE clauses, which can have varying numbers of aggregate operators and aggregate targets. The computeid is returned by dbnextrow or dbgetrow.

Returns

The number of columns for the particular computeid. If computeid is invalid,
- 1 is returned.

Remarks

Call this function after dbresults has returned SUCCEED.

Example

In this example, dbnumalts(dbproc, 1) returns 3:

select dept, year, sales from employee
order by dept, year
compute avg(sales), min(sales), max(sales) by dept

See Also

dbadata, dbadlen, dbaltlen, dbalttype, dbgetrow, dbnextrow, dbresults


dbnumcols

Determines the number of columns for the current results set.

Syntax

INT dbnumcols ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

The number of columns in the current results set. If there are no columns, 0 is returned. Call dbnumcols after dbresults has returned SUCCEED.

Example

The following program fragment shows how to use dbnumcols:

int        column_count;
DBPROCESS    *dbproc;

// Put the commands into the command buffer
dbcmd(dbproc, "select name, id, type from sysobjects");
dbcmd(dbproc, " select name from sysobjects");

// Send the commands to SQL Server and start execution
dbsqlexec(dbproc);

// Process each command until there are no more
while (dbresults(dbproc) != NO_MORE_RESULTS)
{
    column_count = dbnumcols(dbproc);
    printf("%d columns in this SQL Server result.\n", column_count);
    while (dbnextrow(dbproc) != NO_MORE_ROWS)
        printf("row received.\n");
}

See Also

dbcollen, dbcolname


dbnumcompute

Returns the number of COMPUTE clauses in the current set of results.

Syntax

INT dbnumcompute ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

The number of COMPUTE clauses in the current set of results.

Remarks

Call this function after dbresults has returned SUCCEED.

Example

In this example, dbnumcompute (dbproc) returns 2, since there are two COMPUTE clauses in the SELECT statement:

select dept, name from employee
order by dept, name
compute count(name) by dept
compute count(name)

See Also

dbnumalts, dbresults


dbnumorders

Returns the number of columns specified in a Transact-SQL SELECT statement's ORDER BY clause.

Syntax

INT dbnumorders ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

The number of ORDER BY columns. If there is no ORDER BY clause, dbnumorders returns 0. If there is an error, dbnumorders returns -1.

Remarks

Once a SELECT statement has been executed and dbresults has been called to process it, you can call dbnumorders to find out how many columns were specified in the current statement's ORDER BY clause. Call dbnumorders after dbresults has returned SUCCEED.

See Also

dbordercol, dbresults


dbopen

Allocates and initializes a DBPROCESS connection structure.

Syntax

PDBPROCESS dbopen (
PLOGINREC login,
LPCSTR servername );

where

login
Is a pointer to a LOGINREC structure. You can get one by calling dblogin.
servername
Is the name of the SQL Server that you want to connect to. This parameter can be the name of an actual SQL Server, NULL or a null string to connect to a local SQL Server, or the logical name matching an entry in the WIN.INI file or the Windows NT Registry.

Returns

A DBPROCESS pointer if everything is correct. Ordinarily, NULL is returned if a DBPROCESS structure couldn't be created or initialized, or if your login to SQL Server failed. When NULL is returned, the user-supplied error handler is called to indicate the error.

Note If there is an unexpected communications failure during the SQL Server login process and an error handler has not been installed, the function returns NULL.

Errors

The dbopen function returns NULL if any of the following are true:

Error code | Description
SQLEMEM | Unable to allocate sufficient memory.
SQLEDBPS | Maximum number of DBPROCESS structures already allocated.
SQLECONN | Unable to connect: SQL Server is unavailable or does not exist.
SQLEPWD | Login incorrect.

If the specified server cannot be found, a SQLECONN error is returned to your error handler (if one was registered) after the login timeout expires. For more information on setting the login timeout, see dbsetlogintime.

Remarks

The DBPROCESS structure is the basic data structure that DB-Library uses to communicate with SQL Server. The application needs a DBPROCESS structure to communicate with SQL Server. It is the first parameter in almost every DB-Library call. Besides allocating the DBPROCESS structure, this function sets up communication with the network, logs in to SQL Server, and initializes any default options.

In the call to dbopen, DB-Library uses the server name and connection information in the [SQLSERVER] section of WIN.INI, or the following subtree of the Windows NT Registry:

HKEY_LOCAL_MACHINE\
SOFTWARE\
Microsoft\
MSSQLServer\
Client\
ConnectTo

Use the SQL Client Configuration Utility to configure server name and connection information.

Note also that the SQL Server ODBC driver uses the same Net-Library mechanism as DB-Library.

There can be only one Net-Library TSR loaded for MS-DOS, so there is no .INI file configuration. Environment variables for the name of the server are used to specify any network-specific connection information.

Example

The following example shows how to use dbopen:

DBPROCESS    *dbproc;
LOGINREC    *loginrec;

loginrec = dblogin();
DBSETLUSER(loginrec, "user");
DBSETLPWD(loginrec, "my_password");
DBSETLAPP(loginrec, "my_program");
dbproc = dbopen(loginrec, "my_server");

See Also

dbclose, dbexit, dblogin, dbsetlogintime


dbordercol

Returns the ID of a column appearing in the most recently executed query's ORDER BY clause.

Syntax

INT dbordercol (
PDBPROCESS dbproc,
INT order );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
order
Is the ID that identifies the particular ORDER BY column. The first column named within the ORDER BY clause is number 1.

Returns

The column ID (based on the column's position in the select list) for the column in the specified place in the ORDER BY clause. If the order is invalid, then -1 is returned.

Remarks

Call dbordercol after dbresults has returned SUCCEED.

Example

In this example, dbordercol(dbproc, 1) returns 3 since the first column named in the ORDER BY clause refers to the third column in the SELECT statement:

select dept, name, salary from employee
order by salary, name

See Also

DBNUMORDERS


dbprhead

Prints the column headings for rows returned from SQL Server.

Syntax

void dbprhead ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Remarks

This function displays the column headings for a set of query results on the default output device in a format similar to that used by ISQL.EXE. The format is compatible with the format used by dbprrow. The output width is set at 80 columns.

You can call dbprhead after dbresults has succeeded.

The dbprhead function is useful for debugging.

The dbprhead function is not supported with the Windows operating system.

See Also

dbbind, dbnextrow, dbprrow, dbresults


dbprocerrhandle

Supplies a user function to handle DB-Library errors for a specific DBPROCESS connection.

Syntax

DBERRHANDLE_PROC dbprocerrhandle (
PDBHANDLE pdbhandle,
DBERRHANDLE_PROC error_handler );

where

pdbhandle
Is a DBPROCESS structure or a LOGINREC structure. If this is a DBPROCESS connection, the error_handler will be used for that connection. If this is a LOGINREC structure, the error_handler will automatically be used for all future DBPROCESS connections opened (with dbopen) using the LOGINREC.
error_handler
A pointer to the user function that is called whenever DB-Library determines that an error has occurred for the existing or future connection specified in pdbhandle. Define the connection error handler function in exactly the same way as the application error handler function specified in dberrhandle.

Returns

If pdbhandle is a DBPROCESS structure, a pointer to the previously installed connection error handler is returned. This can be NULL.

If pdbhandle is a LOGINREC structure, a pointer to the newly installed connection error handler is returned, or NULL if this function fails.

Remarks

This function is very similar to the dberrhandle function. While dberrhandle installs an error handler global to the entire DB-Library application, dbprocerrhandle installs an error handler for a specific DBPROCESS connection. You define the connection error handler function in exactly the same way as the application error handler function.

When a DB-Library error occurs using a connection that has a connection error handler (installed using dbprocerrhandle), only the connection error handler is called. The application error handler is not called. Because a connection error handler is associated with a connection and is not global to the entire DB-Library application, the connection error handler code does not need to protect against reentrancy by DB-Library.

Note that this function is not supported for MS-DOS.

See Also

dberrhandle


dbprocinfo

Returns information about a DBPROCESS connection.

Syntax

RETCODE dbprocinfo (
PDBPROCESS pdbproc,
LPDBPROCINFO pdbprocinfo );

where

pdbproc
The DBPROCESS structure that is the handle for a particular workstation/SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
pdbprocinfo
A pointer to a DBPROCINFO structure that DB-Library will fill with information about the specified connection.

The DBPROCINFO structure is defined as follows:

typedef struct
{
    DBINT  SizeOfStruct;
    BYTE   ServerType;
    USHORT ServerMajor;
    USHORT ServerMinor;
    USHORT ServerRevision;
    CHAR   ServerName[MAXSERVERNAME+1];
    CHAR   NetLibName[MAXNETLIBNAME+1];
    CHAR   NetLibConnStr[MAXNETLIBCONNSTR+1];
} DBPROCINFO, PTR LPDBPROCINFO;

The DBPROCINFO fields are described below:
Field | Description
SizeOfStruct | Before calling dbprocinfo, set this field equal to the value returned by the C sizeof function for the DBPROCINFO structure.
ServerType Is one of the following:

SERVTYPE_MICROSOFT if you are connected to a Microsoft SQL Server.

SERVTYPE_UNKNOWN if you are connected to an unknown type of SQL Server.
ServerMajor | Is the XX value in the XX.YY.ZZZ version number of the SQL Server you are connected to. For example, 6.
ServerMinor | Is the YY value in the XX.YY.ZZZ version number of the SQL Server you are connected to. For example, 0.
ServerRevision | Is the ZZZ value in the XX.YY.ZZZ version number of the SQL Server you are connected to. For example, 101.
ServerName | Is the name of the SQL Server you are connected to
NetLibName | Is the name of the Net-Library DLL used to connect to SQL Server.
NetLibConnStr | Is the Net-Library connection string used to connect to SQL Server.

Returns

SUCCEED or FAIL.

Remarks

Before calling dbprocinfo, set the SizeOfStruct field equal to the value returned by the C sizeof function for the DBPROCINFO structure. The dbprocinfo function fills the supplied DBPROCINFO structure with information about the DBPROCESS connection.

See Also

dbopen


dbprocmsghandle

Supplies a user function to handle SQL Server messages for a specific DBPROCESS connection.

Syntax

DBMSGHANDLE_PROC dbprocmsghandle (
PDBHANDLE pdbhandle,
DBMSGHANDLE_PROC message_handler)

where

pdbhandle
Either a DBPROCESS structure or a LOGINREC structure. If this is a DBPROCESS connection, the message_handler will be used for that connection. If this is a LOGINREC structure, the message_handler will automatically be used for all future DBPROCESS connections opened (with dbopen) using the LOGINREC.
message_handler
A pointer to the user function that is called whenever DB-Library receives an error or informational message from SQL Server for the existing or future connection specified in pdbhandle. Define the connection message handler function in exactly the same way as the application message handler function specified in dbmsghandle.

Returns

If pdbhandle is a DBPROCESS, a pointer to the previously installed connection message handler is returned. This can be NULL.

If pdbhandle is a LOGINREC, a pointer to the newly installed connection message handler is returned, or NULL if this function fails.

Remarks

This function is very similar to the dbmsghandle function. While dbmsghandle installs a message handler global to the entire DB-Library application, dbprocmsghandle installs a message handler for a specific DBPROCESS connection. You define the connection message handler function in exactly the same way as the application message handler function.

When DB-Library receives a message from SQL Server using a connection that has a connection message handler (installed using dbprocmsghandle), only the connection message handler is called. The application message handler is not called. Because a connection message handler is associated with a connection and is not global to the entire DB-Library application, the connection message handler code does not need to protect against reentrancy by DB-Library.

Note that this function is not supported for MS-DOS.

See Also

dbmsghandle


dbprrow

Prints all rows returned from SQL Server.

Syntax

RETCODE dbprrow ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

SUCCEED or FAIL.

Remarks

This function displays the rows for a set of query results on the default output device in a format similar to that used by ISQL.EXE. This function reads and prints all the rows. Although it doesn't require allocating program variables to store the data and calling dbbind, the format is predetermined.

This function can be called after dbresults has succeeded.

When using this function, do not call dbnextrow to loop through the rows.

The dbprrow function is useful for debugging. The output line width is set at 80 columns.

This function is not supported with the Windows operating system.

See Also

dbbind, dbnextrow, dbprhead, dbresults


dbprtype

Converts a SQL Server token value to a readable string.

Syntax

LPCSTR dbprtype ( INT token );

where

token
Is the SQL Server token value.

Returns

A pointer to a null-terminated string that is the readable translation of the SQL Server token value. The pointer points to space that is never overwritten, so it is safe to call this function more than once in the same statement. If the token is unknown, the function returns a pointer to an empty string. The strings correspond to SQL Server datatype names.

Remarks

Functions such as dbcoltype and dbalttype return SQL Server token values. To print out what the token value means, use dbprtype.

The following token values are used by dbprtype:

Token value | Datatype
SQLINT1 | tinyint
SQLINT2 | smallint
SQLINT4 | int
SQLMONEY | money
SLQFLT8 | float
SQLDATETIME | datetime
SQLBIT | bit
SQLCHAR | char
SQLVARCHAR | varchar
SQLTEXT | text
SQLBINARY | binary
SQLVARBINARY | varbinary
SQLIMAGE | image
SQLDECIMAL | decimal
SQLNUMERIC | numeric
SQLINTN | integer-null
SQLDATETIMN | datetime-null
SQLMONEYN | money-null
SQLFLTN | float-null
SQLAOPSUM | sum
SQLAOPAVG | avg
SQLAOPCNT | count
SQLAOPMIN | min
SQLAOPMAX | max
SQLDATETIM4 | smalldatetime
SQLMONEY4 | smallmoney
SQLFLT4 | real

See Also

dbaltop, dbalttype, dbcoltype; DB-Library Datatypes; Microsoft SQL Server Transact-SQL Reference


dbresults

Sets up the results of the next query.

Syntax

RETCODE dbresults ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

SUCCEED, FAIL, NO_MORE_RESULTS, or NO_MORE_RPC_RESULTS. The most common reason for failing is a NULL or inactive dbproc. NO_MORE_RPC_RESULTS is returned when stored procedure return information is available from one stored procedure in a batch of multiple stored procedures. from by if there are no more results to be processed. NO_MORE_RESULTS is returned if there are no more results to be processed.

Note This function is one of the four that do not return control to the application until the server sends the required response. The application can be blocked for a considerable time if the server is waiting for a lock or processing a large sort. If this is unacceptable, always call dbdataready before dbresults and set the DB-Library timeout to regain control periodically.

Remarks

This function sets up the next statement in the command batch for processing. It is called after dbsqlexec or dbsqlok returns SUCCEED. The dbresults function returns SUCCEED or NO_MORE_RESULTS on the first call if dbsqlexec or dbsqlok has returned SUCCEED, unless a network error or out-of-memory error has occurred. Once dbresults returns SUCCEED, the user typically processes any rows with dbnextrow.

The dbresults function must be called for each statement in the command batch, whether or not the statement returns any rows. If the application code doesn't know how many statements are in the batch, dbresults can be called until it returns NO_MORE_RESULTS. Ordinarily, call dbresults once for any stored procedure in the command batch. However, if the stored procedure contains more than one Transact-SQL SELECT statement, call dbresults once for each SELECT statement. The easiest way to do this is to continue to call dbresults until it returns no_more_results.

You must call dbresults until it returns no_more_results, or any continued use of the DBPROCESS causes the DB-Library error 10038 "Results Pending."

Example

This example shows the typical sequence of calls when using dbresults with dbsqlexec:

DBINT    xvariable;
DBCHAR    yvariable[10];

// Read the query into the command buffer.
dbcmd(dbproc, "select x = 100, y = 'hello'");

// Send the query to SQL Server.
dbsqlexec(dbproc);
// Get ready to process the results of the query.
dbresults(dbproc);
// Bind column data to program variables.
dbbind(dbproc, 1, INTBIND, (DBINT) 0, (BYTE *) &xvariable);
dbbind(dbproc, 2, STRINGBIND, (DBINT) 0, yvariable);
// Now process each row.
while (dbnextrow(dbproc) != NO_MORE_ROWS)
{
    // C-code to print or process row data
}

See Also

dbbind, dbcancel, dbcanquery, dbnextrow, dbsqlexec, dbsqlok


dbrows

Indicates whether the current statement returned rows.

Syntax

RETCODE dbrows ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

SUCCEED or FAIL.

Remarks

Call dbrows after dbresults returns SUCCEED. Note that dbrows should be called before dbnextrow; otherwise, dbrows returns an incorrect value. Use dbcmdrow to determine whether the current statement can return rows (that is, a Transact-SQL SELECT or EXECUTE statement on a stored procedure containing a SELECT statement).

Even if dbrows returns FAIL, you must still process the results by calling dbnextrow until it returns NO_MORE_ROWS.

See Also

dbcmdrow, dbnextrow, dbresults, dbrowtype


dbrowtype

Returns the type of the current row.

Syntax

STATUS dbrowtype ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

One of four values:

  • If the current row is a regular row, REG_ROW is returned.
  • If the current row is a compute row, the computeid of the row is returned. (For information about computeid, see "dbaltbind.")
  • If no rows have been read, NO_MORE_ROWS is returned.
  • If dbrowtype was unsuccessful, FAIL is returned.

Remarks

Because dbnextrow returns the type (regular or compute) of the current row, you can usually determine the row type without using dbrowtype.

See Also

dbaltbind, dbnextrow


dbserverenum

Searches for the names of SQL Servers locally, over the network, or both.

Syntax

INT dbserverenum (
USHORT searchmode,
LPSTR servnamebuf,
USHORT sizeservnamebuf,
LPUSHORT numentries );

where

searchmode
Defines whether the dbserverenum function checks for server names locally, on the network, or both.

Set searchmode to loc_search to search for the names of servers in the WIN.INI file (Windows) or in the following subtree of the Windows NT Registry:

HKEY_LOCAL_MACHINE\
SOFTWARE\
Microsoft\
MSSQLServer\
Client\
ConnectTo

The loc_search constant has the value 0x0001.

To search for the names of servers registered by the default Net-Library, set searchmode to net_search. The net_search constant has the value 0x0002.

To search both locally and on the network for server names, use a bitwise OR operation (net_search | loc_search) to combine the values of loc_search and net_search. In this case, a server name is duplicated if the server name is defined both locally and on the network.

DB-Library first tries to load the default Net-Library set by the DSQUERY entry in the Windows NT Registry or in the .INI file (Windows). If no default entry exists, DB-Library loads the appropriate named pipe Net-Library.

servnamebuf
Is a pointer to a buffer that stores the server names returned by a search. When the dbserverenum function successfully returns a list of server names, the servnamebuf buffer contains the server names separated by null characters. The end of the list is designated by two consecutive null characters. Only complete server names are copied to the buffer. When a buffer is full and there are additional names that could not be copied to the buffer, dbserverenum returns the value more_data. Server names are returned in non-sorted order; names found using the loc_search constant are returned before those names found using the net_search constant. Note that dbserverenum can return server names even when the SQL Server is not running. Therefore, although a server name is returned in the list of servers, it does not guarantee that you can access the server.
sizeservnamebuf
Specifies the size of the buffer for the server names returned by a successful search. The buffer size limits the maximum number of names that dbserverenum can return in a single call.
numentries
Returns the number of server names copied to the buffer by the current call to dbserverenum.

Returns

The dbserverenum function returns one or more of the following status code constants:

enum_success (0x0000)
Indicates that the search to detect server names succeeded. enum_success can be returned even when no servers are detected (when numentries = 0).
more_data (0x0001)
Indicates that DB-Library has enough memory to service the dbserverenum request but the buffer passed to dbserverenum is not large enough to hold all the names returned. Increasing the size of sizeservnamebuf enables the buffer to hold more server names.
net_not_available (0x0002)
Indicates that the Net-Library DLL is unavailable. A Net-Library DLL might be unavailable because no DLL is found or because the available Net-Library DLL does not support the dbserverenum function. When the searchmode parameter includes the net_search mode, dbserverenum calls the default Net-Library DLL. When searchmode includes both the net_search and loc_search modes (net_search | loc_search), dbserverenum can return both more_data and net_not_available (more_data | net_not_available).
out_of_memory (0x0004)
Indicates that DB-Library cannot allocate enough memory to service the dbserverenum request.
not_supported (0x0008)
Indicates that the capability is not supported by the current Net-Library version or the current server platform.
enum_invalid_param (0x0010)
Indicates that an invalid parameter, such as a null pointer, was passed to the function.

Remarks

Using dbserverenum, you can obtain the names of servers to which you can connect. The dbserverenum function can search for the names of SQL Servers either locally or over the network. For network searches, the Net-Library DLL used must support the dbserverenum function. A Net-Library DLL registers and finds servers on networks for a specific network environment such as LAN Manager - based networks.

When the search mode is set to net_search, dbserverenum calls the default Net-Library DLL (for example, named pipes or Novell® IPX/SPX). Because only one Net-Library DLL can be the default, those servers discernible to the specific Net-Library are enumerated using the net_search parameter. You must add a specific server entry in the Windows NT Registry to use a Net-Library DLL other than the default Net-Library DLL. Servers listed in the Registry are enumerated when the search mode is set to loc_search.

See Also

dbopen


dbsetavail

Marks a DBPROCESS as being available for general use.

Syntax

void dbsetavail ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Remarks

Any subsequent call to DBISAVAIL returns TRUE until some use is made of the DBPROCESS. Many DB-Library functions automatically set the DBPROCESS to "not available." This is useful when many different parts of a program are attempting to share a single DBPROCESS.

See Also

DBISAVAIL


DBSETLAPP

Sets the application name in the LOGINREC structure.

Syntax

RETCODE DBSETLAPP (
PLOGINREC loginrec,
LPCSTR application );

where

loginrec
Is a pointer to a LOGINREC structure, which is passed as a parameter to dbopen. You can get one of these pointers by calling dblogin.
application
Is the application name that will be sent to SQL Server. It must be a null-terminated character string. The maximum length of the string is 30 characters, not including the null-terminating character. SQL Server stores only the first 16 characters and ignores the rest.

Returns

SUCCEED or FAIL.

Remarks

DBSETLAPP sets the application field in the LOGINREC structure. For it to have any effect, it must be called before dbopen. DBSETLAPP is optional. If not called, the application name is set to NULL.

SQL Server uses the application name in its sysprocesses table to help identify your process. If you set the application name, you will see it if you query the sysprocesses table in the master database.

See Also

dblogin, dbopen, DBSETLHOST, DBSETLPWD, DBSETLUSER


DBSETLHOST

Sets the workstation name in the LOGINREC structure.

Syntax

RETCODE DBSETLHOST ( PLOGINREC loginrec, LPCSTR workstation );

where

loginrec
Is a pointer to a LOGINREC structure, which is passed as a parameter to dbopen. You can get one of these pointers by calling dblogin.
workstation
Is the workstation name to be sent to SQL Server. It must be a null-terminated character string. The maximum length of the string is 30 characters, not including the null-terminating character. SQL Server stores only the first 10 characters and ignores the rest.

Returns

SUCCEED or FAIL.

Remarks

For DBSETLHOST to have any effect, call it before dbopen.

The workstation name shows up in the sysprocesses table in the master database, or on the screen if you issue an sp_who command.

Calling DBSETLHOST is not necessary, because if it's not called, DB-Library sets the workstation name to NULL.

See Also

dblogin, dbopen, DBSETLAPP, DBSETLPWD, DBSETLUSER


DBSETLNATLANG

Sets the name of the national language in the LOGINREC structure.

Syntax

RETCODE DBSETLNATLANG (
PLOGINREC loginrec,
LPCSTR language );

where

loginrec
Is a pointer to a LOGINREC structure to be passed as a parameter to dbopen. Execute dblogin to get LOGINREC structures.
language
Is the name of the national language to use. This parameter must be a null-terminated character string.

Returns

SUCCEED or FAIL.

Remarks

To set a language other than the SQL Server default, call DBSETLNATLANG before dbopen. If language support is installed in the server, error messages are returned in the designated national language.

See Also

dblogin, dbopen


dbsetlogintime

Sets the number of seconds that DB-Library waits for SQL Server to respond to a request for a DBPROCESS connection (after calling dbopen).

Syntax

RETCODE dbsetlogintime ( INT seconds );

where

seconds
Is the timeout value ¾ the number of seconds that DB-Library waits for a login response before timing out. A timeout value of 0 represents an infinite timeout period. The default timeout value is 60 seconds.

Returns

SUCCEED or FAIL.

See Also

dberrhandle, dbopen, dbsettime


DBSETLPACKET

Sets the tabular data stream (TDS) packet size in an application's LOGINREC structure.

Syntax

RETCODE DBSETLPACKET (
PLOGINREC login,
USHORT packet_size );

where

loginrec
Is a pointer to the LOGINREC structure to be passed as an argument to dbopen.
packet_size
Is the size requested, in bytes (0 through 65535). The server will set the actual packet size to a value less than or equal to the requested size.

Returns

SUCCEED or FAIL.

Remarks

Tabular data stream (TDS) is an application protocol used for the transfer of requests and request results between clients and servers. TDS data is sent in fixed-size chunks, called "packets." TDS packets have a default size set by SQL Server. If an application does bulk copy operations, or sends or receives large amounts of text or image data, a packet size larger than the default might improve efficiency, since it results in fewer network reads and writes. For large data transfers, a packet size between 4092 and 8192 is usually best. Any larger size can degrade performance.

The only way an application can change the TDS packet size is by using DBSETLPACKET. If DBSETLPACKET is not called, all DBPROCESS connections in an application will use the default size.

Note that when the application logs in to the server, the server sets the TDS packet size for that DBPROCESS connection to be equal to or less than the value of the packet_size parameter. If the server is experiencing space constraints, the packet size is set to a value less than the value of the packet_size parameter. Otherwise, the packet size is equal to the value of this parameter. To determine the packet size that the server has set, call dbgetpacket.

Different DBPROCESS connections in an application can use different packet sizes. To set different packet sizes for DBPROCESS connections, an application can either change the packet size in a single LOGINREC between the dbopen calls that create the DBPROCESS connections, or it can set different packet sizes in multiple LOGINREC structures and use these different LOGINREC structures when creating the DBPROCESS connections.

See Also

dbgetpacket, dblogin, dbopen


DBSETLPWD

Sets the user SQL Server password in the LOGINREC structure.

Syntax

RETCODE DBSETLPWD (
PLOGINREC loginrec,
LPCSTR password );

where

loginrec
Is a pointer to a LOGINREC structure, which is passed as a parameter to dbopen. To get one of these pointers, call dblogin.
password
Is the SQL Server password that is sent to SQL Server. It must be a null-terminated character string. The maximum length of the string is 30 characters, not including the null-terminating character.

Returns

SUCCEED or FAIL.

Remarks

For DBSETLPWD to have any effect, call it before dbopen.

You do not need to call it if the password is a null value.

See Also

dblogin, dbopen, DBSETLAPP, DBSETLHOST, DBSETLUSER


DBSETLSECURE

Sets the secure connection flag in a LOGINREC structure.

Syntax

RETCODE DBSETLSECURE ( PLOGINREC ploginrec );

where

ploginrec
A pointer to a LOGINREC structure, which is passed as a parameter to dbopen. You can get one of these pointers by calling dblogin.

Returns

SUCCEED or FAIL.

Remarks

By setting the secure connection flag in a LOGINREC structure with DBSETLSECURE, the application requests a secure, or trusted, connection to SQL Server. This means that SQL Server will use integrated login security to establish connections made (using dbopen) with this LOGINREC, regardless of the current login security mode at the server. Any login ID or password supplied by DBSETLUSER or DBSETLPWD is ignored.

To use DBSETLSECURE and trusted connections, you must first use xp_grantlogin or SQL Security Manager to grant SQL Server system administrator or user privilege to the appropriate Windows NT - based groups or users. Use xp_revokelogin or SQL Security Manager to revoke SQL Server privileges and stop a user or group from using a trusted connection.

Note that DBSETLSECURE enables trusted connections even when the server is in standard login security mode.

See Also

dblogin, dbopen, DBSETLAPP, DBSETLHOST, DBSETLUSER


DBSETLTIME

Sets the connection-specific connection timeout in a LOGINREC structure.

Syntax

RETCODE DBSETLTIME (
PLOGINREC ploginrec,
DWORD seconds);

where

ploginrec
A pointer to a LOGINREC structure, which is passed as a parameter to dbopen. You can get one of these pointers by calling dblogin.
seconds
The number of seconds that DB-Library waits for a login response from SQL Server before timing out. The following special values are also available:
seconds | Description
TIMEOUT_IGNORE | Use the global connection timeout set using dbsetlogintime.
TIMEOUT_INFINITE | No timeout.
TIMEOUT_MAXIMUM | Maximum DB-Library connection timeout.

Returns

SUCCEED or FAIL.

Remarks

The seconds value overrides the global timeout value set using dbsetlogintime or the default login timeout.

See Also

dblogin, dbopen, DBSETLAPP, DBSETLHOST, dbsetlogintime, DBSETLUSER


DBSETLUSER

Sets the username in the LOGINREC structure.

Syntax

RETCODE DBSETLUSER (
PLOGINREC loginrec,
LPCSTR username );

where

loginrec
Is a pointer to a LOGINREC structure, which is passed as a parameter to dbopen. To get one of these pointers, call dblogin.
username
Is the username that is sent to SQL Server. It must be a null-terminated character string. The maximum length of the string is 30 characters, not including the null-terminating character. SQL Server uses it to determine who is attempting the connection. The SQL Server usernames are defined in the syslogins table in the master database.

Returns

SUCCEED or FAIL.

Remarks

For DBSETLUSER to have any effect, it must be called before dbopen.

See Also

dblogin, dbopen, DBSETLAPP, DBSETLHOST, DBSETLPWD


DBSETLVERSION

Sets the DB-Library client behavior to version 4.2 or version 6.0 behavior in a LOGINREC structure.

Syntax

RETCODE DBSETLVERSION (
PLOGINREC ploginrec,
BYTE version)

where

ploginrec
A pointer to a LOGINREC structure, which is passed as a parameter to dbopen. You can get one of these pointers by calling dblogin.
version
The DB-Library client behavior to use. Must be either DBVER60 to set DB-Library 6.0 behavior or DBVER42 to set DB-Library 4.2 behavior.

Returns

SUCCEED or FAIL.

Remarks

If this function is not called, the default is DB-Library 4.2 behavior.

Using the DBVER60 value means that SQL Server will treat the connection as a DB-Library 6.0 client in every way. SQL Server will:

  • Return decimal and numeric data values
  • Return complete column information (including identity column information) to DB-Library and dbcolinfo

Using the DBVER42 value (or not calling DBSETLVERSION for the LOGINREC) means that SQL Server will treat the connection as a DB-Library 4.2 client. SQL Server will:

  • Convert decimal and numeric data values to float before returning them to the client
  • Return limited, version 4.2 column information (not including identity column information) to DB-Library and dbcolinfo

Note that using DBVER60 is not required to use SQL Server 6.0 server cursors.

See Also

dblogin, dbopen, DBSETLAPP, DBSETLHOST, DBSETLPWD


dbsetmaxprocs

Sets the maximum number of simultaneously open DBPROCESS structures.

Syntax

RETCODE dbsetmaxprocs ( SHORT maxprocs );

where

maxprocs
Is the new limit on simultaneously open DBPROCESS structures for this particular application.

Returns

SUCCEED if the function call is successful, or else FAIL (that is, maxprocs <= 0).

Remarks

A DB-Library application has a maximum number of simultaneously open DBPROCESS structures. Although the default number is 25, the application can change it by calling dbsetmaxprocs.

Similarly, the program can find out what the current limit is by calling dbgetmaxprocs.

The following table shows platform-dependent connection limitations:

Operating system | Maximum number of connections per workstation
Windows | 45 for all SQL Server running applications
MS-DOS | 15

See Also

dbgetmaxprocs, dbopen


dbsetnull

Defines substitution values for use when binding null values.

Syntax

RETCODE dbsetnull (
PDBPROCESS dbproc,
INT bindtype,
INT bindlen,
LPCBYTE bindval );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
bindtype
Is the type of variable binding to which the substitute value applies. (For more information about the different bindtypes, see "dbbind.")
bindlen
Is the length, in bytes, of the substitute value you are supplying. It is ignored in all cases except CHARBIND and BINARYBIND. All the other types are either fixed-length or have a special terminator or embedded byte count that provides the length of the data.
bindval
Is a generic BYTE pointer to the value you want to use as a null value substitution. The dbsetnull function always makes a copy of this data, so you can free this pointer any time after this call.

Returns

SUCCEED or FAIL. The dbsetnull function fails if you give it a null bindval or if the length is smaller than 1 when CHARBIND and BINARYBIND types are used.

Remarks

The dbbind and dbaltbind functions are used to bind returned SQL Server column values to your program variables. Since a null value can be returned, there is a mechanism for defining what values should be substituted for the null value when doing automatic copying of column data to program variables. Associated with each DBPROCESS is a list of substitute values for each of the binding types. The default substitution values are as follows:

Binding type | Default substitution value
TINYBIND | 0
SMALLBIND | 0
INTBIND | 0
BITBIND | 0
CHARBIND | Empty string (padded with blanks)
STRINGBIND | Empty string (padded with blanks, null-terminated)
NTBSTRINGBIND | Empty string (null-terminated)
VARYCHARBIND | Empty string
BINARYBIND | Empty array (padded with zeros)
VARYBINBIND | Empty array
DATETIMEBIND | 8 bytes of zeros
MONEYBIND | $0.00
FLT8BIND | 0.0
FLT4BIND | 0.0
SMALLMONEYBIND | $0.00
SMALLDATETIBIND | 4 bytes of zeros
DECIMALBIND | 0.0
NUMERICBIND | 0.0
SRCDECIMALBIND | 0.0
SRCNUMERICBIND | 0.0

Call dbsetnull to supply your own null substitution values. Whenever you call dbsetnull to change a particular null substitution value, the new value remains in force for that DBPROCESS until you change it with another call to dbsetnull.

The dbconvert function also uses the current null substitution values when it needs to set a destination variable to null.

See Also

dbaltbind, dbbind, dbconvert; DB-Library Datatypes


dbsetopt

Sets a SQL Server or DB-Library option.

Syntax

RETCODE dbsetopt (
PDBPROCESS dbproc,
INT option,
LPCSTR param );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server. If dbproc is NULL, the option is set for all active DBPROCESS structures.
option
Is the option to be set. See DB-Library Options.
param
Is a parameter for an option. Certain options take parameters. For example, the DBOFFSET option takes as its parameter the construct for which offsets are to be returned:

dbsetopt(dbproc, DBOFFSET, "compute")

The DBBUFFER option takes as its parameter the number of rows to be buffered. A parameter of -1 selects the default (currently 100 rows). The syntax is as follows:

dbsetopt(dbproc, DBBUFFER, "500")

Note The param variable must always be a character string enclosed in quotation marks, even in the case of a numeric value, as in the preceding DBBUFFER example.

If the option takes no parameters, param is ignored and may be NULL.

Returns

SUCCEED or FAIL.

This function fails if param is invalid for one of the DB-Library options. However, an invalid param for a SQL Server option does not cause dbsetopt to fail, because such a parameter does not get validated until the command buffer is sent to SQL Server.

Remarks

Although SQL Server options can be set and cleared directly through SQL, the application should use dbsetopt and dbclropt to set and clear options. This provides a uniform interface for setting both SQL Server and DB-Library options. It also allows the application to use the dbisopt function to check the status of an option.

This function does not immediately set the options specified. They are not set until the command buffer is sent to SQL Server (by invoking the dbsqlexec function). An additional result for each option set is returned through the dbresults function. (For information about results returned, see "dbresults.")

For a list of each option and its default status, see DB-Library Options.

See Also

dbclropt, dbisopt, dbresults, dbsqlexec; Bulk-Copy Functions, and DB-Library Options


dbsettime

Sets the number of seconds that DB-Library waits for SQL Server to respond during calls to dbsqlexec, dbsqlok, dbresults, dbnextrow, and dbrpcexec.

Syntax

RETCODE dbsettime ( INT seconds );

where

seconds
Is the timeout value ¾ the number of seconds that DB-Library waits for SQL Server to respond before timing out. The default timeout value of 0 represents an infinite timeout period.

Returns

SUCCEED or FAIL.

Remarks

This function sets the length of time, in seconds, that DB-Library waits for a SQL Server response during calls to dbsqlexec, dbsqlok, dbresults, dbnextrow, and dbrpcexec. The dbsettime function does not override existing network timeout settings.

The dbsettime function can be called at any time during the application ¾ before or after a call to dbopen. It takes effect immediately upon being called.

To set a timeout value for calls to dbopen, use dbsetlogintime.

Note that if an application sends a command to SQL Server using dbsqlexec, control is not returned to the calling application until SQL Server completes the processing of the command. If the application program needs to continue execution while SQL Server is processing the command, it should send the command with dbsqlsend, continue its processing, and then, when it is ready to retrieve the results, call dbsqlok.

The program can call dbgettime for the current timeout value.

See Also

dbdataready, dberrhandle, dbgettime, dbnextrow, dbresults, dbrpcexec, dbsetlogintime, dbsqlexec, dbsqlok, dbsqlsend


dbsetuserdata

Saves, in a DBPROCESS structure, a pointer to user-allocated data.

Syntax

void dbsetuserdata ( PDBPROCESS dbproc, LPVOID ptr );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
ptr
Is a generic BYTE pointer to the user's private data space.

Remarks

The dbsetuserdata function lets an application associate user data with a particular DBPROCESS, eliminating the need for global variables. This function is especially useful when an application has more than one DBPROCESS.

Make sure each application allocates the data that ptr points to. DB-Library never manipulates this data; it merely saves the pointer so the application can use it later.

Example

The following example shows how dbsetuserdata handles deadlock, an occasional occurrence in high-volume applications. For more information about deadlock, see the Microsoft SQL Server Administrator's Companion.

This program fragment sends updates to the SQL Server and reruns the transaction when its message handler detects deadlock:

// Deadlock detection:
// In the DBPROCESS structure, save a pointer to a DBBOOL variable.
// The message handler sets the variable when deadlock occurs.
// The result processing logic checks the variable and resends the
// transaction in case of deadlock.

// Allocate the space for the DBBOOL variable and save it in
// the DBPROCESS structure.

dbsetuserdata(dbproc, malloc(sizeof(DBBOOL)));

// Initialize the variable to FALSE.
*((DBBOOL *) dbgetuserdata(dbproc)) = FALSE;
// Run queries and check for deadlock.
deadlock:

// Did the application get here via deadlock?
// If so, the server has already canceled the transaction.
// Start the application again. In a real application,
// the deadlock handling may need to be somewhat more
// sophisticated. For instance, you may want to keep a
// counter and retry the transaction a fixed number
// of times.

if (*((DBBOOL *) dbgetuserdata(dbproc)) == TRUE)
{
    // Reset the variable to FALSE.
    *((DBBOOL *) dbgetuserdata(dbproc)) = FALSE;
}

// Start the transaction.
dbcmd(dbproc, "begin transaction ");

// Run the first UPDATE command.
dbcmd(dbproc, "update ......");
dbsqlexec(dbproc);
while (dbresults(dbproc) ! = NO_MORE_RESULTS)
{
// application code
}

// Did the application deadlock?
if (*(DBBOOL *) dbgetuserdata(dbproc)) == TRUE)
    goto deadlock;

// Run the second UPDATE command.
dbcmd(dbproc, "update ......");
dbsqlexec(dbproc);
while (dbresults(dbproc) ! = NO_MORE_RESULTS
{
    // application code
}

// Did the application deadlock?
if (*((DBBOOL *) dbgetuserdata(dbproc)) == TRUE)
    goto deadlock;

// No deadlock -- Commit the transaction.
dbcmd(dbproc, "commit transaction");
dbsqlexec(dbproc);
dbresults(dbproc);

// SERVERMSGS
// This is the server message handler. Assume that the dbmsghandle
// function installed it earlier in the application.

servermsgs(dbproc, msgno, msgstate, severity, msgtext, srvname, procname, line)
DBPROCESS    *dbproc;
DBINT        msgno;
int            msgstate;
int            severity;
char            *msgtext;
char            srvname;
char            *procname;
DBUSMALLINT    line;
{

// Is this a deadlock message?
if (msgno = 1205)
{
    // Set the deadlock indicator.
    * ((DBBOOL *) dbgetuserdata(dbproc)) = TRUE;
    return (O);
}

// Normal message handling code here.
}

See Also

dbgetuserdata


dbsqlexec

Sends a command batch to SQL Server.

Syntax

RETCODE dbsqlexec ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

SUCCEED or FAIL. The most common reason for failing is a Transact-SQL syntax error or SQL Server permission violation. Other reasons include incorrect column or table names. The dbsqlexec function also fails if previous results were not processed, if no statement was specified, or if a network connection is broken.

Note that if a series of commands is sent to SQL Server and if one or more of the commands contains syntax errors, SQL Server processes none of the commands, and dbsqlexec returns FAIL.

Remarks

This function sends SQL statements, stored in the command buffer of the DBPROCESS, to SQL Server. Statements can be added to the DBPROCESS structure by calling dbcmd or dbfcmd.

The dbsqlexec function is equivalent to dbsqlsend followed by dbsqlok. However, after sending a query to SQL Server, dbsqlexec waits until it receives a response or until the timeout period has elapsed. If you prefer not to have your application wait, substitute dbsqlsend, dbdataready, and dbsqlok.

Once dbsqlexec has returned SUCCEED, the application must call dbresults to process the results.

Example

This example shows the typical sequence of calls:

DBINT    xvariable;
DBCHAR    yvariable[10];

// Place the query into the command buffer
dbcmd(dbproc, "select x = 100, y = 'hello'");

// Send the command buffer to SQL Server
dbsqlexec(dbproc);

// Get ready to process the results of the query
dbresults(dbproc);

// Bind column data to program variables
dbbind(dbproc, 1, INTBIND, (DBINT) 0, (BYTE *) &xvariable);
dbbind(dbproc, 2, STRINGBIND, (DBINT) 0, yvariable);

// Now process each row
while (dbnextrow(dbproc) != NO_MORE_ROWS)
{
    // C-code to print or process row data
}

See Also

dbcmd, dbfcmd, dbnextrow, dbresults, dbsettime, dbsqlok, dbsqlsend


dbsqlok

Verifies the correctness of a command batch.

Syntax

RETCODE dbsqlok ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

SUCCEED or FAIL. The most common reason for failing is a SQL syntax error.

Remarks

dbsqlok following dbsqlsend is the equivalent of dbsqlexec. This function must be called after dbsqlsend returns SUCCEED. If dbsqlok returns SUCCEED, then dbresults can be called to process the results.

The dbsqlok function is also useful in text update operations. When chunks of text are sent to SQL Server using dbmoretext, dbsqlok must be called before the first call to dbmoretext and after the last call to dbmoretext. For an example of its use in this context, see "dbwritetext."

Note This function is one of the four that do not return control to the application until the server sends the required response. The application can be blocked for a considerable time if the server is waiting for a lock or processing a large sort. If this is unacceptable, always call dbdataready before dbsqlok and set the DB-Library timeout to regain control periodically.

See Also

dbcmd, dbfcmd, dbmoretext, dbnextrow, dbresults, dbsettime, dbsqlexec, dbsqlsend, dbwritetext


dbsqlsend

Sends a command batch to SQL Server and does not wait for a response.

Syntax

RETCODE dbsqlsend ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

SUCCEED or FAIL.

Remarks

This function sends SQL statements, stored in the command buffer of the DBPROCESS, to SQL Server. Statements can be added to the command buffer by calling dbcmd or dbfcmd.

Once dbsqlsend returns SUCCEED, dbsqlok must be called to verify the accuracy of the command batch. Then dbresults can be called to process the results.

This function is particularly useful for multitasking with the Windows operating system.

See Also

dbcmd, dbfcmd, dbnextrow, dbresults, dbsettime, dbsqlexec, dbsqlok; Building Applications


dbstrcpy

Copies a portion of the command buffer in the DBPROCESS structure to a specified memory location.

Syntax

RETCODE dbstrcpy (
PDBPROCESS dbproc,
INT start,
INT numbytes,
LPSTR dest );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
start
Is the character position in the command buffer to start copying from. The first character position is 0. If start is greater than the length of the command buffer, a null terminator is inserted at dest[0].
numbytes
Is the number of characters to copy.
numbytes setting | Result
< 0 | dbstrcpy copies the entire command buffer. It is legal to copy 0 bytes.
= 0 | A null terminator is inserted at dest[0].
> 0 | dbstrcpy copies the number of bytes available and returns SUCCEED.

dest
Is a pointer to the memory location to copy the source string into.

Returns

SUCCEED or FAIL. FAIL is returned if start is a negative number.

Remarks

The copy is null-terminated. The dbstrcpy function assumes that the destination string is large enough to receive the source string. If not, unexpected errors may occur.

Internally, the command buffer is a linked list of non-terminated text strings. Parts of the command buffer can be located and copied using the dbgetchar, dbstrcpy, and dbstrlen functions.

See Also

dbcmd, dbfcmd, dbfreebuf, dbgetchar, dbstrlen


dbstrlen

Returns the length, in characters, of the command buffer.

Syntax

INT dbstrlen ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

The length, in characters, of the command buffer.

Remarks

Internally, the command buffer is a linked list of non-terminated text strings. Parts of the command buffer can be located and copied using the dbgetchar, dbstrcpy, and dbstrlen functions.

See Also

dbcmd, dbfcmd, dbfreebuf, dbgetchar, dbstrcpy


dbuse

Uses a particular database.

Syntax

RETCODE dbuse (
PDBPROCESS dbproc,
LPCSTR dbname );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
dbname
Is a character pointer to a null-terminated string specifying the database name.

Returns

SUCCEED or FAIL.

Remarks

This function executes a Transact-SQL USE statement for the specified database for a particular DBPROCESS. It sets up the statement and calls dbsqlexec and dbresults.

If the USE statement fails because the requested database has not yet completed a recovery process, dbuse continues to send USE statements at 1-second intervals until it either succeeds or encounters some other error.

The function uses the dbproc provided by the caller and its command buffer. Any existing statements in the buffer are lost, and the command buffer is cleared by dbuse when it is finished.

See Also

dbchange, dbname, dbresults, dbsqlexec


dbvarylen

Determines whether the specified data in a regular result column can vary in length.

Syntax

BOOL dbvarylen (
PDBPROCESS dbproc,
INT column );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
column
Is the number of the regular result column of interest. The first column is number 1. For further information, see "dbadata."

Returns

TRUE or FALSE, indicating whether or not the column's data can vary in length. dbvarylen also returns FALSE if the column number is out of range.

This function returns TRUE if:

  • The result column is derived from a database column of type varchar, varbinary, text, or image.
  • The source database column is defined as NULL, meaning that it may contain a null value.

Remarks

Use dbvarylen especially with programs that handle ad hoc queries and that need to be alerted to possible null data or data of variable length. Call dbvarylen only after dbresults returns SUCCEED.

To get a column's datatype, execute dbcoltype.

See Also

dbcollen, dbcolname, dbcoltype, dbdata, dbdatlen, dbnumcols, dbprtype; DB-Library Datatypes


dbwillconvert

Determines whether a specific datatype conversion is available within DB-Library.

Syntax

BOOL dbwillconvert (
INT srctype,
INT desttype );

where

srctype
Is the datatype of the data to be converted. This parameter can be any of the SQL Server datatypes.
desttype
Is the datatype that the source data is to be converted into. This parameter can be any of the SQL Server datatypes.

Returns

TRUE if the datatype conversion is supported; FALSE otherwise.

Remarks

When dbconvert is asked to perform a conversion that it doesn't support, it calls a user-supplied error handler (if any) and returns -1.

The dbconvert function can convert data stored in any of the SQL Server datatypes (not all conversions are allowable):

SQL Server datatype | Program variable type
SQLCHAR | DBCHAR
SQLTEXT | DBCHAR
SQLBINARY | DBBINARY
SQLIMAGE | DBBINARY
SQLINT1 | DBTINYINT
SQLINT2 | DBSMALLINT
SQLINT4 | DBINT
SQLFLT8 | DBFLT8
SQLBIT | DBBIT
SQLMONEY | DBMONEY
SQLDATETIME | DBDATETIME
SQLDATETIM4 | DBDATETIM4
SQLMONEY4 | DBMONEY4
SQLFLT4 | DBFLT4
SQLDECIMAL | DBDECIMAL
SQLNUMERIC | DBNUMERIC

For more information on datatype conversions, see dbconvert.

See Also

dbaltbind, dbbind, dbconvert; DB-Library Options


dbwinexit (Windows only)

Informs DB-Library that the Windows application is about to exit.

Syntax

void dbwinexit ( void );

Remarks

DB-Library for Windows maintains information about each application that has referenced it. DB-Library creates the information when a library application calls dbinit; it does this to prevent conflicts between applications that use DB-Library concurrently. In order for DB-Library to release this information, the application must call dbwinexit just before it exits. You should put the call to dbwinexit within the message handling code for the WM_DESTROY message. For example:

case WM_DESTROY:
    dbwinexit();
    break;

This call releases the memory DB-Library allocated to keep track of this application and makes that memory available to other applications.

Important Once your application has called dbwinexit, it cannot call any other DB-Library function. If you have called dbwinexit and then need to issue one or more DB-Library calls, you must call dbinit again to re-register your application.

See Also

dbinit


Chapter 5 Cursor Functions

Cursor Functions

dbcursor

dbcursorbind

dbcursorclose

dbcursorcolinfo

dbcursorfetch

dbcursorfetchex

dbcursorinfo

dbcursorinfoex

dbcursoropen


dbcursor

Inserts, updates, deletes, locks, or refreshes a particular row in the fetch buffer of a client cursor, a transparent server cursor, or an explicit server cursor.

Syntax

RETCODE dbcursor (
PDBCURSOR hc,
INT optype,
INT row,
LPCSTR table,
LPCSTR values );

where

hc
Is the cursor handle previously returned by dbcursoropen.
optype
Specifies the type of cursor operation to perform on a row or rows in the fetch buffer, as follows:
optype | Description
CRS_DELETE | Deletes row(s).
CRS_INSERT | Inserts a single row using data specified in values.
CRS_LOCKCC Locks row(s).

Client cursor:

An exclusive lock is placed on the data page that contains the specified row. The lock is maintained only if it is inside an open transaction block defined by BEGIN TRANSACTION; the lock is released when the transaction is closed by a COMMIT TRANSACTION or ROLLBACK TRANSACTION statement.

Transparent server cursor, explicit server cursor:

An update intent lock is placed on the data page that contains the specified row. If not inside an open transaction, this lock is released when the next fetch is performed. If inside an open transaction, this lock is released when the transaction is closed.

CRS_REFRESH | Refreshes row(s) by retrieving current row data from SQL Server.
CRS_UPDATE | Updates row(s) using data specified in values.

If the cursor was opened using a concuropt of CUR_READONLY (specified in dbcursoropen), only CRS_REFRESH is valid.

row
Is the row number in the fetch buffer to which the optype operation applies. The first row in the buffer is number 1. The specified row must contain valid row data.

Client cursor, transparent server cursor:

When optype is CRS_REFRESH, a row value of 0 indicates that all rows in the fetch buffer will be refreshed.

Explicit server cursor:

When optype is one of the following values:

  • CRS_DELETE
  • CRS_LOCKCC
  • CRS_REFRESH
  • CRS_UPDATE

a row value of 0 indicates that the optype operation will be performed on all rows in the fetch buffer.

table
Is the table to which the optype operation applies. If optype is CRS_REFRESH use NULL. It must be one of the tables specified in the FROM clause of the SELECT statement (specified in dbcursoropen) that defines the cursor. If the FROM clause includes only one table, this parameter is not required, and you can specify that table or NULL.

Client cursor:

If the FROM clause includes more than one table, this parameter is required unless:

  • optype is CRS_INSERT and values points to a complete INSERT statement
  • optype is CRS_UPDATE and values points to a complete UPDATE statement

Transparent server cursor, explicit server cursor:

If the FROM clause includes more than one table and the dbcursor operation is being performed with an ambiguous column name, this parameter is required. If table is required but not specified, the default is the first table listed in the FROM clause.

values
Is a pointer to a string that contains a Transact-SQL statement or clause, or NULL. This parameter specifies the data to be inserted or updated. The following table lists the valid values parameters for each optype:
optype | values
CRS_DELETE | NULL
CRS_INSERT Can be one of the following:

NULL, indicating that the single row to be inserted will come from the data stored in the bound program variables (pvaraddr and poutlen in dbcursorbind) for the specified row in the fetch buffer. This requires overwriting the values in the bound program variables for an existing row.

A pointer to a string that contains a complete Transact-SQL INSERT statement that specifies the single row to be inserted, with no WHERE clause. The table specified in the INSERT statement overrides the table parameter. The row parameter is ignored.

A pointer to a string that contains just the VALUES clause (from an INSERT statement) that specifies the single row to be inserted. The VALUES keyword is optional, but the list of values to be inserted must be surrounded by parentheses. The row parameter is ignored.
CRS_LOCKCC | NULL
CRS_REFRESH | NULL
CRS_UPDATE Can be one of the following:

NULL, indicating that the changes made to a single row will come from the data stored in the bound program variables (pvaraddr and poutlen in dbcursorbind) for the specified row in the fetch buffer. To do this, the SELECT statement that defines the cursor (specified in dbcursoropen) cannot include an expression (for example, "length 10") or a function (such as CONVERT) in the SELECT list.

A pointer to a string that contains a complete UPDATE statement that specifies the changes made to a single row, with no WHERE clause. The table specified in the UPDATE statement overrides the table parameter. The row parameter is ignored.

A pointer to a string that contains just the SET clause (from an UPDATE statement) that specifies the changes made to a single row. The SET keyword is optional. The row parameter is ignored.

Returns

SUCCEED or FAIL.

This function can fail for the following reasons:

  • The cursor is opened as read only, no updates allowed.
  • A server or connection failure or timeout occurs.
  • You have not been granted permission to update or change the database.
  • DB-Library is out of memory.
  • A trigger in the database caused the INSERT, LOCK, or UPDATE operation to fail.
  • You are using optimistic concurrency control, and the row has changed.

Remarks

Using dbcursor does not affect the current cursor position.

When optype is CRS_UPDATE and the values parameter is not NULL and points to a string that contains the UPDATE statement or SET clause, the bound program variables (pvaraddr and poutlen in dbcursorbind) are automatically refreshed to their newly updated values.

The select list used to define the cursor (specified in dbcursoropen) can contain timestamp or identity columns. When optype is CRS_INSERT or CRS_UPDATE and the values parameter is NULL (indicating that new data is obtained from bound program variables), any read-only columns (including timestamp or identity columns) in the fetch buffer are skipped. Because no attempt is made to change these read-only columns, the insert or update can succeed without receiving errors.

When using CRS_UPDATE, if a change is made to a column that is part of the unique index used to open the cursor, the changed row will:

  • Be missing from a keyset cursor. The next time the changed row is fetched, the row status indicator (pstatus in dbcursoropen) for that row will be FTC_MISSING.
  • Appear in a new position in a dynamic cursor. The new position depends on the new value of the unique index column, and later fetches might retrieve the changed row.

After using CRS_DELETE, deleted rows will be missing from a keyset cursor (later fetches will have a row status of FTC_MISSING), and will disappear from later fetches using dynamic cursors.

Client cursor:

When using CRS_INSERT with a keyset cursor, the inserted row does not appear in the cursor results set, and thus does not appear in later fetches.

Transparent server cursor, explicit server cursor:

When optype is one of the following:

  • CRS_INSERT with a keyset cursor involving only one table
  • CRS_UPDATE to change a column that is part of the unique index used to open the cursor

the inserted or updated row will appear as a new row at the end of the keyset (even if the inserted row does not match the WHERE clause criteria), or it will appear in the position of a missing row if the unique index columns of the inserted or updated row match the unique index columns of the missing row.

See Also

dbcursorbind, dbcursorclose, dbcursorcolinfo, dbcursorfetch, dbcursorinfo, dbcursoropen; Bulk-Copy Functions


dbcursorbind

Binds a column of a client cursor, transparent server cursor, or explicit server cursor to an array of program variables. This array of program variables is filled with result data after every fetch or refresh.

Syntax

RETCODE dbcursorbind (
PDBCURSOR hc,
INT col,
INT vartype,
DBINT varlen,
LPDBINT poutlen,
LPBYTE pvaraddr );

where

hc
Is the cursor handle created by dbcursoropen.
col
Is the column number in the cursor to be bound to a program variable. The first column is number 1.
vartype
Is the bind type used to bind the col column to the pvaraddr array of program variables. This bind type is identical to the vartype parameter of dbbind and uses the same conversion rules. The vartype parameter indicates the program variable datatype of the pvaraddr array elements.

In addition to the dbbind bind types, vartype can be set to NOBIND, indicating that no binding is established for a column. After a fetch:

  • Each element of the pvaraddr array will contain a pointer to the column data for that row, similar to dbdata.
  • Each element of the poutlen array will contain the length of the column data for that row, similar to dbdatlen.
varlen
Is the maximum length, in bytes, of a variable-length datatype. This parameter must be supplied when vartype is one of the following:
  • CHARBIND, VARYCHARBIND
  • STRINGBIND, NTBSTRINGBIND
  • BINARYBIND, VARYBINBIND

This parameter is ignored for fixed-length datatypes (all other vartype values except those given above) and when vartype is NOBIND.

poutlen
Is a pointer to an array of DBINT elements, one element for each row in the fetch buffer. The required number of elements in this array is given below. After a fetch, each element of this array will contain the length of the column data for that row, similar to dbdatlen. A length element value of 0 indicates that the column is NULL.

If poutlen is set to NULL, the lengths are not returned.

Before calling dbcursor to update or insert a row with values from the pvaraddr array of bound program variables, set the corresponding poutlen element (for that row in the fetch buffer) to one of the following values:

  • Set an element to 0 to indicate a NULL value.
  • When vartype is NOBIND, CHARBIND, VARYCHARBIND, BINARYBIND, or VARYBINBIND, set the element to the length, in bytes, of the new column data.
  • When vartype is STRINGBIND or NTBSTRINGBIND, any non-zero value is ignored, and the length of the string is determined by scanning for the null terminator.
  • For fixed-length datatypes, non-zero values are ignored.

Client cursor, transparent server cursor:

The number of elements in this array must equal the nrows parameter of dbcursoropen.

Explicit server cursor:

The maximum number of elements in this array is the nrows parameter of dbcursoropen. Before a fetch is made, the number of elements in this array must be equal to or greater than the nfetchnrows parameter that will be passed to dbcursorfetchex.

pvaraddr
Is a pointer to an array of elements, one element for each row in the fetch buffer. The required number of elements in this array is given below. After a fetch, each element of this array will contain:
  • A copy of the column data for that row, converted as specified by the vartype parameter (similar to dbbind) when vartype is one of the standard dbbind bind types
  • A pointer to the actual column data for that row (similar to dbdata) when vartype is NOBIND

Setting pvaraddr to NULL breaks any existing binding established by a previous call to dbcursorbind for the column.

Client cursor, transparent server cursor:

The number of elements in this array must equal the nrows parameter of dbcursoropen.

Explicit server cursor:

The maximum number of elements in this array is the nrows parameter of dbcursoropen. Before a fetch is made, the number of elements in this array must be equal to or greater than the nfetchnrows parameter that will be passed to dbcursorfetchex.

Returns

SUCCEED or FAIL.

Remarks

If dbcursorbind is called more than once for any column, only the last call will be effective.

See Also

dbcursor, dbcursorclose, dbcursorcolinfo, dbcursorfetch, dbcursorinfo, dbcursoropen; Bulk-Copy Functions


dbcursorclose

Closes the client cursor, transparent server cursor, or explicit server cursor, and releases the memory associated with a cursor handle or connection.

Syntax

RETCODE dbcursorclose ( PDBHANDLE handle );

where

handle
Is a DBPROCESS connection or DBCURSOR cursor handle. Cast handle to a PDBHANDLE value (for example, (PDBHANDLE)mydbproc or (PDBHANDLE)mycursor) to avoid compiler warnings. The following table shows the dbcursorclose operation for each type of handle:
handle | Operation
PDBCURSOR | Closes the specified cursor.
PDBPROCESS | Closes all open cursors using the specified connection.

Returns

SUCCEED or FAIL. If handle is a DBPROCESS connection, and this function returns FAIL, call dbcursorclose again to continue closing all open cursors for the specified connection.

Remarks

After issuing dbcursorclose, the cursor handle should not used.

See Also

dbcursor, dbcursorbind, dbcursorcolinfo, dbcursorfetch, dbcursorinfo, dbcursoropen; Bulk-Copy Functions


dbcursorcolinfo

Returns information about the specified column of a client cursor, transparent server cursor, or explicit server cursor.

Syntax

RETCODE dbcursorcolinfo (
PDBCURSOR hcursor,
INT column,
LPSTR colname,
LPINT coltype,
LPDBINT collen,
LPINT usertype );

where

hcursor
Is the cursor handle created by dbcursoropen.
column
Is the column number in the cursor for which information is to be returned. The first column is number 1.
colname
Is a pointer to the program variable that will contain the name of the column. The program variable should be large enough to accommodate the column name. If colname is set to NULL or -1, the column name is not returned.
coltype
Is a pointer to the program variable that will contain the datatype token of the column. If coltype is set to NULL or -1, the column datatype is not returned.
collen
Is a pointer to the program variable that will contain the maximum length of the column, in bytes. If collen is set to NULL or -1, the maximum column length is not returned.
usertype
Is a pointer to the program variable that will contain the user-defined datatype of the column. If usertype is set to NULL or -1, the column user-defined datatype is not returned.

Returns

SUCCEED or FAIL.

Remarks

Call dbcursorcolinfo after dbcursoropen returns a valid cursor handle. The dbcolinfo function returns more detailed information about a cursor column.

See Also

dbcolinfo, dbcursor, dbcursorbind, dbcursorclose, dbcursorfetch, dbcursorinfo, dbcursoropen


dbcursorfetch

Fetches a block of rows (called the fetch buffer) from a client cursor or transparent server cursor, and stores the rows in the bound program variables established using dbcursorbind. If you are connected to SQL Server 6.0, you should use dbcursorfetchex.

Syntax

RETCODE dbcursorfetch (
PDBCURSOR hc,
INT fetchtype,
INT rownum );

where

hc
Is the cursor handle created by dbcursoropen.
fetchtype
Specifies the type of fetch to execute, changing the position of the fetch buffer within the cursor results set. The following table describes the different fetchtype values:
fetchtype | Description
FETCH_FIRST | Fetches the first block of rows from a dynamic or keyset cursor. The first row of the new fetch buffer is the first row in the cursor results set.
FETCH_NEXT Fetches the next block of rows from a dynamic or keyset cursor. The first row of the new fetch buffer is the row after the last row of the current fetch buffer.

If this is the first fetch using a new cursor, it behaves the same as FETCH_FIRST.
FETCH_PREV | Fetches the previous block of rows from a fully dynamic or keyset cursor. The first row of the new fetch buffer is nrows (specified in dbcursoropen) before the first row of the current fetch buffer.
FETCH_RANDOM | Fetches a block of rows from a keyset cursor. The first row of the new fetch buffer is the specified rownum row in the keyset cursor results set.
FETCH_RELATIVE | Fetches a block of rows from a keyset cursor. The first row of the new fetch buffer is rownum rows before or after the first row of the current fetch buffer.
FETCH_LAST | Fetches the last block of rows from a keyset cursor. The last row of the new fetch buffer is the last row of the cursor results set.

The block of rows retrieved by a fetch is called the fetch buffer. The number of rows in the fetch buffer is determined by the nrows parameter of dbcursoropen.

For a forward-only dynamic cursor (scrollopt is CUR_FORWARD in dbcursoropen), you can use only FETCH_FIRST or FETCH_NEXT.

rownum
Is the specified random or relative row number to use as the first row of the new fetch buffer. Use this parameter only with a fetchtype of FETCH_RANDOM or FETCH_RELATIVE. Specify 0 for any other fetchtype.

When fetchtype is FETCH_RANDOM, the first row of the new fetch buffer is the rownum row (counting forward from the beginning) of the keyset cursor results set. The rownum parameter must be positive.

When fetchtype is FETCH_RELATIVE:

  • A positive rownum means that the first row of the new fetch buffer is rownum rows after the first row of the current fetch buffer.
  • A negative rownum means that the first row of the new fetch buffer is rownum rows before the first row of the current fetch buffer.
  • A rownum of 0 means that all rows in the fetch buffer are refreshed with current data from SQL Server without moving the current cursor position. This is identical to calling dbcursor with optype set to CRS_REFRESH.

Returns

SUCCEED or FAIL.

SUCCEED is returned if every row was fetched successfully. Note that for a keyset cursor, a fetch that results in a missing row will not cause dbcursorfetch to FAIL.

FAIL is returned if at least one of the following is true:

  • A fetchtype of FETCH_RANDOM, FETCH_RELATIVE, or FETCH_LAST was used on a dynamic cursor.
  • A fetchtype other than FETCH_FIRST or FETCH_NEXT was used on a forward-only dynamic cursor.
  • The SQL Server connection is broken or times out.
  • DB-Library is out of memory.

Remarks

Specify the size of the fetch buffer in the nrows parameter of dbcursoropen.

After the fetch, the elements of the array of row status indicators (pstatus in dbcursoropen) are filled with row status values, one for each row in the fetch buffer. Each row status value is a series of fetch status values ORed together. The following table shows the meaning of each row status value:

Fetch status | Description
FTC_SUCCEED | The row was successfully fetched. The array of bound program variables and the array of data length values (specified in dbcursorbind) contain valid data for the row.
FTC_MISSING | The row has been deleted or a unique index column of the row has been changed. Do not use the values in the array of bound program variables and the array of data length values (specified in dbcursorbind) for the row. For keyset cursors, this fetch status can appear at any time. For dynamic cursors, this fetch status can appear only after the current fetch buffer is refreshed.
FTC_ENDOFKEYSET | Is the end of the keyset. This fetch status is set for backward compatibility with "mixed" client cursors used by existing applications.
FTC_ENDOFRESULTS | Is the end of the results set of a dynamic or keyset cursor. Rows in the fetch buffer after this row are invalid and will have a row status indicator of 0; do not use the values in the array of bound program variables and the array of data length values (specified in dbcursorbind) for those rows. If ORed with FTC_SUCCEED, this is the last row in the cursor results set; it contains valid data. If ORed with FTC_MISSING, this is the last row in the cursor results set, but the row is missing. If not ORed with FTC_SUCCEED or FTC_MISSING, this row is invalid.

A row status indicator of 0 means that the row is invalid, and the values in the array of bound program variables and the array of data length values (specified in dbcursorbind) do not contain valid data. This usually happens when the row is before the beginning (first row) or after the end (last row) of the cursor results set.

After the fetch, the elements of the array of bound program variables and the array of data length values (previously specified in dbcursorbind):

  • Are filled with valid data for all rows with a fetch status of FTC_SUCCEED.
  • Contain invalid data for all rows without a fetch status of FTC_SUCCEED.

If no fetches have been performed on a cursor, the current cursor position is before the beginning (first row) of the cursor results set.

After a fetch is complete, the new cursor position is one of the following:

  • The first row of the new fetch buffer, as specified under fetchtype, if the first row of the new fetch buffer stayed within the cursor results set.
  • Adjusted to the first row of the cursor results set if the first row of the new fetch buffer would have been before the first row of the cursor results set and the last row of the new fetch buffer would have stayed within the cursor results set due to a FETCH_PREV operation.
  • Unchanged from the current position if all rows of the new fetch buffer would have been before the first row of the cursor results set, if the first row (and thus all rows) of the new fetch buffer would have been after the last row of the cursor results set, or, if for a keyset cursor, if the first row of the new fetch buffer would have been before the first row of the cursor results set and the last row of the new fetch buffer would have stayed within the cursor results set due to a FETCH_RELATIVE attempt with a negative rownum.

When the new cursor position is unchanged because the first row (and thus all rows) of the new fetch buffer would have been after the last row of the cursor results set, all rows in the fetch buffer are invalid and will not have a fetch status of FTC_SUCCEED. In the case of dynamic cursors, the first row of the fetch buffer will have a fetch status of FTC_ENDOFRESULTS, and later rows will have a row status of 0. In the case of keyset cursors, all rows in the fetch buffer will have a row status of 0.

When the new position of a dynamic cursor is unchanged because all rows of the new fetch buffer would have been before the first row of the cursor results set, all rows in the fetch buffer are invalid and will not have a fetch status of FTC_SUCCEED. The first row of the fetch buffer will have a fetch status of FTC_ENDOFRESULTS, and later rows will have a row status of 0.

When the new cursor position is unchanged and all rows in the fetch buffer are invalid, you can use dbcursor to refresh the rows in the fetch buffer with current data from SQL Server. This will result in valid rows that reflect the current cursor position.

Each call to dbcursorfetch leaves the DBPROCESS available for use with no pending results.

Note This function works with client cursors and transparent server cursors. Do not use both dbcursorfetch and dbcursorfetchex with the same cursor handle. Once one of these functions is used on a specific cursor handle, any attempt to use the other function will return fail.

If rows in the current fetch buffer of a dynamic cursor are deleted, a fetch using a client cursor might behave differently than a fetch using a transparent server cursor.

Client cursor:

When the new position of a dynamic cursor is adjusted to be the first row of the cursor results set (which happens when the first row of the new fetch buffer would have been before the first row of the dynamic cursor results set and the last row of the new fetch buffer would have stayed within the dynamic cursor results set due to a FETCH_PREV operation), some rows at the end of the new fetch buffer might be invalid. Any invalid rows will have a row status indicator of 0.

If rows in the current fetch buffer of a dynamic cursor are deleted, a fetch next or fetch previous might result in a new fetch buffer that skips rows in the cursor results set or includes rows from the current fetch buffer again.

Transparent server cursor:

A fetchtype of FETCH_NEXT or FETCH_PREV using a dynamic cursor is actually mapped to a relative fetch on SQL Server 6.0. Because of this, if the first row in the current fetch buffer is deleted before a FETCH_NEXT (mapped to a forward relative fetch on SQL Server 6.0) is performed, the current cursor position becomes invalid. For more information about the fetch behavior in this case, see dbcursorfetchex.

See Also

dbcursor, dbcursorbind, dbcursorcolinfo, dbcursorclose, dbcursorinfo, dbcursoropen; Bulk-Copy Functions


dbcursorfetchex

Fetches a block of rows (called the fetch buffer) from an explicit server cursor and stores the rows in the bound program variables established using dbcursorbind.

Syntax

RETCODE dbcursorfetchex (
PDBCURSOR hc,
INT fetchtype,
DBINT rownum,
DBINT nfetchrows,
DBINT reserved )

where

hc
Is a PDBCURSOR pointer to a server cursor returned by dbcursoropen.
fetchtype
Specifies the type of fetch to execute, changing the position of the fetch buffer within the cursor results set. The following table describes the different fetchtype values:
fetchtype | Description
FETCH_FIRST | Fetches the first block of rows from a dynamic or keyset cursor. The first row of the new fetch buffer is the first row in the cursor results set.
FETCH_NEXT Fetches the next block of rows from a dynamic or keyset cursor. The first row of the new fetch buffer is the row after the last row of the current fetch buffer.

If this is the first fetch using a new cursor, it behaves the same as FETCH_FIRST.
FETCH_PREV | Fetches the previous block of rows from a fully dynamic or keyset cursor. The first row of the new fetch buffer is nrows (specified in dbcursoropen) before the first row of the current fetch buffer.
FETCH_RANDOM | Fetches a block of rows from a keyset cursor. The first row of the new fetch buffer is the specified rownum row in the cursor results set.
FETCH_RELATIVE | Fetches a block of rows from a dynamic or keyset cursor. The first row of the new fetch buffer is rownum rows before or after the first row of the current fetch buffer.
FETCH_LAST | Fetches the last block of rows from a dynamic or keyset cursor. The last row of the new fetch buffer is the last row of the cursor results set.

The block of rows retrieved by a fetch is called the fetch buffer. The number of rows in the fetch buffer is determined by the nfetchrows parameter.

For a forward-only dynamic cursor (scrollopt is CUR_FORWARD in dbcursoropen), you can only use the FETCH_FIRST, FETCH_NEXT, or FETCH_RELATIVE (with a positive rownum) types.

rownum
Is the specified random or relative row number to use as the first row of the new fetch buffer. Use this parameter only with a fetchtype of FETCH_RANDOM or FETCH_RELATIVE. Specify 0 for any other fetchtype.

When fetchtype is FETCH_RANDOM:

  • A positive rownum means that the first row of the new fetch buffer is the rownum row (counting forward from the beginning) of the cursor results set.
  • A negative rownum means that the first row of the new fetch buffer is rownum rows backward from the end of the cursor results set. Given N rows in the cursor results set, the first row of the new fetch buffer is row N+1+rownum of the cursor results set.

    For example, a rownum of - 1 means the first row of the new fetch buffer is row N (N+1 - 1), or the last row, of the current results set. A rownum of - N means the first row of the new fetch buffer is row 1 (N+1 - N), or the first row, of the current results set.

  • A rownum of 0 means that the first row of the new fetch buffer is before the beginning (first row) of the cursor results set.

When fetchtype is FETCH_RELATIVE:

  • A positive rownum means that the first row of the new fetch buffer is rownum rows after the first row of the current fetch buffer.

    For dynamic cursors, if the first row in the current fetch buffer is deleted before a relative fetch, the current cursor position becomes invalid. Let D be the number of contiguous rows, including the first row, deleted from the beginning of the current fetch buffer. Before executing a relative fetch, the current cursor position is set to before the first non-deleted row (row D+1) in the current fetch buffer.

    In this case, when a relative fetch is performed with a positive rownum, the first row of the new fetch buffer is row rownum+D of the current fetch buffer.

  • A negative rownum means that the first row of the new fetch buffer is rownum rows before the first row of the current fetch buffer.
  • For dynamic cursors, a rownum of 0 means that all the rows in the current fetch buffer are fetched again without moving the current cursor position. This is different from a refresh because the rows in the new fetch buffer can differ from the rows in the current fetch buffer. New rows can appear, and old rows can disappear.

    In the case given above, after D contiguous rows have been deleted from the beginning of the current fetch buffer, when a relative fetch is performed with a rownum of 0, the first row of the new fetch buffer is the first non-deleted row (row D+1) of the current fetch buffer.

    For keyset cursors, a rownum of 0 means that the current fetch buffer is refreshed with current data from SQL Server without moving the current cursor position. This is identical to calling dbcursor with optype set to CRS_REFRESH.

nfetchrows
Is the number of rows in the new fetch buffer. This value must be less than or equal to the nrows parameter specified for this cursor in dbcursoropen. The poutlen and pvaraddr arrays specified in calls to dbcursorbind must have at least nfetchrows elements. If these arrays are not large enough, you must break the existing bindings and then rebind with large enough arrays (at least nfetchrows elements) before calling dbcursorfetchex.

When fetchtype is FETCH_FIRST, an nfetchrows value of 0 means that the new cursor position is set to before the beginning (first row) of the cursor results set.

When fetchtype is FETCH_LAST, an nfetchrows value of 0 means that the new cursor position is set to after the end (last row) of the cursor results set.

reserved
Reserved for future use. Use 0.

Returns

SUCCEED or FAIL.

SUCCEED is returned if every row was fetched successfully. Note that for a keyset cursor, a fetch that results in a missing row will not cause dbcursorfetchex to FAIL.

FAIL is returned if at least one of the following is true:

  • A fetchtype of FETCH_RANDOM was used on a dynamic cursor.
  • A fetchtype other than FETCH_FIRST, FETCH_NEXT, or FETCH_RELATIVE (with a positive rownum) was used on a forward-only dynamic cursor.
  • The SQL Server connection is broken or times out.
  • DB-Library is out of memory.

Remarks

After the fetch, the elements of the array of row status indicators (pstatus in dbcursoropen) are filled with row status values, one for each row in the fetch buffer. Each row status value is a series of fetch status values ORed together. The following table shows the meaning of each row status value:

Fetch status | Description
FTC_SUCCEED | The row was successfully fetched. The array of bound program variables and the array of data length values (specified in dbcursorbind) contain valid data for the row.
FTC_MISSING | The row has been deleted or a unique index column of the row has been changed. Do not use the values in the array of bound program variables and the array of data length values (specified in dbcursorbind) for the row. For keyset cursors, this fetch status can appear at any time. For dynamic cursors, this fetch status can appear only after the current fetch buffer is refreshed.

A row status indicator of 0 means that the row is invalid, and the values in the array of bound program variables and the array of data length values (specified in dbcursorbind) do not contain valid data. This happens when the row is before the beginning (first row) or after the end (last row) of the cursor results set.

After the fetch, the elements of the array of bound program variables and the array of data length values (previously specified in dbcursorbind):

  • Are filled with valid data for all rows with a fetch status of FTC_SUCCEED.
  • Contain invalid data for all rows without a fetch status of FTC_SUCCEED.

If no fetches have been performed on a cursor, the current cursor position is before the beginning (first row) of the cursor results set.

After a fetch is complete, the new explicit server cursor position is one of the following:

  • The first row of the new fetch buffer, as specified under fetchtype, if the first row of the new fetch buffer stayed within the cursor results set.
  • Adjusted to the first row of the cursor results set if the first row of the new fetch buffer would have been before the first row of the cursor results set and the last row of the new fetch buffer would have stayed within the cursor results set.
  • Before the beginning of the cursor results set if all rows of the new fetch buffer are before the first row of the cursor results set, or if any backward fetch (FETCH_PREV or FETCH_RELATIVE with a negative rownum) is performed when the first row of the current fetch buffer is the first row of the cursor results set.
  • After the end of the cursor results set if the first row (and thus all rows) of the new fetch buffer is after the last row of the cursor results set.

When the current cursor position is before the beginning of the cursor, a FETCH_NEXT operation is identical to a FETCH_FIRST operation. When the current cursor position is after the end of the cursor, a FETCH_PREV operation is identical to a FETCH_LAST operation.

Note This function works with explicit server cursors in SQL Server 6.0. Do not use both dbcursorfetchex and dbcursorfetch with the same server cursor handle. Once one of these functions is used on a specific cursor handle, any attempt to use the other function will return fail.

Each call to dbcursorfetch leaves the DBPROCESS available for use with no pending results.

See Also

dbcursor, dbcursorbind, dbcursorcolinfo, dbcursorclose, dbcursorinfo, dbcursoropen; Bulk-Copy Functions


dbcursorinfo

Returns the number of columns and the number of rows in the keyset for a client cursor, a transparent server cursor, or an explicit server cursor. The dbcursorinfoex function returns more detailed information.

Syntax

RETCODE dbcursorinfo (
PDBCURSOR hcursor,
LPINT ncols,
LPDBINT nrows );

where

hcursor
Is the cursor handle created by dbcursoropen.
ncols
Is a pointer to a program variable that will contain the number of columns in the cursor.
nrows
Is a pointer to a program variable that will contain the number of rows in a cursor results set.

Client cursor:

For a keyset cursor, this number is always valid. For a dynamic cursor, this number is valid only if the current fetch buffer contains the last row in the cursor results set; otherwise, - 1 is returned.

Transparent server cursor, explicit server cursor:

For a dynamic cursor, - 1 is returned.

For a keyset cursor, this value can be the number of rows populated if asynchronous population of the cursor results set is incomplete, or the total number of rows in the cursor results set. You can call dbcursorinfoex to determine this.

Returns

SUCCEED or FAIL.

Remarks

Call dbcursorinfoex for more complete information about transparent server cursors and explicit server cursors.

See Also

dbcursor, dbcursorbind, dbcursorclose, dbcursorcolinfo, dbcursorfetch, dbcursorinfoex, dbcursoropen; Bulk-Copy Functions


dbcursorinfoex

Returns information about a client cursor, a transparent server cursor, or an explicit server cursor.

Syntax

RETCODE dbcursorinfoex(
PDBCURSOR hc,
LPDBCURSORINFO pdbcursorinfo )

where

hc
Is a PDBCURSOR pointer to a server cursor returned by dbcursoropen.
pdbcursorinfo
Is a pointer to a DBCURSORINFO structure that DB-Library will fill with information about the specified cursor.

The DBCURSORINFO structure is defined as follows:

typedef struct
{
    DBINT SizeOfStruct;
    ULONG TotCols;
    ULONG TotRows;
    ULONG CurRow;
    ULONG TotRowsFetched;
    ULONG Type;
    ULONG Status;
} DBCURSORINFO, PTR LPDBCURSORINFO;

The DBCURSORINFO fields are described below:
Field | Description
SizeOfStruct | Before calling dbcursorinfoex, set this field equal to the value returned by the C sizeof function for the DBCURSORINFO structure.
TotCols | Is the total number of columns in the cursor.
TotRows Is the total number of rows in the cursor results set.

Client cursor:

For a keyset cursor, this number is always valid. For a dynamic cursor, this number is valid only if the current fetch buffer contains the last row in the cursor results set; otherwise, - 1 is returned.

Transparent server cursor, explicit server cursor:

For a dynamic cursor, - 1 is returned.

For a keyset cursor, if the Status field is CU_FILLING, the asynchronous population of the cursor results set is incomplete, and this value indicates the number of rows populated. If the Status field is CU_FILLED, the cursor results set is completely populated, and this value indicates the total number of rows in the cursor results set.
CurRow Is the row number within the cursor results set of the current cursor position (first row of the fetch buffer). The first row of the cursor results set is number 1.

Client cursor:

This value will be 0.

Transparent server cursor, explicit server cursor:

For a keyset cursor, this value is always valid.

For a dynamic cursor, this value will always be 1 when the current position is within the cursor results set.

This value will be 0 if the current position is before the beginning of the cursor. This value will be - 1 if the current position is after the end of the cursor.
TotRowsFetched | Is the total number of valid rows in the current fetch buffer.
Type Is a bitmap of cursor type, scroll option, and concurrency control information. It is a series of the following values ORed together:

Type:

CU_CLIENT: Client cursor

CU_SERVER: Transparent server cursor or explicit server cursor

Scroll option:

CU_DYNAMIC: Dynamic cursor

CU_FORWARD: Forward-only dynamic cursor

CU_KEYSET: Keyset cursor

CU_INSENSITIVE: Insensitive keyset cursor

CU_MIXED: Mixed-mode cursor (provided for backward compatibility only)

Concurrency control:

CU_READONLY: Read-only concurrency

CU_LOCKCC: Intent to update concurrency

CU_OPTCC: Optimistic concurrency based on timestamp or values

CU_OPTCCVAL: Optimistic concurrency based on values
Status Bitmap of status information. It is a series of the following values ORed together:

Client cursor:

CU_FILLED: All cursors

Transparent server cursor, explicit server cursor:

CU_FILLING: Incomplete asynchronous population of a keyset transparent server cursor or keyset explicit server cursor results set

CU_FILLED: Incomplete asynchronous population of a keyset transparent server cursor or keyset explicit server cursor results set, or the cursor is a dynamic cursor

Returns

SUCCEED or FAIL.

Remarks

Before calling dbcursorinfoex, set the SizeOfStruct field equal to the value returned by the C sizeof function for the DBCURSORINFO structure. The dbcursorinfoex function fills the supplied DBCURSORINFO structure with information about the open server cursor.

See Also

dbcursor, dbcursorbind, dbcursorclose, dbcursorcolinfo, dbcursorfetch, dbcursorinfoex, dbcursoropen; Bulk-Copy Functions


dbcursoropen

Opens a cursor. It is an explicit server cursor if you are connected to SQL Server 6.0 and dbcursorfetchex is used for the first fetch. It is a transparent server cursor if you are connected to SQL Server 6.0 and dbcursorfetch is used for the first fetch. It is a client cursor if you are connected to SQL Server 4.2, or if the DBCLIENTCURSORS option is set, and only dbcursorfetch can be used to fetch rows.

Syntax

PDBCURSOR dbcursoropen (
PDBPROCESS dbproc,
LPCSTR stmt,
INT scrollopt,
INT concuropt,
UINT nrows,
LPDBINT pstatus );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
stmt
Is the SELECT statement that defines a cursor.

Client cursor:

This must be a single SELECT statement. All tables included in the FROM clause must have a unique index.

The SELECT statement cannot contain any of the following:

  • INTO
  • FOR BROWSE
  • COMPUTE
  • UNION
  • COMPUTE BY
  • aggregate function
  • Table alias

If scrollopt is CUR_KEYSET, the SELECT statement can contain the following keywords:

  • ORDER BY
  • HAVING
  • GROUP BY

If the SELECT statement includes a view, the FROM clause must include only a single view (no other tables or views). All base tables included in the FROM clause of the view definition must have a unique index, and the select list must include all unique index columns of the base tables.

Transparent server cursor, explicit server cursor:

This can be a single SELECT statement or the name of a stored procedure that contains only a single SELECT statement.

The SELECT statement (alone or in a stored procedure) cannot contain any of the following keywords:

  • INTO
  • FOR BROWSE
  • COMPUTE

The SELECT statement can contain an ORDER BY clause. If the columns in the ORDER BY clause match the columns of the unique indexes used by the cursor, the cursor will use the scrollopt requested. If they do not match, SQL Server must generate a temporary table, and a CUR_KEYSET cursor will be used if a scrollopt of CUR_FORWARD or CUR_DYNAMIC is requested. This also occurs if the SELECT contains a subquery.

The cursor is automatically opened with a scrollopt of CUR_INSENSITIVE and a concuropt of CUR_READONLY if the SELECT statement contains any of the following:

  • Table with no unique index
  • UNION
  • DISTINCT
  • GROUP BY
  • HAVING
  • aggregate function
  • Outer join

If a stored procedure is used, any input parameters must be constants. Declared variables cannot be used for input parameters. Any output parameters or return values from the stored procedure are ignored.

scrollopt
Is one of the following requested scroll options:
scrollopt Description
CUR_DYNAMIC Dynamic cursor.

Client cursor, transparent server cursor:

The dbcursorfetch function will allow only a fetchtype of FETCH_FIRST, FETCH_NEXT, or FETCH_PREV.

Explicit server cursor:

The dbcursorfetchex function will allow all fetchtype values except FETCH_RANDOM.
CUR_FORWARD Forward-only dynamic cursor.

Client cursor, transparent server cursor:

The dbcursorfetch function will allow only a fetchtype of FETCH_FIRST or FETCH_NEXT.

Explicit server cursor:

The dbcursorfetchex function will allow only a fetchtype of FETCH_FIRST, FETCH_NEXT, or FETCH_RELATIVE with a positive rownum.
CUR_KEYSET Keyset cursor.

The dbcursorfetch and dbcursorfetchex functions will allow all fetchtype values.
CUR_INSENSITIVE Client cursor:

Not supported.

Transparent server cursor, explicit server cursor:

Insensitive keyset cursor. Use a concuropt of READ_ONLY. SQL Server will generate a temporary table, so changes made to the rows by others will not be visible through the cursor.

The dbcursorfetch and dbcursorfetchex functions will allow all fetchtype values.
n > 1 Client cursor:

For backward compatibility with "mixed" client cursors.

Transparent server cursor, explicit server cursor:

Mapped to a CUR_KEYSET cursor.

concuropt
Is one of the following concurrency control options:
concuropt | Description
CUR_READONLY | Read-only cursor. You cannot modify rows in the cursor results set.
CUR_LOCKCC Intent to update locking.

Client cursor:

Places an exclusive lock on the data page that contains each row as it is fetched. The locks are maintained only if it is inside an open transaction block defined by BEGIN TRANSACTION; the locks are released when the transaction is closed by a COMMIT TRANSACTION or ROLLBACK TRANSACTION statement.

Transparent server cursor, explicit server cursor:

Places an update intent lock on the data page that contains each row as it is fetched. If not inside an open transaction, the locks are released when the next fetch is performed. If inside an open transaction, the locks are released when the transaction is closed.
CUR_OPTCC | Optimistic concurrency control using timestamp or values. Changes to a row through the cursor succeed only if the row remains unchanged since the last fetch. Changes are detected by comparing timestamps or by comparing all non-text, non-image values if timestamps are not available.
CUR_OPTCCVAL | Optimistic concurrency control using values. Changes to a row through the cursor succeed only if the row remains unchanged since the last fetch. Changes are detected by comparing all non-text, non-image values.

nrows
Client cursor, transparent server cursor:

Is the number of rows in the fetch buffer filled by calls to dbcursorfetch.

Explicit server cursor:

Is the maximum number of rows in the fetch buffer. The nfetchrows parameter of dbcursorfetchex must be less than or equal to this value.

pstatus
Is a pointer to the array of row status indicators. This array must contain nrows DBINT elements. A row status value is a bitmap of fetch status values ORed together.

Each row in the fetch buffer has a corresponding row status indicator. After a fetch, the status of every row in the fetch buffer is returned in the corresponding element of this array.

Client cursor, transparent server cursor:

For more information about fetch status values, see dbcursorfetch.

Explicit server cursor:

For more information about fetch status values, see dbcursorfetchex.

Returns

A handle to the cursor if the cursor open succeeds. If it fails, NULL is returned. Several errors, such as the following, can cause the cursor to fail:

  • Not enough memory to complete the request. Reduce the number of rows in the keyset cursor results set by using a more limiting WHERE clause, use a dynamic cursor, or reduce the number of rows in the fetch buffer.
  • Tables did not have the required unique indexes.
  • A syntax error occurred or the SELECT statement failed.

Remarks

After dbcursoropen returns a valid cursor handle, you can call dbcursorinfoex and examine the Type field to determine the actual type of cursor that was opened.

With a dynamic cursor, membership of rows in the cursor results set is determined at fetch time, and it can change between each fetch. A row disappears from the cursor results set if it is deleted or if it is updated such that it no longer meets the WHERE clause criteria. A row appears in the cursor results set if it is inserted or updated such that it meets the WHERE clause criteria.

With a keyset cursor, membership and order of rows in the cursor results set is fixed at open time. A row is marked as missing from the cursor results set if it is deleted or if it is updated such that it no longer meets the WHERE clause criteria. A row appears in the cursor results set only if it inserted through a cursor based on a single table.

Multiple cursors (as many as the system's memory allows) can be opened using the same DBPROCESS connection. When cursor functions are called, there should be no commands waiting to be executed or results pending in the DBPROCESS connection.

See Also

dbcursor, dbcursorbind, dbcursorclose, dbcursorcolinfo, dbcursorfetch, dbcursorinfo, dbcursoropen; Bulk-Copy Functions


Chapter 6 Stored Procedure Functions

Stored Procedure Functions

dbhasretstat

dbnumrets

dbretdata

dbretlen

dbretname

dbretstatus

dbrettype

dbrpcexec

dbrpcinit

dbrpcparam

dbrpcsend


dbhasretstat

Determines whether a stored procedure or a remote stored procedure generated a return status number.

Syntax

BOOL dbhasretstat ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

TRUE or FALSE.

Remarks

Status numbers are returned only by stored procedures running on SQL Server version 4.2 or later.

The server returns stored procedure information (including any return status and parameter values) immediately after returning all normal results for that stored procedure. Process the normal results, and then call dbhasretstat after dbresults returns NO_MORE_RPC_RESULTS (for all stored procedures in a batch except the last one) or NO_MORE_RESULTS (for a single stored procedure, or for the last stored procedure in a batch).

The dbretstatus function actually retrieves the status number. Stored procedures that complete normally return a status number of 0.

The order in which the application processes the status number and any return parameter values is unimportant.

See Also

dbnextrow, dbresults, dbretdata, dbretstatus, dbrpcinit, dbrpcparam, dbrpcsend


dbnumrets

Calculates the number of returned parameter values generated by a stored procedure or a remote stored procedure.

Syntax

INT dbnumrets ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

The number of parameter values associated with the most recently executed stored procedure.

Remarks

For more information about stored procedure return parameters, see "dbretdata."

The server returns stored procedure information (including any return status and parameter values) immediately after returning all normal results for that stored procedure. Process the normal results, and then call dbnumrets after dbresults returns NO_MORE_RPC_RESULTS (for all stored procedures in a batch except the last one) or NO_MORE_RESULTS (for a single stored procedure, or for the last stored procedure in a batch).

See Also

dbnextrow, dbresults, dbretdata, dbretlen, dbretname, dbrettype, dbrpcinit, dbrpcparam


dbretdata

Returns a pointer to a return-parameter value generated by a stored procedure or a remote stored procedure.

Syntax

LPCBYTE dbretdata (
PDBPROCESS dbproc,
INT retnum );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
retnum
Is the number of the returned value of interest. The first return value is number 1. Values are returned in the same order as the parameters were originally specified in the stored procedure's CREATE PROCEDURE statement. (Note that the order is not necessarily the same as that specified in the remote stored procedure.) When specifying retnum, non-return parameters are not counted. For example, if the second parameter in a stored procedure is the only return parameter, its retnum is 1, not 2.

Returns

A pointer to the specified return value. If retnum is out of range, dbretdata returns NULL. To determine whether the data really has a null value (and retnum is not merely out of range), check for a return value of 0 from dbretlen.

Remarks

The server returns stored procedure information (including any return status and parameter values) immediately after returning all normal results for that stored procedure. Process the normal results, and then call dbretdata after dbresults returns NO_MORE_RPC_RESULTS (for all stored procedures in a batch except the last one) or NO_MORE_RESULTS (for a single stored procedure, or for the last stored procedure in a batch).

Stored procedures can return values for specified parameters. If the value of one of these parameters is changed within a stored procedure, the new value is returned to the program that called the procedure. This action parallels the pass-by-reference facility available in some programming languages.

To function as a return parameter, a parameter must be declared as such:

  • When a stored procedure is created with CREATE PROCEDURE, the parameter must be declared as OUTPUT.
  • For a stored procedure executed using the Transact-SQL EXECUTE statement, the parameter must be declared as OUTPUT.
  • For a stored procedure executed using DB-Library functions (such as dbrpcinit), when the parameter is added using dbrpcparam, the status bitmask must contain the DBRPCRETURN option.

If a stored procedure is executed using DB-Library functions (such as dbrpcinit), the return parameter values are automatically available to the application. If the stored procedure is invoked with an EXECUTE statement, the return parameter values are available only if the command batch containing the EXECUTE statement uses Transact-SQL local variables, not constants, for the return parameters.

See Also

dbnextrow, dbnumrets, dbresults, dbretlen, dbretname, dbrettype, dbrpcinit, dbrpcparam


dbretlen

Determines the length of a return-parameter value generated by a stored procedure or a remote stored procedure.

Syntax

DBINT dbretlen (
PDBPROCESS dbproc,
INT retnum );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
retnum
Is the number of the returned value of interest. The first return value is number 1. Values are returned in the same order as the parameters were originally specified in the stored procedure's CREATE PROCEDURE statement. (Note that this is not necessarily the same order as that specified in the remote stored procedure.) When specifying retnum, non-return parameters are not counted. For example, if the second parameter in a stored procedure is the only return parameter, its retnum is 1, not 2.

Returns

The length of the specified returned value. If retnum is out of range, dbretlen returns -1. If the return value is null, dbretlen returns 0.

Remarks

For more information about stored procedure return parameters, see "dbretdata."

The server returns stored procedure information (including any return status and parameter values) immediately after returning all normal results for that stored procedure. Process the normal results, and then call dbretlen after dbresults returns NO_MORE_RPC_RESULTS (for all stored procedures in a batch except the last one) or NO_MORE_RESULTS (for a single stored procedure, or for the last stored procedure in a batch).

See Also

dbnextrow, dbnumrets, dbresults, dbretdata, dbretname, dbrettype, dbrpcinit, dbrpcparam


dbretname

Determines the name of a return parameter of a stored procedure or a remote stored procedure.

Syntax

LPCSTR dbretname (
PDBPROCESS dbproc,
INT retnum );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
retnum
Is the number of the returned value of interest. The first return value is number 1. Values are returned in the same order as the parameters were originally specified in the stored procedure's CREATE PROCEDURE statement. (Note that this is not necessarily the same order as that specified in the remote stored procedure.) When specifying retnum, non-return parameters are not counted. For example, if the second parameter in a stored procedure is the only return parameter, its retnum is 1, not 2.

Returns

A pointer to the null-terminated parameter name for the specified return-parameter value. If retnum is out of range, dbretname returns NULL.

Remarks

For more information about stored procedure return parameters, see "dbretdata."

The server returns stored procedure information (including any return status and parameter values) immediately after returning all normal results for that stored procedure. Process the normal results, and then call dbretname after dbresults returns NO_MORE_RPC_RESULTS (for all stored procedures in a batch except the last one) or NO_MORE_RESULTS (for a single stored procedure, or for the last stored procedure in a batch).

See Also

dbnextrow, dbnumrets, dbresults, dbretdata, dbretlen, dbrettype, dbrpcinit, dbrpcparam


dbretstatus

Determines the stored procedure status number returned by a stored procedure or a remote stored procedure.

Syntax

DBINT dbretstatus ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

The return status number for the stored procedure or remote stored procedure.

Remarks

Normally, completed stored procedures return a status number of 0. A RETURN statement in a stored procedure is used for application-specific return status numbers. If a RETURN statement is not used and an error occurs when the stored procedure is executed, SQL Server can return one of the following values:

Value | Description
-1 | Missing object
-2 | Datatype error
-3 | Process was chosen as deadlock victim
-4 | Permission error
-5 | Syntax error
-6 | Miscellaneous user error
-7 | Resource error, such as out of space
-8 | Nonfatal internal problem
-9 | System limit was reached
-10 | Fatal internal inconsistency
-11 | Fatal internal inconsistency
-12 | Table or index is corrupt
-13 | Database is corrupt
-14 | Hardware error

The values -15 through -99 are reserved for future SQL Server expansion.

The dbhasretstat function determines whether the most recently executed stored procedure actually generated a return status number.

The server returns stored procedure information (including any return status and parameter values) immediately after returning all normal results for that stored procedure. Process the normal results, and then call dbretstatus after dbresults returns NO_MORE_RPC_RESULTS (for all stored procedures in a batch except the last one) or NO_MORE_RESULTS (for a single stored procedure, or for the last stored procedure in a batch).

The order in which the application processes the status number and any returned parameter values is unimportant.

See Also

dbhasretstat, dbnextrow, dbresults, dbretdata, dbrpcinit, dbrpcparam, dbrpcsend


dbrettype

Determines the datatype of a return-parameter value generated by a stored procedure or a remote stored procedure.

Syntax

INT dbrettype (
PDBPROCESS dbproc,
INT retnum );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
retnum
Is the number of the returned value of interest. The first return value is number 1. Values are returned in the same order as the parameters were originally specified in the stored procedure's CREATE PROCEDURE statement. (Note that this is not necessarily the same order as that specified in the remote stored procedure.) When specifying retnum, non-return parameters are not counted. For example, if the second parameter in a stored procedure is the only return parameter, its retnum is 1, not 2.

Returns

A token value for the datatype of the specified return value.

Column datatype | Returned constant
char | SQLCHAR
varchar | SQLCHAR
binary | SQLBINARY
varbinary | SQLBINARY
tinyint | SQLINT1
smallint | SQLINT2
int | SQLINT4
real | SQLFLT4
float | SQLFLT8
smallmoney | SQLMONEY4
money | SQLMONEY
decimal | SQLDECIMAL
numeric | SQLNUMERIC
smalldatetime | SQLDATETIM4
datetime | SQLDATETIME

If retnum is out of range, -1 is returned.

Remarks

For more information about stored procedure return parameters, see "dbretdata."

The server returns stored procedure information (including any return status and parameter values) immediately after returning all normal results for that stored procedure. Process the normal results, and then call dbrettype after dbresults returns NO_MORE_RPC_RESULTS (for all stored procedures in a batch except the last one) or NO_MORE_RESULTS (for a single stored procedure, or for the last stored procedure in a batch).

The dbrettype function actually returns an integer token value for the datatype (SQLCHAR, SQLFLT8, and so on). To convert the token value into a readable token string, use dbprtype. For a list of all token values and their equivalent token strings, see dbprtype. For a list of SQL Server datatypes, see Appendix B: DB-Library Datatypes.

See Also

dbnextrow, dbnumrets, dbprtype, dbresults, dbretdata, dbretlen, dbretname, dbrpcinit, dbrpcparam


dbrpcexec

Executes a single stored procedure, a single remote stored procedure, or batch of stored procedures and/or remote stored procedures on SQL Server.

Syntax

RETCODE dbrpcexec ( PDBPROCESS pdbproc );

where

pdbproc
The DBPROCESS structure that is the handle for a particular workstation/SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

SUCCEED or FAIL.

Remarks

After initializing and setting up each stored procedure using dbrpcinit and dbrpcparam, call dbrpcexec to execute the stored procedure or batch of stored procedures on SQL Server. Then call dbsqlok before processing the stored procedure results. dbrpcexec can be faster than dbrpcsend on some networks. For more information about executing stored procedures using DB-Library functions, see "dbrpcinit."

Note This function is one of the five (dbnextrow, dbresults, dbrpcexec, dbsqlexec, dbsqlok) that do not return control to the application until after the server sends the required response. The application can be blocked for a considerable time if the server is waiting for a lock or is processing a large sort. If this is unacceptable, use dbrpcsend and dbsqlok, or set the DB-Library timeout to regain control periodically.

See Also

dbnextrow, dbresults, dbretdata, dbretstatus, dbrpcinit, dbrpcparam, dbsqlok


dbrpcinit

Initializes a stored procedure or a remote stored procedure.

Syntax

RETCODE dbrpcinit (
PDBPROCESS dbproc,
LPCSTR rpcname,
DBSMALLINT options );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
rpcname
Is a pointer to the name of the stored procedure to be invoked.
options
Is a 2-byte bitmask of options for stored procedures. Specify 0 to indicate no options. The following options are available:
Option | Description
DBRPCRECOMPILE | Recompiles a stored procedure before it is executed.
DBRPCRESET | Cancels a single stored procedure or a batch of stored procedures. If rpcname is specified, that new stored procedure is initialized after the cancel is complete.

Returns

SUCCEED or FAIL.

Remarks

An application can execute a single stored procedure, or it can execute a batch containing multiple stored procedures. To execute a single stored procedure, you can use DB-Library functions (such as dbrpcinit) or the Transact-SQL EXECUTE statement. To retrieve the status number and parameter values returned by each stored procedure in a batch, you must use DB-Library functions.

To execute a single stored procedure or a batch of stored procedures using DB-Library functions:
  1. Call dbrpcinit once to initialize a new stored procedure.
  2. Call dbrpcparam for each parameter of the stored procedure that does not have a default value.
  3. Repeat steps 1 and 2 for each stored procedure in the batch.
  4. Call dbrpcsend or dbrpcexec to send the entire stored procedure batch to SQL Server.
  5. Call dbsqlok to wait for SQL Server to start returning results.
  6. Call dbresults to process the results from each stored procedure.

    If dbresults returns SUCCEED, call dbnextrow until it returns NO_MORE_ROWS to process the normal results from the stored procedure.

    If dbresults returns NO_MORE_RPC_RESULTS, and you want to retrieve status number and return parameter information returned by the stored procedure, follow the steps given below.

  7. Repeat step 6 until dbresults returns NO_MORE_RESULTS.
  8. If you want to retrieve status number and return parameter information returned by the last stored procedure in the batch, follow the steps given below.

After dbresults returns NO_MORE_RPC_RESULTS (for all stored procedures in a batch except the last one) or NO_MORE_RESULTS (for a single stored procedure, or for the last stored procedure in a batch), you can retrieve status number and return parameter information for a stored procedure.

To retrieve status number and return parameter information returned by a stored procedure using DB-Library functions:
  • Call dbretstatus and dbhasretstat to retrieve the return status number.
  • Call dbnumrets to determine the number of return parameters.
  • Call dbretdata, dbrettype, dbretlen, and dbretname about retrieve information for each return parameter.

Executing stored procedures with DB-Library functions has some advantages over using an EXECUTE statement:

  • Using DB-Library functions to call a stored procedure passes parameters in their native datatypes; using an EXECUTE statement passes parameters as ASCII characters. Calling stored procedures with DB-Library functions works faster and usually more efficiently than an EXECUTE statement, because neither the application nor the server is required to convert native datatypes into their ASCII equivalents.
  • Using DB-Library functions instead of an EXECUTE statement accommodates return parameters for stored procedures more quickly. With a remote stored procedure, the return parameters are always available to the application by calling dbretdata. (Note, however, that a return parameter must be specified as such when it is first added to the stored procedure through dbrpcparam.)

    If a stored procedure is called with an EXECUTE statement, the return parameter values are available only if the command batch containing the EXECUTE statement uses local variables, rather than constants, as the return parameters. This involves additional parsing each time the command batch is executed.

  • The client application can use DB-Library functions to issue a stored procedure call directly to an Open Data Services server application. The Open Data Services server application will detect this request as a remote stored procedure event. The Open Data Services server application is not required to parse the language buffer to find out what the client is requesting.

Stored procedures executed on the local SQL Server (using the dbproc connection) participate in transactions normally and can be rolled back. Remote stored procedures executed on a remote SQL Server cannot be rolled back.

See Also

dbnextrow, dbresults, dbretdata, dbretstatus, dbrpcparam, dbrpcsend, dbsqlok


dbrpcparam

Adds a parameter to a stored procedure or a remote stored procedure.

Syntax

RETCODE dbrpcparam (
PDBPROCESS dbproc,
LPCSTR paramname,
BYTE status,
INT type,
DBINT maxlen,
DBINT datalen,
LPCBYTE value );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
paramname
Is a pointer to the name of the parameter to be invoked. This name must begin with "@", as do all parameter names within stored procedures. As in the Transact-SQL EXECUTE statement, the name is optional. If no name is used, this parameter should be specified as NULL. In that case, the order of the dbrpcparam calls determines the parameter to which each call refers.
status
Is a 1-byte bitmask of parameter options for stored procedures. The only option currently available is DBRPCRETURN, which signifies that an application designates this parameter as a return parameter. Specify 0 to indicate no options.
type
Is the datatype of the value parameter (such as SQLINT1, SQLCHAR, and so on).
maxlen
For variable-length return parameters (when type is SQLCHAR, SQLBINARY, SQLTEXT, or SQLIMAGE), maxlen is the maximum desired byte length for the value parameter returned from a stored procedure.

Set maxlen to -1 in any of these cases:

  • For fixed-length return parameters (such as when type is SQLINT4).
  • To pass a NULL fixed-length parameter value (such as when type is SQLINT4) to the stored procedure.
  • For parameters that are not designated as return parameters.

Set maxlen to 0 to pass a NULL variable-length parameter value (when type is SQLCHAR, SQLBINARY, SQLTEXT, or SQLIMAGE) to the stored procedure.

datalen
For variable-length return parameters (where type is SQLCHAR, SQLBINARY, SQLTEXT, or SQLIMAGE), datalen is the actual byte length of the value parameter sent to the stored procedure. The byte length should not count any null terminator.

Set datalen to - 1 for non-NULL fixed-length parameters (such as when type is SQLINT4).

Set datalen to 0 to pass a NULL parameter value (fixed or variable length) to the stored procedure.

value
Is a pointer to the program variable containing the stored procedure parameter value itself.

The following table summarizes the required maxlen and datalen values for each type of parameter.
Parameter | maxlen | datalen
Fixed-length | - 1 | - 1
Variable-length | Maximum desired length of return value | Length of input value not counting null terminator
Fixed-length NULL | - 1 | 0
Variable-length NULL | 0 | 0

When specifying a NULL parameter, the actual contents of value is not used, and a NULL parameter is added to the stored procedure. However, when type is SQLDECIMAL or SQLNUMERIC, value must still point to a valid DBDECIMAL or DBNUMERIC structure.

Returns

SUCCEED or FAIL.

Remarks

After initializing a stored procedure using dbrpcinit, you must call dbrpcparam once for each parameter of the stored procedure that does not have a default value. You specify default values for stored procedure parameters in the CREATE PROCEDURE statement. For more information about executing stored procedures using DB-Library functions, see "dbrpcinit."

See Also

dbnextrow, dbresults, dbretdata, dbretstatus, dbrpcinit, dbrpcsend, dbsqlok


dbrpcsend

Sends a single stored procedure, a single remote stored procedure, or batch of stored procedures and/or remote stored procedures to SQL Server to be executed.

Syntax

RETCODE dbrpcsend ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

SUCCEED or FAIL.

Remarks

After initializing and setting up each stored procedure using dbrpcinit and dbrpcparam, call dbrpcsend to send the stored procedure or batch of stored procedures to SQL Server. Then call dbsqlok before processing the stored procedure results. For more information about executing stored procedures using DB-Library functions, see "dbrpcinit."

See Also

dbnextrow, dbresults, dbretdata, dbretstatus, dbrpcinit, dbrpcparam, dbsqlok


Chapter 7 Text and Image Functions

Text and Image Functions

dbmoretext

dbreadtext

dbtxptr

dbtxtimestamp

dbtxtsnewval

dbtxtsput

dbupdatetext

dbwritetext


dbmoretext

Sends part of a text or image value to SQL Server.

Syntax

RETCODE dbmoretext (
PDBPROCESS dbproc,
DBINT size,
LPCBYTE text );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
size
Is the size, in bytes, of the particular part of the text or image value being sent to SQL Server. It is an error to send more text or image bytes to SQL Server than were specified in the call to dbwritetext or dbupdatetext.
text
Is a pointer to the text or image portion to be written.

Returns

SUCCEED or FAIL.

Remarks

This function is used in conjunction with dbwritetext or dbupdatetext to send a large SQLTEXT or SQLIMAGE value to SQL Server in the form of a number of smaller chunks. This is particularly useful with operating systems that cannot allocate extremely long data buffers. A text/image fragment must be shorter than 64K.

After calling dbmoretext for the last time, call dbsqlok.

For an example of dbmoretext, see "dbwritetext."

See Also

dbtxptr, dbtxtimestamp, dbwritetext


dbreadtext

Reads part of a text or image value from SQL Server.

Syntax

DBINT dbreadtext (
PDBPROCESS dbproc,
LPVOID buf,
DBINT bufsize );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
buf
Is a pointer to a caller-allocated buffer that will contain the chunk of text or image data.
bufsize
Is the size, in bytes, of the caller's buffer. This value must be smaller than 64K.

Returns

Returns | Description
>0 | The number of bytes put into the caller's buffer.
0 | The end of a row.
-1 | An error.
NO_MORE_ROWS | All rows read.

Remarks

Use dbreadtext instead of dbnextrow to read SQLTEXT and SQLIMAGE values.

This function takes a large SQLTEXT or SQLIMAGE value from SQL Server and breaks it into several smaller chunks. A buffer cannot be larger than 64K although the text or image value can be much larger.

To read successive chunks of the same SQLTEXT or SQLIMAGE value, call dbreadtext until it returns 0 (end of row).

The dbreadtext function processes the results of Transact-SQL queries if those queries return only one column containing either text or image data. The Transact-SQL READTEXT statement returns results of this type.

See Also

dbmoretext, dbnextrow, dbwritetext; Bulk-Copy Functions


dbtxptr

Returns the value of the text or image pointer for a column in the current row.

Syntax

LPCDBBINARY dbtxptr (
PDBPROCESS dbproc,
INT column );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
column
Is the number of the column. The first column in a table is number 1. For further information, see "dbadata."

Returns

A DBBINARY pointer to the text or image pointer for the column. This pointer can be NULL.

Remarks

Every database column of type SQLTEXT or SQLIMAGE has an associated text pointer that uniquely identifies the text or image value. Use this text pointer with dbwritetext. Call dbtxptr only after dbnextrow or dbgetrow has returned reg_row.

Important Do not modify this identifier in any way. Modifying the identifier can cause unpredictable results.

Text pointers are of fixed length and can be NULL when the text or image value is NULL.

See Also

dbreadtext, dbtxtimestamp, dbwritetext


dbtxtimestamp

Returns the value of the text timestamp for a column in the current row.

Syntax

LPCDBBINARY dbtxtimestamp (
PDBPROCESS dbproc,
INT column );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
column
Is the number of the column. The first column in a table is number 1. For further information, see "dbadata."

Returns

A DBBINARY pointer to the text timestamp for the column. This pointer can be NULL when the text or image value is null, or when there is no current row.

Important Do not modify this identifier in any way. Modifying the identifier can cause unpredictable results.

Remarks

Every database column of type SQLTEXT or SQLIMAGE has an associated text timestamp, which marks the time of the column's last modification. Use the text timestamp with dbwritetext to ensure that one user doesn't inadvertently overwrite another's modifications to the same value in the database. The text timestamp is returned to the DBPROCESS when a Transact-SQL SELECT statement is performed on a SQLTEXT or SQLIMAGE column.

The length of a non-NULL text timestamp is always DBTXTSLEN (currently defined as eight bytes). Call dbtxtimestamp only after dbnextrow or dbgetrow has returned reg_row.

See Also

dbreadtext, dbtxptr, dbwritetext


dbtxtsnewval

Returns the new value of a text timestamp after a call to dbwritetext.

Syntax

LPCDBBINARY dbtxtsnewval ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

A pointer to the new text timestamp value for the SQLTEXT or SQLIMAGE value modified by a dbwritetext operation. This pointer can be NULL.

Important Do not modify this identifier in any way. Modifying the identifier can cause unpredictable results.

Remarks

Every database column of type SQLTEXT or SQLIMAGE has an associated text timestamp, which is updated whenever the column's value is changed. Use the text timestamp with dbwritetext to ensure that one user doesn't inadvertently overwrite another's modifications to the same value in the database. It is returned to the DBPROCESS when a Transact-SQL SELECT statement is performed on a SQLTEXT or SQLIMAGE column and can be examined by calling dbtxtimestamp.

After each successful dbwritetext operation (which can include a number of calls to dbmoretext), SQL Server sends the updated text timestamp value back to DB-Library. The dbtxtsnewval function lets the application get this new timestamp value. The application can then use dbtxtsput to put the new timestamp value in the DBPROCESS for future access through dbtxtimestamp.

The application can use dbtxtsnewval in two ways. First, the return from dbtxtsnewval can be used as the timestamp parameter of a dbwritetext call. Second, dbtxtsnewval and dbtxtsput can be used together to put the new timestamp value into the DBPROCESS row buffer for future access using dbtxtimestamp. This is particularly useful when the application is buffering result rows and does not need the new timestamp immediately.

See Also

dbmoretext, dbreadtext, dbtxtimestamp, dbtxtsput, dbwritetext


dbtxtsput

Puts the new value of a text timestamp into the specified column of the current row in the DBPROCESS.

Syntax

RETCODE dbtxtsput (
PDBPROCESS dbproc,
LPCDBBINARY newtxts,
INT colnum );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
newtxts
Is a pointer to the new text timestamp value. It is returned by dbtxtsnewval.
colnum
Is the number of the column associated with this text timestamp. Column numbers start at 1.

Returns

SUCCEED or FAIL.

Remarks

Every database column of type SQLTEXT or SQLIMAGE has an associated text timestamp, which is updated whenever the column's value is changed. Use the text timestamp with dbwritetext to ensure that one user doesn't inadvertently overwrite another's modifications to the same value in the database. It is returned to the DBPROCESS when a Transact-SQL SELECT statement is performed on a SQLTEXT or SQLIMAGE column and can be examined by calling dbtxtimestamp. Call dbtxtsput only after dbnextrow or dbgetrow has returned reg_row.

After each successful dbwritetext operation (which can include a number of calls to dbmoretext), SQL Server sends the updated text timestamp value back to DB-Library. The dbtxtsnewval function allows the application to get this new timestamp value. The application can then use dbtxtsput to put the new timestamp value in the DBPROCESS row buffer for future access through dbtxtimestamp. This is particularly useful when the application is buffering result rows and does not need the new timestamp immediately.

See Also

dbmoretext, dbreadtext, dbtxtimestamp, dbtxtsnewval, dbwritetext


dbupdatetext

Updates an existing text or image value. Unlike dbwritetext which replaces an entire text or image value, dbupdatetext can change only a portion of a text or image value in place.

Syntax

RETCODE dbupdatetext (
PDBPROCESS pdbproc,
LPCSTR dest_object,
LPCDBBINARY dest_textptr,
LPCDBBINARY dest_timestamp,
INT update_type,
DBINT insert_offset,
DBINT delete_length,
LPCSTR src_object,
DBINT src_size,
LPCBYTE src_text );

where

pdbproc
Is the DBPROCESS structure that is the handle for a particular workstation/SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
dest_object
Is the destination table and text or image column name (separated with a period) of the existing text or image value to be updated.
dest_textptr
Is the text pointer of the existing text or image value to be updated. Call dbtxptr to get this value. This parameter cannot be NULL.
dest_timestamp
Is the timestamp of the existing text or image value to be updated. Call dbtxtimestamp to get this value. This parameter cannot be NULL.
update_type
The type of update operation to perform.

Use UT_TEXT to insert new data from a C program variable specified in this call to dbupdatetext. You must specify an src_object value of NULL, an src_size equal to the size in bytes of the new data value being inserted, and a non-NULL src_text that points to the C program variable that contains the new data value being inserted.

Use UT_MORETEXT to insert new data from a C program variable with later calls to dbmoretext. You must specify a src_object value of NULL, a src_size equal to the total size in bytes of the new data value (that will be inserted by calls to dbmoretext), and a src_text value of NULL. Then call dbmoretext to insert the new data value in chunks.

Use UT_TEXTPTR to insert new data from a text or image column of an existing table. You must specify a non-NULL src_object value that gives the table and column, a src_size of 0, and a non-NULL src_text that gives the text pointer (returned by dbtxptr) of the new data value being inserted from the src_object.

Use UT_DELETEONLY to only delete existing data. You must specify an insert_offset value other than -1 and a non-zero delete_length value. Specify that no new data be inserted by using a src_object value of NULL, a src_size of 0 and a src_text value of NULL.

By default, a dbupdatetext operation is not recorded in the transaction log. You can bitwise OR the UT_LOG bit flag with any of these update_type values (for example UT_TEXT | UT_LOG) to indicate that this operation will be recorded in the transaction log.

insert_offset
Is the zero-based starting position, specified as the number of bytes (from the start of the existing text or image value) to skip before inserting the new data. The existing text or image data beginning at this zero-based starting position will be shifted to the right to make room for the new data. A value of 0 means that the new data will be inserted at the beginning of the existing data value. A value of -1 means that the new data will be appended to the existing data value.
delete_length
Is the number of bytes to delete from the existing text or image value, starting at the insert_offset position. A value of 0 means that no data will be deleted. A value of -1 means that all data from the insert_offset position to the end of the existing text or image value will be deleted.
src_object
Is the source table and text or image column name (separated with a period) that can be used as the source of the inserted data. If non-NULL, the src_size and src_text parameters are ignored. If NULL, the src_size and src_text parameters specify the data to be inserted.
src_size
Is the total size, in bytes, of the source text or image value (specified by src_text) to be inserted. Use this parameter only if the src_object parameter is NULL.
src_text
Is a pointer to the source data value to be inserted. Use this parameter only if the src_object parameter is NULL.

Returns

SUCCEED or FAIL.

Remarks

The dbupdatetext function can be used to delete existing data and then insert new data, to delete only existing data, or to insert only new data.

To delete existing data and then insert new data, specify an update_type other than UT_DELETEONLY, an insert_offset value other than -1, a non-zero delete_length value, and the new data to be inserted.

To delete only existing data, specify an update_type value of UT_DELETEONLY, an insert_offset value other than -1 and a non-zero delete_length value. Do not specify any new data to be inserted.

To insert only new data, specify an update_type other than UT_DELETEONLY, a delete_length value of 0, and the new data to be inserted.

See Also

dbmoretext, dbreadtext, dbresults, dbsqlok, dbtxptr, dbtxtimestamp, dbtxtsnewval, dbtxtsput


dbwritetext

Sends a text or image value to SQL Server.

Syntax

RETCODE dbwritetext (
PDBPROCESS dbproc,
LPCSTR objname,
LPCDBBINARY textptr,
DBTINYINT textptrlen,
LPCDBBINARY timestamp,
BOOL log,
DBINT size,
LPCBYTE text );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
objname
Is the database table name and column name. Separate the table name from the column name with a period.
textptr
Is the text pointer of the text or image value to be modified. Call dbtxptr to get this pointer. The pointer cannot be NULL.
textptrlen
Is a parameter included for future compatibility. For now, define its value with the constant DBTXPLEN.
timestamp
Is the text timestamp of the text or image value to be modified. Call dbtxtimestamp to get this timestamp. This value changes whenever the text or image value itself is changed. The pointer cannot be NULL.
log
Is a boolean value, specifying whether this dbwritetext operation should be recorded in the transaction log.
size
Is the total size, in bytes, of the text or image value to be written.
text
Is a pointer to the text or image to be written. If this pointer is NULL, DB-Library expects the application to call dbmoretext one or more times until all size bytes of data have been sent to SQL Server. For 16-bit DB-Library applications, no single data block can be 64K or larger. (Win32-based DB-Library applications are not limited to 64K data blocks.) DB-Library does not support huge pointers.

Returns

SUCCEED or FAIL.

Remarks

This function updates entire text and image values, allowing the application to send long values to SQL Server without having to copy them into a Transact-SQL UPDATE statement. In addition, it gives applications access to the text timestamp mechanism, which ensures that one user doesn't inadvertently overwrite another's modifications to the same value in the database.

The dbwritetext function succeeds only if its timestamp parameter, usually obtained when the column's value was originally retrieved, matches the text column's timestamp in the database. If a match occurs, dbwritetext updates the text column, and at the same time updates the column's timestamp. This has the effect of governing updates by competing applications ¾ an application's dbwritetext call fails if a second application updated the text column between the time the first application retrieved the column and the time it called dbwritetext.

The dbwritetext function is similar to the Transact-SQL WRITETEXT statement. It is usually more efficient to call dbwritetext than to send a WRITETEXT statement through the command buffer. For information about WRITETEXT, see the Microsoft SQL Server Transact-SQL Reference.

The dbwritetext function can be invoked with or without logging, according to the value of the log parameter. To use dbwritetext with logging turned off, the database option select into/bulkcopy must be set to true, as shown in the following example:

sp_dboption 'mbdb', 'select into/bulk', 'true'

This function, in conjunction with the dbmoretext function, also allows the application to send a large text or image value to SQL Server in the form of a number of smaller chunks. This is particularly useful with operating systems that are unable to allocate extremely long data buffers. All blocks must be shorter than 64K for 16-bit applications. (Win32-based DB-Library applications are not limited to 64K data blocks.) DB-Library does not support huge pointers.

When dbwritetext is used with dbmoretext, it locks the specified database text column, and the lock is not released until the final dbmoretext has sent its data. This ensures that a second application does not read or update the text column in the middle of the first application's update.

Examples

If the text parameter is a non-null value, dbwritetext executes the data transfer from start to finish, including any necessary calls to dbsqlok and dbresults.

The following code fragment shows this use of dbwritetext:

LOGINREC    *login;
DBPROCESS        *q_dbproc;
DBPROCESS        *u_dbproc;
DBCHAR            abstract_var[512];

// Open separate DBPROCESSes for querying and updating.

login = dblogin();
DBSETLUSER(login, "user");
DBSETLPWD(login, "my_passwd");
DBSETLAPP(login, "example1");
q_dbproc = dbopen(login, "my_server");
u_dbproc = dbopen(login, "my_server");

// The database column "abstract" is a text column. Retrieve the
// value of one of its rows.

dbcmd(q_dbproc, "select abstract from articles where article_id = 10");
dbsqlexec(q_dbproc);
dbresults(q_dbproc);
dbbind(q_dbproc, 1, STRINGBIND, (DBINT)0, abstract_var);

while (dbnextrow(q_dbproc) != NO_MORE_ROWS)
{
    // Change the value of "abstract_var".
    strcpy(abstract_var, "A brand new value.");

    // Update the text column.
    dbwritetext (u_dbproc, "articles.abstract", dbtxptr(q_dbproc, 1),
        DBTXPLEN, dbtxtimestamp(q_dbproc, 1), TRUE,
        (DBINT)strlen(abstract_var), abstract_var);
}
// Done.
dbexit();

To send chunks of text or image, rather than the whole value at once, set the text parameter to NULL. Then, dbwritetext returns control to the application immediately after notifying SQL Server that a text transfer is about to begin. The actual text is sent to SQL Server with dbmoretext, which can be called multiple times, once for each chunk.

The following code fragment uses dbwritetext with dbmoretext:

LOGINREC    *login;
DBPROCESS        *q_dbproc;
DBPROCESS        u_dbproc;
DBCHAR            art1[512];
static DBCHAR    part2[512] = "This adds another sentence to the text.";

login = dblogin();
DBSETLUSER(login, "user");
DBSETLPWD(login, "my_passwd");
DBSETLAPP(login, "example2");
q_dbproc = dbopen(login, "my_server");
u_dbproc = dbopen(login, "my_server");

dbcmd(q_dbproc, "select abstract from articles where article_id = 10");
dbsqlexec(q_dbproc);
dbresults(q_dbproc);
dbbind(q_dbproc, 1, STRINGBIND, (DBINT)0, part1);

while (dbnextrow(q_dbproc) != NO_MORE_ROWS)
{
    // Change the value of part of the text column. This example
    // adds a sentence to the end of the existing text.
    // Update the text column.

    dbwritetext(u_dbproc, "articles.abstract", dbtxptr(q_dbproc, 1),             DBTXPLEN, dbtxtimestamp(q_dbproc, 1), TRUE,
        (DBINT)(strlen(part1)  strlen(part2)), NULL);
    dbsqlok(u_dbproc);
    dbresults(u_dbproc);

    // Send the update value in chunks.

    dbmoretext(u_dbproc, (DBINT)strlen(part1), part1);
    dbmoretext(u_dbproc, (DBINT)strlen(part2), part2);

    dbsqlok(u_dbproc);
    while (dbresults(u_dbproc) != NO_MORE_RESULTS);
}
dbexit();

Note Notice the required calls to dbsqlok and dbresults, between the call to dbwritetext and the first call to dbmoretext and after the final call to dbmoretext.

When dbwritetext is used with dbmoretext, it locks the specified database text column. The lock is not released until the final dbmoretext has sent its data. This ensures that a second application does not read or update the text column in the midst of the first application's update.

See Also

dbmoretext, dbreadtext, dbresults, dbsqlok, dbtxptr, dbtxtimestamp, dbtxtsnewval, dbtxtsput


Chapter 8 Browse Functions

Browse Functions

dbcolbrowse

dbcolsource

dbqual

dbtabbrowse

dbtabcount

dbtabname

dbtabsource

dbtsnewlen

dbtsnewval

dbtsput


dbcolbrowse

Determines whether the source of a result column can be updated with the DB-Library browse-mode facilities.

Syntax

BOOL dbcolbrowse (
PDBPROCESS dbproc,
INT colnum );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
colnum
Is the number of the result column. The first column is number 1.

Returns

TRUE or FALSE.

Remarks

The dbcolbrowse function is one of the DB-Library browse-mode functions. It determines whether the database column that is the source of a result column in a select list can be updated with the DB-Library browse-mode facilities. This function is useful for examining ad hoc queries. If the query has been hardcoded into the program, dbcolbrowse is unnecessary.

The dbcolbrowse function can be called any time after dbresults.

To determine the name of the source column given the name of the result column, use dbcolsource.

Example

Only a column derived from a table that has a unique index and a timestamp column can be updated. It cannot be the result of a Transact-SQL expression. For example, in the following select list, result columns 1 and 2 (title and category) can be updated, but column 3 (wholesale) cannot because it is the result of an expression:

select title, category=type, wholesale=(price * 0.6)
from inventory for browse

See Also

dbcolsource, dbqual, dbtabbrowse, dbtabcount, dbtabname, dbtabsource, dbtsnewlen, dbtsnewval, dbtsput; Browse Mode, Programming with DB-Library, and Bulk-Copy Functions


dbcolsource

Returns a pointer to the name of the database column from which the specified result column was derived.

Syntax

LPCSTR dbcolsource (
PDBPROCESS dbproc,
INT colnum );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
colnum
Is the number of the result column. The first column is number 1.

Returns

A pointer to a null-terminated column name. This pointer is NULL if the column number is out of range or if the column is the result of a Transact-SQL expression, such as MAX(colname).

Remarks

The dbcolsource function is one of the DB-Library browse-mode functions. This function gives an application the information it needs to update a database column, based on an ad hoc query. SELECT statements can optionally specify header names for result columns. For example:

select author = au_lname from authors for browse

When updating a table, you must use the database column name, not the header name (in this example, au_lname, not author). You can use the dbcolsource function if a FOR BROWSE is issued on a view and to get the underlying database column name. For example:

dbcolsource(dbproc, 1)

This call returns a pointer to the string au_lname.

The dbcolsource function is useful for ad hoc queries. If the query has been hardcoded into the program, this function is unnecessary.

The dbcolsource function can be called any time after dbresults returns SUCCEED.

See Also

dbcolbrowse, dbqual, dbresults, dbtabbrowse, dbtabcount, dbtabname, dbtabsource, dbtsnewlen, dbtsnewval, dbtsput; Browse Mode, Programming with DB-Library, Bulk-Copy Functions


dbqual

Returns a pointer to a WHERE clause to update the current row in a browsable table.

Syntax

LPCSTR dbqual (
PDBPROCESS dbproc,
INT tabnum,
LPCSTR tabname );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
tabnum
Is the number of the table, as specified in the SELECT statement's FROM clause. Table numbers start at 1. If tabnum is -1, the tabname parameter is used to identify the table.
tabname
Is a pointer to the null-terminated name of a table specified in the SELECT statement's FROM clause. If tabname is NULL, the tabnum parameter is used to identify the table.

Returns

A pointer to a null-terminated WHERE clause for the current row in the specified table. This buffer is dynamically allocated, and the application must free it by calling dbfreequal. If dbqual is asked to construct a WHERE clause for a table that cannot be browsed, it returns a NULL pointer. For details, see "dbtabbrowse."

Remarks

The dbqual function is one of the DB-Library browse-mode functions. For a discussion of browse mode, see Getting Started.

The dbqual function provides a WHERE clause that the application can use to update a single row in a browsable table. Columns from this row must have been previously retrieved through a browse-mode SELECT query.

The WHERE clause produced by dbqual begins with the keyword WHERE and contains references to the row's unique index and timestamp column. The application appends the WHERE clause to an UPDATE or DELETE statement without needing to examine or manipulate it in any way.

The timestamp column indicates the time that the particular row was last updated. An update on a browsable table fails if the timestamp column in the dbqual-generated WHERE clause is different from the timestamp column in the table. Such a condition, which provokes SQL Server error message 532, indicates that another user updated the row between the time this application selected it for browsing and the time it tried to update it. The application itself must provide the logic for handling the update failure. For one approach, see the example in the next section.

The dbqual function can construct WHERE clauses only for tables that can be browsed. Use dbtabbrowse to determine whether a table can be browsed.

The dbqual function is usually called after dbnextrow.

Example

This code fragment shows what to do when a browse-mode update fails because another user has already updated the row. This example retrieves the entire row again, allows the user to examine and modify it, and tries the update again.

Note that q_dbproc is the DBPROCESS used to query the database, and u_dbproc is the DBPROCESS used to update the database.

// First, find out which employee record the user wants to update.
employee_id = which_employee();
while (1)
{
    // Retrieve that employee record from the database.
    // Assume that "empid" is a unique index, so this query will
    // return only one row.

    dbfcmd
    (q_dbproc,
    "select * from employees where empid = %d for browse",
    employee_id);
    dbsqlexec(q_dbproc);
    dbresults(q_dbproc);
    while (dbnextrow(q_dbproc)
        != NO_MORE_ROWS);

    // Now, let the user examine or edit the employee's
    // data, first placing the data into the program variables.

    extract_employee_data(q_dbproc, employee_struct);
    examine_and_edit(employee_struct, &edit_flag);

    if (edit_flag == FALSE)
    {
        // The user didn't edit this record,
        // so it's done.

        break;
    }
    else
    {
        // The user edited this record, so the application
        // uses the edited data to update the corresponding row
        // in the database.

        qualptr = dbqual(q_dbproc, -1, "employees");
        dbcmd(u_dbproc, "update employees");
        dbfcmd
        (u_dbproc,
        " set address = '%s', salary = %d %s",
        employee_struct->address, employee_struct->salary,
        qualptr);
        dbfreequal(qualptr);
        if ((dbsqlexec(u_dbproc) == FAIL)
        || (dbresults(u_dbproc) == FAIL))

        {
            // The update failed. In a real program, it
            // would be necessary to examine the messages
            // returned from SQL Server to determine
            // why it failed. In this example,
            // assume that the update failed because
            // someone else has already updated this
            // row, thereby changing the timestamp.
            //
            // To cope with this situation, repeat
            // the loop, retrieving the changed row
            // for the user to examine and edit.
            // This will give the user the opportunity
            // to decide whether to overwrite
            // the change made by the other user.

            continue;
        }
        else
        {
            // The update succeeded, so the
            // application is done.
            break;
        }
    }
}

See Also

dbcolbrowse, dbcolsource, dbfreequal, dbnextrow, dbtabbrowse, dbtabcount, dbtabname, dbtabsource, dbtsnewlen, dbtsnewval, dbtsput; Bulk-Copy Functions


dbtabbrowse

Determines whether the specified table can be updated with the DB-Library browse-mode facilities.

Syntax

BOOL dbtabbrowse (
PDBPROCESS dbproc,
INT tabnum );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
tabnum
Is the number of the table as specified in the SELECT statement's FROM clause. Table numbers start at 1.

Returns

TRUE or FALSE. If you drop the unique index of a table while browsing, dbtabbrowse continues to return TRUE.

Remarks

The dbtabbrowse function is one of the DB-Library browse-mode functions. For a detailed discussion of browse mode, see Browse Mode in Programming with DB-Library.

The dbtabbrowse function provides a way to identify tables that can be browsed. It is useful for examining ad hoc queries prior to performing browse-mode updates based on the queries. If the query has been hardcoded into the program, this function is unnecessary.

A table must have a unique index and a timestamp column before it can be browsed.

Call dbtabbrowse any time after calling dbresults.

See Also

dbcolbrowse, dbcolsource, dbqual, dbresults, dbtabcount, dbtabname, dbtabsource, dbtsnewlen, dbtsnewval, dbtsput; Bulk-Copy Functions


dbtabcount

Returns the number of tables involved in the current SELECT statement.

Syntax

INT dbtabcount ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

The number of tables, including SQL Server work tables, involved in the current set of row results. A value of -1 is returned if an invalid dbproc value is sent to dbtabcount.

Remarks

The dbtabcount function is one of the DB-Library browse-mode functions. For a detailed discussion of browse mode, see Browse Mode in Programming with DB-Library.

A SELECT statement can generate a set of result rows whose columns are derived from several database tables. To perform browse-mode updates of columns in a statement's select list, the application must know how many tables were involved in the query, because each table requires a separate UPDATE statement. The dbtabcount function can provide this information for ad hoc queries. If the query has been hardcoded into the program, this function is unnecessary.

The count returned by this function includes any SQL Server "work tables" used in processing the query. The SQL Server sometimes creates temporary, internal work tables to process a query. It deletes these work tables by the time it finishes processing the statement. Work tables cannot be updated and are not available to the application. Therefore, before using a table number, the application must make sure that it does not belong to a work table. The dbtabname function can be used to determine whether a particular table number refers to a work table.

The dbtabcount function can be called any time after dbresults.

See Also

dbcolbrowse, dbcolsource, dbqual, dbresults, dbtabbrowse, dbtabname, dbtabsource, dbtsnewlen, dbtsnewval, dbtsput; Bulk-Copy Functions


dbtabname

Returns the name of a table based on its number.

Syntax

LPCSTR dbtabname (
PDBPROCESS dbproc,
INT tabnum );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
tabnum
Is the number of the table. Table numbers start with 1. Use dbtabcount to find out the total number of tables involved in a particular statement.

Returns

A pointer to the null-terminated name of the specified table. This pointer is NULL if the table number is out of range or if the specified table is a SQL Server work table. For a description of work tables, see "dbtabcount."

Remarks

The dbtabname function is one of the DB-Library browse-mode functions. For a detailed discussion of browse mode, see Browse Mode in Programming with DB-Library.

A SELECT statement can generate a set of result rows whose columns are derived from several database tables. The database tables are specified by the FROM clause. The dbtabname function provides a way for an application to determine the name of each table involved in an ad hoc query. If the query has been hard-coded into the program, this function is unnecessary.

The dbtabname function can be called any time after dbresults.

See Also

dbcolbrowse, dbcolsource, dbqual, dbresults, dbtabbrowse, dbtabcount, dbtabsource, dbtsnewlen, dbtsnewval, dbtsput; Bulk-Copy Functions


dbtabsource

Returns the name and number of the table from which a particular result column was derived.

Syntax

LPCSTR dbtabsource (
PDBPROCESS dbproc,
INT colnum,
LPINT tabnum );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
colnum
Is the number of the result column. Column numbers start at 1.
tabnum
Is a pointer to an integer, which is filled in with the table's number. Many DB-Library functions that deal with browse mode accept either a table name or a table number. If dbtabsource returns NULL (see the next section, "Returns"), tabnum is set to -1.

Returns

A pointer to the name of the table from which this result column was derived. A NULL return value can mean one of the following:

  • The DBPROCESS is inactive or not enabled. This is an error that causes an application's error handler to be invoked.
  • The SELECT statement does not contain the FOR BROWSE clause.
  • The column number is out of range.
  • The column is the result of an expression, such as "max(colname)".

Remarks

The dbtabsource function is one of the DB-Library browse-mode functions. For a detailed discussion of browse mode, see Browse Mode in Programming with DB-Library.

The dbtabsource function allows an application to determine which tables provided the columns in the current set of result rows. This information is valuable when using dbqual to construct WHERE clauses for UPDATE and DELETE statements based on ad hoc queries. If the query has been hardcoded into the program, this function is unnecessary.

The dbtabsource function can be called any time after dbresults.

See Also

dbcolbrowse, dbcolsource, dbqual, dbresults, dbtabbrowse, dbtabcount, dbtabname, dbtsnewlen, dbtsnewval, dbtsput; Bulk-Copy Functions


dbtsnewlen

Returns the length of the new value of the timestamp column after a browse-mode update.

Syntax

INT dbtsnewlen ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

The length, in bytes, of the new timestamp value for the updated row. If no timestamp was returned to the application (because the update was unsuccessful or because the UPDATE statement did not contain the TSEQUAL built-in function), the function returns -1.

Remarks

The dbtsnewlen function is one of the DB-Library browse-mode functions. For a detailed discussion of browse mode, see Browse Mode in Programming with DB-Library.

The dbtsnewlen function provides information about the timestamp column. The WHERE clause returned by dbqual contains a call to the TSEQUAL built-in function. When such a WHERE clause is used in an UPDATE statement, the TSEQUAL function places a new value in the updated row's timestamp column and returns the new timestamp value to the application (if the update is successful). The dbtsnewlen function allows the application to save the length of the new timestamp value, possibly for use with dbtsput.

See Also

dbcolbrowse, dbcolsource, dbqual, dbtabbrowse, dbtabcount, dbtabname, dbtabsource, dbtsnewval, dbtsput; Bulk-Copy Functions


dbtsnewval

Returns the new value of the timestamp column after a browse-mode update.

Syntax

LPCDBBINARY dbtsnewval ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

A pointer to the new timestamp value for the updated row. If no timestamp was returned to the application (possibly because the update was unsuccessful or because the UPDATE statement did not contain the TSEQUAL built-in function), the pointer is NULL.

Important Do not modify the identifier in any way. Modifying the identifier can cause unpredictable results.

Remarks

The dbtsnewval function is one of the DB-Library browse-mode functions. For a detailed discussion of browse mode, see Browse Mode in Programming with DB-Library.

The dbtsnewval function provides information about the timestamp column. The WHERE clause returned by dbqual contains a call to the TSEQUAL built-in function. When such a WHERE clause is used in an UPDATE statement, the TSEQUAL function places a new value in the updated row's timestamp column and returns the new timestamp value to the application (if the update is successful). This function allows the application to save the new timestamp value, possibly for use with dbtsput.

See Also

dbcolbrowse, dbcolsource, dbqual, dbtabbrowse, dbtabcount, dbtabname, dbtabsource, dbtsnewlen, dbtsput; Bulk-Copy Functions


dbtsput

Puts the new value of the timestamp column into the given table's current row in the DBPROCESS.

Syntax

RETCODE dbtsput (
PDBPROCESS dbproc,
LPCDBBINARY newts,
INT newtslen,
INT tabnum,
LPCSTR tabname );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server. This must be the DBPROCESS used to perform the original SELECT query.
newts
Is a pointer to the new timestamp value. It is returned by dbtsnewval.
newtslen
Is the length of the new timestamp value. It is returned by dbtsnewlen.
tabnum
Is the number of the updated table. Table numbers start at 1. The tabnum must refer to a table that can be browsed. The dbtabbrowse function determines whether a table can be browsed. If this value is -1, the tabname parameter identifies the table.
tabname
Is a pointer to a null-terminated table name. The tabname must refer to a table that can be browsed. Set this pointer to NULL if the tabnum parameter is used to identify the table. The value of tabname is returned by dbtabsource.

Returns

SUCCEED or FAIL. The following situations cause this function to return FAIL:

  • The application tries to update the timestamp of a nonexistent row.
  • The application tries to update the timestamp, using NULL as the new timestamp value (newts).
  • The specified table cannot be browsed.

Remarks

The dbtsput function is one of the DB-Library browse-mode functions. For a detailed discussion of browse mode, see Browse Mode in Programming with DB-Library.

The dbtsput function manipulates the timestamp column. The WHERE clause returned by dbqual contains a call to the TSEQUAL built-in function. When such a WHERE clause is used in an UPDATE statement, the TSEQUAL function places a new value in the updated row's timestamp column and returns the new timestamp value to the application (if the update is successful). If the same row is updated a second time, the UPDATE statement's WHERE clause must use the latest timestamp value. This function updates the timestamp in the DBPROCESS for the row currently being browsed. Then, if the application needs to update the row a second time, it can call dbqual to formulate a new WHERE clause that uses the new timestamp. Call dbtsput only after dbnextrow or dbgetrow has returned reg_row.

See Also

dbcolbrowse, dbcolsource, dbqual, dbtabbrowse, dbtabcount, dbtabname, dbtabsource, dbtsnewlen, dbtsnewval; Bulk-Copy Functions


Chapter 9 Bulk-Copy Functions

Bulk-Copy Functions

The following is a list of the Bulk-Copy Functions.

bcp_batch

bcp_bind

bcp_colfmt

bcp_collen

bcp_colptr

bcp_columns

bcp_control

bcp_done

bcp_exec

bcp_init

bcp_moretext

bcp_readfmt

bcp_sendrow

BCP_SETL

bcp_writefmt


bcp_batch

Saves any rows previously bulk copied from program variables and sent to SQL Server by bcp_sendrow.

Syntax

DBINT bcp_batch ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

The number of rows saved since the last call to bcp_batch, or -1 in case of error.

Remarks

When an application uses bcp_bind and bcp_sendrow to bulk copy rows from program variables to SQL Server tables, the rows are permanently saved in SQL Server only when the program calls bcp_batch or bcp_done.

You can call bcp_batch once every n rows or when there is a lull between periods of incoming data (as in a telemetry application). Of course, you can choose some other criteria, or you can decide not to call bcp_batch at all. If bcp_batch is not called, the rows are permanently saved in SQL Server when bcp_done is called.

See Also

bcp_bind, bcp_done, bcp_sendrow


bcp_bind

Binds data from a program variable to a table column for bulk copy into SQL Server.

Syntax

RETCODE bcp_bind (
PDBPROCESS dbproc,
LPCBYTE varaddr,
INT prefixlen,
DBINT varlen,
LPCBYTE terminator,
INT termlen,
INT type,
INT table_column );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
varaddr
Is the address of the program variable from which the data is copied. If type is SQLTEXT or SQLIMAGE, varaddr can be NULL. A NULL varaddr indicates that text and image values are sent to SQL Server in chunks by bcp_moretext, rather than all at once by bcp_sendrow.
prefixlen
Is the length, in bytes, of any length prefix this column can have; valid length prefixes are 0, 1, 2, or 4 bytes. For example, strings in some non-C programming languages are made up of a 1-byte length prefix, followed by the string data itself. If the data does not have a length prefix, set prefixlen to 0.
varlen
Is the length of the data in the program variable, not including the length of any length prefix and/or terminator. Setting varlen to 0 signifies that the data is NULL. Setting varlen to -1 indicates that the system should ignore this parameter.

For fixed-length datatypes, such as integers, the datatype itself indicates to the system the length of the data. Therefore, for fixed-length datatypes, varlen must always be -1 except when the data is NULL, in which case varlen must be 0.

For character, text, binary, and image data, varlen can be -1, 0, or some positive value. If varlen is -1, the system uses either a length prefix or a terminator sequence to determine the length. (If both are supplied, the system uses the one that results in the shortest amount of data being copied.) If varlen is -1 and neither a prefix length nor a terminator sequence is specified, the system returns an error message. If varlen is 0, the system assumes the data is NULL. If varlen is some positive value, the system uses varlen as the data length. However, if, in addition to a positive varlen, a prefix length and/or terminator sequence is provided, the system determines the data length by using the method that results in the shortest amount of data being copied.

terminator
Is a pointer to the byte pattern, if any, that marks the end of this program variable. For example, C strings usually have a 1-byte terminator whose value is 0. If there is no terminator for the variable, set terminator to NULL. If you want to designate the C null terminator as the program variable terminator, use an empty string (" ") as terminator and set termlen to 1, since the null terminator constitutes a single byte. For instance, to use a C null terminator:
bcp_bind (dbproc, co_name, 0, -1, "", 1, 0, 2)

If there is no terminator:

bcp_bind (dbproc, co_name, 0, -1, NULL, 0, 0, 2)
termlen
Is the length of this program variable's terminator, if any. If there is no terminator for the variable, set termlen to 0.
type
Is the datatype of your program variable. The data in the program variable is automatically converted to the type of the database column. If this parameter is 0, no conversion is performed. For a list of supported conversions, see "dbconvert." For the list of valid SQL Server datatypes, see Appendix B: DB-Library Datatypes.
table_column
Is the column number in the database table to which the data is copied. Column numbers start at 1.

Returns

SUCCEED or FAIL.

Remarks

Use bcp_bind for a fast, efficient way to copy data from a program variable into a table in SQL Server without first putting the data into a user file or using the Transact-SQL INSERT statement.

Call bcp_init before calling this or any other bulk copy functions.

Make a separate bcp_bind call for every column in the SQL Server table into which you want to copy. After the necessary bcp_bind calls have been made, then call bcp_sendrow to send a row of data from your program variables to SQL Server. Call bcp_init to set the table to be copied into.

Whenever you want SQL Server to checkpoint the rows already received, call bcp_batch. For example, call bcp_batch once for every 1000 rows inserted or at any other interval.

When there are no more rows to be inserted, call bcp_done. Failure to do so results in an error.

When using bcp_bind, the user filename parameter, set hfile, in the call to bcp_init, to NULL, and set direction, the direction parameter, to DB_IN.

Control parameter settings, specified with bcp_control, have no effect on bcp_bind row transfers.

Calling bcp_columns when using bcp_bind results in an error.

Example

The following example shows how to use bcp_bind:

LOGINREC    *login;
DBPROCESS    *dbproc;
char        co_name[MAXNAME];
DBINT        co_id;
DBINT        rows_sent;
DBBOOL        more_data;
char        *terminator = "\t\t";

// Install error-handler and message-handler.
dberrhandle(err_handler);
dbmsghandle(msg_handler);

// Open a DBPROCESS.
login = dblogin();
DBSETLUSER(login, "user");
DBSETLPWD(login, "my_passwd");
DBSETLAPP(login, "example");
BCP_SETL(login, TRUE);
dbproc = dbopen(login, "my_server");

// Initialize bcp.
if (bcp_init(dbproc, "comdb..accounts_info", (BYTE *)NULL,
    (BYTE *)NULL, DB_IN) == FAIL)
    exit(ERREXIT);
// Bind program variables to table columns.
if (bcp_bind(dbproc, (BYTE *)&co_id, 0, (DBINT)-1, (BYTE *)NULL, 0, 0,     1)     == FAIL)
{
    fprintf(stderr, "bcp_bind, column 1, failed.\n");
    exit(ERREXIT);
}

if (bcp_bind
    (dbproc, co_name, 0, (DBINT)-1, terminator, strlen(terminator), 0,     2)     == FAIL)
{
    fprintf(stderr, "bcp_bind, column 2, failed.\n");
    exit(ERREXIT);
}

while (TRUE)
{
    // Process and retrieve program data.
    more_data = getdata(&co_id, co_name);

    if (more_data == FALSE)
        break;
        // Send the data.
    if (bcp_sendrow(dbproc) == FAIL)
        exit(ERREXIT);
}

// Terminate the bulk copy operation.
if ((rows_sent = bcp_done(dbproc)) == -1)
    printf("Bulk-copy unsuccessful.\n");
else
    printf("%ld rows copied.\n", rows_sent);

See Also

bcp_batch, bcp_colfmt, bcp_collen, bcp_colptr, bcp_columns, bcp_control, bcp_done, bcp_exec, bcp_init, bcp_moretext, bcp_sendrow, dbconvert; DB-Library Datatypes


bcp_colfmt

Specifies the format of a user file for bulk copy into or out of SQL Server.

Syntax

RETCODE bcp_colfmt (
PDBPROCESS dbproc,
INT file_column,
BYTE file_type,
INT file_ prefixlen,
DBINT file_collen,
LPCBYTE file_term,
INT file_termlen,
INT table_column );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/
SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
file_column
Is the column number in the user file for which the format is being specified. The first column is number 1.
file_type
Is the datatype of this column in the user file. If it is different from the datatype of the corresponding column in the database table (table_column), the conversion is performed automatically. For a table of allowable data conversions, see dbconvert. If you want to specify the same datatype as in the corresponding column of the database table (table_column), set this parameter to 0.

For a bulk copy out of SQL Server into a file, when file_type is SQLDECIMAL or SQLNUMERIC:

  • If the source column is not decimal or numeric, the default precision and scale are used.
  • If the source column is decimal and numeric, the precision and scale of the source column are used.
file_ prefixlen
Is the length of the length prefix for this column in the user file. Legal prefix lengths are 1, 2, and 4 bytes. To avoid using a length prefix, set this parameter to 0. To let DB-Library determine whether to use a length prefix, set this parameter to -1. In such a case, DB-Library uses a length prefix (of whatever length is necessary) if the database column length is variable.

If more than one means of specifying a user file column length is used (such as a length prefix and a maximum column length, or a length prefix and a terminator sequence), DB-Library chooses the one that results in the shortest amount of data being copied.

Length prefixes simplify the way null data values are specified in a user file. For instance, assume you have a 1-byte length prefix for a 4-byte integer column. Ordinarily, the length prefix contains a value of 4 to indicate that a 4-byte value follows. However, if the value of the column is NULL, the length prefix can be set to 0 to indicate that 0 bytes follow for the column.

file_collen
Is the maximum length of this column's data in the user file, not including the length of any length prefix and/or terminator. Setting file_collen to 0 signifies that the data is NULL. Setting file_collen to -1 indicates that the system should ignore this parameter (that is, there is no default maximum length).

For fixed-length datatypes, such as integers, the length of the data is constant, except for the special case of null values. Therefore, for fixed-length datatypes, file_collen must always be -1, except when the data is NULL, in which case file_collen must be 0. For character, text, binary, and image data, file_collen can be -1, 0, or some positive value. If file_collen is -1, the system uses either a length prefix or a terminator sequence to determine the length of the data. (If both are supplied, the system uses the one that results in the shortest amount of data being copied.) If file_collen is -1 and neither a prefix length nor a terminator sequence is specified, the system returns an error message. If file_collen is 0, the system assumes the data is NULL. If file_collen is a positive value, the system uses file_collen as the maximum data length. However, if, in addition to a positive file_collen, a prefix length and/or terminator sequence is provided, the system determines the data length by using the method that results in the shortest amount of data being copied.

file_term
Is the terminator sequence to be used for this column. This parameter is useful mainly for character, text, binary, and image datatypes because all other types are of fixed length. To avoid using a terminator, set this parameter to NULL. To set the terminator to NULL, set file_term to "\0". To make the tab character the terminator, set file_term to "\t". To make the newline character the terminator, set file_term to "\n".

If more than one means of specifying a user file column length is used (such as a terminator and a length prefix, or a terminator and a maximum column length), bcp chooses the one that results in the shortest amount of data being copied.

file_termlen
Is the length, in bytes, of the terminator sequence to be used for this column. To avoid using a terminator, set this value to 0.
table_column
Is the corresponding column number in the database table. If this value is 0, this column is not copied. The first column number is column 1.

Returns

SUCCEED or FAIL.

Remarks

The bcp_colfmt function allows you to specify the user file format for bulk copies. For bulk copy, a format contains the following parts:

  • A mapping from user file columns to database columns.
  • The datatype of each user file column.
  • The length of the optional length prefix of each column.
  • The maximum length of the user file column's data.
  • The optional terminating byte sequence for each column.
  • The length of this optional terminating byte sequence.

Each call to bcp_colfmt specifies the format for one user file column. For example, to change the default settings for three columns in a five-column table, first call bcp_columns(5), and then call bcp_colfmt five times, with three of those calls setting your custom format. Set file_type of the remaining two calls to 0, and set their file_ prefixlen, file_collen, and file_termlen parameters to -1. This procedure copies all five columns ¾ three with your customized format and two with the default format.

The bcp_columns function must be called before any calls to bcp_colfmt.

You must call bcp_colfmt once and only once for every column in the user file, regardless of whether some of those columns use the default format or are skipped.

To skip a column, set the table_column parameter to 0.

See Also

bcp_batch, bcp_bind, bcp_collen, bcp_colptr, bcp_columns, bcp_control, bcp_done, bcp_exec, bcp_init, bcp_sendrow, dbconvert


bcp_collen

Sets the program variable data length for the current bulk copy into SQL Server.

Syntax

RETCODE bcp_collen (
PDBPROCESS dbproc,
DBINT varlen,
INT table_column );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
varlen
Is the length of the program variable, which does not include the length of the length prefix or terminator. Setting varlen to 0 signifies that the data is NULL. Setting it to -1 signifies that the data is variable length and that the length is determined by the length prefix or terminator. If both a length prefix and a terminator exist, bcp uses the one that results in the shortest amount of data being copied.
table_column
Is the column in the SQL Server table to which the data is copied. Column numbers start at 1.

Returns

SUCCEED or FAIL.

Remarks

The bcp_collen function allows you to change the program variable data length for a particular column while running a copy IN through calls to bcp_bind.

Initially, the program variable data length is determined when bcp_bind is called. If the program variable data length changes between calls to bcp_sendrow and no length prefix or terminator is being used, you can call bcp_collen to reset the length. The next call to bcp_sendrow uses the length you just set.

There must be a separate bcp_collen call for every column in the table whose data length you want to modify.

See Also

bcp_bind, bcp_colptr, bcp_sendrow


bcp_colptr

Sets the program variable data address for the current copy into SQL Server.

Syntax

RETCODE bcp_colptr (
PDBPROCESS dbproc,
LPCBYTE colptr,
INT table_column );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
colptr
Is the address of the program variable.
table_column
Is the column in the SQL Server table to which the data is copied. Column numbers start at 1.

Returns

SUCCEED or FAIL.

Remarks

The bcp_colptr function allows you to change the program variable data address for a particular column while running a copy IN through calls to bcp_bind.

Initially, the program variable data address is determined when bcp_bind is called. If the program variable data address changes between calls to bcp_sendrow, you can call bcp_colptr to reset the address of the data. The next call to bcp_sendrow uses the data at the address you just set.

There must be a separate bcp_colptr call for every column in the table whose data address you want to modify.

See Also

bcp_bind, bcp_collen, bcp_sendrow


bcp_columns

Sets the total number of columns found in the user file for use with a bulk copy into or out of SQL Server.

Syntax

RETCODE bcp_columns (
PDBPROCESS dbproc,
INT file_colcount );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
file_colcount
Is the total number of columns in the user file. Even if you are preparing to bulk copy data from the user file to a SQL Server table and do not intend to copy all columns in the user file, you must still set file_colcount to the total number of user file columns.

Returns

SUCCEED or FAIL.

Remarks

This function can be called only after bcp_init has been called with a valid filename.

You should call this function only if you intend to use a user file format that differs from the default. For a description of the default user file format, see "bcp_init."

After calling bcp_columns, you must call bcp_colfmt file_colcount times because you are defining a completely custom file format.

See Also

bcp_colfmt, bcp_init


bcp_control

Changes the default settings for various control parameters for a bulk copy between a file and SQL Server.

Syntax

RETCODE bcp_control (
PDBPROCESS dbproc,
INT field,
DBINT value );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
field
One of the following:
BCPMAXERRS
Is the number of errors allowed before giving up. The default is 10; a value less than 1 resets this field to its default value. If a value larger than 65,535 is specified, this field is set to 65,535.
BCPFIRST
Is the first row to copy. The default is 1; a value less than 1 resets this field to its default value.
BCPLAST
Is the last row to copy. The default is to copy all rows; a value less than 1 resets this field to its default value.
BCPBATCH
Is the number of rows per batch. The default is 0; a value less than 1 resets this field to its default value.
BCPKEEPNULLS
Specifies whether empty data values in the file will be converted to NULL values in the SQL Server table. If this option is set before calling bcp_exec, empty values will be converted to NULL values in the SQL Server table. The default is for empty values to be converted to the column's default value in the SQL Server table.
value
Is the value for the specified field.

Returns

SUCCEED or FAIL.

Remarks

This function sets various control parameters for bulk copy operations, including the number of errors allowed before canceling a bulk copy, the numbers of the first and last rows to copy, and the batch size.

These control parameters are only meaningful when copying between a user file and a SQL Server table. Control parameter settings have no effect on bcp_bind row transfers.

Example

The following example shows how to use bcp_control:

LOGINREC    *login;
DBPROCESS    *dbproc;
DBINT        rowsread;

// Install error-handler and message-handler.
dberrhandle(err_handler);
dbmsghandle(msg_handler);

// Open a DBPROCESS.
login = dblogin();
BCP_SETL(login, TRUE);
DBSETLUSER(login, "user");
DBSETLPWD(login, "my_passwd");
DBSETLAPP(login, "example");
dbproc = dbopen(login, "my_server");

// Initialize bcp.
if (bcp_init(dbproc, "comdb..address", "address.add", "addr.err",
    DB_IN) == FAIL)
    exit(ERREXIT);

// Set the number of rows per batch.
if (bcp_control(dbproc, BCPBATCH, (DBINT) 1000) == FAIL)
{
    printf("bcp_control failed to set batching behavior.\n");
    exit(ERREXIT);
}

// Set file column count.
if (bcp_columns(dbproc, 1) == FAIL)
{
    printf("bcp_columns failed.\n");
    exit(ERREXIT);
}

// Set the file format.
if (bcp_colfmt(dbproc, 1, 0, 0, (DBINT)-1, "\n", 1, 1) == FAIL)
{
    printf("bcp_colformat failed.\n");
    exit(ERREXIT);
}

// Now, execute the bulk copy.
if (bcp_exec(dbproc, &rowsread) == FAIL)
{
    printf("Incomplete bulk copy.    Only %ld row%c copied.\n",
        rowsread, (rowsread == 1) ? ' ': 's');
    exit(ERREXIT);
}

See Also

bcp_batch, bcp_bind, bcp_colfmt, bcp_collen, bcp_colptr, bcp_columns, bcp_done, bcp_exec, bcp_init


bcp_done

Ends a bulk copy from program variables into SQL Server performed with bcp_bind and bcp_sendrow.

Syntax

DBINT bcp_done ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

The number of rows permanently saved since the last call to bcp_batch, or -1 in case of error.

Remarks

Call bcp_done after the last call to bcp_sendrow or bcp_moretext. Failure to call bcp_done after copying in all your data results in unpredictable errors.

See Also

bcp_batch, bcp_bind, bcp_moretext, bcp_sendrow


bcp_exec

Executes a complete bulk copy of data between a database table and a user file.

Syntax

RETCODE bcp_exec (
PDBPROCESS dbproc,
LPDBINT rows_copied );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
rows_copied
Is a pointer to a DBINT. The bcp_exec function fills this DBINT with the number of rows successfully copied. If set to NULL, this parameter is not filled in by bcp_exec.

Returns

SUCCEED or FAIL. The bcp_exec function returns SUCCEED if all rows are copied. If a partial or complete failure occurs, bcp_exec returns FAIL. Check the rows_copied parameter for the number of rows successfully copied.

Remarks

This function copies data from a user file to a database table or vice versa, depending on the value of the direction parameter in bcp_init.

Before calling bcp_exec, call bcp_init with a valid user filename. Failure to do so results in an error.

Example

The following example shows how to use bcp_exec:

LOGINREC    *login;
DBPROCESS    *dbproc;
DBINT        rowsread;

// Install error-handler and message-handler.
dberrhandle(err_handler);
dbmsghandle(msg_handler);

// Open a DBPROCESS.
login = dblogin();
DBSETLUSER(login, "user");
DBSETLPWD(login, "my_passwd");
DBSETLAPP(login, "example");
BCP_SETL(login, TRUE);
dbproc = dbopen(login, "my_server");

// Initialize bcp.
if (bcp_init(dbproc, "pubs..authors", "authors.sav",
    (BYTE *)NULL, DB_OUT) == FAIL)
    exit(ERREXIT);

// Now, execute the bulk copy.
if (bcp_exec(dbproc, &rowsread) == FAIL)
    printf("Incomplete bulk copy.    Only %ld row%s copied.\n",
        rowsread, (rowsread == 1) ? "": "s");

See Also

bcp_batch, bcp_bind, bcp_colfmt, bcp_collen, bcp_colptr, bcp_columns, bcp_control, bcp_done, bcp_init, bcp_sendrow


bcp_init

Initializes bulk copy operation.

Syntax

RETCODE bcp_init (
PDBPROCESS dbproc,
LPCSTR tblname,
LPCSTR hfile,
LPCSTR errfile,
INT direction );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
tblname
Is the name of the database table to be copied in or out. This name can also include the database name or the database owner name. For example, pubs.gracie.titles, pubs..titles, gracie.titles, and titles are all legal table names.

If direction is DB_OUT, tblname can also be the name of a database view.

hfile
Is the name of the user file to be copied into or out of SQL Server. If data is being copied directly from variables using bcp_sendrow, set hfile to NULL.
errfile
Is the name of the error file to be used. This error file is filled with progress messages, error messages, and copies of any rows that, for any reason, could not be copied from a user file to a SQL Server table. If NULL is passed as errfile, no error file is used.
direction
Is the direction of the copy. It must be one of two values: DB_IN or DB_OUT. DB_IN indicates a copy from program variables or a user file to the database table, while DB_OUT indicates a copy from the database table to the user file. It is illegal to request a bulk copy from the database table (DB_OUT) without supplying a user filename.

Returns

SUCCEED or FAIL.

Remarks

The bcp_init function performs the necessary initializations for a bulk copy of data between the workstation and SQL Server. It sets the default user file data formats and examines the structure of the database table.

If a user file is being used (see the description of the hfile parameter), the default data native formats are as follows:

  • The order, type, length, and number of the columns in the user file are assumed to be identical to the order, type, and number of the columns in the database table.
  • If a given database column's data is fixed length, then the user file's data column is also fixed length. When a given database column's data is variable length or when it can contain null values, the user file's data column is prefixed by a 4-byte length value for SQLTEXT and SQLIMAGE datatypes and a 1-byte length value for all other types.
  • There are no terminators of any kind between user file columns.

Any of these defaults can be overridden by calling bcp_columns and bcp_colfmt.

To use the bulk copy functions to copy data to a database table, follow these examples:

  • Call BCP_SETL to make the DBPROCESS structure usable for bulk copy purposes:
    login = dblogin();
BCP_SETL(login, TRUE);
  • If the table has no indexes, set the database option select into/bulkcopy to TRUE, use the database, and send the SQL Server CHECKPOINT statement:
    sp_dboption 'mydb', 'select into/bulkcopy', 'true'
go
use mydb
go
checkpoint

If no user file is being used, it is necessary to call bcp_bind to specify the format and location in memory for each column's data value, and send the rows using bcp_sendrow

The bcp_init function must be called before any other bulk copy functions. Failure to do so results in an error.

See Also

bcp_batch, bcp_bind, bcp_colfmt, bcp_collen, bcp_colptr, bcp_columns, bcp_control, bcp_done, bcp_exec, bcp_sendrow


bcp_moretext

Sends part of a text or image value to SQL Server.

Syntax

RETCODE bcp_moretext (
PDBPROCESS dbproc,
DBINT size,
LPCBYTE text );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
size
Is the size of this particular part of the text or image value being sent to SQL Server. Sending more text or image bytes to SQL Server than were specified in the call to bcp_bind or bcp_collen results in an error.
text
Is a pointer to the text or image portion to be sent to SQL Server.

Returns

SUCCEED or FAIL.

Remarks

This function is used in conjunction with bcp_bind and bcp_sendrow to send a large SQLTEXT or SQLIMAGE value to SQL Server in a number of smaller chunks. This is particularly useful with operating systems unable to allocate extremely long data buffers.

If bcp_bind is called with a type parameter of SQLTEXT or SQLIMAGE and a non-null varaddr parameter, bcp_sendrow sends the entire text or image data value, just as it does for all other datatypes. If, however, bcp_bind has a null varaddr parameter, bcp_sendrow returns control to the application immediately after all nontext and nonimage columns are sent to SQL Server. The application can then call bcp_moretext repeatedly to send the text and image columns to SQL Server, a chunk at a time.

If you use bcp_moretext to send one text or image column in the row, you must also use it to send all other text and image columns in the row.

If the row contains more than one text or image column, bcp_moretext first sends its data to the lowest numbered (that is, leftmost) text or image column, followed by the next lowest numbered column, and so on.

An application normally calls bcp_sendrow and bcp_moretext within loops to send a number of rows of data. Here's an outline of how to do this for a table containing two text columns:

while (there are still rows to send)
{
bcp_sendrow(...);

for (all the data in the first text column)
bcp_moretext(...);

for (all the data in the second text column)
bcp_moretext(...);
}

Example

This example shows how to use bcp_moretext with bcp_bind and bcp_sendrow:

LOGINREC    *login;
DBPROCESS    *dbproc;

DBINT    id = 5;
char    *part1 = "This text value isn't very long,";
char    *part2 = " but it's broken up into three parts";
char    *part3 = " anyhow.";

// Install error handler and message handler.
dberrhandle(err_handler);
dbmsghandle(msg_handler);

// Open a DBPROCESS
login = dblogin();
BCP_SETL(login, TRUE);
DBSETLUSER(login, "user");
DBSETLPWD(login, "my_passwd");
DBSETLAPP(login, "example");
dbproc = dbopen(login, "my_server");
// Initialize bcp.
if (bcp_init(dbproc, "comdb..articles", (BYTE *)NULL,
    (BYTE *)NULL, DB_IN) == FAIL)
    exit(ERREXIT);

// Bind program variables to table columns.
if (bcp_bind(dbproc, (BYTE *)&id, 0, (DBINT)-1, (BYTE *)NULL, 0,     SQLINT4, 1)
    == FAIL)
{
    fprintf(stderr, "bcp_bind, column 1, failed.\n");
    exit(ERREXIT);
}

if (bcp_bind
    (dbproc, (BYTE *)NULL, 0, (DBINT)(strlen(part1)
    strlen(part2)  strlen(part3)), (BYTE *)NULL, 0,
    SQLTEXT, 2) == FAIL)
{
    fprintf(stderr, "bcp_bind, column 2, failed.\n");
    exit(ERREXIT);
}

// Now send this row, with the text value broken into three chunks.
if (bcp_sendrow(dbproc) == FAIL)
    exit(ERREXIT);
if (bcp_moretext(dbproc, (DBINT)strlen(part1), part1) == FAIL)
    exit(ERREXIT);
if (bcp_moretext(dbproc, (DBINT)strlen(part2), part2) == FAIL)
    exit(ERREXIT);
if (bcp_moretext(dbproc, (DBINT)strlen(part3), part3) == FAIL)
    exit(ERREXIT);

// All done.
bcp_done(dbproc);
dbclose(dbproc);

See Also

bcp_bind, bcp_collen, bcp_sendrow; dbwritetext


bcp_readfmt

Reads a datafile format definition from a user file for a bulk copy between a file and SQL Server.

Syntax

RETCODE bcp_readfmt (
PDBPROCESS dbproc,
LPCSTR filename );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
filename
Is the full directory and file name specification of the file containing the format definitions.

Returns

SUCCEED or FAIL.

Remarks

After bcp_readfmt reads a datafile format definition from a host file, it makes the appropriate calls to bcp_columns and bcp_colfmt. These calls automate the bulk copy of multiple files that share a common data format.

The bulk copy utility (bcp) copies a database table to or from a host file in a user-specified format, which can be saved with bcp in definition files for datafile format. These files can later automate the process of bulk copying files that share a common format. For more information on the bcp utility and definition files for datafile format, see the Microsoft SQL Server Transact-SQL Reference.

Applications can call bcp_writefmt to create files that define datafile formats.

Note The format file cannot have been produced by a version of the bcp utility program earlier than version 4.2.

The following code fragment shows how to use bcp_readfmt:

bcp_init(dbproc, "mytable", "bcpdata", "bcperrs", DB_IN);

bcp_readfmt(dbproc, "my_fmtfile");

bcp_exec(dbproc, &rows_copied);

See Also

bcp_colfmt, bcp_columns, bcp_writefmt


bcp_sendrow

Sends a row of data from program variables to SQL Server.

Syntax

RETCODE bcp_sendrow ( PDBPROCESS dbproc );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.

Returns

SUCCEED or FAIL.

Remarks

The bcp_sendrow function builds a row from program variables and sends it to SQL Server.

Before calling bcp_sendrow, you must make calls to bcp_bind to specify the program variables to be used.

If bcp_bind is called with a type parameter of SQLTEXT or SQLIMAGE and a non-null varaddr parameter, bcp_sendrow sends the entire text or image data value, just as it does for all other datatypes. If, however, bcp_bind has a null varaddr parameter, bcp_sendrow returns control to the application immediately after all nontext and nonimage columns are sent to SQL Server. The application can then call bcp_moretext repeatedly to send the text and image columns to SQL Server, a chunk at a time. For an example, see bcp_moretext.

After the last call to bcp_sendrow, you must call bcp_done to ensure proper internal cleanup.

When bcp_sendrow is used to bulk copy rows from program variables into SQL Server tables, rows are permanently saved in SQL Server only when the user calls bcp_batch or bcp_done. The user can choose to call bcp_batch once every n rows or when there is a lull between periods of incoming data. Of course, the user can choose some other criteria or decide not to call bcp_batch at all. If bcp_batch is never called, the rows are permanently saved in SQL Server when bcp_done is called.

See Also

bcp_batch, bcp_bind, bcp_colfmt, bcp_collen, bcp_colptr, bcp_columns, bcp_control, bcp_done, bcp_exec, bcp_init, bcp_moretext


BCP_SETL

Sets the LOGINREC to enable bulk copy operations.

Syntax

RETCODE BCP_SETL (
PLOGINREC loginrec,
BOOL enable );

where

loginrec
Is a pointer to a LOGINREC structure, which is passed as a parameter to dbopen. You can get a LOGINREC structure by calling dblogin.
enable
Is a boolean value (TRUE or FALSE) that specifies whether to enable bulk copy operations for the resulting DBPROCESS. By default, DBPROCESS structures are not enabled for bulk copy operations.

Returns

SUCCEED or FAIL.

Remarks

This function sets a field in the LOGINREC structure that tells SQL Server that the DBPROCESS connection can be used for bulk copy operations. For it to have any effect, it must be called before dbopen, the function that actually allocates the DBPROCESS structure.

In applications that allow users to make ad hoc queries, you may want to avoid calling this function to keep users from initiating a bulk copy sequence with Transact-SQL statements. Or you may want to call it with the enable parameter set to FALSE. Once a bulk copy sequence has begun, it cannot be stopped with a Transact-SQL statement.

See Also

bcp_init, dblogin, dbopen, DBSETLAPP, DBSETLHOST, DBSETLPWD, DBSETLUSER


bcp_writefmt

Writes a datafile format definition to a user file for a bulk copy between a file and SQL Server.

Syntax

RETCODE bcp_writefmt (
PDBPROCESS dbproc,
LPCSTR filename );

where

dbproc
Is the DBPROCESS structure that is the handle for a particular workstation/ SQL Server process. It contains all the information that DB-Library uses to manage communications and data between the workstation and SQL Server.
filename
Is the full path and filename of the file containing the format definitions.

Returns

SUCCEED or FAIL.

Remarks

The format of the datafile reflects previous calls to bcp_columns and bcp_colfmt.

The bulk copy utility (bcp) copies a database table to or from a host file in a user-specified format, which can be saved with bcp in definition files that store the datafile format. These files can later automate the process of bulk copying files that share a common format. For more information on the bcp utility and definition files for datafile format, see the Microsoft SQL Server Transact-SQL Reference.

Read format-definition files with bcp_readfmt.

Note The file produced by bcp_writefmt is not compatible with versions of the bcp utility program before version 4.2.

Example

The following example shows how to use bcp_writefmt:

bcp_init(dbproc, "mytable", "bcpdata", "bcperrs", DB_OUT);

bcp_columns(dbproc, 3);
bcp_colfmt(dbproc, 1, SQLCHAR, 0, -1, '\t', 1, 1);
bcp_colfmt(dbproc, 2, SQLCHAR, 0, -1, '\t', 1, 2);
bcp_colfmt(dbproc, 3, SQLCHAR, 0, -1, '\t', 1, 3);

bcp_writefmt(dbproc, "my_fmtfile");

bcp_exec(dbproc, &rows_copied);

See Also

bcp_colfmt, bcp_columns, bcp_readfmt


Chapter 10 Two-Phase Commit Functions

Two-Phase Commit Functions

Programming Distributed Transactions

The Commit Service and the Application Program

The Probe Process

Two-Phase Commit Functions

Two-Phase Commit Example

abort_xact

build_xact_string

close_commit

commit_xact

open_commit

remove_xact

scan_xact

start_xact

stat_xact


Programming Distributed Transactions

The two-phase commit service allows an application to coordinate updates among multiple SQL Servers. This implementation of distributed transactions treats transactions on separate SQL Servers as a single transaction. The service uses one SQL Server, the commit server, as a record keeper that helps the application determine whether to commit or to roll back transactions. Thus, the two-phase commit guarantees that either all the databases on the participating servers are updated or that none of them are.

A distributed transaction submits Transact-SQL statements to SQL Servers through DB-Library functions. An application opens a session with each server, executes the update commands, and then prepares to commit the transaction. Through DB-Library, the application executes the following to each participating server:

  • A BEGIN TRANSACTION statement with identifying information about the application, the transaction, and the commit server.
  • The Transact-SQL update statements.
  • A PREPARE TRANSACTION statement that indicates that the updates have been performed and that the server is prepared to commit. This statement cannot be used outside the context of DB-Library.

After all servers participating in the distributed transaction have been updated, the two-phase commit begins:

  1. In the first phase, all servers agree that they are ready to commit.
  2. In the second phase, they all commit ¾ a COMMIT TRANSACTION statement is executed to all servers.

The application then tells the commit service that the transaction is complete, and the connections are closed. If an error occurs between phases one and two, all servers coordinate with the commit service to see if the transaction should be committed or canceled.


The Commit Service and the Application Program

The commit service acts as a single place of record to help the application decide whether the transaction should be committed or canceled.

If the SQL Server cannot communicate with the server functioning as the commit service, it retries the connection every minute. The current command displayed in the command column of sp_who for any transaction still attempting to connect to the commit service server is PREPARE TRANSACTION. The system administrator can use the KILL command to stop the server's attempts to retry the connection. If a connection cannot be established within 1 minute, the database is marked as "not recovered" and an attempt is made to recover the next database. When the commit service server is available again, shutting down the server with the unrecovered database and bringing the server back up again enables the recovery of the transaction in doubt.

The role of the application is to deliver the Transact-SQL statements to the SQL Servers in the proper order, using the proper DB-Library functions. The role of the commit service is to provide a single place where the commit/rollback status is maintained. The SQL Servers communicate with the commit service only if a failure happens during the two-phase commit.

To keep transaction records, the commit service needs its own DBPROCESS structure, separate from those used in the distributed transaction. Note, however, that the server handling the commit service also can be one of the servers participating in the transaction, as long as the commit service has its own DBPROCESS. In fact, all the servers in the transaction could be one and the same, although then you would not need this special library.


The Probe Process

If any server must recover the transaction, it initiates a process called probe, which determines the last known status of the transaction. The probe process makes use of the same status-checking function, stat_xact, that the commit service uses to check on the progress of a distributed transaction. After it returns the status of that transaction to the commit service, the probe process ends.


Two-Phase Commit Functions

The functions that make up the two-phase commit service are as follows:

open_commit
Opens a connection with the commit service. The function is given the login ID of the user initiating the session and the name of the commit service. It returns a pointer to a DBPROCESS structure used in subsequent commit service calls.
start_xact
Records the start of a distributed transaction and stores initial information about the transaction (DBPROCESS ID, application name, transaction name, and number of sites participating) in a lookup table on the commit server. It returns the commid identifying number for the transaction.
build_xact_string
Builds a name string for use by each participating SQL Server for its BEGIN TRANSACTION and PREPARE TRANSACTION statements. This string encodes the application's transaction name, the commit service name, and the commid.
commit_xact
Tells the commit service to commit the transaction.
abort_xact
Tells the commit service to cancel the transaction.
remove_xact
Decreases the number of servers still participating in the transaction.
close_commit
Closes the connection with the commit service.

Two additional functions are used for ongoing status reports:

scan_xact
Returns the status of a single transaction or all distributed transactions.
stat_xact
Returns the completion status of a distributed transaction.

During a session, the diagnostic functions, scan_xact and stat_xact, check that the commit service carried out the request.

The scan_xact function uses the commit service lookup table, spt_committab, which holds the values of the following:

  • Transaction ID.
  • Time the transaction started.
  • Last time the row was updated.
  • Number of servers initially involved in the transaction.
  • Number of servers that have not finished processing.
  • Status ("a" for abort, "c" for commit, "b" for begin).
  • Application name.
  • Transaction name.

The two-phase commit functions call internal stored procedures (for example, sp_start_xact) that are created in each server's master database. The INSTMSTR.SQL script creates the commit service lookup table and stored procedures in each server's master database for use whenever the server becomes a commit server.


Two-Phase Commit Example

The following example program illustrates the two-phase commit service. Periodically, the code is interrupted by comments to orient you and to document how recovery occurs for different types of errors. The corresponding example file, TWOPHASE.C, is found in \SQL\DBLIB\SAMPLES.

To compile and link the example, follow the instructions for compiling and linking programs for your operating system. (See Building Applications.)

This example assumes that you have two servers running, sql_svr1 and sql_svr2, and a third server, sql_svr3, to coordinate transactions. If you don't have a second and third server available, contact your system administrator. If your servers are named differently, replace sql_svr1, sql_svr2, and sql_svr3 in the source code with the actual names of your servers.

//    Demo of Two-Phase Commit Service
//
//    This example uses the two-phase commit service
//    to perform a simultaneous update on two servers.
//    In this example, one of the servers participating
//    in the distributed transaction also functions as
//    the commit service.
//
//    In this particular example, the same update is
//    performed on both servers. You can, however, use
//    the commit server to perform completely different
//    updates on each server.

#define DBNTWIN32
#include <windows.h>
#include <stdio.h>
#include <sqlfront.h>
#include <sqldb.h>

char    cmdbuf[256];
char    xact_string[128];
// Forward declarations of the error handler and message handler.
int    err_handler();
int    msg_handler();
main(argc,argv)
int argc;
char *argv[];
{
    DBPROCESS    *dbproc_server1;
    DBPROCESS    *dbproc_server2;
    DBPROCESS    *dbproc_commit;
    LOGINREC    *login;
    DBINT        commid;

    RETCODE    ret_server1;
    RETCODE    ret_server2;

    dberrhandle(err_handler);
    dbmsghandle(msg_handler);

    // Initialize private DB-Library structures.
    dbinit();

    printf("Demo of Two Phase Commit\n");

    // Open connections with the servers and the commit service.
    login = dblogin();
    DBSETLUSER(login, "user");
    DBSETLPWD(login, "my_passwd");
    DBSETLAPP(login, "example");
    dbproc_server1 = dbopen (login, "sql_svr1");
    dbproc_server2 = dbopen (login, "sql_svr2");
    dbproc_commit = open_commit (login, "sql_svr3");

    if (dbproc_server1 == NULL ||
        dbproc_server2 == NULL ||
        dbproc_commit    == NULL)
    {
        printf(" Connections failed!\n");
        return (ERREXIT);
    }

    // Use the "pubs" database.
    dbuse(dbproc_server1, "pubs");
    dbuse(dbproc_server2, "pubs");

    // Start the distributed transaction on the commit service.
    commid = start_xact(dbproc_commit, "demo", "test", 2);

The application is now in the begin phase of the two-phase commit transaction.

// Build the transaction name.
build_xact_string ("test", "sql_svr3", commid, xact_string);

// Build the first command buffer.
sprintf(cmdbuf, "BEGIN TRANSACTION %s", xact_string);

// Begin the transactions on the different servers.
dbcmd(dbproc_server1, cmdbuf);
dbsqlexec(dbproc_server1);
dbcmd(dbproc_server2, cmdbuf);
dbsqlexec(dbproc_server2);

dbcancel (dbproc_server1);
dbcancel (dbproc_server2);

// Do various updates.
sprintf(cmdbuf, " update titles set price = $1.50 where");
strcat(cmdbuf, " title_id = 'BU1032'");
dbcmd(dbproc_server1, cmdbuf);
ret_server1 = dbsqlexec(dbproc_server1);
dbcmd(dbproc_server2, cmdbuf);
ret_server2 =dbsqlexec(dbproc_server2);

If any type of failure occurs at this point, the application should roll back the transactions, using abort_xact.

if (ret_server1 == FAIL || ret_server2 == FAIL)
{
    // Some part of the transaction failed.
    printf(" Transaction aborted -- dbsqlexec failed\n");
    abortall(dbproc_server1, dbproc_server2, dbproc_commit, commid);
}

dbcancel (dbproc_server1);
dbcancel (dbproc_server2);

// Find out if all servers can commit the transaction.
sprintf(cmdbuf, "PREPARE TRANSACTION");
dbcmd(dbproc_server1, cmdbuf);
dbcmd(dbproc_server2, cmdbuf);
ret_server1 = dbsqlexec(dbproc_server1);

The application has entered the prepare stage of the two-phase commit transaction, but the commit server thinks the application is still in the begin phase.

ret_server2 = dbsqlexec(dbproc_server2);

If any type of failure occurs at this point, the application should roll back the transactions, using abort_xact.

if (ret_server1 == FAIL || ret_server2 == FAIL)
{
    // One or both of the servers failed to prepare.
    printf(" Transaction aborted -- PREPARE failed\n");
    abortall(dbproc_server1, dbproc_server2, dbproc_commit, commid);
}

dbcancel (dbproc_server1);
dbcancel (dbproc_server2);

At this point, the following failures and related consequences can occur:

  • Either the application's link to the commit server, or the commit server itself shuts down.

    The following call to commit_xact fails, and the application must roll back the transactions with abort_xact.

  • The application's link to a participating server shuts down.

    The following call to commit_xact succeeds, but the application's COMMIT TRANSACTION command to the participating server fails. However, aware that its connection with the application has been broken, the server uses probe to communicate with the commit server to determine whether to commit the transaction locally.

  • A participating server shuts down.

    The following call to commit_xact succeeds, but the application's COMMIT TRANSACTION command to the participating server fails. When the participating server starts back up, it uses probe to determine whether to commit the transaction locally.

  • Both the application's link to the commit server and its link to the participating server shut down.

    The following call to commit_xact fails. The application must then roll back the transactions with abort_xact, but it cannot communicate with the participating server. The participating server, communicating with the commit server through probe, learns that the transaction was not committed in the commit service. It then rolls back the transaction locally.

  • Both the application's link to the participating server and the participating server's link to the commit server shut down.

    The following call to commit_xact succeeds, but the application cannot inform the participating server. When its connection to the application is broken, the participating server tries (unsuccessfully) to communicate with the commit server through probe to determine whether or not to commit the transaction locally.

    If a connection cannot be established within 1 minute, the database is marked as "not recovered" and an attempt is made to recover the next database. When the commit service server is available again, shutting down the server with the unrecovered database and bringing the server back up again enables the recovery of the transaction in doubt.

    // Commit the transaction.
if (commit_xact(dbproc_commit, commid) == FAIL)
{
    // The commit server failed to record the commit.
    printf( " Transaction aborted -- commit_xact failed\n");
    abortall(dbproc_server1, dbproc_server2, dbproc_commit, commid);
}

The application has entered the committed phase of the two-phase commit transaction. Now, any probe process querying the commit server is told to commit the transaction locally. From here on, the application does not need to be concerned about canceling the transaction.

// The transaction has successfully committed.
// Inform the servers.
sprintf(cmdbuf, "COMMIT TRANSACTION");
dbcmd(dbproc_server1, cmdbuf);
if (dbsqlexec(dbproc_server1) != FAIL)
    remove_xact(dbproc_commit, commid, 1);
  • If the dbsqlexec call to server1 in the previous lines of code returns FAIL because the application's link to the server has been broken, server1 uses probe to communicate with the commit server. The probe process finds that the transaction is committed in the commit server and tells server1 to commit it locally.

    If possible, the system administrator should always wait until communication with the commit server has been re-established before canceling the infected process.

  • If the dbsqlexec call to server1 returns FAIL because server1 has shut down, the local transaction remains in limbo until server1 is restored. As part of the recovery process, server1 uses probe to communicate with the commit server. When probe finds that the transaction is committed in the commit server, it tells server1 to commit the transaction locally.

    If probe can't communicate with the commit server, server1 marks the database as "not recovered." After communication with the commit server is re-established, the suspect database should be recovered.)

    dbcmd(dbproc_server2, cmdbuf);
if (dbsqlexec(dbproc_server2) != FAIL)
remove_xact(dbproc_commit, commid, 1);
  • If the dbsqlexec to server2 in the preceding lines returns FAIL because the application's link to the server has been interrupted, server 2 uses probe to communicate with the commit server. When probe finds that the transaction is committed in the commit server, it tells server2 to commit the transaction locally.

    If possible, the system administrator should always wait until communication with the commit server has been re-established before canceling the infected process.

  • If the dbsqlexec call to server2 returns FAIL because server2 has shut down, the local transaction remains in limbo until server2 is restored. As part of the recovery process, server2 uses probe to communicate with the commit server. When probe finds that the transaction is committed in the commit server, it tells server2 to commit the transaction locally.

    If probe can't communicate with the commit server, server2 marks the database as "not recovered." After communication with the commit server is re-established, the suspect database should be recovered again.

    // Close the connection to the commit server.
close_commit(dbproc_commit);

The close_commit function marks the transaction as complete in the spt_committab table on the commit server. If close_commit fails, no harm is done. The transaction is simply not marked as complete. In this case, the system administrator can manually update spt_committab.

    printf( "We made it!\n");
    dbexit();
    return(STDEXIT);
}

// Function to terminate the distributed transaction.

abortall( dbproc_server1, dbproc_server2, dbproc_commit, commid )
DBPROCESS    *dbproc_server1;
DBPROCESS    *dbproc_server2;
DBPROCESS    *dbproc_commit;
DBINT        commid;
{
    // Some part of the transaction failed.

    // Inform the commit server of the failure.
    abort_xact(dbproc_commit, commid);

    // Roll back the transactions on the different servers.
    sprintf(cmdbuf, "ROLLBACK TRANSACTION");
    dbcmd(dbproc_server1, cmdbuf);
    if (dbsqlexec(dbproc_server1) != FAIL)
        remove_xact(dbproc_commit, commid, 1);
    dbcmd(dbproc_server2, cmdbuf);
    if (dbsqlexec(dbproc_server2) != FAIL)
        remove_xact(dbproc_commit, commid, 1);

    dbexit();
    return(ERREXIT);
}
// Message and error-handling functions.
int msg_handler(dbproc,msgno,msgstate, severity, msgtext)
DBPROCESS    *dbproc;
DBINT    msgno;
int    msgstate;
int    severity;
char    *msgtext;
{
    // Msg 5701 is just a USE DATABASE message, so skip it.
    if (msgno == 5701)
        return (0);
    // Print any severity 0 message as is, without extra stuff.
    if (severity == 0)
    {
        printf("%s\n",msgtext);
        return (0);
    }

    printf("SQL Server message %ld, severity %d:\n\t%s\n",
    msgno, severity, msgtext);

    if (severity >= 16)
    {
        printf("Program Terminated! Fatal SQL Server error.\n");
        exit(ERREXIT);
    }
    return (0);
}

int err_handler(dbproc, severity, dberr, oserr, dberrstr, oserrstr)
DBPROCESS    *dbproc;
int    severity;
int    dberr;
int    oserr;
char    *dberrstr;
char    *oserrstr;

    if ((dbproc == NULL) || (DBDEAD(dbproc)))
        return (INT_CANCEL);
    else
    {    printf("DB-Library error: \n\t%s\n", dberrstr);
    if (oserr != DBNOERR)
            printf ("Operating system error:\n\t%s\n", oserrstr);
    }
    return (INT_CANCEL);
}


abort_xact

Marks a distributed transaction as canceled.

Syntax

RETCODE abort_xact (
PDBPROCESS connect,
DBINT commid );

where

connect
Is the DBPROCESS structure used to communicate with the commit service.
commid
Is the number used by the commit service to identify the transaction.

Returns

SUCCEED or FAIL.

Remarks

This function informs the commit service that the status of a distributed transaction should be changed from "begin" to "abort."

See Also

commit_xact, remove_xact, scan_xact, start_xact, stat_xact


build_xact_string

Builds a name for a distributed transaction.

Syntax

void build_xact_string (
LPCSTR xact_name,
LPCSTR service_name,
DBINT commid,
LPSTR result );

where

xact_name
Is the application or username for the transaction. This name is encoded in the name string, but it is not used by the commit service or SQL Server. It identifies the transaction for debugging.
service_name
Is the name through which SQL Server contacts the commit service. You must supply a name for this parameter.
commid
Is the number used by the commit service to identify the transaction. The commid is the number returned by the call to start_xact.
result
Is the address of the buffer where the string should be built. The space must be allocated by the caller.

Remarks

This function builds a name string for use in the BEGIN TRANSACTION and PREPARE TRANSACTION statements in the SQL Server transaction. If SQL Server has to recover the transaction, it uses information encoded in the name to determine which commit service to contact and which transaction in that service to inquire about. The application should execute a Transact-SQL BEGIN TRANSACTION statement, using the string built by build_xact_string.

See Also

commit_xact, start_xact


close_commit

Ends a connection with the commit service by calling dbclose.

Syntax

void close_commit ( PDBPROCESS connect );

where

connect
Is the pointer to the DBPROCESS structure that was originally returned by open_commit.

Remarks

When the application is through with the commit service, call close_commit to free resources.

See Also

dbclose, open_commit


commit_xact

Marks a distributed transaction as committed.

Syntax

RETCODE commit_xact (
PDBPROCESS connect,
DBINT commid );

where

connect
Is the DBPROCESS structure used to communicate with the commit service.
commid
Is the number used by the commit service to identify the transaction.

Returns

SUCCEED or FAIL.

Remarks

This function informs the commit service that the status of a distributed transaction should be changed from "begin" to "commit."

See Also

abort_xact, remove_xact, scan_xact, start_xact, stat_xact


open_commit

Establishes a connection with the commit service.

Syntax

PDBPROCESS open_commit (
PLOGINREC login,
LPCSTR servername );

where

login
Is a LOGINREC structure containing information about the user initiating the session, such as login name, password, or options desired. The LOGINREC must be obtained from a prior call to the DB-Library function dblogin. The caller may want to initialize fields in the LOGINREC. For more details, see dblogin in DB-Library Functions.
servername
Is the name of the commit service, for example, my_server.

Returns

A pointer to a DBPROCESS structure used in subsequent commit service calls or other DB-Library calls, or NULL if the open failed.

Remarks

This function calls dbopen to establish a connection with the commit service. A call to open_commit must precede any calls to other commit service functions, such as start_xact, commit_xact, abort_xact, remove_xact, and scan_xact. A session with the commit service is closed by calling close_commit.

See Also

abort_xact, close_commit, commit_xact, dblogin, dbopen,, remove_xact, scan_xact, start_xact


remove_xact

Decrements the count of sites still active in the distributed transaction.

Syntax

RETCODE remove_xact (
PDBPROCESS connect,
DBINT commid,
INT n );

where

connect
Is the DBPROCESS structure used to communicate with the commit service.
commid
Is the number used by the commit service to identify the transaction.
n
Is the number of sites to remove from the transaction.

Returns

SUCCEED or FAIL.

Remarks

The commit service records the number of sites participating in a distributed transaction. The remove_xact function informs the commit service that one or more sites has committed or canceled the transaction locally and therefore is no longer participating. The commit service removes the sites from the transaction by decrementing the count of sites. The transaction record is deleted entirely if the count drops to zero.

See Also

abort_xact, commit_xact, scan_xact, start_xact, stat_xact


scan_xact

Prints the commit service record for distributed transactions.

Syntax

RETCODE scan_xact (
PDBPROCESS connect,
DBINT commid );

where

connect
Is the DBPROCESS structure used to communicate with the commit service.
commid
Is the number used by the commit service to identify the transaction. If commid is -1, all commit service records are displayed.

Returns

SUCCEED or FAIL.

Remarks

This function displays the commit service record for a specific distributed transaction or for all distributed transactions known to the commit service or the default output device.

The Windows operating system does not support scan_xact.

See Also

abort_xact, commit_xact, remove_xact, start_xact, stat_xact


start_xact

Starts a distributed transaction using the commit service.

Syntax

DBINT start_xact (
PDBPROCESS connect,
LPCSTR application_name,
LPCSTR xact_name,
INT site_count );

where

connect
Is the DBPROCESS structure used to communicate with the commit service.
application_name
Is the name of the application. This name can be anything you choose. It appears in the table maintained by the commit service but is not used by the commit service or the SQL Server recovery system.
xact_name
Is the name of the transaction. This name appears in the table maintained by the commit service and must be supplied as part of the transaction name string built by build_xact_string. The name cannot contain a period (.) nor a colon (:).
site_count
Is the number of sites participating in the transaction.

Returns

An integer called commid. This number is used to identify the transaction in subsequent calls to the commit service. In case of error, this function returns 0.

Remarks

This function records the start of a distributed transaction with the commit service. A record is placed in the commit service containing the commid, which is a number that the caller subsequently uses to identify the transaction to the commit service.

See Also

abort_xact, build_xact_string, commit_xact, remove_xact, scan_xact, stat_xact


stat_xact

Returns the status of the specified distributed transaction.

Syntax

INT stat_xact (
PDBPROCESS connect,
DBINT commid );

where

connect
Is the DBPROCESS structure used to communicate with the commit service.
commid
Is the number used by the commit service to identify the transaction. If commid is -1, all commit service records are displayed.

Returns

A character code: "a" (abort), "b" (begin), "c" (commit), "u" (unknown), or -1 (request failed).

See Also

abort_xact, commit_xact, remove_xact, scan_xact, start_xact


Appendix A DB-Library Options

DB-Library Options

This appendix describes the DB-Library options.

Options


Options

The functions dbsetopt and dbclropt use the following constants, defined in SQLDB.H, for setting and clearing options. All options are off by default.

DBANSItoOEM | DBOEMtoANSI (Windows and Windows NT only)
Translates, through the Windows functions AnsiToOem and OemToAnsi, all characters or text coming from or going to the server. Since MS-DOS uses the OEM character set and the Windows operating system uses the ANSI character set, this translation becomes necessary when international characters (character code larger than 127) are in the database.

There are two ways to convert data with transfers to and from the server:

  • Calling dbsetopt with DBANSItoOEM or DBOEMtoANSI.

Or

  • For Windows, in the WIN.INI file's [SQLSERVER] section, setting AutoANSItoOEM=ON.

    For Windows NT, use the SQL Client Configuration Utility's Automatic ANSI TO OEM option. This modifies the Registry under the following subtree:

    HKEY_LOCAL_MACHINE\
    SOFTWARE\
    Microsoft\
    MSSQLServer\
    Client\
    DB-Lib

    and sets the AutoAnsiToOem entry to ON (AutoAnsiToOem:REG_SZ:ON). This is the default entry.

The AutoANSItoOEM entry controls the default conversion behavior when you connect to a server. If AutoANSItoOEM is set to ON, conversion is turned on in the following cases:

  • ANSI clients to OEM servers (Windows and Windows NT)
  • OEM clients to ANSI servers (Windows NT)

If AutoANSItoOEM is set to OFF, conversion is turned off for all connections.

You can override the default conversion by calling dbsetopt after calling dbopen.

Use the DBANSItoOEM option to enable conversion when connecting an ANSI client to an OEM server. Use the DBOEMtoANSI option to enable conversion when connecting to an OEM client (Windows NT Console application) to an ISO server. You cannot set both options for the same DBPROCESS.

DBARITHABORT
Cancels a query during execution when an arithmetic exception occurs. If neither DBARITHABORT nor DBARITHIGNORE is set, SQL Server substitutes null values and prints a warning after the query has been executed.
DBARITHIGNORE
Substitutes (without warning) null values for selected or updated values when an arithmetic exception occurs during query execution. If neither DBARITHABORT nor DBARITHIGNORE is set, SQL Server substitutes null values and prints a warning after the query has been executed.
DBBUFFER
Buffers the result rows to access them nonsequentially with dbgetrow. DB-Library handles this option locally. With the option set, supply a parameter that equals the number of rows you want buffered. If you choose 0, the buffer is set to a default size (currently 100).

Row buffering keeps a specified number of SQL Server result rows in the program's memory. Without row buffering, the result row generated by each new dbnextrow call overwrites the contents of the previous result row. So use row buffering for programs that need to look at result rows nonsequentially.

When turned on, DBBUFFER reduces memory and performance because each row in the buffer must be allocated and freed individually. Therefore, write the application to turn on the DBBUFFER option only if it calls dbgetrow. Note that row buffering, an independent issue, has nothing to do with network buffering. (For more information about row buffering, see dbgetrow, dbnextrow, and dbclrbuf in DB-Library Functions.)

DBCLIENTCURSORS

Forces the use of client cursors. When this option is set, every cursor opened with dbcursoropen will be a client cursor. Even when connected to SQL Server 6.0, server cursors will not be used.

This option can be enabled for a client running Windows by placing the line UseClientCursors=ON in the [SQLSERVER] section of WIN.INI. This option can be enabled for a client running Windows NT by setting the value UseClientCursors to ON (UseClientCursors : REG_SZ : ON) in the following Windows NT Registry key:

HKEY_LOCAL_MACHINE\
SOFTWARE\
Microsoft\
MSSQLServer\
Client\
DB-Lib

DBNOAUTOFREE
Clears the command buffer only by a call to dbfreebuf. When DBNOAUTOFREE is not set, after a call to dbsqlexec or dbsqlsend, the first call to either dbcmd or dbfcmd automatically clears the command buffer before the new text is entered.
DBNOCOUNT
Stops returning information about the number of rows affected by each Transact-SQL statement. The application can otherwise get this information by calling DBCOUNT.
DBNOEXEC
Processes the query through the compile step, but does not execute it. You can use this option with DBSHOWPLAN.
DBOFFSET
Indicates where SQL Server should return offsets to certain constructs in the query. This option takes a parameter that specifies the particular construct. Valid values of this parameter include:
  • select
  • from
  • table
  • order
  • compute
  • statement
  • procedure
  • execute
  • param

Note The value param refers to parameters of stored procedures.

Calls to functions such as dbsetopt can specify these parameters in either uppercase or lowercase. For the internal types that correspond to the offsets, see dbgetoff in DB-Library Functions. Offsets are returned only if the batch contains no syntax errors.

DBPARSEONLY
Checks the syntax of the query and returns error messages to the host. Offsets are returned if the DBOFFSET option is set and there are no errors.
DBROWCOUNT
Specifies a maximum number of regular rows to be returned on SELECT statements. This option does not limit the number of compute rows returned. Different from most options, DBROWCOUNT is always on, never off. Setting DBROWCOUNT to 0 sets it back to the default, returning all the rows generated by a SELECT statement. Therefore, to turn DBROWCOUNT off, turn it on with a count of 0.
DBSETTIME
Overrides the global DB-Library timeout (set using dbsettime) and sets a new DB-Library timeout for a specific DBPROCESS connection. When setting this option, supply a parameter that specifies the connection specific DB-Library timeout in seconds.
DBSHOWPLAN
Generates a description of the processing plan after compilation and continues executing the query.
DBSTAT
Determines, after each query, when performance statistics (CPU time, elapsed time, I/O, and so on) will be returned to the host. DBSTAT takes one of two parameters: io, for statistics about SQL Server internal I/O; and time, for information about SQL Server's parsing, compilation, and execution times. DB-Library receives these statistics as informational messages, and applications can access them through the user-supplied message handler.
DBSTORPROCID
Sends the stored procedure ID to the host before sending rows generated by the stored procedure.
DBTEXTLIMIT
Causes DB-Library to limit the size of returned text or image values. When setting this option, supply a parameter with the same length, in bytes, as the longest text or image value that your program can handle. DB-Library will read but ignore any part of a text or image value that goes over this limit.

In the case of huge text values, it may take some time for the entire text value to be returned over the network. To keep SQL Server from sending this extra text, use the DBTEXTSIZE option instead of DBTEXTLIMIT.

DBTEXTSIZE
Causes SQL Server to limit the size of returned text or image values. When setting this option, supply a parameter with the same length, in bytes, as the longest text or image value that SQL Server should return.

Note that, in programs that allow ad hoc queries, the application user can override this option with the Transact-SQL SET TEXTSIZE command. To set a text limit that the user cannot override, use the DBTEXTLIMIT option instead.

DBBUFFER, DBNOAUTOFREE, and DBTEXTLIMIT are DB-Library options. That is, they affect DB-Library but are not sent to SQL Server. The others are SQL Server options (options that get sent to the SQL Server). You can set them with Transact-SQL.

As mentioned in the preceding descriptions, certain options take parameters. The following table lists these options and the possible values of their parameters:

Option | Possible parameter values
DBBUFFER | 0 to 32767
DBOFFSET | select, from, table, order, compute, statement, procedure, execute, or param
DBROWCOUNT | 0 to 2,147,483,647
DBSTAT | io or time
DBTEXTLIMIT | 0 to 65,534
DBTEXTSIZE | 0 to 2,147,483,647

The function dbsetopt requires you to specify parameters when setting any of the options in the preceding table. On the other hand, the functions dbclropt and dbisopt require you to specify a parameter only for DBOFFSET and DBSTAT, because they can have simultaneous multiple settings, which require further definition before being cleared or checked.

Note that parameters specified in calls to dbsetopt, dbclropt, and dbisopt are always passed as character strings and enclosed in quotation marks, even if they are numeric values. For more information, see dbsetopt, dbclropt, and dbisopt in DB-Library Functions.


Appendix B DB-Library Datatypes

DB-Library Datatypes

This appendix contains a list of SQL Server datatypes. To use these datatypes, include the SQLFRONT.H and SQLDB.H header files in your program. For a detailed description of SQL Server datatypes, refer to the Microsoft SQL Server Transact-SQL Reference.

Datatypes

Type Definitions


Datatypes

The following list describes the SQL Server datatypes. The dbconvert and dbwillconvert functions use these types. In addition, dbcoltype, dbalttype, dbrettype each returns one of these types.

Datatype | Description
SQLARRAY | 1 byte with variable length
SQLBINARY | binary
SQLBIT | bit
SQLCHAR | char
SQLDATETIM4 | 4-byte smalldatetime
SQLDATETIME | 8-byte datetime
SQLDATETIMN | datetime or smalldatetime with null values allowed
SQLDECIMAL | decimal
SQLFLT4 | 4-byte real
SQLFLT8 | 8-byte float
SQLFLTN | float or real with null values allowed
SQLIMAGE | image
SQLINT1 | 1-byte tinyint
SQLINT2 | 2-byte smallint
SQLINT4 | 4-byte int
SQLINTN | tinyint, smallint, or int with null values allowed
SQLMONEY4 | 4-byte smallmoney
SQLMONEY | 8-byte money
SQLMONEYN | money or smallmoney with null values allowed
SQLNUMERIC | numeric
SQLTEXT | text
SQLVARBINARY | varbinary
SQLVARCHAR | varchar


Type Definitions

DB-Library functions use the following type definitions. Use these when defining C program variables, particularly those in dbbind, dbaltbind, dbconvert, and dbdata.

typedef char            DBCHAR;        // Char and text
typedef unsigned char   DBBINARY;      // Binary and image
typedef unsigned char   DBTINYINT;     // 1-byte tinyint
typedef short           DBSMALLINT;    // 2-byte smallint
typedef unsigned short  DBUSMALLINT;   // Unsigned 2-byte integer
typedef long            DBINT;         // 4-byte int
typedef float           DBFLT4;        // 4-byte real
typedef double          DBFLT8;        // 8-byte float
typedef unsigned char   DBBIT;         // Bit
typedef unsigned char   DBBOOL;        // Boolean
typedef long            DBMONEY4;      // 4-byte smallmoney
typedef struct dbmoney       // 8-byte money
{
    DBINT mnyhigh;
    ULONG mnylow;
} DBMONEY;
typedef struct dbdatetime4   // 4-byte smalldatetime
{
    USHORT numdays;          // Days since Jan 1, 1900
    USHORT nummins;          // Minutes since midnight
} DBDATETIM4;

typedef struct dbdatetime    // 8-byte datetime
{
    DBINT dtdays;            // Days since Jan 1, 1900
    ULONG dttime;            // 300ths of a second since midnight
} DBDATETIME;

#define MAXNUMERICLEN 16

typedef struct dbnumeric     // Numeric (and decimal)
{
    BYTE precision;          // Precision
    BYTE scale;              // Scale
    BYTE sign;               // 1 = Positive, 0 = Negative
    BYTE val[MAXNUMERICLEN]; // Padded little endian value
} DBNUMERIC;

typedef DBNUMERIC DBDECIMAL; // Decimal

#define DBMAXCHAR 256

typedef struct dbvarychar          // Pascal-type string
{
    DBSMALLINT  len;               // Character count
    DBCHAR      str[DBMAXCHAR];    // Non-terminated string
} DBVARYCHAR;

typedef struct dbvarybin           // Pascal-type byte array
{
    DBSMALLINT  len;               // Byte count
    BYTE        array[DBMAXCHAR];  // Non-terminated array
} DBVARYBIN;


Appendix C Error Messages

Error Messages

This appendix contains the complete range of possible DB-Library errors and error severity levels. The table in "Errors" lists the errors alphabetically and with their severities. The table in "Error Severities" summarizes the severity levels. Number values corresponding to the errors are passed to the currently installed, user-supplied error handler. For information about creating an error handler function for your application, see dberrhandle in DB-Library Functions.

To access these error definitions, include the SQLFRONT.H and SQLDB.H header files in your program.

Errors

Error Severities


Errors

The following error values are defined in the header file SQLFRONT.H. Note that errors with a severity of EXCOMM also have a network-related error message appended to the dberrstr value. EXCOMM errors also have network-specific error information in oserr and oserrstr.

Error no. | Error/ Error severity | Description
10000 | SQLEMEM EXRESOURCE | Unable to allocate sufficient memory.
10001 | SQLENULL EXPROGRAM | NULL DBPROCESS pointer encountered.
10002 | sqlenlog exconsistency | NULL LOGINREC pointer encountered.
10003 | SQLEPWD EXUSER | Login incorrect.
10004 | SQLECONN EXCOMM | Unable to connect: SQL Server is unavailable or does not exist.
10005 | SQLEDDNE EXINFO | DBPROCESS is dead or not enabled.
10006 | SQLENULLO EXCONSISTENCY | Attempt to login with NULL LOGINREC.
10007 | SQLESMSG EXSERVER | General SQL Server error: Check messages from SQL Server.
10008 | SQLEBTOK EXCOMM | Bad token from SQL Server: Datastream processing out of synchronization.
10009 | SQLENSPE EXPROGRAM | General nonspecific DB-Library error.
10010 | SQLEREAD EXCOMM | Read from SQL Server failed.
10011 | SQLECNOR EXPROGRAM | Column number out of range.
10012 | SQLETSIT EXINFO | Attempt to call dbtsput with an invalid timestamp.
10013 | SQLEPARM EXCONSISTENCY | Invalid parameter in DB-Library function reference.
10014 | SQLEAUTN EXPROGRAM | Attempt to update the timestamp of a table with no timestamp column.
10015 | SQLECOFL EXCONVERSION | Data conversion resulted in overflow.
10016 | SQLERDCN EXCONVERSION | Requested data conversion does not exist.
10017 | SQLEICN EXPROGRAM | Invalid value for computeid or invalid compute column number.
10018 | SQLECLOS EXCOMM | Error in closing network connection.
10019 | SQLENTXT EXPROGRAM | Attempt to get text point/timestamp from a nontext column.
10020 | SQLEDNTI EXPROGRAM | Attempt to use dbtxtsput to put a new text timestamp into a column whose datatype is neither SQLTEXT nor SQLIMAGE.
10021 | SQLETMTD EXPROGRAM | Attempt to send too much TEXT data through dbmoretext.
10022 | SQLEASEC EXPROGRAM | Attempt to send an empty command buffer to the SQL Server.
10023 | SQLENTLL EXUSER | Name too long for LOGINREC field.
10024 | SQLETIME EXTIME | SQL Server connection timed out.
10025 | SQLEWRIT EXCOMM | Write to SQL Server failed.
10026 | SQLEMODE EXCOMM | Network connection not in correct mode ¾ invalid SQL Server connection.
10027 | SQLEOOB EXCOMM | Error in sending out-of-band data to SQL Server.
10028 | SQLEITIM EXPROGRAM | Illegal timeout value specified.
10029 | SQLEDBPS EXRESOURCE | Maximum number of DBPROCESSes already allocated.
10030 | SQLEIOPT EXPROGRAM | Attempt to use invalid dboption.
10031 | SQLEASNL EXPROGRAM | Attempt to set fields in a null LOGINREC.
10032 | SQLEASUL EXPROGRAM | Attempt to set unknown LOGINREC field.
10033 | SQLENPRM EXPROGRAM | NULL parameter not allowed for this dboption.
10034 | SQLEDBOP EXPROGRAM | Invalid or out of range dbn parameter.
10035 | SQLENSIP EXPROGRAM | Negative starting index passed to dbstrcpy.
10036 | SQLECNULL EXPROGRAM | NULL destination variable not allowed.
10037 | SQLESEOF EXCOMM | Unexpected EOF from SQL Server.
10038 | SQLERPND EXPROGRAM | Attempt to initiate a new SQL Server operation with results pending.
10039 | SQLECSYN EXCONVERSION | Attempt to convert data stopped by syntax error in source field.
10040 | SQLENONET EXCOMM | DB-Library network communications layer not loaded.
10041 | SQLEBTYP EXPROGRAM | Unknown bind type passed to DB-Library function.
10042 | SQLEABNC EXPROGRAM | Attempt to bind to a nonexistent column.
10043 | SQLEABMT EXPROGRAM | User attempted a dbbind with mismatched column and variable types.
10044 | SQLEABNP EXPROGRAM | Attempt to bind using NULL pointers.
10045 | SQLEBNCR EXPROGRAM | Attempt to bind user variable to a nonexistent compute row.
10046 | SQLEAAMT EXPROGRAM | User attempted a dbaltbind with mismatched column and variable types.
10047 | SQLENXID EXNONFATAL | The server did not grant us a distributed-transaction ID.
10048 | SQLEIFNB EXPROGRAM | Illegal field number passed to bcp_control.
10049 | SQLEKBCO EXINFO | 1000 rows successfully bulk copied to host file.
10050 | SQLEBBCI EXINFO | Batch successfully bulk copied to SQL Server.
10051 | SQLEKBCI EXINFO | 1000 rows sent to SQL Server.
10052 | SQLEBCWE EXNONFATAL | I/O error while writing bcp datafile.
10053 | SQLEBCNN EXUSER | Attempt to bulk copy a null value into a server column that does not accept null values.
10054 | SQLEBCOR EXCONSISTENCY | Attempt to bulk copy an oversized row to SQL Server.
10055 | SQLEBCPI EXPROGRAM | Call bcp_init before any other bcp routines.
10056 | SQLEBCPN EXPROGRAM | Use bcp_bind, bcp_collen, and bcp_colptr only after calling bcp_init with the copy direction set to DB_IN.
10057 | SQLEBCPB EXPROGRAM | Do not use bcp_bind after bcp_init has been passed a non-null input filename.
10058 | SQLEVDPT EXUSER | For bulk copy, all variable-length data must have either a length-prefix or a terminator specified.
10059 | SQLEBIVI EXPROGRAM | Use bcp_columns and bcp_colfmt only after bcp_init has been passed a valid input file.
10060 | SQLEBCBC EXPROGRAM | Call bcp_columns before bcp_colfmt.
10061 | SQLEBCFO EXUSER | Host files must contain at least one column: bcp.
10062 | SQLEBCVH EXPROGRAM | Call bcp_exec only after bcp_init has been passed a valid host file.
10063 | SQLEBCUO EXRESOURCE | Unable to open host datafile: bcp.
10064 | SQLEBUOE EXRESOURCE | Unable to open error file: bcp.
10065 | SQLEBWEF EXNONFATAL | I/O error while writing bcp error file.
10066 | SQLEBTMT EXPROGRAM | Attempt to send too much text data with bcp_moretext.
10067 | SQLEBEOF EXNONFATAL | Unexpected EOF encountered in bcp datafile.
10068 | SQLEBCSI EXCONSISTENCY | Host-file columns may be skipped only when copying into the server.
10069 | SQLEPNUL EXCONSISTENCY | NULL program pointer encountered.
10070 | SQLEBSKERR EXCONSISTENCY | Cannot seek in data file.
10071 | SQLEBDIO EXPROGRAM | Bad bulk-copy direction.
10072 | SQLEBCNT EXUSER | Attempt to use bulk copy with a nonexistent server table.
10073 | SQLEMDBP EXPROGRAM | Attempt to set maximum number of DPPROCESS lower than 1.
10075 | SQLCRSINV EXPROGRAM | Invalid cursor statement.
10076 | SQLCRSCMD EXPROGRAM | Attempt to call cursor functions when there are commands waiting to be executed.
10077 | SQLCRSNOIND EXINFO | One of the tables involved in the cursor statement does not have a unique index.
10078 | SQLCRSDIS EXPROGRAM | Cursor statement contains one of the disallowed phrases COMPUTE, UNION, FOR BROWSE, or SELECT INTO.
10079 | SQLCRSAGR EXPROGRAM | Aggregate functions are not allowed in a cursor statement.
10080 | SQLCRSORD EXPROGRAM | Only fully keyset driven cursors can have ORDER BY, GROUP BY, or HAVING PHRASES.
10081 | SQLCRSMEM EXPROGRAM | Keyset or window scroll size exceeds the memory limitations of this machine.
10082 | SQLCRSBSKEY EXPROGRAM | Keyset cannot be scrolled backward in mixed cursors with a previous fetch type.
10083 | SQLCRSNORES EXINFO | Cursor statement generated no results.
10084 | SQLCRSVIEW EXPROGRAM | A view cannot be joined with another table or a view in a cursor statement.
10085 | SQLCRSBUFR EXPROGRAM | Row buffering should not be turned on when using cursor functions.
10086 | SQLCRSFROWN EXINFO | Row number to be fetched is outside valid range.
10087 | SQLCRSBROL EXPROGRAM | Backward scrolling cannot be used in a forward scrolling cursor.
10088 | SQLCRSFRAND EXPROGRAM | Fetch types RANDOM and RELATIVE can only be used within the keyset of keyset driven cursors.
10089 | SQLCRSFLAST EXPROGRAM | Fetch type LAST requires fully keyset driven cursors.
10090 | SQLCRSRO EXPROGRAM | Data locking or modifications cannot be made in a READONLY cursor.
10091 | SQLCRSTAB EXPROGRAM | Table name must be determined in operations involving data locking or modifications.
10092 | SQLCRSUPDTAB EXPROGRAM | Update or insert operations using bind variables require single table cursors.
10093 | SQLCRSUPDNB EXPROGRAM | Update or insert operations cannot use bind variables when binding type is NOBIND.
10094 | SQLCRSVIIND EXPROGRAM | The view used in the cursor statement does not include all the unique index columns of the underlying tables.
10095 | SQLCRSNOUPD EXINFO | Update or delete operation did not affect any rows.
10096 | SQLCRSOS2 EXPROGRAM | Cursors are not supported for this server.
10097 | SQLEBCSA EXPROGRAM | The BCP hostfile %s contains only %ld rows. Skipping all of these rows is not allowed.
10098 | SQLCRSRO EXPROGRAM | Data locking or modifications cannot be made in a READONLY cursor.
10099 | SQLEBCNE EXPROGRAM | The table %s contains only %ld rows. Copying up to row %ld is not possible.
10100 | SQLEBCSK EXPROGRAM | The table %s contains only %ld rows. Skipping all of these rows is not allowed.
10101 | SQLEUVBF EXPROGRAM | Attempt to read unknown version of bcp format file.
10102 | SQLEBIHC EXPROGRAM | Incorrect host-column number found in bcp format file.
10103 | SQLEBWFF EXRESOURCE | I/O error while reading bcp format file.
10104 | SQLNUMVAL EXPROGRAM | The data stored in the DBNUMERIC/DBDECIMAL structure is invalid.
10105 | SQLEOLDVR EXPROGRAM | The SQL Server's TDS is obsolete with this version of DB-Library.


Before You Begin

The programming components in Microsoft® SQL Server™ 6.0 enable you to develop sophisticated client/server applications that tap the power of Microsoft SQL Server from workstations running the Microsoft® Windows NT™, Microsoft® Windows®, and MS-DOS® operating systems.

Microsoft® DB-Library™ is used to create client applications for SQL Server.

Note This book contains background information about Microsoft SQL Server and provides some information specific to SQL Server 6.0. For information about changes and enhancements specific to SQL Server 6.5, see the supplementary "What's New in SQL Server 6.5."


About Programming DB-Library for Visual Basic

This book describes Microsoft DB-Library for the Microsoft® Visual Basic® programming system. DB-Library for Visual Basic is a set of Visual Basic functions and routines that lets your application interact with Microsoft SQL Server. This book is written for programmers who are using Visual Basic programming system to develop SQL Server applications for the Microsoft Windows operating system.

To use this documentation effectively, you should already be familiar with Visual Basic and with Transact-SQL®, an enhanced version of the SQL database language. For more information about Transact-SQL, see the Microsoft SQL Server Transact-SQL Reference.


Finding Further Information

This book contains reference information to help you write DB-Library for Visual Basic applications for Microsoft SQL Server. Information about DB-Library for Visual Basic and SQL Server 6.0 is available from the following sources, as well as from the Microsoft® Development Library and Microsoft® TechNet.

The Microsoft Developer Network provides in-depth information for developers. With Level 1 of the Developer Network, you get four quarterly releases of the Development Library, packed with inside information on programming for Microsoft Windows and Windows NT, plus other program benefits. With Level 2 of the Developer Network, you'll receive all the Level 1 benefits plus quarterly releases of the Development Platform, containing the latest Windows and Windows NT Workstation operating systems and API-level SDKs and DDKs from Microsoft. For ordering information, call (800) 759-5474.

Microsoft TechNet is the front-line resource for fast complete answers to technical questions on Microsoft desktop and system products. Through two monthly CDs, you get everything from crucial data on client/server and workgroup computing, systems platforms, and database products to the latest applications support for Microsoft Windows and the Apple® Macintosh®. For ordering information, call your reseller or (800) 344-2121.

DB-Library Online Help

To access online Help while using DB-Library, chose the Help file icon from within Program Manager.

SQL Server Documentation

The documentation for SQL Server 6.0 is available online as part of the Microsoft® Development Library and as Microsoft SQL Server Books Online, which is part of Microsoft SQL Server and Microsoft® SQL Workstation.

Important SQL Server Books Online contains the most up-to-date information about SQL Server 6.0, including information that changed or was unavailable when the SQL Server 6.0 books were printed.

Microsoft SQL Server Setup
Provides instructions for installing SQL Server 6.0 servers and clients.
Microsoft SQL Server Administrator's Companion
Incorporates configuration, administration, and troubleshooting topics. Describes server and client configuration. Explains system administration tasks, such as managing devices and databases, backing up and recovering data, performing replication, scheduling tasks, managing security, and monitoring performance. Describes error conditions and gives troubleshooting procedures.
Microsoft SQL Server Database Developer's Companion
Provides an overview of Transact-SQL, which is an enhanced version of SQL (structured query language). Discusses managing data and database objects, such as tables, views, indexes, stored procedures, defaults, rules, constraints, and user-defined datatypes.
Microsoft SQL Server Transact-SQL Reference
Explains how to use Transact-SQL statements and other features to access databases, and provides syntax and descriptions for Transact-SQL statements, system procedures, utility programs, and system tables.
Microsoft SQL Server Programming SQL Distributed Management Objects
Provides syntax and reference information for the SQL Distributed Management Objects, which are 32-bit OLE Automation objects for the Microsoft® Windows® 95 and Windows NT operating systems. These objects, properties, methods, and collections are used to write scripts and programs that can administer multiple SQL Servers distributed across a network.
Microsoft SQL Server Programming DB-Library for C
Provides syntax and reference information for the DB-Library application programming interface (API), which is used to write C/C++ client programs for the Windows, Windows 95, Windows NT, and MS-DOS operating systems.
Microsoft SQL Server Programming DB-Library for Visual Basic
The online version of this book, provides syntax and reference information for the DB-Library API, which is used to write Microsoft® Visual Basic® programming system-based client programs for the Windows operating system.
Microsoft SQL Server Programming Open Data Services
Provides syntax and reference information for Open Data Services, used to write server applications for client/server systems.


Chapter 1 Getting Started

Getting Started

DB-Library for Visual Basic is a set of functions and routines for building front-end applications for the Windows operating system that interact with Microsoft SQL Server. DB-Library for Visual Basic is built on and is a subset of the SQL Server client library for C programmers.

DB-Library for Visual Basic functions and routines:

  • Send Transact-SQL statements to a SQL Server workgroup database.
  • Process the results of Transact-SQL statements.
  • Provide information about the way an application interacts with SQL Server.

For information about Transact-SQL, see the Microsoft SQL Server Transact-SQL Reference. For information about DB-Library for C, see Microsoft SQL Server Programming DB-Library for C.

With DB-Library for Visual Basic functions and routines, you can create applications that interact directly with SQL Server. DB-Library for Visual Basic applications do not require a language precompiler. As a result, your SQL Server becomes an integral part of your Visual Basic application by:

  • Retrieving and updating values from a database directly
  • Manipulating database values from database tables
  • Inserting program values into a database
  • Moving data between SQL Server and an operating-system file


System Requirements

To develop Win16 DB-Library for Visual Basic applications, you must meet the same system requirements as a Microsoft SQL Server Windows-based client. Visual Basic for Windows version 3.0 or later is also required.

For information about the system requirements for running SQL Server, see Microsoft SQL Server Setup.


DB-Library for Visual Basic Files

The following files are included with DB-Library for Visual Basic:

In C:\SQL60\BIN

File | Description
VBSQL.VBX | Default DB-Library client library file, compatible with Microsoft Visual Basic for Windows version 3.0 or later.

In C:\SQL60\HELP

File | Description
DBLIBVB.HLP | Help file containing reference information about DB-Library for Visual Basic functions, available for the Visual Basic for Windows programming system.

In C:\SQL60\DBLIB\INCLUDE

File | Description
VBSQL.BAS | Include file containing all DB-Library for Visual Basic function and routine declarations.
VBSQL.BI | Old name of include file provided for backward compatibility. (Use VBSQL.BAS, not this file. The contents of this file are identical to VBSQL.BAS.)

In C:\SQL60\DBLIB\VSAMPLES

File | Description
README.TXT | Summary of sample programs available in each directory.


Chapter 2 Programming with DB-Library for Visual Basic

Programming with DB-Library for Visual Basic

This chapter discusses the concepts behind programming with DB-Library for Visual Basic. The first half of the chapter describes the fundamental building blocks of a DB-Library for Visual Basic application, and provides a framework that uses the primary set of functions around which most DB-Library for Visual Basic applications are built. The second half of the chapter summarizes the full set of DB-Library for Visual Basic functions that are available to your application.


Application Framework

To build a DB-Library for Visual Basic application, you typically follow these steps:

  1. Provide an error handler.
  2. Initialize DB-Library for Visual Basic.
  3. Open a connection to SQL Server.
  4. Send Transact-SQL statements to SQL Server.
  5. Process the results.
  6. Close the connection(s) to SQL Server and exit the application.

The following sections briefly describe each of these steps, provide examples, and tell how to locate the functions described here in the sample applications for Windows.


Error and Message Handling

When either DB-Library for Visual Basic or SQL Server encounter an error condition, the error is reported to your application. To respond to error conditions, DB-Library for Visual Basic applications must implement an error handler and a message handler.

Errors detected by DB-Library for Visual Basic (such as a failure to connect to SQL Server) invoke the error handler, and provide information such as a description of the error and a severity rating. Errors detected by SQL Server (for example, invalid SQL syntax) are sent back to the client as messages and invoke both the error handler and the message handler. Based on the error information, the code that you supply for each handler can take whatever actions you define, such as informing the user of a problem.

The sections that follow tell how to implement each type of handler, and provide examples. The sample applications include examples of error and message handlers.


Setting Up the Error- and Message-Handling Interface

The error-handling interface between your application and DB-Library for Visual Basic is provided by a custom control. When you add this custom control to your application, it installs two error handler event procedures, assigns them the default names VBSQL1_Error and VBSQL1_Message, and supplies the appropriate parameter list as part of each procedure name.

You must explicitly include the DB-Library for Visual Basic procedures for handling errors in your application's primary form before you can use them in your application. These error-handling procedures are contained in the VBSQL.VBX file as part of a custom-control tool that is represented by a stop sign icon in the Toolbox palette. You can place only one error-handler control in an application.

To include the error-handling procedures in your application
  1. From the File menu, choose Add File to add the file VBSQL.VBX (available in the C:\SQL60\BIN directory by default) to your Project.

    Visual Basic adds the VBSQL.VBX file to your Project window and adds the VBSQL.VBX error handler to the bottom of the Toolbox as a custom control that is shown as a stop sign.

  2. Select the error-handler custom control and place it on your startup form. Only a single copy of the VBSQL.VBX control should be used for an application. The form containing the VBSQL.VBX should remain loaded as long as the DB-Library application is running, and it should be the last form unloaded when the application ends.

    It appears on the form with a default name of VBSQL1. (Since the VBSQL1 custom control requires no action from the user to make it active, you can set its Visible property to FALSE (0) to make it invisible.) The code for the startup form now includes the object VBSQL1 and includes procedure templates for two error event handlers: VBSQL1_Error and VBSQL1_Message.

To implement your error handlers, add code to these event procedures to perform whatever specialized error handling is appropriate to your application. Note that you can also rename the error-handler custom control using the Properties window.


Error- and Message-Handling Interface Syntax

This section describes the syntax for the DB-Library for Visual Basic error and message handlers. VBSQL1_Error is called automatically whenever the application encounters a DB-Library for Visual Basic error. VBSQL1_Message is called in response to messages returned by SQL Server.

VBSQL1_Error Procedure

The VBSQL1_Error procedure has the following syntax:

VBSQL1_Error ( sqlconn%, severity%, errornum%, errorstr$, retcode% )

where

sqlconn%
Is a SQL Server connection that encountered an error.
severity%
Is an integer that denotes the severity of an error. For a list of error severities, see Error Messages.
errornum%
Is an integer, or error number, that denotes an error constant. Error numbers and their corresponding constants are listed in the VBSQL.BAS include file. For a list of DB-Library for Visual Basic error constants and their corresponding error messages, see Error Messages.
errorstr$
Is a string that is the error message for a corresponding error constant. For a list of DB-Library for Visual Basic error constants and their corresponding error messages, see Error Messages.
retcode%
Is an output parameter that determines how DB-Library for Visual Basic will proceed following the error. Custom error handling code can set retcode% to one of the following integers prior to exiting the VBSQL1_Error procedure:
0INTEXIT
Treated as an intcancel error.
1INTCONTINUE
Meaningful only for timeout errors (sqletime). It continues to wait for a second timeout period. At the end of the second period, the error handler is called again. In any other case, this value is considered an error and is treated as an intcancel.
2INTCANCEL
Returns FAIL from the DB-Library for Visual Basic function that caused the error.

For timeout errors (SQLETIME) only, DB-Library will call SqlCancel% in an attempt to cancel the current command batch and flush any pending results. If this SqlCancel% attempt also times out, the connection is broken.

VBSQL1_Message Procedure

The VBSQL1_Message procedure has the following syntax:

VBSQL1_Message ( sqlconn%, message&, state%, severity%, msgstr$ )

where

sqlconn%
Is the SQL Server connection that encountered an error.
message&
Is an integer that is a message number returned by SQL Server. Each number has a corresponding message to which it is associated. For more information about SQL Server messages, see the Microsoft SQL Server Administrator's Companion.
state%
Is the SQL Server state number. The number provides information about the context of the current error.
severity%
Is an integer that denotes the SQL Server severity of an error. For information about SQL Server severities, see the Microsoft SQL Server Administrator's Companion.
msgstr$
Is a message string corresponding to the message number returned by SQL Server. For more information about SQL Server messages, see the Microsoft SQL Server Administrator's Companion.


Error- and Message-Handling Interface Examples

The following code fragment implements the VBSQL.VBX VBSQL1_Error and VBSQL1_Message procedures by calling the UserSQLErrorHandler and UserSQLMessageHandler routines defined in code module VBSQLGEN.BAS:

Sub VBSQL1_Error (Sqlconn%, Severity%, ErrorNum%, ErrorStr$, RetCode%)
    OsErr% = -1
    RetCode% = UserSQLErrorHandler (Sqlconn%, Severity%, ErrorNum%,
        OsErr%, ErrorStr$, OsErrStr$)
END SUB
Sub VBSQL1_Message (Sqlconn%, Message&, State%, Severity%, MsgStr$)
    UserSQLMsgHandler Sqlconn%, Message&, State%, Severity%, MsgStr$
END SUB

For a list of the code in the routines UserSQLErrorHandler and UserSQLMsgHandler, see the VBSQLGEN.BAS sample code.

For a list of DB-Library for Visual Basic messages, see Error Messages.


Using Declarations

Declarations for all DB-Library for Visual Basic procedures are included in the VBSQL.BAS file. You must add the contents of this file to the global declarations file for each application. For example, the QUERY sample application contains these declarations in the file QUERY.BAS.


Initializing DB-Library for Visual Basic

The first task of a DB-Library for Visual Basic application is to call the SqlInit$ function to initialize DB-Library for Visual Basic. During initialization, your application becomes "registered" with DB-Library, preventing conflicts with other applications that might call this library at the same time.

Your application must call SqlInit$ before it calls any other DB-Library for Visual Basic function. Because no other DB-Library for Visual Basic actions can take place before the call to SqlInit$, call SqlInit$ at the start of your application (usually the Form_Load event procedure of the application's primary, or startup, form).

SqlInit$ takes no parameters and returns the DB-Library version number as a string (where DB-Library is the generic name for the standard SQL Server client interface on which DB-Library for Visual Basic is based). Your error handlers should be available when SqlInit$ is called.

The following program fragment illustrates a valid call to SqlInit$:

'Initialize DB-Library for Visual Basic Library.
IF SqlInit$() = "" THEN
   PRINT "DB-Library for Visual Basic Library has not been initialized."
   END
END IF

For an example of how SqlInit$ is used, refer to the QUERY sample application. This sample application satisfies the initialization requirement by calling the routine InitializeApplication, which in turn calls SqlInit$. InitializeApplication is defined separately in the INIEXITW.BAS common code module.


Opening SQL Server Connections

Once the application has been initialized, your application interacts with SQL Server by opening one or more SQL Server connections with the appropriate user login information. Your application uses the connection to send Transact-SQL statements to SQL Server and to receive the results of those statements from SQL Server.

To open a SQL Server connection, use the SqlLogin% and SqlOpen% functions. DB-Library for Visual Basic also offers a function called SqlOpenConnection%, which provides a convenient method for logging in to SQL Server and opening a connection in one step. It combines the work of several lower-level functions into a single function, reducing the amount of code needed to log in a user and open a connection.

The following sections describe how to use SqlLogin% and SqlOpen% and provide examples for each function. For an example of how the utility function SqlOpenConnection% is used, refer to the QUERY sample application. This sample application logs in and opens a connection by calling the routine LoginToServer, which in turn calls SqlOpenConnection%. LoginToServer is defined separately in the VBSQLGEN.BAS common code module.


Logging In to SQL Server

The SqlLogin% function allocates a SQL Server login record and returns a value that serves as the identifier for that login record. The login record is made up of a set of attributes that are initially assigned default values. Although you cannot manipulate the login record directly, you can use DB-Library for Visual Basic functions to specify a username, a password, an application name, and several optional attributes. For example:

  • The SqlSetLUser% and SqlSetLPwd% functions set the username and password that DB-Library for Visual Basic will use to log in to SQL Server.
  • The SqlSetLApp% function sets the application name that appears in the SQL Server sysprocesses system table.

A Visual Basic form is a good tool for obtaining the required login information from the user. The following program fragment uses SqlLogin% to allocate a login record:

'Get a login record and set login attributes.
Login% = SqlLogin%()
Result% = SqlSetLUser%(Login%, "loginid")
Result% = SqlSetLPwd%(Login%, "passwd")
Result% = SqlSetLApp%(Login%, "example")


Opening a Connection

The SqlOpen% function logs in to SQL Server (using the SqlLogin% login record) and establishes a connection. The parameters required by the SqlOpen% function are the SqlLogin% login record identifier and a SQL Server server name. For each connection it establishes, SqlOpen% returns a connection identifier.

The SqlOpen% connection identifier remains associated with the connection as long as the connection is active. This documentation uses the variable sqlconn% to represent the connection identifier returned by SqlOpen%. Because most DB-Library for Visual Basic functions perform operations that are associated with a particular connection, most functions require you to specify the sqlconn% connection identifier as the first parameter.

Important Do not modify a connection's identifier in any way. If you modify an identifier, the connection and its associated data can be lost.

Once you open a connection with the SqlOpen% function, a data structure is associated with that connection to store a variety of information about the connection and its interaction with SQL Server. Your application uses DB-Library for Visual Basic functions to extract this information.

The following program fragment uses SqlOpen% to open a single SQL Server connection:

'Get a connection for communicating with SQL Server.
Sqlconn% = SqlOpen%(Login%, "server")

You can use SqlOpen% to open two or more SQL Server connections at the same time.


Sending Transact-SQL Statements to SQL Server

The SqlCmd% and SqlExec% functions allow your application to execute Transact-SQL statements.

The SqlCmd% function fills the command buffer with Transact-SQL statements that you then send to SQL Server. Each succeeding call to SqlCmd% appends the supplied Transact-SQL text to the end of text already in the buffer. When you add text to text already in the buffer, be sure to supply necessary blanks between words, such as the blank space at the beginning of the WHERE clause in the program fragment that follows.

'Retrieve two columns from the "authors" table
'in the "pubs" database.

'Put the command into the command buffer.
Result% = SqlCmd%(Sqlconn%, "SELECT au_lname, city")
Result% = SqlCmd%(Sqlconn%, " FROM pubs..authors")
Result% = SqlCmd%(Sqlconn%, " WHERE state = 'CA'")

'Send the command to SQL Server and start execution.
Result% = SqlExec%(Sqlconn%)

SqlExec% sends the contents of the buffer to SQL Server, which parses and executes the specified Transact-SQL statements. You can also use SqlSend% and SqlOk% instead of SqlExec%.

For an example of how these functions are used, refer to the QUERY sample application. This sample application calls the routine ExecuteSqlCommand, which in turn calls the functions SqlCmd% and SqlExec%. ExecuteSqlCommand is defined separately in the VBSQLGEN.BAS common code module.


Processing Results

The functions SqlResults%, SqlNextRow%, and SqlData$ or SqlAData$ process the results of Transact-SQL statements and return information to the user.

The SqlResults% function sets up the results of the current Transact-SQL statement for processing. Normally, you call SqlResults% once for every Transact-SQL statement placed in the command buffer (SqlResults% should return SUCCEED), and then one last time to return the NOMORERESULTS indicator. In the preceding program fragment, three calls to SqlCmd% are used to place a single Transact-SQL statement in the command buffer. In this case, you need to call SqlResults% only twice. The first call should return SUCCEED, and the second call should return NOMORERESULTS.

When a call to SqlResults% returns SUCCEED (indicating that the results of the current Transact-SQL statement are available), call SqlNextRow% to read a row of data from SQL Server. Each successive call to SqlNextRow% reads another row until the last row has been read and the nomorerows indicator is returned. Row processing must take place after SqlNextRow% returns SUCCEED and before the next call to SqlNextRow%, because each call to SqlNextRow% overwrites the values in the previous row (unless row buffering has been turned on). You must call SqlNextRow% until it returns NOMOREROWS (to complete the processing of a result set) before calling SqlResults% again. The following program fragment uses a DO loop to call SqlNextRow% until nomorerows is returned.

Result% = SqlResults%(Sqlconn%)

'Process the command.
IF Result% = SUCCEED THEN

   'Retrieve and print the result rows.
   PRINT
   DO UNTIL SqlNextRow%(Sqlconn%) = NOMOREROWS
      Name$ = SqlData$(Sqlconn%, 1)
      City$ = SqlData$(Sqlconn%, 2)
      PRINT Name$, City$
   LOOP

END IF

Even when you know that a Transact-SQL query returns only one row, you must call SqlNextRow% twice: once to get the result row, and once to get the nomorerows flag.

Transact-SQL statements return two types of result rows: regular rows and compute rows. Regular rows are generated from columns in a Transact-SQL SELECT statement. Compute rows are generated from columns in a COMPUTE clause. Because these two types of rows contain very different data, the application must process them separately.

The SqlData$ function returns a string containing data from a regular result column. The SqlAData$ function returns a string containing data from a compute column. This data is always returned as a string, regardless of its datatype. Binary strings of the datatypes binary, varbinary, and image are returned as binary strings.

For an example of how these functions are used, refer to the QUERY sample application. This sample application calls the routines GetDatabases and Process_Sql_query, defined separately in the VBSQLGEN.BAS common code module.


Closing SQL Server Connections

The SqlExit routine closes all SQL Server connections that have been opened by your application and frees the system memory associated with each connection. The following program fragment illustrates the use of SqlExit:

'Close connections.
SqlExit
END

To close a single specified SQL Server connection, use SqlClose.

To free the additional memory associated with a Windows-based application, you must make an additional call to the SqlWinExit function, described in Exiting a Windows-based Application.

For an example of how SqlExit is used, refer to the QUERY sample application. This sample application calls the routine ExitApplication, which in turn calls SqlExit. ExitApplication is defined separately in the INIEXITW.BAS common code modules.


Exiting a Windows-based Application

For Windows, your application must make an additional call to free all memory associated with your application. More than one application can reference DB-Library for Visual Basic at the same time. To avoid conflicts between these applications, DB-Library for Visual Basic allocates memory to store information identifying each application. When you exit a DB-Library for Visual Basic application, you must call SqlWinExit to release this memory and make it available to other applications.

The following program fragment illustrates the use of SqlWinExit:

SUB Quit_Click()
   'Close and free all SQL Server connections.
   SqlExit

   'Release memory allocated for VBSQL.
   SqlWinExit

   'End VBSQL application.
   END
END SUB

Typically, Windows-based applications include an Exit or Quit menu option with the File menu. The Visual Basic event procedure associated with the Exit menu option must include calls to both SqlExit and SqlWinExit to close all connections and release memory allocated to the application.


Example

This example program provides the framework for most DB-Library for Visual Basic applications. The example uses sample subroutine names for Visual Basic event procedures with which this code might be associated.

SUB Form_Load()
   'Initialize VBSQL.
   IF SqlInit$() = "" THEN
      PRINT "VBSQL has not been initialized."
      END
   END IF
END SUB

SUB LoginCmd_Click()
   'Get a Login record and set login attributes.
   Login% = SqlLogin%()
   loginid = LoginIDText.Text
   passwd = PasswordText.Text
   example = ExampleText.Text
   Result% = SqlSetLUser%(Login%, loginid)
   Result% = SqlSetLPwd%(Login%, passwd)
   Result% = SqlSetLApp%(Login%, example)

   'Get a connection for communicating with SQL Server.
   server = ServerText.Text
   Sqlconn% = SqlOpen%(Login%, server)
END SUB

SUB ExecuteCmd_Click()
   'Retrieve two columns from the "authors" table
   'in the "pubs" database.

   'Put the command into the command buffer.
   Result% = SqlCmd%(Sqlconn%, "SELECT au_lname, city")
   Result% = SqlCmd%(Sqlconn%, " FROM pubs..authors")
   Result% = SqlCmd%(Sqlconn%, " WHERE state = 'CA'")

   'Send the command to SQL Server and start execution.
   Result% = SqlExec%(Sqlconn%)
   Result% = SqlResults%(Sqlconn%)

   'Process the command.
   IF Result% = SUCCEED THEN
      'Retrieve and print the result rows.
      PRINT
      DO UNTIL SqlNextRow%(Sqlconn%) = NOMOREROWS
         Name$ = SqlData$(Sqlconn%, 1)
         City$ = SqlData$(Sqlconn%, 2)
         PRINT Name$, City$
      LOOP

   END IF
END SUB

SUB QuitApp_Click()
   'Close connection and exit program.
   SqlExit
   SqlWinExit
   END
END SUB

Sub VBSQL1_Error (Sqlconn%, Severity%, ErrorNum%, ErrorStr$, RetCode%)
   MsgBox ("DB-Library Error: "  Str$(ErrorNum%)  " "  ErrorStr$)
END SUB

Sub VBSQL1_Message (Sqlconn%, Message&, State%, Severity%, MsgStr$)
   MsgBox ("SQL Server Error: "  Str$(Message&)  " "  MsgStr$)
END SUB


Advanced Topics

This section includes useful information about specific groups of DB-Library for Visual Basic functions.


Retrieving Regular Result Column Information

Call the following DB-Library for Visual Basic functions to retrieve information on regular result columns after SqlExec% or SqlOk% returns SUCCEED.

Function | Description
SqlColLen% | Returns the maximum length of the data, in bytes, converted to a string in a regular column.
SqlColName$ | Returns the name of a regular result column.
SqlColType% | Returns the SQL Server datatype for a regular result column.
SqlDatLen& | Returns the actual length, in bytes, converted to a string of the data in a regular column. This function is often used in conjunction with SqlData$. The value returned by SqlDatLen& can be different for each row that SqlNextRow% reads.
SqlNumCols% | Returns the number of columns in the current set of results.
SqlPrType$ | Converts a SQL Server token value to a string.


Retrieving Compute Result Column Information

Call the following DB-Library for Visual Basic functions to retrieve information on compute result columns after SqlNextRow% or SqlGetRow% returns a compute ID.

Function | Description
SqlADLen& | Returns the actual length of the data in a compute column in the form of a string. This function is often used in conjunction with SqlAData$. The value returned by SqlADLen& can be different for each compute row that SqlNextRow% reads.
SqlAltColId% | Returns the identification number in a compute column.
SqlAltLen% | Returns the maximum length of the data, in bytes. The length is converted to a string in a compute column.
SqlAltOp% | Returns the type of aggregate function of a compute column.
SqlAltType% | Returns the datatype of a compute column.
SqlByList$ | Returns the bylist of a compute row.
SqlNumAlts% | Returns the number of columns in a compute row.
SqlNumCompute% | Returns the number of COMPUTE clauses in the current set of results.


Browse Mode

With DB-Library for Visual Basic browse mode, your application can browse through database rows and update their values one row at a time. Each row must be transferred from the database into program variables before it can be browsed and updated. As a result, browsing involves several steps.

Because a row being browsed is not the actual row residing in the database but a copy residing in program variables, changes to the values in those variables must be transferred reliably to ensure that the original database row is kept up to date. In particular in multiuser situations, updates made to the database by one user must not incorrectly overwrite updates made by another user. Regulating updating is especially important because an application typically selects a number of rows from the database at once, but users browse and update the database one row at a time. A timestamp column in browsable database tables provides the information necessary to regulate multiuser updating.

Browse-mode functions also allow an application to handle ad hoc queries. Several browse-mode functions return information that an application can use to examine the structure of a complicated ad hoc query.

To implement the DB-Library for Visual Basic browse mode in an application
  1. Execute a SELECT statement, generating result rows containing result columns. The SELECT statement must include the for browse option.
  2. Copy the values in the result column into the program variables one row at a time.
  3. If appropriate, change the variables' values in response to user input.
  4. If appropriate, execute an UPDATE statement that updates the database row corresponding to the current result row. To handle multiuser updates, the WHERE clause of the UPDATE statement must refer to the timestamp column. You can obtain a WHERE clause with the SqlQual$ function.
  5. Repeat steps 2 through 4 for each result row.

To use browse mode, the following conditions must be true:

  • The SELECT statement must end with the keywords FOR BROWSE.
  • The table(s) to be updated must have a unique index and timestamp column.
  • The result columns used in the updates must derive from browsable tables and cannot be the result of SQL expressions, such as MAX(colname). In other words, there must be a valid correspondence between the result column and the database column to be updated.

In addition to these conditions, the browse mode always requires two connections ¾ one for selecting the data and another for performing updates based on the selected data.


Chapter 3 Building Applications

Building Applications

This chapter discusses building a DB-Library for Visual Basic application. The guidelines it describes apply to the development of DB-Library for Visual Basic applications.


Overview

Developing a Visual Basic application involves two basic processes:

  • Providing a user interface that requests information from and conveys information to the person using the application.
  • Supplying the programming code that performs a set of tasks in response to specific user actions.

These two processes are strongly interdependent. When the user of the application uses a particular screen object to initiate an action, Visual Basic responds by invoking the Basic code contained in whatever event procedure is associated with that screen object. User interaction with SQL Server occurs when the Basic code for an event procedure contains functions and routines from DB-Library for Visual Basic.

Unless your DB-Library for Visual Basic application is very simple, use multiple forms to divide an application into logical parts. For example, a form that gets login information from a user ties together the user data and the functions that act on that user data. The login information and the login functions are part of the same process ¾ logging in to SQL Server.

DB-Library for Visual Basic applications can be large and complex, and can manage several SQL Server processes. For example, an application can manage querying databases, processing and retrieving information, accessing stored procedures, bulk-copying data, and so on. Dividing applications into forms and modules that control the various processes makes it easier to maintain and change the applications.


Required Project Files

When testing or building a DB-Library for Visual Basic application, the Visual Basic Project that contains your application's form and module files must use DB-Library for Visual Basic files described in the sections below.

For DB-Library for Visual Basic applications, add the files VBSQL.VBX and VBSQL.BAS to each Visual Basic application Project.

  • The VBSQL.VBX file provides DB-Library for Visual Basic of functions and routines.
  • The VBSQL.BAS file contains all the DB-Library for Visual Basic function and routine declarations and global constants.

When testing or building a DB-Library for Visual Basic application, all the information in the VBSQL.BAS file must be included in a global module for your Project. You can either make VBSQL.BAS the global module for your Project, or you can copy the contents of the VBSQL.BAS file and paste it into an existing global module.


Setting Up the Development Environment

The Visual Basic development environment allows you to test your application interactively during the development process.

Before you start interactive development of SQL Server applications in Windows, verify that your PATH command includes the DB-Library client support file, MSDBLIB3.DLL, and a corresponding Net-Library file, such as DBNMP3.DLL. These files, available with your SQL Server client software for Windows, allow you to test your connection to SQL Server using either custom application functions or a Windows-based tool such as the ISQL/w utility.

A new Visual Basic Project that uses DB-Library for Visual Basic must include the VBSQL.VBX custom control as a Project file. Adding this file includes the custom error-handling control (stop sign icon) to your Toolbox palette. Be sure to place one instance of this custom control on the startup form of your application.


Running Applications

To run your completed executable application, you must first make sure that the SQL Server communications software is loaded at the client computer.

For Windows-based applications, the client computer must have the VBSQL.VBX and MSDBLIB3.DLL files, and an appropriate Net-Library such as DBNMP3.DLL.


Chapter 4 Core Functions

Core Functions

SqlAData$

SqlADLen&

SqlAltColId%

SqlAltLen%

SqlAltOp%

SqlAltType%

SqlAltUType&

SqlByList$

SqlCancel%

SqlCanQuery%

SqlChange$

SqlClose

SqlClrBuf

SqlClrOpt%

SqlCmd%

SqlCmdRow%

SqlColInfo%

SqlColLen%

SqlColName$

SqlColType%

SqlColUType&

SqlCount&

SqlCurCmd%

SqlCurRow&

SqlData$

SqlDataReady%

SqlDateCrack%

SqlDatLen&

SqlDead%

SqlExit

SqlFirstRow&

SqlFreeBuf

SqlFreeLogin

SqlGetChar$

SqlGetMaxProcs%

SqlGetOff%

SqlGetPacket%

SqlGetRow%

SqlGetTime%

SqlInit$

SqlIsAvail%

SqlIsCount%

SqlIsOpt%

SqlLastRow&

SqlLogin%

SqlMoreCmds%

SqlName$

SqlNextRow%

SqlNumAlts%

SqlNumCols%

SqlNumCompute%

SqlNumOrders%

SqlOpen%

SqlOrderCol%

SqlProcInfo%

SqlPrType$

SqlResults%

SqlRows%

SqlRowType%

SqlServerEnum%

SqlSetAvail

SqlSetLApp%

SqlSetLHost%

SqlSetLNatLang%

SqlSetLoginTime%

SqlSetLPacket%

SqlSetLPwd%

SqlSetLSecure%

SqlSetLUser%

SqlSetLVersion%

SqlSetMaxProcs%

SqlSetOpt%

SqlSetTime%

SqlExec%

SqlOk%

SqlSend%

SqlStrCpy%

SqlStrLen%

SqlUse%

SqlWinExit


SqlAData$

Returns the data in a COMPUTE clause column.

Syntax

SqlAData$ ( sqlconn%, computeid%, column% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
computeid%
Is the COMPUTE clause. A SELECT statement can have multiple COMPUTE clauses, which can have varying numbers of aggregate operators and aggregate targets. The computeid% is returned by SqlNextRow% or SqlGetRow%.
column%
Is the number of the column. The first column returned is number 1.

Returns

A string containing the data in the compute column. For the SQL Server datatypes binary, varbinary, and image, SqlAData$ returns a string of binary data. For all other datatypes, SqlAData$ returns a string of characters. When there is no such column or when the data is NULL, an empty string is returned. To make sure that the data really is NULL, always check for a return of 0 by using SqlADLen&.

Remarks

After each call to SqlNextRow% that returns a value greater than 0, use SqlAData$ to obtain the data in a particular COMPUTE clause column. The data is not null-terminated. Use SqlADLen& to get the length of the data in a COMPUTE clause column.

Example

'Put commands into the command buffer.
cmd$ = "SELECT db_name(dbid), dbid, size FROM sysusages"
cmd$ = cmd$  " ORDER BY dbid"
cmd$ = cmd$  " COMPUTE SUM(size) BY dbid"
Result% = SqlCmd%(Sqlconn%, cmd$)
'Send commands to SQL Server and start execution.
Result% = SqlExec%(Sqlconn%)
Result% = SqlResults%(Sqlconn%)
'Examine the results of the COMPUTE clause.
IF Result% = SUCCEED THEN
   DO UNTIL Result% = NOMOREROWS
      Result% = SqlNextRow%(Sqlconn%)
      IF Result% = NOMOREROWS THEN Exit DO
      IF Result = REGROW THEN
         PRINT "regular row returned."
         PRINT
      ELSE
         'This row is the result of a COMPUTE clause
         'and Result% is the computeid% of this
         'COMPUTE clause
         sum = Val(SqlAData$(Sqlconn%, Result%, 1))
         PRINT "sum = "; sum
         PRINT
      END IF
   LOOP

See Also

SqlADLen&, SqlAltLen%, SqlAltType%, SqlGetRow%, SqlNextRow%, SqlNumAlts%


SqlADLen&

Returns the length of the data in a compute column.

Syntax

SqlADLen& ( sqlconn%, computeid%, column% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
computeid%
Is the COMPUTE clause. A SELECT statement can have multiple COMPUTE clauses, which can have varying numbers of aggregate operators and aggregate targets. The computeid% is returned by SqlNextRow% or SqlGetRow%.
column%
Is the column number. The first column is number 1.

Returns

The length, in bytes, of the data in a compute column. When no such column or COMPUTE clause exists, -1 is returned. When the data has a null value, 0 is returned.

Remarks

Example

'Put the command into the command buffer.
cmd$ = "SELECT name FROM sysobjects"
cmd$ = cmd$  " ORDER BY name"
cmd$ = cmd$  " COMPUTE MAX(name)"

'Send the command to SQL Server and start execution.
Result% = SqlCmd%(Sqlconn%,cmd$)
Result% = SqlExec%(Sqlconn%)

'Process the results of each statement.
 DO UNTIL Result% = NOMOREROWS
   Result% = SqlNextRow%(Sqlconn%)
   IF Result% = NOMOREROWS THEN Exit DO
   ELSE IF Result = REGROW THEN
      PRINT "regular row returned."
      PRINT
   ELSE
      'This row is the result of a COMPUTE clause.
      DataLength& = SqlADLen&(Sqlconn%, ComputeID%, 1)
      Data$ = SqlAData$(Sqlconn%, ComputeID%, 1)
      PRINT "The length of "  Data$  " is "  DataLength&  "bytes."
   END IF LOOP

See Also

SqlAData$, SqlAltLen%, SqlAltType%, SqlGetRow%, SqlNextRow%, SqlNumAlts%


SqlAltColId%

Returns the ID of a compute column.

Syntax

SqlAltColId% ( sqlconn%, computeid%, column% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
computeid%
Is the COMPUTE clause. A SELECT statement can have multiple COMPUTE clauses, which can have varying numbers of aggregate operators and aggregate targets. The computeid% is returned by SqlNextRow% or SqlGetRow%.
column%
Is the number of the compute column. The first column returned is number 1.

Returns

The ID that the aggregate operator in the COMPUTE clause column applies to. The first column is number 1. When either the computeid% or the column% is invalid, -1 is returned. Call this function after SqlNextRow% or SqlGetRow% returns a computeid.

Remarks

SqlAltColId% returns the ID of the column to which the aggregate operator applies for a particular column in a COMPUTE clause. For example, the function SqlAltColId%(sqlconn%, 1, 1) returns 2, since the COMPUTE COUNT clause in the following example refers to the second column in the select list:

select dept, name from employee
order by dept, name
compute count(name) by dept

See Also

SqlAData$, SqlADLen&, SqlAltLen%, SqlGetRow%, SqlNextRow%, SqlNumAlts%, SqlPrType$


SqlAltLen%

Returns the maximum length of the data in a compute column.

Syntax

SqlAltLen% ( sqlconn%, computeid%, column% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
computeid%
Is the COMPUTE clause. A SELECT statement can have multiple COMPUTE clauses, which can have varying numbers of aggregate operators and aggregate targets. The computeid% is returned by SqlNextRow% or SqlGetRow%.
column%
Is the number of the column. The first column returned is number 1.

Returns

The maximum number of bytes that the data can be in a particular column in a COMPUTE clause. When no such column or COMPUTE clause exists, -1 is returned.

Remarks

Example

In the following example, SqlAltLen%(sqlconn%, 1, 1) returns 11 because COUNT is an int datatype, which is 11 bytes long:

select dept, name from employee
order by dept, name
compute count(name) by dept

See Also

SqlAData$, SqlADLen&, SqlAltType%, SqlGetRow%, SqlNextRow%, SqlNumAlts%


SqlAltOp%

Returns the type of aggregate function in a compute column.

Syntax

SqlAltOp% ( sqlconn%, computeid%, column% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
computeid%
Is the COMPUTE clause. A SELECT statement can have multiple COMPUTE clauses, which can have varying numbers of aggregate operators and aggregate targets. The computeid% is returned by SqlNextRow% or SqlGetRow%.
column%
Is the number of the column. The first column returned is number 1.

Returns

The type of aggregate function in a particular column in a COMPUTE clause, as follows:

Aggregate function type | Aggregate operator
SQLAOPSUM | SUM
SQLAOPAVG | AVG
SQLAOPCNT | COUNT
SQLAOPMIN | MIN
SQLAOPMAX | MAX

Call SqlAltOp% only after SqlNextRow% or SqlGetRow% returns a computeid. When the computeid% or column% is not valid, -1 is returned.

Remarks

SqlAltOp% returns the type of aggregate function in a particular column in a COMPUTE clause. In the following example, SqlAltOp%(sqlconn%, 1, 1) returns the type for COUNT because the first aggregate operator in the first COMPUTE clause is COUNT:

select dept, name from employee
order by dept, name
compute count(name) by dept

To convert the type to a readable string, use SqlPrType$.

See Also

SqlAData$, SqlADLen&, SqlAltLen%, SqlGetRow%, SqlNextRow%, SqlNumAlts%, SqlPrType$


SqlAltType%

Returns the SQL Server datatype of a compute column.

Syntax

SqlAltType% ( sqlconn%, computeid%, column% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
computeid%
Is the COMPUTE clause. A SELECT statement can have multiple COMPUTE clauses, which can have varying numbers of aggregate operators and aggregate targets. The computeid% is returned by SqlNextRow% or SqlGetRow%.
column%
Is the number of the column. The first column returned is number 1.

Returns

The type of data in a column in the COMPUTE clause, as follows:

Column datatype | Returned constant
char | SQLCHAR
varchar | SQLCHAR
binary | SQLBINARY
varbinary | SQLBINARY
tinyint | SQLINT1
smallint | SQLINT2
int | SQLINT4
real | SQLFLT4
float | SQLFLT8
smallmoney | SQLMONEY4
money | SQLMONEY
decimal | SQLDECIMAL
numeric | SQLNUMERIC
smalldatetime | SQLDATETIM4
datetime | SQLDATETIME
image | SQLIMAGE
text | SQLTEXT

Call SqlAltType% only after SqlNextRow% or SqlGetRow% returns a computeid.

If either the computeid% or the column% is invalid, - 1 is returned.

Remarks

SqlAltType% returns the datatype in a particular column in a COMPUTE clause. In the following example, SqlAltType%(sqlconn%, 1, 1) returns the type for SQLINT4 because the counts are of sqlint4 datatype.

select dept, name from employee
order by dept, name
compute count(name) by dept

To convert the type to a readable string, use SqlPrType$.

See Also

SqlAData$, SqlADLen&, SqlAltLen%, SqlGetRow%, SqlNextRow%, SqlNumAlts%, SqlPrType$; DB-Library for Visual Basic Options.


SqlAltUType&

Returns the user-defined datatype of a compute column.

Syntax

SqlAltUType& ( sqlconn%, computeid%, column% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
computeid%
Is the COMPUTE clause. A SELECT statement can have multiple COMPUTE clauses, which can have varying numbers of aggregate operators and aggregate targets. The computeid% is returned by SqlNextRow% or SqlGetRow%.
column%
Is the number of the column. The first column returned is number 1.

Returns

The user-defined datatype of the specified compute column on success, or - 1 on error.

Remarks

Call SqlAltUType& only after SqlNextRow% or SqlGetRow% returns a compute ID.

See Also

SqlAData$, SqlGetRow%, SqlNextRow%, SqlNumAlts%


SqlByList$

Returns the bylist for a COMPUTE row.

Syntax

SqlByList$ ( sqlconn%, computeid%, column% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
computeid%
Is the COMPUTE clause. A SELECT statement can have multiple COMPUTE clauses, which can have varying numbers of aggregate operators and aggregate targets. The computeid% is returned by SqlNextRow% or SqlGetRow%.
column%
Is the number of the column. The first column is number 1.

Returns

A binary string of column positions for the bylist in the SELECT statement of the current SQL commands.

Remarks

A COMPUTE clause in a SELECT statement can contain the keyword BY, followed by a list of columns. This list, known as the bylist, divides the results of the COMPUTE clause into subgroups based on changing values in the specified columns. The COMPUTE clause's row aggregate is applied to each subgroup, generating a COMPUTE clause row for each subgroup.

The number of columns is equal to the length of the binary string and can be determined by calling LEN( ) with the returned string. Each character is a binary value representing the position of a column in the bylist.

Call SqlByList$ after SqlResults% returns SUCCEED.

Example

The following program fragment shows how to convert a binary value to an integer to get the number of a column position:

ByList$ = SqlByList$(Sqlconn%, ComputeID%)
DIM ByListNumber(LEN(ByList$)) as Integer
FOR x% = 1 to LEN(ByList$)
   ByListNumber(x%) = ASC(MID$(ByList$,x%,1))
NEXT x%

See Also

SqlAData$, SqlADLen&, SqlAltLen%, SqlAltType%, SqlColName$, SqlGetRow%, SqlNextRow%, SqlResults%


SqlCancel%

Cancels the execution of the statements in the command buffer and flushes any pending results.

Syntax

SqlCancel% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

SUCCEED (1) or FAIL (0).

Remarks

When you call SqlCancel%, SQL Server stops executing the statements associated with sqlconn% or sqlconn& in the command buffer. Any pending results are read and discarded. You can call SqlCancel% after calling SqlExec%, SqlSend%, SqlOk%, SqlResults%, or SqlNextRow%. SqlCancel% cancels all statements in the command buffer. To cancel a single statement in a command buffer containing multiple statements, use SqlCanQuery%.

If you receive the DB-Library error 10038 "Results Pending," you can call SqlCancel to clear the pending results. If SqlCancel returns FAIL, the server may not be able to respond to the cancel request. Either continue to call SqlCancel until it returns SUCCEED, or close the DBPROCESS connection and open a new one.

See Also

SqlCanQuery%, SqlExec%, SqlNextRow%, SqlOk%, SqlResults%, SqlSend%


SqlCanQuery%

Cancels any rows pending from the most recently executed query.

Syntax

SqlCanQuery% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

SUCCEED (1) or FAIL (0).

Remarks

Use SqlCanQuery% to cancel any unread rows that result from the most recently executed SQL query. Calling SqlCanQuery% is the same as calling SqlNextRow% until it returns nomorerows.

The SqlResults% function must return SUCCEED before an application can call SqlCanQuery%.

To ignore the results of all of the statements in the command buffer, use SqlCancel%.

See Also

SqlCancel%, SqlNextRow%, SqlResults%, SqlSend%


SqlChange$

Determines whether a command batch has changed the current database to another database.

Syntax

SqlChange$ ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

The name of the new database, if any. If the database has not changed, an empty string is returned.

Remarks

SqlChange$ informs the application of a switch from one database to another by catching any instance of the Transact-SQL USE statement.

When connected to SQL Server 4.2, a USE statement does not take effect until the end of the batch. The SqlChange$ function is therefore useful only in determining whether the current command batch has changed to another database for subsequent command batches. The simplest way to keep track of database switches is to call SqlChange$ when SqlResults% returns NOMORERESULTS at the end of each command batch.

When connected to SQL Server 6.0, a USE statement takes effect immediately.

You can also get the name of the current database by calling SqlName$.

See Also

SqlExec%, SqlName$, SqlResults%, SqlSend%, SqlUse%


SqlClose

Closes and frees a single SQL Server connection.

Syntax

SqlClose ( sqlconn% )

where

sqlconn% ( )
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

SUCCEED(1) or FAIL(0).

Remarks

SqlClose stops any activity associated with a SQL Server connection, closes the connection, and frees allocated memory. Closing a sqlconn connection with SqlClose automatically closes all the cursors associated with it.

To open a SQL Server connection, use SqlOpen%. To close all open SQL Server connections, use SqlExit.

Calling SqlClose with a sqlconn% or sqlconn& value not returned by SqlOpen% causes an error.

See Also

SqlExit, SqlOpen%


SqlClrBuf

Clears rows from the row buffer.

Syntax

SqlClrBuf ( sqlconn%, rows& )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
rows&
Is the number of rows to clear from the row buffer. If rows& is equal to or greater than the number of rows in the buffer, all but the newest row are removed. If rows& is less than 1, the call is ignored. Rows are cleared on a first-in/first-out basis.

Remarks

DB-Library for Visual Basic buffers rows as they are returned from SQL Server. If the row buffer fills completely, you can use SqlClrBuf to drop rows from the buffer.

Turn on row buffering by using SqlSetOpt% with the sqlbuffer option as follows:

SqlSetOpt%(sqlconn%, SqlBUFFER, "n")

Replace n with the number of rows you want to buffer. After turning buffering on, you can randomly refer to rows that have been read from SQL Server by using SqlGetRow%. The row buffer can fill completely when SQL Server returns more than the number of rows you specify. When the row buffer is full, SqlNextRow% returns buffull until you free at least one row by calling SqlClrBuf. SqlClrBuf frees the oldest rows in the buffer.

See Also

SqlGetRow%, SqlNextRow%, SqlSetOpt%; DB-Library for Visual Basic Options


SqlClrOpt%

Clears an option set by SqlSetOpt%.

Syntax

SqlClrOpt% ( sqlconn%, opt%, optparam$ )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%. When sqlconn% is 0, the specified option is cleared for every active SQL Server connection.
opt%
Is the option to be cleared. Do not enclose opt% in quotation marks. For a list of the options available in DB-Library for Visual Basic, see DB-Library for Visual Basic Options.
optparam$
Is a parameter for an option. You must include optparam$ for all options, whether or not they take parameters. Enclose optparam$ in quotation marks.

If an option does not take a parameter, optparam$ is ignored. If an option does take a parameter, optparam$ is ignored for all options except SQLOFFSET and SQLSTAT.

The SQLOFFSET and SQLSTAT options can have several settings, each with a different parameter. In these cases, SqlClrOpt% needs a valid optparam$ to determine which option parameter to clear.

For a list of the options available in DB-Library for Visual Basic, see DB-Library for Visual Basic Options.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlClrOpt% turns off options that have been set with SqlSetOpt%. Although you can set and clear some options directly through Transact-SQL, design your application to use SqlSetOpt% and SqlClrOpt% to set and clear options because SqlSetOpt% and SqlClrOpt% provide a uniform interface for setting and clearing all options. With these functions, your application can also use SqlIsOpt% to check the status of an option.

SqlClrOpt% does not immediately clear the options specified (with the exception of sqlbuffer and sqlnoautofree). Options are cleared when you send the statements in the command buffer to SQL Server by invoking SqlExec%. Also, the results of the command generated by SqlClrOpt% are not returned until the command is transferred to SQL Server. Therefore, design your application to expect the results returned from the command string generated by SqlClrOpt%. If an invalid parameter is specified, it is not detected until the command is sent to SQL Server and the results for that command are returned using SqlResults%.

Note that the command string generated by this function is not immediately sent to SQL Server. Instead, it is buffered within DB-Library and sent the next time SqlExec% is invoked. Therefore, any options requested by this function do not go into effect until then. Also, the results of the command generated by this function are not returned until the command is transferred to SQL Server. The application should be expecting the results returned from the command string generated by this function.

For a list of the options available in DB-Library for Visual Basic, see DB-Library for Visual Basic Options.

See Also

SqlIsOpt%, SqlSetOpt%; DB-Library for Visual Basic Options


SqlCmd%

Adds Transact-SQL text to the command buffer.

Syntax

SqlCmd% ( sqlconn%, cmd$ )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
cmd$
Is a character string to be copied into the command buffer.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlCmd% adds text to the existing command buffer. The added text does not delete or overwrite the current contents until the contents of the buffer are sent to SQL Server.

After a call to SqlExec% or SqlSend%, the first call to SqlCmd% automatically clears the command buffer before the new text is entered. If you do not want the command buffer automatically cleared, set the sqlnoautofree option with SqlSetOpt%. When sqlnoautofree is set, the command buffer is cleared only by a call to SqlFreeBuf.

The size of the command buffer depends on the amount of available memory.

Note You can call SqlCmd% repeatedly. Sequential calls are concatenated, so be sure to add any necessary blanks at the end of one line or the beginning of the next.

Example

The following code fragment shows how to use SqlCmd% to build up a multiline SQL command:

Result% = SqlCmd%(Sqlconn%, "SELECT name FROM sysobjects")
Result% = SqlCmd%(Sqlconn%, " WHERE id = 5")
Result% = SqlCmd%(Sqlconn%, " AND type = 'S'")

See Also

SqlFreeBuf; DB-Library for Visual Basic Options


SqlCmdRow%

Indicates whether the current statement can return rows.

Syntax

SqlCmdRow% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlCmdRow% determines whether the current command can return rows. The following types of statements can return rows:

  • A Transact-SQL SELECT statement
  • A Transact-SQL EXECUTE statement that is executing a stored procedure containing a SELECT statement

Call SqlCmdRow% after SqlResults% returns SUCCEED. Even if SqlCmdRow% returns SUCCEED, the statement will not return rows if none have qualified. To determine whether any rows are returned, use SqlRows%.

Even if SqlCmdRow% returns FAIL, you must still process the results by calling SqlNextRow% until it returns NOMOREROWS.

See Also

SqlNextRow%, SqlResults%, SqlRows%, SqlRowType%


SqlColInfo%

Returns information about a regular column or a compute column in a result set, or a column in a cursor.

Syntax

SqlColInfo% ( sqlhandle%, type%, column%, computeid%, columninfo )

where

sqlhandle%
Is a SQL Server connection or a cursor handle. If type% is SQLCI_REGULAR% or SQLCI_ALTERNATE%, this is a SQL Server connection (returned by SqlOpen%). If type% is SQLCI_CURSOR%, this is a cursor handle (returned by SqlCursorOpen%).
type%
Is the type of column information to return. The following table describes the different type% values:
type% | Description
SQLCI_REGULAR% | Return information about a regular column in the current result set.
SQLCI_ALTERNATE% | Returns information about a compute column in the current result set.
SQLCI_CURSOR% | Returns information about a column in the open cursor.

column%
The number of the column. The first column is number 1.
computeid%
If type% is SQLCI_ALTERNATE, this is the ID that identifies the compute (the result of a COMPUTE clause) value. The computeid% is returned by SqlNextRow% or SqlGetRow%.
columninfo
A ColInfo structure that DB-Library will use to return detailed information about the specified column.

The ColInfo structure is defined as follows:

Type ColInfo
    Name As String * 31
    ActualName As String * 31
    TableName As String * 31
    CType As Integer
    UserType As Long
    MaxLength As Long
    Precision As Integer
    Scale As Integer
    VarLength As Integer
    Null As Integer
    CaseSensitive As Integer
    Updatable As Integer
    Identity As Integer
End Type

The ColInfo fields (and the equivalent DB-Library functions, if any) are described below:
Field | Description
Name | Is the name of the returned column (SqlColName$).
ActualName | Is the actual name of the column in TableName if type% is SQLCI_CURSOR%; otherwise, this is the same as Name.
TableName | Is the table that contains the column if type% is SQLCI_CURSOR%; otherwise, an empty string.
CType | Is the datatype of the column (SqlColType%, SqlAltType%).
UserType | Is the user-defined datatype of the column (SqlColUType&, SqlAltUType&).
MaxLength | Is the maximum length, in bytes, of the column (SqlColLen%, SqlAltLen%).
Precision | The precision if Type is SQLDECIMAL or SQLNUMERIC; otherwise, - 1.
Scale | The scale if Type is SQLDECIMAL or SQLNUMERIC; otherwise, - 1.
VarLength Is one of the following:

SUCCEED (1) if the column is variable-length.

FAIL (0) if the column is fixed-length.
Null Is one of the following:

SUCCEED (1) if the column allows nulls.

FAIL (0) if the column does not allow nulls.

SQLUNKNOWN (2) if nullability is unknown.
CaseSensitive Is one of the following:

SUCCEED (1) if the column is case sensitive.

FAIL (0) if the column is case insensitive.

SQLUNKNOWN (2) if case sensitivity is unknown.
Updatable Is one of the following:

SUCCEED (1) if the column can be changed.

FAIL (0) if the column is read-only and cannot be changed.

SQLUNKNOWN (2) if updatability is unknown.
Identity Is one of the following:

SUCCEED (1) if the column is an identity column.

FAIL (0) if the column is not an identity column.

Returns

succeed (1) or fail (0).

Remarks

The SqlColInfo% function fills the supplied ColInfo structure with information about the specified column. Call this function after SqlResults% returns SUCCEED, or after SqlCursorOpen% returns a cursor handle.

See Also

SqlAltLen%, SqlAltType%, SqlAltUType&, SqlColLen%, SqlColName$, SqlColType%, SqlColUType&


SqlColLen%

Returns the maximum length, in bytes, of the data in a column.

Syntax

SqlColLen% ( sqlconn%, column% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
column%
Is the number of the column. The first column is number 1.

Returns

The maximum length of the data in a specified column. If the column number is not within range of the maximum length of the data, SqlColLen% return -1.

Remarks

SqlColLen% do not return the actual length of the data in a column, but rather the maximum length that the data can be. For the actual length of data in a column, use SqlDatLen&. Call SqlColLen% after SqlResults% returns SUCCEED.

Example

The following code fragment uses SqlColLen% to return the maximum length of the data in the name, id, and type columns from the sysobjects table:

'Put the statement into the command buffer.
cmd$ = "SELECT name, id, type FROM sysobjects"
Result% = SqlCmd%(Sqlconn%, cmd$)

'Send the statement to SQL Server and start execution.
Result% = SqlExec%(Sqlconn%)

'Process the statement results.
Result% = SqlResults%(Sqlconn%)

'Print the column lengths.
FOR ColumnNum% = 1 TO 3
   ColumnLen& = SqlColLen%(Sqlconn%, ColumnNum%)
   PRINT "Column"; ColumnNum%; " length is"; ColumnLen&
NEXT ColumnNum%

Output:

Column 1 length is 30
Column 2 length is 11
Column 3 length is 2

See Also

SqlColName$, SqlColType%, SqlData$, SqlDatLen&, SqlNumCols%


SqlColName$

Returns the name of a result column.

Syntax

SqlColName$ ( sqlconn%, column% )

where

sqlconn% ( )
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
column%
Is the number of the column. The first column is number 1.

Returns

A string containing the name of a result column. If the column number is out of range or if the column is the result of an expression with no name assigned, an empty string is returned.

Example

The following code fragment uses SqlColName$ to return the name, id, and type column names from the sysobjects table:

'Put the statement into the command buffer.
cmd$ = "SELECT name, id, type FROM sysobjects"
Result% = SqlCmd%(Sqlconn%, cmd$)

'Send the statement to SQL Server and start execution.
Result% = SqlExec%(Sqlconn%)

'Process the statement results.
Result% = SqlResults%(Sqlconn%)

'Print the column names.
FOR ColumnNum% = 1 TO 3
   ColumnName$ = SqlColName$(Sqlconn%, ColumnNum%)
   PRINT "Column"; ColumnNum%; " name is "; ColumnName$
NEXT ColumnNum%

Output:

Column 1 name is name
Column 2 name is id
Column 3 name is type

See Also

SqlColLen%, SqlColType%, SqlData$, SqlDatLen&, SqlNumCols%


SqlColType%

Returns the SQL Server datatype for a result column.

Syntax

SqlColType% ( sqlconn%, column% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
column%
Is the number of the column. The first column is number 1.

Returns

An integer value for the datatype of a specified column. If the column number is not in range, -1 is returned.

These are the returned values:

Column datatype | Returned constant
char | SQLCHAR
varchar | SQLCHAR
binary | SQLBINARY
varbinary | SQLBINARY
tinyint | SQLINT1
smallint | SQLINT2
int | SQLINT4
real | SQLFLT4
float | SQLFLT8
smallmoney | SQLMONEY4
money | SQLMONEY
decimal | SQLDECIMAL
numeric | SQLNUMERIC
smalldatetime | SQLDATETIM4
datetime | SQLDATETIME
image | SQLIMAGE
text | SQLTEXT

Remarks

The SqlColType% function returns an integer value for the type. Use SqlPrType% to convert the type value into a readable string. This function cannot determine whether a column allows null values.

Example

'Put the statement into the command buffer.
cmd$ = "SELECT name, id, type FROM sysobjects"
Result% = SqlCmd%(Sqlconn%, cmd$)

'Send the statement to SQL Server and start execution.
Result% = SqlExec%(Sqlconn%)

'Process the statement results.
Result% = SqlResults%(Sqlconn%)

'Print the column type.
FOR ColumnNum% = 1 TO 3
   ColumnType% = SqlColType%(Sqlconn%, ColumnNum%)
   PRINT "Column"; ColumnNum%; " type is"; ColumnType%
NEXT ColumnNum%

See Also

SqlColLen%, SqlColName$, SqlData$, SqlDatLen&, SqlNumCols%


SqlColUType&

Returns the user-defined datatype of a regular result column.

Syntax

SqlColUType& ( sqlconn%, column% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
column%
Is the number of the column. The first column returned is number 1.

Returns

The user-defined datatype of the specified compute column on success, or - 1 on error.

Remarks

Call SqlColUType& only after SqlNextRow% or SqlGetRow% returns SUCCEED.

See Also

SqlData$, SqlGetRow%, SqlNextRow%, SqlNumCols%


SqlCount&

Returns the number of rows affected by the current statement.

Syntax

SqlCount& ( sqlconn% )

where

sqlconn% ( )
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

The number of rows affected by the current statement. Call SqlIsCount% to determine if this count is correct.

Remarks

After the results of a Transact-SQL statement are processed, use SqlCount& to find out how many rows have been affected by the statement. For example, if a SELECT statement is sent to SQL Server and you read all the rows by calling SqlNextRow% until it returns nomorerows, you can call SqlCount& to find out how many rows have been retrieved. If the current Transact-SQL statement does not return rows (the DELETE statement, for example), call SqlCount& after SqlResults%.

If the current statement executes a stored procedure, for example an EXEC or a call to a remote stored procedure, SqlCount& reports the number of rows returned by the last SELECT statement executed by the stored procedure. Note that a stored procedure without a SELECT statement can execute a SELECT anyway simply by calling another stored procedure with a SELECT.

See Also

SqlIsCount%, SqlNextRow%, SqlResults%


SqlCurCmd%

Returns the number of the current statement in the command buffer.

Syntax

SqlCurCmd% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

The number of the current statement. The first statement in a group of statements is number 1.

Remarks

The statement number is incremented every time SqlResults% returns SUCCEED or FAIL. Unsuccessful statements are counted. The statement number is reset by each call to SqlExec% or SqlSend%.

See Also

SqlCmdRow%, SqlExec%, SqlMoreCmds%, SqlResults%, SqlRows%, SqlSend%


SqlCurRow&

Returns the number of the row currently being read.

Syntax

SqlCurRow& ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

The number of the current row.

Remarks

SqlCurRow& returns the number of the row most recently read by SqlGetRow% or SqlNextRow%. When you do not turn on row buffering, SqlFirstRow&, SqlCurRow&, and SqlLastRow& always return the same value (the number of the current row).

Use SqlGetRow% to read rows from the row buffer. The first row SQL Server returns from the row buffer is number 1. The row number changes every time SqlNextRow% or SqlGetRow% returns SUCCEED. The row number is reset to 0 by each call to SqlResults%.

See Also

SqlClrBuf, SqlFirstRow&, SqlGetRow%, SqlLastRow&, SqlNextRow%, SqlSetOpt%; DB-Library for Visual Basic Options


SqlData$

Returns a string containing data in a result column.

Syntax

SqlData$ ( sqlconn%, column% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
column%
Is the number of the result column. The first column is number 1.

Returns

A string containing the data in a result column. For the SQL Server datatypes binary, varbinary, and image, SqlData$ returns a string of binary data, with one character in the string per byte of data in the result column. For all other datatypes, SqlData$ returns a string of readable characters. When there is no such column or when the data is NULL, an empty string is returned. To make sure that the data really is NULL, always check for a return of 0 by using SqlDatLen&.

Remarks

Use SqlDatLen& to get the length of the data for variable-length datatypes. For numeric datatypes, use the Visual Basic LEN function to determine the length of the string returned by SqlData$.

To convert the data from a string to a different datatype, use SqlColType% to get the datatype of the data, then use Visual Basic functions to convert to Visual Basic datatypes. Some helpful Visual Basic conversion functions are shown in the following table. For more information, see your documentation for Visual Basic.

Visual Basic function | Description
CDBL | Converts a numeric expression to a double-precision value.
CLNG | Converts a numeric expression to a long integer.
VAL | Converts a string representation of a value to a numeric expression.

Example

'Put the statement into the command buffer.
Result% = SqlCmd%(Sqlconn%, "SELECT id FROM sysobjects")

'Send the statement to SQL Server and start execution.
Result% = SqlExec%(Sqlconn%)

'Process the statement results.
Result% = SqlResults%(Sqlconn%)

'Retrieve and print the data in each row.
RowNum% = 0
DO UNTIL SqlNextRow%(Sqlconn%) = NOMOREROWS
   RowNum% = RowNum%  1
   PRINT "Row"; RowNum%;" object id is ";
   PRINT SqlData$(Sqlconn%, 1)
LOOP

See Also

SqlColLen%, SqlColName$, SqlColType%, SqlDatLen&, SqlNumCols%


SqlDataReady%

Indicates whether SQL Server has completed processing a command.

Syntax

SqlDataReady% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

SUCCEED (1) or FAIL (0). SUCCEED means that the data is available to be read.

Remarks

With SqlDataReady%, you can write an application that can continue processing while SQL Server is actually performing the database operation.

SqlDataReady% is ordinarily used after a call to SqlSend% and before a call to SqlOk%. After SqlSend%, SQL Server begins executing the statements in the command buffer. When SqlOk% is called, DB-Library for Visual Basic waits for SQL Server to complete processing before returning control to the application.

SqlDataReady% provides a way to determine when statement processing is complete. Call SqlDataReady% repeatedly until it returns a value other than 0. At that point, you can call SqlOk%.

Important Unless you provide a way for your application to time out, SqlDataReady% can return FAIL indefinitely if another process causes a conflicting lock or if the connection is broken.

See Also

SqlOk%, SqlResults%, SqlSend%


SqlDateCrack%

Converts a string of date and time values into a format more usable to the user.

Syntax

SqlDateCrack% ( sqlconn%, dateinfo, datetime$ )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
dateinfo
Identifies a structure containing the components of the datetime$ string. The dateinfo structure contains the following fields:
Field | Description
year% | A number of a year in the range 1753 through 9999.
quarter% | A number of a quarter of a year in the range 1 though 4.
month% | A number of a month in the range 1 through 12.
dayofyear% | A number of a day of a year in the range 1 through 366. Leap years are counted.
day% | A number of a day of a month in the range 1 through 31.
week% | A number of a week of a year in the range 1 through 54. Leap years are counted.
weekday% | A number of the day of a week in the range 1 through 7 (Monday though Sunday).
hour% | A number of an hour in the range 0 through 23.
minute% | A number of a minute in the range 0 through 59.
second% | A number of a second in the range 0 through 59.
millisecond% | A number of a millisecond in the range 0 through 999.

datetime$
Is a string containing the date and time.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlDateCrack% converts a SQL Server DATETIME string into its integer components and puts them into a dateinfo structure.

Date and time values are maintained in an internal format that is not readily usable. For example, a time value is stored as the number of 300ths of a second since midnight, and a date value is stored as the number of days since January 1, 1900. The SqlDateCrack% function converts the internal value to something easily usable by an application.

Example

'Put the statement into the command buffer.
Result% = SqlCmd%(Sqlconn%, "SELECT name, crdate FROM master..sysdatabases")

'Send the statement to SQL Server and start execution.
Result% = SqlExec%(Sqlconn%)

'Process the statement results.
Result% = SqlResults%(Sqlconn%)

'Retrieve and print the database name and its date info.
DO UNTIL SqlNextRow%(Sqlconn%) = NOMOREROWS
   PRINT "Database Name is "
   PRINT SqlData$(Sqlconn%, 1)
   PRINT
   PRINT "Creation date string info is "
   PRINT SqlData$(Sqlconn%, 2)
   PRINT

   'Break up the creation date into its constituent parts.

   Datetime$ = SqlData$(Sqlconn%, 2)

   SqlDateCrack(Sqlconn%, Dateinfo(), Datetime$)

   'Print the parts of the creation date.
   PRINT
   PRINT "Year = "; Dateinfo.year
   PRINT "Month = "; Dateinfo.month
   PRINT "Day of month = "; Dateinfo.day
   PRINT "Day of year = "; Dateinfo.dayofyear
   PRINT "Day of week = "; Dateinfo.weekday
   PRINT "Hour = "; Dateinfo.hour
   PRINT "Minute = "; Dateinfo.minute
   PRINT "Second = "; Dateinfo.second
   PRINT "Millisecond = "; Dateinfo.millisecond

LOOP

See Also

SqlData$


SqlDatLen&

Returns the actual length, in bytes, of the data in a column.

Syntax

SqlDatLen& ( sqlconn%, column% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
column%
Is the number of a column. The first column is number 1.

Returns

The actual length of the data in a specified column. If the column has a null value, SqlDatLen& returns 0. If the column number is out of range, SqlDatLen& returns -1. Calling SqlDatLen& after SqlNextRow% or SqlGetRow% returns regrow.

Remarks

For numeric datatypes such as smallint and float, SqlDatLen& returns the maximum printable width, not the length of the string that would be returned by SqlData$. For example, if you store the value 10,000 in a smallint column, SqlDatLen& returns 6 (the storage size of the smallint datatype). The length of the string returned by SqlData$, in this case 5, is determined by using the Visual Basic LEN function.

You obtain the maximum possible length for the data in a column by calling SqlColLen%. The data itself is returned by SqlData$.

Example

'Put the statement into the command buffer.
Result% = SqlCmd%(Sqlconn%, "SELECT name FROM sysobjects")

'Send the statement to SQL Server and start execution.
Result% = SqlExec%(Sqlconn%)

'Process the statement results.
Result% = SqlResults%(Sqlconn%)

'Print the data length of each row.
RowNum% = 0
DO UNTIL SqlNextRow%(Sqlconn%) = NOMOREROWS
   RowNum% = RowNum%  1
   PRINT "Row"; RowNum%;" data length is ";
   PRINT SqlDatLen&(Sqlconn%, 1)
LOOP

Output:

Row 1 data length is 10
Row 2 data length is 10
   .
   .
   .
Row 103 data length is 13

See Also

SqlColLen%, SqlColName$, SqlColType%, SqlData$, SqlNumCols%


SqlDead%

Indicates whether a SQL Server connection is inactive.

Syntax

SqlDead% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlDead% is particularly useful in user-supplied error handlers. If the SQL Server connection is dead, almost every DB-Library for Visual Basic procedure that receives that connection as a parameter immediately fails, calling the error handler. You must close an inactive sqlconn% connection with SqlClose% and open a new connection with SqlOpen%.

SqlDead% usually returns true when a network connection is broken. Note any other errors or messages that you receive.

See Also

Programming with DB-Library for Visual Basic; Error Messages


SqlExit

Closes and frees all SQL Server connections.

Syntax

SqlExit

Remarks

SqlExit calls SqlClose repeatedly for all allocated SQL Server connections. SqlClose stops any activity associated with a SQL Server connection, closes a SQL Server connection, and frees allocated memory. SQL Server connections are opened with SqlOpen%.

You can use SqlClose directly to close a single SQL Server connection.

See Also

SqlClose, SqlOpen%


SqlFirstRow&

Returns the number of the first row in the row buffer.

Syntax

SqlFirstRow& ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

The number of the first row in the row buffer. The first row returned is number 1. Use this return value when making a call to SqlGetRow%.

Remarks

If you do not turn on row buffering, SqlFirstRow&, SqlCurRow&, and SqlLastRow& always return the same value (the number of the current row).

If you turn on row buffering by setting the SQLBUFFER option with SqlSetOpt%, SqlFirstRow& returns the number of the lowest (oldest) row of results in the buffer. For example, if a query returns 100 result rows and you read 20 rows into the buffer using SqlNextRow%, SqlFirstRow& returns 1, regardless of which row is current. As the application processes and clears rows from the buffer using SqlClrBuf and more data is read from the server using SqlNextRow%, SqlFirstRow& returns the number of the result row stored in the lowest (oldest) buffer location.

SqlLastRow& returns the number of the result row stored in the highest (newest) buffer location.

See Also

SqlClrBuf, SqlCurRow&, SqlGetRow%, SqlLastRow&, SqlNextRow%, SqlSetOpt%; DB-Library for Visual Basic Options


SqlFreeBuf

Clears the command buffer.

Syntax

SqlFreeBuf ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Remarks

This function frees any space allocated to the command buffer of the sqlconn% structure. Statements for SQL Server are added to the command buffer with SqlCmd%. After a call to SqlExec% or SqlSend%, the first call to SqlCmd% automatically calls SqlFreeBuf to clear the command buffer before the new text is entered. If you don't want the buffer automatically cleared, set the SQLNOAUTOFREE option using SqlSetOpt%. When SQLNOAUTOFREE is set, the command buffer is cleared only by a call to SqlFreeBuf.

You can access the contents of the command buffer by using SqlGetChar$, SqlStrLen% and SqlStrCpy%.

See Also

SqlCmd%, SqlExec%, SqlSend%, SqlStrCpy%, SqlStrLen%; DB-Library for Visual Basic Options


SqlFreeLogin

Frees the memory allocated by SqlLogin% for a login record.

Syntax

SqlFreeLogin ( loginrec% )

where

loginrec%
Is a login record. The value of loginrec% is returned by SqlLogin%.

Remarks

You can call SqlFreeLogin immediately after you call SqlOpen, and you can use the same login record for multiple calls to SqlOpen. Call SqlFreeLogin when you are completely finished with a login record.

Example

Login% = SqlLogin%
Result% = SqlSetLUser%(Login%, "loginid")
Result% = SqlSetLPwd%(Login%, "passwd")
Result% = SqlSetLApp%(Login%, "myapp")
Sqlconn% = SqlOpen%(Login%, "server")
CALL SqlFreeLogin(Login%)

See Also

SqlLogin%, SqlOpen%


SqlGetChar$

Returns the value of a character in the command buffer.

Syntax

SqlGetChar$ ( sqlconn%, charnum% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
charnum%
Is the character to find in the command buffer. The first character is the 0th character.

Returns

The value of charnum% in the command buffer. If charnum% is not in range, an empty string is returned.

Remarks

Use SqlGetChar$ to find a particular character in the command buffer. It returns a string of the charnum% character in the command buffer.

Internally, the command buffer is a linked list of non - null-terminated text strings. Parts of the command buffer can be located and copied using the SqlGetChar$, SqlStrCpy%, and SqlStrLen% functions.

See Also

SqlCmd%, SqlFreeBuf, SqlStrCpy%, SqlStrLen%


SqlGetMaxProcs%

Determines the current maximum number of simultaneously open sqlconn connections.

Syntax

SqlGetMaxProcs% ( )

Returns

An integer representing the current limit on the number of simultaneously open sqlconn connections.

Remarks

A DB-Library for Visual Basic program has a maximum number of simultaneously open sqlconn connections. The initial default limit is set to 25. The application program can change this limit by calling SqlSetMaxProcs%.

See Also

SqlOpen%, SqlSetMaxProcs%


SqlGetOff%

Checks for the existence of Transact-SQL statements in the command buffer.

Syntax

SqlGetOff% ( sqlconn%, offtype%, startfrom% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
offtype%
Is the type of offset you want to find. The types are off_select, off_from, off_order, off_compute, off_table, off_procedure, off_statement, off_param, and off_exec.

For details, see DB-Library for Visual Basic Options.

startfrom%
Is the point in the buffer from which to start looking. The command buffer begins at 0.

Returns

The character offset into the command buffer for a specified offset. If the offset is not found, -1 is returned.

Remarks

If the SQLOFFSET option has been set (see DB-Library for Visual Basic Options.), SqlGetOff% can check for the location of certain Transact-SQL statements in the command buffer.

Examples

In example A, assume that the program doesn't know the contents of the command buffer but needs to know where the SQL keyword SELECT appears:

A.
       Dim SelectOffset (9) As Integer
       Dim LastOffset As Integer
       Dim i AS Integer
       'Set the offset option.
       SqlSetOption% (Sqlconn%, SQLOFFSET, "select")

       'Execute the option on the server.
       SqlExec%(Sqlconn%)

       'Read the returned results.
       Do Until SqlResults%(Sqlconn%) = NOMORERESULTS

          'Assume the command buffer contains the following SELECTs:
          Result% = SqlCmd%(Sqlconn%, "SELECT x = 100 SELECT y = 5")

    'Send the statement to SQL Server and start execution.
          Result% = SqlExec%(Sqlconn%)

          'Process the statement results.
          Result% = SqlResults%(Sqlconn%)

          'Get all the offsets to the SELECT keyword.
          LastOffset% = 0
          i% = 0
          Do Until LastOffset% = -1
             LastOffset% = SqlGetOff(Sqlconn%, OFF_SELECT, LastOffset%)
             SelectOffset% (i) = LastOffset%  1
             i% = i%  1
          Loop
       Loop

In example B, the function SqlGetOff% does not recognize SELECT statements in a subquery. So, if the command buffer contains the following program fragment, the second SELECT statement goes unrecognized:

B.
       select pub_name
       from publishers
       where pub_id not in
       (select pub_id
       from titles
       where type = "business")

See Also

SqlCmd%, SqlGetChar$, SqlSetOpt%, SqlStrCpy%, SqlStrLen%; Text and image Functions


SqlGetPacket%

Returns the tabular data stream (TDS) packet size currently in use.

Syntax

SqlGetPacket% ( sqlconn% )

where

sqlconn%
A SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

The TDS packet size currently in use.

Remarks

To determine the TDS packet size in use, an application should call SqlGetPacket% after SqlOpen%.

You can change the TDS packet size by using SqlSetLPacket%, which sets the packet size field in the login record.

If the call to SqlGetPacket% fails (for example, when sqlconn% is null), SqlGetPacket% returns 0. Other than the failure case of 0, however, the call should never return less than 512 bytes.

See Also

SqlSetLPacket%


SqlGetRow%

Sets the current row in the row buffer to a specific row number and reads it.

Syntax

SqlGetRow% ( sqlconn%, row& )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
row&
Is the number of the row to read. The first row returned is number 1.

Returns

One of four types of values depending on certain conditions:

  • If the current row is a regular row, REGROW (-1) is returned.
  • If the current row is a compute row, the ID of the COMPUTE clause is returned.
  • If the function is unsuccessful, FAIL (0) is returned.
  • If the row is not in the row buffer, NOMOREROWS (-2) is returned.

Remarks

SqlGetRow% works only if the SQLBUFFER option is set using SqlSetOpt%. When buffering is turned off, each row is processed by repeatedly calling SqlNextRow% until it returns NOMOREROWS. When buffering is turned on, you can use SqlGetRow% to jump to any row that has already been read and is still in the row buffer. After you call SqlGetRow% to read a row, you can call SqlNextRow% to return rows in order following the row read by SqlGetRow%.

See Also

SqlClrBuf, SqlNextRow%, SqlSetOpt%; DB-Library for Visual Basic Options


SqlGetTime%

Returns the number of seconds that DB-Library for Visual Basic waits for a SQL Server response to a Transact-SQL statement.

Syntax

SqlGetTime% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

The number of seconds that DB-Library for Visual Basic waits for a SQL Server response to a Transact-SQL statement. A value of 0 (the default) represents an infinite timeout period.

Remarks

SqlGetTime% returns the number of seconds that DB-Library for Visual Basic waits for a SQL Server response to calls to SqlExec%, SqlOk%, SqlResults%, and SqlNextRow%. You can change the timeout value by calling SqlSetTime%.

See Also

SqlSetTime%, SqlExec%, SqlOk%, SqlResults%, SqlNextRow%


SqlInit$

Initializes DB-Library for Visual Basic.

Syntax

SqlInit$ ( )

Returns

A string containing the version number of DB-Library for Visual Basic. If initialization is unsuccessful, SqlInit$ returns an empty string.

Important If SqlInit$ returns an empty string, do not attempt to call any other DB-Library for Visual Basic procedures because unpredictable results can occur.

Remarks

You must call SqlInit$ before calling any other DB-Library for Visual Basic procedures.

SqlInit$ initializes the user-defined error and message handlers, if present. When running with the Windows environment, DB-Library maintains information about each application that has referenced it. DB-Library creates the information when a library application calls SqlInit$; it does this to prevent conflicts between applications that use DB-Library concurrently. In order for DB-Library to release this information, the application must call SqlWinExit just before it exits.

See also

SqlOpen% and SqlWinExit


SqlIsAvail%

Determines whether a sqlconn connection is available for general use.

Syntax

SqlIsAvail% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

SUCCEED (1) if the sqlconn connection is available for general use; otherwise, FAIL (0).

Remarks

SqlIsAvail% indicates whether the specified sqlconn connection is available for general use. When a sqlconn connection is first opened, it is marked as being available until it is used. Many DB-Library for Visual Basic functions automatically set sqlconn to "not available," but only SqlSetAvail resets it to "available." This facility is useful when several parts of an application are trying to share a single sqlconn connection.

See Also

SqlSetAvail


SqlIsCount%

Indicates whether or not the count returned by SqlCount& is real.

Syntax

SqlIsCount% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

SUCCEED (1) if the count returned by SqlCount& is real or FAIL (0) if the count returned by SqlCount& is not real.

Remarks

You can have commands that return or affect 0 or more rows and commands that do not affect rows. In both cases SqlCount& returns 0.

Calling SqlIsCount% after SqlCount& determines whether the count is real.

See Also

SqlCount&


SqlIsOpt%

Checks the status of an option set by SqlSetOpt%.

Syntax

SqlIsOpt% ( sqlconn%, opt%, optparam$ )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%. Unlike the value of sqlconn% when you use SqlSetOpt% and SqlClrOpt%, the value of sqlconn% cannot be 0 when you use SqlIsOpt%.
opt%
Is the option to be checked. Do not enclose the option name in quotation marks. For a list of the options available in DB-Library for Visual Basic, see DB-Library for Visual Basic Options.
optparam$
Is a parameter for an option. You must include optparam$ for all options, whether or not they take parameters. Enclose optparam$ in quotation marks.

If an option does not take a parameter, optparam$ is ignored. If an option does take a parameter, optparam$ is ignored for all options except SQLOFFSET and SQLSTAT.

The SQLOFFSET and SQLSTAT options can have several settings, each with a different parameter. In these cases, SqlIsOpt% needs a valid optparam$ to determine which option parameter to check.

For a list of the options available in DB-Library for Visual Basic, see DB-Library for Visual Basic Options.

Returns

SUCCEED (1) or FAIL (0).

Remarks

Although you can set and clear SQL Server query options directly through Transact-SQL, design your application to use SqlSetOpt% and SqlClrOpt% to set and clear options because these functions provide a uniform interface for setting both SQL Server and Visual Basic options. With these functions, your application can also use SqlIsOpt% to check the status of an option. For a list of each option in DB-Library for Visual Basic and its default status, see DB-Library for Visual Basic Options.

See Also

SqlClrOpt%, SqlSetOpt%; DB-Library for Visual Basic Options


SqlLastRow&

Returns the number of the last row in the row buffer.

Syntax

SqlLastRow& ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

The number of the last row in the row buffer. The first row returned from SQL Server is number 1.

Remarks

If you do not turn on row buffering, SqlFirstRow&, SqlCurRow&, and SqlLastRow& always return the same value (the number of the current row).

If you turn on row buffering by setting the SQLBUFFER option with SqlSetOpt%, SqlLastRow& returns the number of the highest (newest) row of results in the buffer. For example, if a query returns 100 result rows and you read 20 rows into the buffer using SqlNextRow%, SqlLastRow& returns 20 regardless of which row is current. As the application processes and clears rows from the buffer using SqlClrBuf and more data is read from the server using SqlNextRow%, SqlLastRow& returns the number of the result row stored in the highest (newest) buffer location.

SqlFirstRow& returns the number of the result row stored in the lowest (oldest) buffer location.

See Also

SqlClrBuf, SqlCurRow&, SqlFirstRow&, SqlGetRow%, SqlNextRow%, SqlSetOpt%; DB-Library for Visual Basic Options


SqlLogin%

Allocates a login record for use with SqlOpen%.

Syntax

SqlLogin% ( )

Returns

The identifier of a login record. If the login record cannot be allocated, 0 is returned.

Important Do not modify this identifier in any way. Modifying the identifier can cause unpredictable results.

Remarks

Your program can use the following functions to supply the components of a login record:

  • SqlSetLUser% supplies the login ID.
  • SqlSetLPwd% supplies the user's password. The password is required only if the user has a password on SQL Server.
  • SqlSetLHost% supplies the workstation name.
  • SqlSetLApp% supplies the application name.
  • SqlSetLNatLang% supplies the national language.
  • SqlSetLPacket% supplies the TDS packet size.
  • SqlSetLSecure% requests a secure connection.
  • SqlSetLVersion% sets DB-Library 6.0 behavior.
  • SqlBCPSetL% enables bulk copy operations.

See Also

SqlBCPSetL%, SqlFreeLogin, SqlOpen%, SqlSetLApp%, SqlSetLHost%, SqlSetLPacket%, SqlSetLPwd%, SqlSetLSecure%, SqlSetLUser%, SqlSetLVersion%


SqlMoreCmds%

Indicates whether there are more statements in the command buffer to be processed.

Syntax

SqlMoreCmds% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

SUCCEED (1) or FAIL (0). SUCCEED indicates there are more results in the command buffer to be processed.

Remarks

You can call SqlMoreCmds% after SqlNextRow% returns NOMOREROWS. If you know that the current statement is returning no rows, you can call SqlMoreCmds% after SqlResults% returns SUCCEED.

You can get the same information by calling SqlResults% until it returns NOMORERESULTS.

See Also

SqlCmdRow%, SqlResults%, SqlRows%, SqlRowType%


SqlName$

Returns the name of the current database.

Syntax

SqlName$ ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

The name of the current database.

Remarks

If you need to keep track of when the database changes, use SqlChange$.

See Also

SqlChange$, SqlUse%


SqlNextRow%

Reads in the next data row from the row buffer.

Syntax

SqlNextRow% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

One of five types of values depending on certain conditions:

  • If SqlNextRow% reads a regular row, REGROW (-1) is returned. Regular rows contain data from columns designated by a SELECT statement.
  • If SqlNextRow% is unsuccessful, FAIL (0) is returned.
  • If there are no more rows to be read, if the statement returns no rows, or if the server was unable to return more rows (for example, when a deadlock occurs), NOMOREROWS (-2) is returned.
  • If row buffering is turned on (using SqlSetOpt% with the SQLBUFFER option) and reading the next row would fill the buffer, BUFFULL (-3) is returned. In this case, no row is read, and to continue, at least one row must be cleared from the top of the row buffer. Clear the row buffer by calling SqlClrBuf.
  • If the current row is a compute row, the identification number of the COMPUTE clause is returned.

Remarks

Normally, each row is processed in turn by repeatedly calling SqlNextRow%. If row buffering is turned on and the row buffer is cleared by SqlClrBuf, the discarded rows are no longer available. When row buffering is turned off, the last row is cleared when SqlNextRow% returns NOMOREROWS. If row buffering is turned on and you call SqlGetRow% to read a row, you can call SqlNextRow% to return rows in order following the row read by SqlGetRow%.

SqlResults% must be called and must return SUCCEED before you make any calls to SqlNextRow%.

You must continue calling SqlNextRow% until it returns NOMOREROWS. This is true even when you know that your query generates only one results row. Even if SqlRows% or SqlCmdRow% returns FAIL (indicating that no rows were returned), you must process the results by calling SqlNextRow% until it returns NOMOREROWS.

SQL Server can return two types of rows:

  • Regular rows containing data from columns designated by a SELECT statement's select list.
  • Compute rows resulting from the COMPUTE clause.

To help process data rows from SQL Server, SqlNextRow% returns different values according to the type of row. For details, see the previous section, "Returns."

Note This function is one of the four that do not return control to the application until the server sends the required response. The application can be blocked for a considerable time if the server is waiting for a lock or is processing a large sort. If this is unacceptable, always call SqlDataReady% before SqlNextRow% and set the DB-Library timeout to regain control periodically.

Example

The following program fragment uses SqlNextRow% to process a regular row:

'Put the statement into the command buffer.
Result% = SqlCmd%(Sqlconn%, "SELECT data FROM table")

'Send the statement to SQL Server and start execution.
Result% = SqlExec%(Sqlconn%)
'Process the statement results.
Result% = SqlResults%(Sqlconn%)

'Retrieve and process the data in each row.
DO UNTIL SqlNextRow%(Sqlconn%) = NOMOREROWS

   'Code to print or process row of data.

LOOP

See Also

SqlCancel%, SqlCanQuery%, SqlClrBuf, SqlGetRow%, SqlResults%, SqlRows%; DB-Library for Visual Basic Options


SqlNumAlts%

Returns the number of columns in a COMPUTE clause row.

Syntax

SqlNumAlts% ( sqlconn%, computeid% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
computeid%
Is the COMPUTE clause. A SELECT statement can have multiple COMPUTE clauses, each of which can have a different number of aggregate operators and aggregate targets. The computeid% is returned by SqlNextRow% or SqlGetRow%.

Returns

The number of columns for a particular computeid%. If computeid% is invalid,
-1 is returned.

Remarks

Call this function after SqlResults% returns SUCCEED.

Example

In the following example, SqlNumAlts%(sqlconn%, 1) returns 3:

select dept, year, sales from employee
order by dept, year
compute avg(sales), min(sales), max(sales) by dept

See Also

SqlAData$, SqlADLen&, SqlAltLen%, SqlAltType%, SqlGetRow%, SqlNextRow%, SqlResults%


SqlNumCols%

Returns the number of columns in the current set of results.

Syntax

SqlNumCols% ( sqlconn% ) ( )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

The number of columns in the current results set. If there are no columns, 0 is returned.

Example

'Put two statements into the command buffer.
cmd$ = "SELECT name, type, id FROM sysobjects"
cmd$ = cmd$  " SELECT type FROM sysobjects"
Result% = SqlCmd%(Sqlconn%, cmd$)

'Send the statements to SQL Server and start execution.
Result% = SqlExec%(Sqlconn%)

'Process the results of each statement.
DO UNTIL SqlResults%(Sqlconn%) = NOMORERESULTS
   PRINT SqlNumCols%(Sqlconn%);
   PRINT "column(s) in this result."
   DO UNTIL SqlNextRow%(Sqlconn%) = NOMOREROWS
   'Code to print or process row of data.
   LOOP
LOOP

Output:

3 column(s) in this result.
1 column(s) in this result.

See Also

SqlColLen%, SqlColName$


SqlNumCompute%

Returns the number of COMPUTE clauses in the current set of results.

Syntax

SqlNumCompute% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

The number of COMPUTE clauses in the current results set.

Remarks

Call SqlNumCompute% after SqlResults% returns SUCCEED.

Example

In this example, SqlNumCompute%(sqlconn%) returns 2 because there are two COMPUTE clauses in the SELECT statement:

SELECT dept, name FROM employee
ORDER BY dept, name
COMPUTE COUNT(name) BY dept
COMPUTE COUNT(name)

See Also

SqlNumAlts%, SqlResults%


SqlNumOrders%

Returns the number of columns specified in the ORDER BY clause of a Transact-SQL SELECT statement.

Syntax

SqlNumOrders% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

The number of ORDER BY columns.

Remarks

Once a SELECT statement is executed and SqlResults% returns SUCCEED, call SqlNumOrders% to find out how many columns are specified in the current statement's ORDER BY clause.

See Also

SqlOrderCol%, SqlResults%


SqlOpen%

Allocate and initialize a SQL Server connection.

Syntax

SqlOpen% ( loginrec%, server$ )

where

loginrec%
Is a login record. The value of loginrec% is returned by SqlLogin%.
server$
Is the name of the SQL Server you want to connect to.

Returns

The identifier of a SQL Server connection. SqlOpen% returns 0 if a SQL Server connection cannot be created or initialized, or if your login to SQL Server fails. When 0 is returned, the DB-Library error handler is called to indicate the error.

Important Do not modify the identifier returned by SqlOpen% in any way. Modifying the SqlOpen% identifier can cause unpredictable results.

Remarks

To communicate with SQL Server, DB-Library for Visual Basic requires a SQL Server connection. SqlOpen% allocates the data structure associated with the connection, sets up communication with the network, logs in to SQL Server, and initializes any default options. SqlOpen% returns an identifier that is subsequently used by almost every DB-Library for Visual Basic procedure. A program can open multiple connections with SQL Server. The same login record can be used for multiple calls to SqlOpen%.

SqlOpen% returns 0 when it encounters any of the errors in the following table:

Error | Description
SQLECONN | Server is unavailable or does not exist.
SQLEPWD | Login is incorrect.
SQLESQLPS | Maximum number of SQL Server connections already allocated.

Example

'Get a login record and set login attributes.
Login% = SqlLogin%()
Result% = SqlSetLUser%(Login%, "loginid")
Result% = SqlSetLPwd%(Login%, "passwd")
Result% = SqlSetLApp%(Login%, "myapp")

'Get a connection for communicating with SQL Server.

Sqlconn% = SqlOpen%(Login%, "server")

See Also

SqlClose, SqlExit, SqlLogin%, SqlSetLoginTime%; Messages


SqlOrderCol%

Returns the number of the column that appears in a specified location within the ORDER BY clause of the most recently executed Transact-SQL SELECT statement.

Syntax

SqlOrderCol% ( sqlconn%, order% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
order%
Is the number that identifies a particular ORDER BY column. The first column named in the ORDER BY clause is number 1.

Returns

The column number (based on the column's position in the select list) for the column in a specified place in the ORDER BY clause. If order% is invalid, -1 is returned.

Remarks

Call SqlOrderCol% after SqlResults% has returned SUCCEED.

Example

In the following Transact-SQL statement, SqlOrderCol% with an order% parameter of 1 returns 3, since the first column named in the ORDER BY clause refers to the third column in the SELECT clause:

SELECT dept, name, salary FROM employee
ORDER BY salary, name

See Also

SqlNumOrders%


SqlProcInfo%

Returns information about a SQL Server connection.

Syntax

SqlProcInfo% ( sqlconn%, conninfo )

where

sqlconn%
A SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
conninfo
A ProcInfo structure that DB-Library will fill with information about the specified connection.

The ProcInfo structure is defined as follows:

Type ProcInfo
    ServerType As Integer
    ServerMajor As Integer
    ServerMinor As Integer
    ServerRevision As Integer
    ServerName As String * 31
    NetLibName As String * 31
    NetLibConnStr As String * 256
End Type

The ProcInfo fields are described below:
Field | Description
ServerType Is one of the following:

SERVTYPE_MICROSOFT if you are connected to a Microsoft SQL Server.

SERVTYPE_UNKNOWN if you are connected to an unknown type of SQL Server.
ServerMajor | Is the XX value in the XX.YY.ZZZ version number of the SQL Server you are connected to. For example, 6.
ServerMinor | Is the YY value in the XX.YY.ZZZ version number of the SQL Server you are connected to. For example, 0.
ServerRevision | Is the ZZZ value in the XX.YY.ZZZ version number of the SQL Server you are connected to. For example, 101.
ServerName | Is the name of the SQL Server you are connected to
NetLibName | Is the name of the Net-Library DLL used to connect to SQL Server.
NetLibConnStr | Is the Net-Library connection string used to connect to SQL Server.

Returns

succeed (1) or fail (0).

Remarks

The SqlProcInfo% function fills the supplied ProcInfo structure with information about the SQL Server connection.

See Also

SqlOpen%


SqlPrType$

Converts a SQL Server token value to a string.

Syntax

SqlPrType$ ( token% )

where

token%
Is the SQL Server token value.

Returns

A string that is the readable translation of the SQL Server token value. When token% is unknown, SqlPrType$ returns an empty string. The strings correspond to SQL Server datatype names.

Remarks

Functions such as SqlColType% and SqlAltType% return SQL Server token values. Use SqlPrType$ to get the string translation of the token value.

The following table shows the token values used by SqlPrType$:

Token value | Datatype
SQLINT1 | tinyint
SQLINT2 | smallint
SQLINT4 | int
SQLMONEY | money
SQLMONEY4 | smallmoney
SLQFLT4 | real
SLQFLT8 | float
SQLDATETIME | datetime
SQLDATETIM4 | smalldatetime
SQLBIT | bit
SQLCHAR | char
SQLVARCHAR | varchar
SQLTEXT | text
SQLBINARY | binary
SQLVARBINARY | varbinary
SQLIMAGE | image
SQLDECIMAL | decimal
SQLNUMERIC | numeric
SQLINTN | integer-null
SQLDATETIMN | datetime-null
SQLMONEYN | money-null
SQLFLTN | float-null
SQLAOPSUM | sum
SQLAOPAVG | avg
SQLAOPCNT | count
SQLAOPMIN | min
SQLAOPMAX | max

See Also

SqlAltOp%, SqlAltType%, SqlColType%


SqlResults%

Sets up the next statement in the command buffer for processing.

Syntax

SqlResults% ( sqlconn% ) ( )

where

sqlconn% ( )
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

SUCCEED (1), FAIL (0), NOMORERESULTS (2), or NOMORERPCRESULTS (3). The most common reason for failing is an invalid SQL Server connection. NOMORERPCRESULTS is returned when stored procedure return information is available from one stored procedure in a batch of multiple stored procedures. NOMORERESULTS is returned if there are no more results to be processed.

Note This function is one of the four that do not return control to the application until the server sends the required response. The application can be blocked for a considerable time if the server is waiting for a lock or processing a large sort. If this is unacceptable, always call SqlDataReady% before SqlResults% and set the DB-Library timeout to regain control periodically.

Remarks

SqlResults% is called after SqlExec% or SqlOk% returns SUCCEED. SqlResults% always returns SUCCEED or NOMORERESULTS on the first call if SqlExec% or SqlOk% has returned SUCCEED, unless a network error or out-of-memory error has occurred. Once SqlResults% returns SUCCEED, you typically process any result rows using SqlNextRow% unless a network error or out-of-memory error has occurred.

SqlResults% must be called for each statement in the command buffer, whether or not the statement returns any rows. If the number of statements in the command buffer is unknown, you can call SqlResults% until it returns NOMORERESULTS. You must also call SqlResults% once for each stored procedure in the command buffer. However, if the stored procedure contains more than one Transact-SQL SELECT statement, SqlResults% must be called once for each statement. The easiest way to do this is to continue to call SqlResults% until it returns NOMORERESULTS.

You must call SqlResults% until it returns NOMORERESULTS or until any continued use of the connection causes the DB-Library error 10038 "Results Pending."

Example

'Put the statement into the command buffer.
Result% = SqlCmd%(Sqlconn%, "SELECT data FROM table")
'Send the statement to SQL Server and start execution.
Result% = SqlExec%(Sqlconn%)
DO UNTIL Result% = NOMORERESULTS    'Process the statement results.
   Result% = SqlResults%(Sqlconn%)

   'Retrieve and process the data in each row.
   DO UNTIL SqlNextRow%(Sqlconn%) = NOMOREROWS
      'Code to print or process row of data.
   LOOP
LOOP

See Also

SqlCancel%, SqlCanQuery%, SqlExec%, SqlNextRow%, SqlOk%, SqlOpen%


SqlRows%

Indicates whether the current statement returned rows.

Syntax

SqlRows% ( sqlconn% )

where

sqlconn% ( )
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

SUCCEED (1) or FAIL (0).

Remarks

Call SqlRows% after SqlResults% returns SUCCEED and before you call SqlNextRow%; otherwise, SqlRows% returns an incorrect value. You can use SqlCmdRow% to determine whether the current statement is one that can return rows (that is, whether it is a Transact-SQL SELECT statement or a Transact-SQL EXECUTE statement executing a stored procedure containing a SELECT statement).

Even if SqlRows% returns FAIL, you must still process the results by calling SqlNextRow% until it returns NOMOREROWS.

See Also

SqlCmdRow%, SqlNextRow%, SqlResults%, SqlRowType%


SqlRowType%

Indicates whether the current result row is a regular row or a COMPUTE row.

Syntax

SqlRowType% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

One of four values depending on certain conditions:

  • If the current row is a regular row, REGROW (-1) is returned.
  • If the current row is a compute row, the ID of the COMPUTE clause is returned.
  • If SqlRowType% was unsuccessful, FAIL (0) is returned.
  • If no rows have been read, NOMOREROWS (-2) is returned.

Remarks

Because SqlNextRow% returns the row type, you can usually determine the type of the current row without using SqlRowType%.

See Also

SqlNextRow%


SqlServerEnum%

Lists the names of local SQL Servers, network SQL Servers, or both.

Syntax

SqlServerEnum% ( searchmode%, serverbuf$, numentries% )

where

searchmode%
Determines whether SqlServerEnum% checks for server names locally, on the network, or both.

LOCSEARCH searches for the server names listed in the WIN.INI file. LOCSEARCH has the value 1.

NETSEARCH searches for server names on the network type defined by the default Net-Library. The VBSQL Library loads the default Net-Library set by the DSQUERY entry in the WIN.INI file. If no default entry exists, the VBSQL Library loads the named pipes Net-Library. NETSEARCH has the value 2.

(LOCSEARCH NETSEARCH) searches for server names using both methods, searching first for server names listed in the WIN.INI file and then for server names on the network type defined by the default Net-Library. A server name is listed twice if it is specified in the WIN.INI file and is also available on the default network type.

serverbuf$
Is the buffer that stores the server names that SqlServerEnum% returns. You must preallocate this buffer using an appropriate Visual Basic function such as Space$. DB-Library for Visual Basic determines the length of the buffer based on what you allocated.
numentries%
Is an output parameter that returns the number of server names copied to the buffer by the current call to SqlServerEnum%.

Returns

SqlServerEnum% returns one or more of the following status codes:

Constant | Value
ENUMSUCCESS% | 0
MOREDATA% | 1
NETNOTAVAIL% | 2
OUTOFMEMORY% | 4
NOTSUPPORTED% | 8

Remarks

The SqlServerEnum% function returns a list of server names to the server$ buffer in the order in which it finds them. LOCSEARCH names are listed before NETSEARCH names. Only complete server names are copied to the buffer. Each server name is separated by a null character (chr$(0)).

The end of the list is designated by two consecutive null characters. If the buffer becomes full before SqlServerEnum% has finished sending names, SqlServerEnum% returns the value MOREDATA.

Note that on named pipes networks, SqlServerEnum% returns the server names of computers on which SQL Server is installed, regardless of whether or not SQL Server is currently running.

See Also

SqlOpen%


SqlSetAvail

Marks a sqlconn% connection as being available for general use.

Syntax

SqlSetAvail ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Remarks

Any subsequent call to SqlIsAvail% returns SUCCEED until some use is made of the sqlconn% connection. SqlSetAvail is not normally required in an application.

See Also

SqlIsAvail%


SqlSetLApp%

Sets the application name in the SQL Server login record.

Syntax

SqlSetLApp% ( loginrec%, app$ )

where

loginrec%
Is a login record. The value of loginrec% is returned by SqlLogin%.
app$
Is the application name sent to SQL Server. This string can have as many as 30 characters. SQL Server stores only the first 16 characters and ignores the rest.

Returns

SUCCEED (1) or FAIL (0).

Remarks

For SqlSetLApp% to have any effect, it must be called before SqlOpen%. SqlSetLApp% is optional. If SqlSetLApp% is not called, the application name is set to an empty string.

SQL Server uses the application name in its sysprocesses table to help identify your connection. You see the application name when you query the sysprocesses table in the master database.

See Also

SqlLogin%, SqlOpen%, SqlSetLHost%, SqlSetLPwd%, SqlSetLUser%


SqlSetLHost%

Sets the workstation name in the SQL Server login record.

Syntax

SqlSetLHost% ( loginrec%, workstation$ )

where

loginrec% ( )
Is a login record. The value of loginrec% is returned by SqlLogin%.
workstation$
Is the workstation name sent to SQL Server. The string can have as many as 30 characters. SQL Server stores only the first 10 characters and ignores the rest.

Returns

SUCCEED (1) or FAIL (0).

Remarks

For SqlSetLHost% to have any effect, it must be called before SqlOpen%. SqlSetLHost% is optional. If SqlSetLHost% is not called, the workstation name is set to an empty string.

SQL Server uses the workstation name in its sysprocesses table and when you issue an sp_who procedure to identify your connection. You see the workstation name when you query the sysprocesses table in the master database.

See Also

SqlLogin%, SqlOpen%, SqlSetLApp%, SqlSetLPwd%, SqlSetLUser%


SqlSetLNatLang%

Sets the name of the national language in the LOGINREC structure.

Syntax

SqlSetLNatLang% ( loginrec%, language$ )

where

loginrec%
Is a login record to be passed as a parameter to SqlOpen%. Execute SqlLogin% to get LOGINREC structures.
language$
Is the name of the national language to use.

Returns

SUCCEED (1) or FAIL (0).

Remarks

To set a language other than the SQL Server default, call SqlSetLNatLang% before SqlOpen%. If language support is installed on the server, error messages are returned in the designated national language.

See Also

SqlLogin% and SqlOpen%


SqlSetLoginTime%

Sets the number of seconds that DB-Library for Visual Basic waits for SQL Server to respond to a connection request from SqlOpen%.

Syntax

SqlSetLoginTime% ( timeout% )

where

timeout%
Is the number of seconds that DB-Library for Visual Basic waits for a login response. A timeout% value of 0 represents an infinite period. The default timeout% value is 60 seconds.

Returns

SUCCEED (1) or FAIL (0).

See Also

SqlSetTime%


SqlSetLPacket%

Sets the tabular data stream (TDS) packet size in a SQL Server login record.

Syntax

SqlSetLPacket% ( loginrec%, packetsize% )

where

loginrec%
A login record, which is passed as a parameter to SqlOpen%. The value of loginrec% is returned by SqlLogin%.
packetsize%
The size requested, in bytes (0 through 65535). The server will set the actual packet size to a value less than or equal to the requested size.

Returns

succeed (1) or fail (0).

Remarks

Tabular data stream (TDS) is an application protocol used for the transfer of requests and request results between clients and servers. TDS data is sent in fixed-size chunks, called "packets." TDS packets have a default size set by SQL Server. If an application does bulk copy operations, or sends or receives large amounts of text or image data, a packet size larger than the default might improve efficiency, since it results in fewer network reads and writes. For large data transfers, a packet size between 4092 and 8192 is usually best. Any larger size can degrade performance.

The only way an application can change the TDS packet size is by using SqlSetLPacket%. If SqlSetLPacket% is not called, all SQL Server connections in an application will use the default size.

Note that when the application logs in to the server, the server sets the TDS packet size for that SQL Server connection to be equal to or less than the value of the packetsize% parameter. If the server is experiencing space constraints, the packet size is set to a value less than the value of the packetsize% parameter. Otherwise, the packet size is equal to the value of this parameter. To determine the packet size that the server has set, call SqlGetPacket%.

Different SQL Server connections in an application can use different packet sizes. To set different packet sizes for connections, an application can either change the packet size in a single login record between the SqlOpen% calls that create the connections, or it can set different packet sizes in multiple login records structures and use these different login records when creating the SQL Server connections.

See Also

SqlGetPacket%, SqlLogin%, SqlOpen%


SqlSetLPwd%

Sets the user's SQL Server password in the SQL Server login record.

Syntax

SqlSetLPwd% ( loginrec%, pwd$ )

where

loginrec% ( )
Is a login record. The value of loginrec% is returned by SqlLogin%.
pwd$
Is the SQL Server password sent to SQL Server. The string can have as many as 30 characters.

Returns

SUCCEED (1) or FAIL (0).

Remarks

For SqlSetLPwd% to have any effect, it must be called before SqlOpen%. SqlSetLPwd% is required only if the user has a SQL Server password. If SqlSetLPwd% is not called, the password is set to an empty string.

The SQL Server passwords are defined in the syslogins table in the master database. Only the system administrator has permission to look at passwords.

See Also

SqlLogin%, SqlOpen%, SqlSetLApp%, SqlSetLHost%, SqlSetLUser%


SqlSetLSecure%

Sets the secure connection flag in a SQL Server login record.

Syntax

SqlSetLSecure% ( loginrec% )

where

loginrec%
A login record, which is passed as a parameter to SqlOpen%. The value of loginrec% is returned by SqlLogin%.

Returns

succeed (1) or fail (0).

Remarks

By setting the secure connection flag in a login record with SqlSetLSecure%, the application requests a secure or trusted connection to SQL Server. This means that SQL Server will use integrated login security to establish connections made (using SqlOpen%) with this login record, regardless of the current login security mode at the server. Any login ID or password supplied by SqlSetLUser% or SqlSetLPwd% is ignored.

To use SqlSetLSecure% and trusted connections, you must first use xp_grantlogin or SQL Security Manager to grant SQL Server system administrator or user privilege to the appropriate Windows NT - based groups or users. Use xp_revokelogin or SQL Security Manager to revoke SQL Server privileges and stop a user or group from using a trusted connection.

Note that SqlSetLSecure% enables trusted connections even when the server is in standard login security mode.

See Also

SqlLogin%, SqlOpen%, SqlSetLApp%, SqlSetLHost%, SqlSetLUser%


SqlSetLUser%

Sets the login ID in the SQL Server login record.

Syntax

SqlSetLUser% ( loginrec%, loginid$ )

where

loginrec% ( )
Is a login record. The value of loginrec% is returned by SqlLogin%.
loginid$
Is the login ID sent to SQL Server. The string can have as many as 30 characters.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SQL Server uses the loginrec% parameter you set with SqlSetLUser% to determine who is attempting a connection. For SqlSetLUser% to have any effect, it must be called before SqlOpen%. You must provide a login ID to establish a SQL Server connection. The SQL Server login IDs are defined in the syslogins table in the master database.

See Also

SqlLogin%, SqlOpen%, SqlSetLApp%, SqlSetLHost%, SqlSetLPwd%


SqlSetLVersion%

Sets the DB-Library client behavior to version 4.2 or version 6.0 behavior in a login record.

Syntax

SqlSetLVersion% ( loginrec%, version% )

where

loginrec%
A login record, which is passed as a parameter to SqlOpen%. The value of loginrec% is returned by SqlLogin%.
version%
The DB-Library client behavior to use. Must be either SQLVER60% to set DB-Library 6.0 behavior or SQLVER42% to set DB-Library 4.2 behavior.

Returns

succeed (1) or fail (0).

Remarks

If this function is not called, the default is DB-Library version 4.2 behavior.

Using the SQLVER60% value means that SQL Server will treat that connection as a DB-Library 6.0 client in every way. SQL Server will:

  • Return decimal and numeric data values
  • Return complete column information (including identity column information) to DB-Library and SqlColInfo%.

Using the SQLVER42% value (or not calling SqlSetLVersion% for the login record) means that SQL Server will treat that connection as a DB-Library 4.2x client. SQL Server will:

  • Convert decimal and numeric data values to float before returning them to the client
  • Return limited, version 4.2 column information (not including identity column information) to DB-Library and SqlColInfo%

Note that using SQLVER60% is not required to use SQL Server 6.0 server cursors.

See Also

SqlLogin%, SqlOpen%, SqlSetLApp%, SqlSetLHost%, SqlSetLPwd%


SqlSetMaxProcs%

Sets the maximum number of simultaneously open sqlconn connections.

Syntax

SqlSetMaxProcs% ( maxprocs% )

where

maxprocs%
Is the new limit on simultaneously open sqlconn connections for this particular application.

Returns

SUCCEED if the call is successful; otherwise, FAIL (maxprocs% <= 0).

Remarks

An application can find out the current connection limit by calling SqlSetMaxProcs%. For Windows-based applications, DB-Library for Visual Basic concurrent Windows-based applications can have as many as 45 simultaneously open sqlconn% connections. Although the default number is 25, the application can change the default by calling SqlSetMaxProcs%.

See Also

SqlGetMaxProcs%, SqlOpen%


SqlSetOpt%

Sets a DB-Library for Visual Basic option.

Syntax

SqlSetOpt% ( sqlconn%, opt%, optparam$ )

where

sqlconn% ( )
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
opt%
Is the option to be set. For a list of the options available in DB-Library for Visual Basic, see DB-Library for Visual Basic Options.
optparam$
Is a parameter for an option. Certain options take parameters. For example, the SQLBUFFER option takes as its parameter the number of rows to be buffered. The optparam$ variable must always be enclosed in quotation marks, even in the case of a numeric value.

If the option takes no parameters, the value of optparam$ is ignored. For options that take no parameters, optparam$ can be an empty string or any other string value.

When you use the Str$ function to convert a numeric optparam$ value to a string, it pads the string with a space. If you don't remove the padded space from the parameter, a call to SqlSetOpt% fails. For example, in the following code fragment, SqlSetOpt% fails:

Optparam$ = Str$(Value%)
SqlSetOpt%(Sqlconn%, X, Optparam$)

To use the Str$ function to convert a numeric optparam$ value to a string, you must use the LTrim function to remove the padded space. For example:

Optparam$ = Str$(Value%)
SqlSetOpt%(Sqlconn%, X, LTrim$(Optparam$))

For a list of the option parameters available in DB-Library for Visual Basic, see DB-Library for Visual Basic Options.

Returns

SUCCEED (1) or FAIL (0).

Remarks

Although some options can be set and cleared directly through Transact-SQL, design your application to use SqlSetOpt% and SqlClrOpt% to set and clear options because SqlSetOpt% and SqlClrOpt% provide a uniform interface for setting both SQL Server and DB-Library for Visual Basic options. They also allow the application to use SqlIsOpt% to check the status of an option.

Three options are unique to DB-Library for Visual Basic: SQLBUFFER, SQLTEXTLIMIT, and SQLNOAUTOFREE. In addition to these options, all Transact-SQL options can be set using SqlSetOpt%. If you set any of the Transact-SQL options using SqlSetOpt%, DB-Library for Visual Basic places the appropriate Transact-SQL SET statement into the command buffer. This SET statement must be executed at some later time to take effect. Each SET statement means another call to SqlResults%. Therefore, design your application to receive the results returned from the statement generated by SqlSetOpt%. If an invalid parameter is specified, its invalidity is not known until the statement is sent to SQL Server and the results for that statement are returned using SqlResults%.

See Also

SqlClrOpt%, SqlIsOpt%, SqlResults%; DB-Library for Visual Basic Options


SqlSetTime%

Sets the number of seconds that DB-Library for Visual Basic waits for a SQL Server response during calls to SqlExec%, SqlOk%, SqlResults%, SqlNextRow%, and SqlRpcExec%.

Syntax

SqlSetTime% ( timeout% )

where

timeout%
Is the number of seconds that DB-Library for Visual Basic waits for a SQL Server response before timing out. The default value of 0 represents an infinite timeout period.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlSetTime% sets the length of time in seconds that DB-Library for Visual Basic waits for a SQL Server response during calls to SqlExec%, SqlOk%, SqlResults%, SqlNextRow%, and SqlRpcExec%. SqlSetTime% can be called at any time before or after a call to SqlOpen%. It takes effect immediately upon being called. The SqlSetTime% function does not override existing network timeout settings.

To set a timeout value for calls to SqlOpen%, use SqlSetLoginTime%.

When an application sends a statement to SQL Server using SqlExec%, control is not returned to the calling application until SQL Server completes processing the statement or until the timeout expires. If you want your application to continue execution while SQL Server is processing the statement, send the statement with SqlSend%, continue its processing, and then, when it is ready to retrieve the results, call SqlOk%.

The application can call SqlGetTime% to learn the current timeout value.

See Also

SqlExec%, SqlGetTime%, SqlOk%, SqlRpcExec%, SqlSend%, SqlSetLoginTime%


SqlExec%

Sends the statements in the command buffer to SQL Server for execution.

Syntax

SqlExec% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

SUCCEED (1) or FAIL (0). Any of the following conditions causes SqlExec% to return FAIL:

  • The command buffer contains a Transact-SQL syntax error.
  • The statements cause a SQL Server permission violation.
  • Previous results are not completely processed.
  • No statement is specified (the command buffer is empty).
  • The network connection is broken.

Remarks

SqlExec% sends Transact-SQL statements stored in the command buffer to SQL Server. You can add statements to the command buffer by calling SqlCmd%. If one or more of the statements sent to SQL Server cannot be executed, none of the statements is processed.

Once SqlExec% returns SUCCEED, you must call SqlResults% to process the results.

SqlExec% is equivalent to SqlSend% followed by SqlOk%.

Example

The following code fragment shows a typical sequence of calls:

'Put the statement into the command buffer.
Result% = SqlCmd%(Sqlconn%, "SELECT data FROM table")

'Send the statement to SQL Server and start execution.
Result% = SqlExec%(Sqlconn%)

'Process the statement results.
Result% = SqlResults%(Sqlconn%)

'Retrieve and process the data in each row.
DO UNTIL SqlNextRow%(Sqlconn%) = NOMOREROWS

    'Code to print or process row of data.

LOOP

See Also

SqlCmd%, SqlNextRow%, SqlOk%, SqlResults%, SqlSend%, SqlSetTime%


SqlOk%

Verifies the correctness of a command batch.

Syntax

SqlOk% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

SUCCEED (1) or FAIL (0). The most common reason that a statement fails is a Transact-SQL syntax error.

Remarks

SqlOk% following SqlSend% is the equivalent of SqlExec%. SqlOk% must be called after SqlSend% returns SUCCEED. When SqlOk% returns SUCCEED, SqlResults% can be called to process the results. SqlOk% is useful in text-update operations. When text is sent to SQL Server using SqlMoreText%, SqlOk% must be called before the first call to SqlMoreText% and after the last call to SqlMoreText%. For an example of using SqlOk% in this context, see "SqlWriteText%."

Note This function is one of the four that do not return control to the application until the server sends the required response. The application can be blocked for a considerable time if the server is waiting for a lock or processing a large sort. If this is unacceptable, always call SqlDataReady% before SqlOk% and set the DB-Library timeout to regain control periodically.

See Also

SqlCmd%, SqlExec%, SqlNextRow%, SqlResults%, SqlSend%, SqlSetTime%


SqlSend%

Sends statements in the command buffer to SQL Server and does not wait for a response.

Syntax

SqlSend% ( sqlconn% )

where

sqlconn% ( )
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlSend% sends Transact-SQL statements stored in the command buffer to SQL Server. You can add statements to the command buffer by calling SqlCmd%. Once SqlSend% returns SUCCEED, you must call SqlOk% to verify the accuracy of the statements in the command buffer. Then call SqlResults% to process the results.

See Also

SqlCmd%, SqlExec%, SqlNextRow%, SqlOk%, SqlResults%, SqlSetTime%


SqlStrCpy%

Copies a portion of the command buffer to a program variable.

Syntax

SqlStrCpy% ( sqlconn%, start%, numbytes%, buffer$ ) ( )

where

sqlconn% ( )
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
start%
Is the character in the command buffer to start copying from. The first character is 0. When start% is greater than the length of the command buffer, the returned string is set to an empty string.
numbytes% ( )
Is the number of characters to copy.
numbytes% setting | Result
< 0 | SqlStrCpy% copies the entire command buffer.
= 0 | cmdstring$ is set to an empty string.
> 0 | SqlStrCpy% copies the actual number of bytes in the buffer and returns SUCCEED.

buffer$
Is a string variable to which the source string is copied.

Returns

SUCCEED (1) or FAIL (0). FAIL is returned if start% is negative.

Remarks

Internally, the command buffer is a linked list of text strings. Parts of the command buffer can be located and copied using SqlStrCpy% and SqlStrLen%.

See Also

SqlCmd%, SqlFreeBuf, SqlStrLen%


SqlStrLen%

Returns the length, in characters, of the command buffer.

Syntax

SqlStrLen% ( sqlconn% )

where

sqlconn% ( )
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

The length, in characters, of the command buffer.

Remarks

Internally, the command buffer is a linked list of text strings. Parts of the command buffer can be located and copied using SqlStrLen% and SqlStrCpy%.

See Also

SqlCmd%, SqlFreeBuf, SqlStrCpy%


SqlUse%

Sets the current database for a particular SQL Server connection.

Syntax

SqlUse% ( sqlconn%, sqlname$ )

where

sqlconn% ( )
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
sqlname$
Is a string containing the database name.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlUse% sets up the Transact-SQL USE statement and calls SqlExec% and SqlResults%. If the USE statement fails because the requested database has not yet completed a recovery process, SqlUse% continues to send USE statements at 1-second intervals until it succeeds or it encounters some other error.

Before SqlUse% sets the current database, it calls SqlFreeBuf to clear the command buffer. If you call SqlCmd% to place statements into the command buffer, execute these statements before calling SqlUse%.

See Also

SqlExec%, SqlResults%


SqlWinExit

Informs DB-Library for Visual Basic that the application is about to exit.

Syntax

SqlWinExit

Remarks

DB-Library for Visual Basic creates and maintains information about each application that has referenced it to prevent conflicts between applications that use DB-Library for Visual Basic concurrently. In order for DB-Library for Visual Basic to release this information, the application must call SqlWinExit just before it exits. Put the call to SqlWinExit before you call the End function to close an application. For example:

Sub Quit_Click()
   SqlExit
   SqlWinExit
   End
End Sub

SqlWinExit releases the memory DB-Library for Visual Basic allocated to keep track of this application and makes that memory available to other applications.

Important Once your application calls SqlWinExit, it cannot call any other DB-Library for Visual Basic function. If you call SqlWinExit and then want to issue one or more DB-Library for Visual Basic calls, you must again call SqlInit$ to re-register your application.

See Also

SqlInit$


Chapter 5 Cursor Functions

Cursor Functions

SqlCursor%

SqlCursorClose

SqlCursorColInfo%

SqlCursorData$

SqlCursorFetch%

SqlCursorFetchEx%

SqlCursorInfo%

SqlCursorInfoEx%

SqlCursorOpen%


SqlCursor%

Inserts, updates, deletes, locks, or refreshes a particular row in the fetch buffer of a client cursor, a transparent server cursor, or an explicit server cursor.

Syntax

SqlCursor% ( cursorhandle%, optype%, row%, table$, values$ )

where

cursorhandle%
Is the cursor handle previously returned by SqlCursorOpen%.
optype%
Specifies the type of cursor operation to perform on a row or rows in the fetch buffer, as follows:
optype% | Description
CRSDELETE% | Deletes row(s).
CRSINSERT% | Inserts a single row using data specified in values$.
CRSLOCKCC% Locks row(s).

Client cursor:

An exclusive lock is placed on the data page that contains the specified row%. The lock is maintained only if it is inside an open transaction block defined by BEGIN TRANSACTION; the lock is released when the transaction is closed by a COMMIT TRANSACTION or ROLLBACK TRANSACTION statement.

Transparent server cursor, explicit server cursor:

An update intent lock is placed on the data page that contains the specified row%. If not inside an open transaction, this lock is released when the next fetch is performed. If inside an open transaction, this lock is released when the transaction is closed.

CRSREFRESH% | Refreshes row(s) by retrieving current row data from SQL Server.
CRSUPDATE% | Updates row(s) using data specified in values$.

If the cursor was opened using a concuropt% of CURREADONLY% (specified in SqlCursorOpen%), only CRSREFRESH% is valid.

row%
Is the row number in the fetch buffer to which the optype% operation applies. The first row in the buffer is number 1. The specified row must contain valid row data.

Client cursor, transparent server cursor:

When optype% is CRSREFRESH%, a row% value of 0 indicates that all rows in the fetch buffer will be refreshed.

Explicit server cursor:

When optype% is one of the following values:

  • CRSDELETE%
  • CRSLOCKCC%
  • CRSREFRESH%
  • CRSUPDATE%

a row% value of 0 indicates that the optype% operation will be performed on all rows in the fetch buffer.

table$
Is the table to which the optype% operation applies. If optype% is CRSREFRESH% use an empty string. It must be one of the tables specified in the FROM clause of the SELECT statement (specified in SqlCursorOpen%) that defines the cursor. If the FROM clause includes only one table, this parameter is not required, and you can specify that table or an empty string.

Client cursor:

If the FROM clause includes more than one table, this parameter is required unless:

  • optype% is CRSINSERT% and values$ points to a complete INSERT statement
  • optype% is CRSUPDATE% and values$ points to a complete UPDATE statement

Transparent server cursor, explicit server cursor:

If the FROM clause includes more than one table and the SqlCursor% operation is being performed with an ambiguous column name, this parameter is required. If table$ is required but not specified, the default is the first table listed in the FROM clause.

values$
Is a string that contains a Transact-SQL statement or clause, or an empty string. This parameter specifies the data to be inserted or updated. The following table lists the valid values$ parameters for each optype%:
optype% | values$
CRSDELETE% | Empty string
CRSINSERT% Can be one of the following:

A string that contains a complete Transact-SQL INSERT statement that specifies the single row to be inserted, with no WHERE clause. The table specified in the INSERT statement overrides the table$ parameter. The row% parameter is ignored.

A string that contains just the VALUES clause (from an INSERT statement) that specifies the single row to be inserted. The VALUES keyword is optional, but the list of values to be inserted must be surrounded by parentheses. The row% parameter is ignored.
CRSLOCKCC% | Empty string
CRSREFRESH% | Empty string
CRSUPDATE% Can be one of the following:

A string that contains a complete UPDATE statement that specifies the changes made to a single row, with no WHERE clause. The table specified in the UPDATE statement overrides the table$ parameter. The row% parameter is ignored.

A string that contains just the SET clause (from an UPDATE statement) that specifies the changes made to a single row. The SET keyword is optional. The row% parameter is ignored.

Returns

SUCCEED (1) or FAIL (0).

This function can fail for the following reasons:

  • The cursor is opened as read only, no updates allowed.
  • A server or connection failure or timeout occurs.
  • You have not been granted permission to update or change the database.
  • DB-Library is out of memory.
  • A trigger in the database caused the INSERT, LOCK, or UPDATE operation to fail.
  • You are using optimistic concurrency control, and the row has changed.

Remarks

Using SqlCursor% does not affect the current cursor position.

When optype% is CRSUPDATE% and the values$ parameter is a string that contains the UPDATE statement or SET clause, the newly updated values are automatically available using SqlCursorData$.

When using CRSUPDATE%, if a change is made to a column that is part of the unique index used to open the cursor, the changed row will:

  • Be missing from a keyset cursor. The next time the changed row is fetched, the row status indicator (pstatus&() in SqlCursorOpen%) for that row will be FTCMISSING%.
  • Appear in a new position in a dynamic cursor. The new position depends on the new value of the unique index column, and later fetches might retrieve the changed row.

After using CRSDELETE%, deleted rows will be missing from a keyset cursor (later fetches will have a row status of FTCMISSING%), and will disappear from later fetches using dynamic cursors.

Client cursor:

When using CRSINSERT% with a keyset cursor, the inserted row does not appear in the cursor results set, and thus does not appear in later fetches.

Transparent server cursor, explicit server cursor:

When optype% is one of the following:

  • CRSINSERT% with a keyset cursor involving only one table
  • CRSUPDATE% to change a column that is part of the unique index used to open the cursor

the inserted or updated row will appear as a new row at the end of the keyset (even if the inserted row does not match the WHERE clause criteria), or it will appear in the position of a missing row if the unique index columns of the inserted or updated row match the unique index columns of the missing row.

See Also

SqlCursorClose, SqlCursorColInfo%, SqlCursorFetch%, SqlCursorInfo%, SqlCursorOpen%


SqlCursorClose

Closes the client cursor, transparent server cursor, or explicit server cursor, and releases the memory associated with the cursor handle.

Syntax

SqlCursorClose ( cursorhandle% )

where

cursorhandle%
Is a cursor handle returned by SqlCursorOpen%.

Returns

SUCCEED (1) or FAIL (0).

Remarks

After issuing SqlCursorClose, the cursor handle should not used.

See Also

SqlCursor%, SqlCursorColInfo%, SqlCursorFetch%, SqlCursorInfo%, SqlCursorOpen%


SqlCursorColInfo%

Returns information about the specified column of a client cursor, transparent server cursor, or explicit server cursor.

Syntax

SqlCursorColInfo% ( cursorhandle%, column%, colname$, coltype%, collen&, usertype% )

where

cursorhandle%
Is the cursor handle created by SqlCursorOpen%.
column%
Is the column number in the cursor for which information is to be returned. The first column is number 1.
colname$
Is a string that will contain the name of the column. The program variable should be large enough to accommodate the column name.
coltype%
Is a program variable that will contain the datatype token of the column. If coltype% is set to -1, the column datatype is not returned.
collen&
Is a program variable that will contain the maximum length of the column, in bytes. If collen& is set to -1, the maximum column length is not returned.
usertype%
Is a program variable that will contain the user-defined datatype of the column. If usertype% is set to -1, the column user-defined datatype is not returned.

Returns

SUCCEED (1) or FAIL (0).

Remarks

Call SqlCursorColInfo% after SqlCursorOpen% returns a valid cursor handle. The SqlColInfo% function returns more detailed information about a cursor column.

See Also

SqlColInfo%, SqlCursor%, SqlCursorClose, SqlCursorFetch%, SqlCursorInfo%, SqlCursorOpen%


SqlCursorData$

Returns the value of the data in a specified row and column of the current fetch buffer for a client cursor, a transparent server cursor, or an explicit server cursor.

Syntax

SqlCursorData$ ( cursorhandle%, rownum%, column% )

where

cursorhandle%
Is the cursor handle created by SqlCursorOpen%.
rownum%
Is the number of the row in the current fetch buffer to retrieve data from. The first row is number 1.
column%
Is the number of the column in the current fetch buffer to retrieve data from. The first column is number 1.

Returns

The value of the data in the specified row and column. When the column is NULL or the rownum% or column% is out of range, an empty string is returned.

Remarks

To convert the data from a string to a different datatype, use SqlColInfo% to get the datatype of the data, and then use Visual Basic functions to convert to Visual Basic datatypes. Some helpful Visual Basic conversion functions are shown in the following table. For more information, see your documentation for Visual Basic.

Visual Basic function | Description
CDBL | Converts a numeric expression to a double-precision value.
CLNG | Converts a numeric expression to a long integer.
VAL | Converts a string representation of a value to a numeric expression.

See Also

SqlColType%, SqlCursor%, SqlCursorClose, SqlCursorColInfo%, SqlCursorFetch%, SqlCursorInfo%, SqlCursorOpen%


SqlCursorFetch%

Fetches a block of rows (called the fetch buffer) from a client cursor or transparent server cursor, and makes the rows available using SqlCursorData$. If you are connected to SQL Server 6.0, you should use SqlCursorFetchEx%.

Syntax

SqlCursorFetch% ( cursorhandle%, fetchtype%, rownum% )

where

cursorhandle%
Is the cursor handle created by SqlCursorOpen%.
fetchtype%
Specifies the type of fetch to execute, changing the position of the fetch buffer within the cursor results set. The following table describes the different fetchtype% values:
fetchtype% | Description
FETCHFIRST% | Fetches the first block of rows from a dynamic or keyset cursor. The first row of the new fetch buffer is the first row in the cursor results set.
FETCHNEXT% Fetches the next block of rows from a dynamic or keyset cursor. The first row of the new fetch buffer is the row after the last row of the current fetch buffer.

If this is the first fetch using a new cursor, it behaves the same as FETCHFIRST%.
FETCHPREV% | Fetches the previous block of rows from a fully dynamic or keyset cursor. The first row of the new fetch buffer is nrows% (specified in SqlCursorOpen%) before the first row of the current fetch buffer.
FETCHRANDOM% | Fetches a block of rows from a keyset cursor. The first row of the new fetch buffer is the specified rownum% row in the keyset cursor results set.
FETCHRELATIVE% | Fetches a block of rows from a keyset cursor. The first row of the new fetch buffer is rownum% rows before or after the first row of the current fetch buffer.
FETCHLAST% | Fetches the last block of rows from a keyset cursor. The last row of the new fetch buffer is the last row of the cursor results set.

The block of rows retrieved by a fetch is called the fetch buffer. The number of rows in the fetch buffer is determined by the nrows% parameter of SqlCursorOpen%.

For a forward-only dynamic cursor (scrollopt% is CURFORWARD% in SqlCursorOpen%), you can use only FETCHFIRST% or FETCHNEXT%.

rownum%
Is the specified random or relative row number to use as the first row of the new fetch buffer. Use this parameter only with a fetchtype% of FETCHRANDOM% or FETCHRELATIVE%. Specify 0 for any other fetchtype%.

When fetchtype% is FETCHRANDOM%, the first row of the new fetch buffer is the rownum% row (counting forward from the beginning) of the keyset cursor results set. The rownum% parameter must be positive.

When fetchtype% is FETCHRELATIVE%:

  • A positive rownum% means that the first row of the new fetch buffer is rownum% rows after the first row of the current fetch buffer.
  • A negative rownum% means that the first row of the new fetch buffer is rownum% rows before the first row of the current fetch buffer.
  • A rownum% of 0 means that all rows in the fetch buffer are refreshed with current data from SQL Server without moving the current cursor position. This is identical to calling SqlCursor% with optype% set to CRSREFRESH%.

Returns

SUCCEED (1) or FAIL (0).

SUCCEED (1) is returned if every row was fetched successfully. Note that for a keyset cursor, a fetch that results in a missing row will not cause SqlCursorFetch% to FAIL (0).

FAIL (0) is returned if at least one of the following is true:

  • A fetchtype% of FETCHRANDOM%, FETCHRELATIVE%, or FETCHLAST% was used on a dynamic cursor.
  • A fetchtype other than FETCHFIRST% or FETCHNEXT% was used on a forward-only dynamic cursor.
  • The SQL Server connection is broken or times out.
  • DB-Library is out of memory.

Remarks

Specify the size of the fetch buffer in the nrows% parameter of SqlCursorOpen%.

After the fetch, the elements of the array of row status indicators (pstatus&() in SqlCursorOpen%) are filled with row status values, one for each row in the fetch buffer. Each row status value is a series of fetch status values ORed together. The following table shows the meaning of each row status value:

Fetch status | Description
FTCSUCCEED% | The row was successfully fetched. SqlCursorData$ will return valid data for the row.
FTCMISSING% | The row has been deleted or a unique index column of the row has been changed. Do not use SqlCursorData$ for the row. For keyset cursors, this fetch status can appear at any time. For dynamic cursors, this fetch status can appear only after the current fetch buffer is refreshed.
FTCENDOFKEYSET% | Is the end of the keyset. This fetch status is set for backward compatibility with "mixed" client cursors used by existing applications.
FTCENDOFRESULTS% | Is the end of the results set of a dynamic or keyset cursor. Rows in the fetch buffer after this row are invalid and will have a row status indicator of 0; do not use SqlCursorData$ for those rows. If ORed with FTCSUCCEED%, this is the last row in the cursor results set; it contains valid data. If ORed with FTCMISSING%, this is the last row in the cursor results set, but the row is missing. If not ORed with FTCSUCCEED% or FTCMISSING%, this row is invalid.

A row status indicator of 0 means that the row is invalid, and SqlCursorData$ will not return valid data. This usually happens when the row is before the beginning (first row) or after the end (last row) of the cursor results set.

After the fetch, SqlCursorData$ returns:

  • Valid data for all rows with a fetch status of FTCSUCCEED%.
  • Invalid data for all rows without a fetch status of FTCSUCCEED%.

If no fetches have been performed on a cursor, the current cursor position is before the beginning (first row) of the cursor results set.

After a fetch is complete, the new cursor position is one of the following:

  • The first row of the new fetch buffer, as specified under fetchtype%, if the first row of the new fetch buffer stayed within the cursor results set.
  • Adjusted to the first row of the cursor results set if the first row of the new fetch buffer would have been before the first row of the cursor results set and the last row of the new fetch buffer would have stayed within the cursor results set due to a FETCHPREV% operation.
  • Unchanged from the current position if all rows of the new fetch buffer would have been before the first row of the cursor results set, if the first row (and thus all rows) of the new fetch buffer would have been after the last row of the cursor results set, or, if for a keyset cursor, if the first row of the new fetch buffer would have been before the first row of the cursor results set and the last row of the new fetch buffer would have stayed within the cursor results set due to a FETCHRELATIVE% attempt with a negative rownum%.

When the new cursor position is unchanged because the first row (and thus all rows) of the new fetch buffer would have been after the last row of the cursor results set, all rows in the fetch buffer are invalid and will not have a fetch status of FTCSUCCEED%. In the case of dynamic cursors, the first row of the fetch buffer will have a fetch status of FTCENDOFRESULTS%, and later rows will have a row status of 0. In the case of keyset cursors, all rows in the fetch buffer will have a row status of 0.

When the new position of a dynamic cursor is unchanged because all rows of the new fetch buffer would have been before the first row of the cursor results set, all rows in the fetch buffer are invalid and will not have a fetch status of FTCSUCCEED%. The first row of the fetch buffer will have a fetch status of FTCENDOFRESULTS%, and later rows will have a row status of 0.

When the new cursor position is unchanged and all rows in the fetch buffer are invalid, you can use SqlCursor% to refresh the rows in the fetch buffer with current data from SQL Server. This will result in valid rows that reflect the current cursor position.

Each call to SqlCursorFetch% leaves the connection available for use with no pending results.

Note This function works with client cursors and transparent server cursors. Do not use both SqlCursorFetch% and SqlCursorFetchEx% with the same cursor handle. Once one of these functions is used on a specific cursor handle, any attempt to use the other function will return fail (0).

If rows in the current fetch buffer of a dynamic cursor are deleted, a fetch using a client cursor might behave differently than a fetch using a transparent server cursor.

Client cursor:

When the new position of a dynamic cursor is adjusted to be the first row of the cursor results set (which happens when the first row of the new fetch buffer would have been before the first row of the dynamic cursor results set and the last row of the new fetch buffer would have stayed within the dynamic cursor results set due to a FETCHPREV% operation), some rows at the end of the new fetch buffer might be invalid. Any invalid rows will have a row status indicator of 0.

If rows in the current fetch buffer of a dynamic cursor are deleted, a fetch next or fetch previous might result in a new fetch buffer that skips rows in the cursor results set or includes rows from the current fetch buffer again.

Transparent server cursor:

A fetchtype% of FETCHNEXT% or FETCHPREV% using a dynamic cursor is actually mapped to a relative fetch on SQL Server 6.0. Because of this, if the first row in the current fetch buffer is deleted before a FETCHNEXT% (mapped to a forward relative fetch on SQL Server 6.0) is performed, the current cursor position becomes invalid. For more information about the fetch behavior in this case, see SqlCursorFetchEx%.

See Also

SqlCursor%, SqlCursorColInfo%, SqlCursorClose, SqlCursorInfo%, SqlCursorOpen%


SqlCursorFetchEx%

Fetches a block of rows (called the fetch buffer) from an explicit server cursor and makes the rows available using SqlCursorData$.

Syntax

SqlCursorFetchEx% ( cursorhandle%, fetchtype%, rownum%, nfetchrows%, reserved& )

where

cursorhandle%
Is an explicit server cursor handle returned by SqlCursorOpen%.
fetchtype%
Specifies the type of fetch to execute, changing the position of the fetch buffer within the cursor results set. The following table describes the different fetchtype% values:
fetchtype% | Description
FETCHFIRST% | Fetches the first block of rows from a dynamic or keyset cursor. The first row of the new fetch buffer is the first row in the cursor results set.
FETCHNEXT% Fetches the next block of rows from a dynamic or keyset cursor. The first row of the new fetch buffer is the row after the last row of the current fetch buffer.

If this is the first fetch using a new cursor, it behaves the same as FETCHFIRST%.
FETCHPREV% | Fetches the previous block of rows from a fully dynamic or keyset cursor. The first row of the new fetch buffer is nrows% (specified in SqlCursorOpen%) before the first row of the current fetch buffer.
FETCHRANDOM% | Fetches a block of rows from a keyset cursor. The first row of the new fetch buffer is the specified rownum% row in the cursor results set.
FETCHRELATIVE% | Fetches a block of rows from a dynamic or keyset cursor. The first row of the new fetch buffer is rownum% rows before or after the first row of the current fetch buffer.
FETCHLAST% | Fetches the last block of rows from a dynamic or keyset cursor. The last row of the new fetch buffer is the last row of the cursor results set.

The block of rows retrieved by a fetch is called the fetch buffer. The number of rows in the fetch buffer is determined by the nfetchrows% parameter.

For a forward-only dynamic cursor (scrollopt% is CURFORWARD% in SqlCursorOpen%), you can only use the FETCHFIRST%, FETCHNEXT%, or FETCHRELATIVE% (with a positive rownum%) types.

rownum%
Is the specified random or relative row number to use as the first row of the new fetch buffer. Use this parameter only with a fetchtype% of FETCHRANDOM% or FETCHRELATIVE%. Specify 0 for any other fetchtype%.

When fetchtype% is FETCHRANDOM%:

  • A positive rownum% means that the first row of the new fetch buffer is the rownum% row (counting forward from the beginning) of the cursor results set.
  • A negative rownum% means that the first row of the new fetch buffer is rownum% rows backward from the end of the cursor results set. Given N rows in the cursor results set, the first row of the new fetch buffer is row N+1+rownum% of the cursor results set.

    For example, a rownum% of - 1 means the first row of the new fetch buffer is row N (N+1 - 1), or the last row, of the current results set. A rownum% of - N means the first row of the new fetch buffer is row 1 (N+1 - N), or the first row, of the current results set.

  • A rownum% of 0 means that the first row of the new fetch buffer is before the beginning (first row) of the cursor results set.

When fetchtype% is FETCHRELATIVE%:

  • A positive rownum% means that the first row of the new fetch buffer is rownum% rows after the first row of the current fetch buffer.

    For dynamic cursors, if the first row in the current fetch buffer is deleted before a relative fetch, the current cursor position becomes invalid. Let D be the number of contiguous rows, including the first row, deleted from the beginning of the current fetch buffer. Before executing a relative fetch, the current cursor position is set to before the first non-deleted row (row D+1) in the current fetch buffer.

    In this case, when a relative fetch is performed with a positive rownum%, the first row of the new fetch buffer is row rownum%+D of the current fetch buffer.

  • A negative rownum% means that the first row of the new fetch buffer is rownum% rows before the first row of the current fetch buffer.
  • For dynamic cursors, a rownum% of 0 means that all the rows in the current fetch buffer are fetched again without moving the current cursor position. This is different from a refresh because the rows in the new fetch buffer can differ from the rows in the current fetch buffer. New rows can appear, and old rows can disappear.

    In the case given above, after D contiguous rows have been deleted from the beginning of the current fetch buffer, when a relative fetch is performed with a rownum% of 0, the first row of the new fetch buffer is the first non-deleted row (row D+1) of the current fetch buffer.

    For keyset cursors, a rownum% of 0 means that the current fetch buffer is refreshed with current data from SQL Server without moving the current cursor position. This is identical to calling SqlCursor% with optype% set to CRSREFRESH%.

nfetchrows%
Is the number of rows in the new fetch buffer. This value must be less than or equal to the nrows% parameter specified for this cursor in SqlCursorOpen%. The poutlen and pvaraddr arrays specified in calls to dbcursorbind must have at least nfetchrows% elements. If these arrays are not large enough, you must break the existing bindings and then rebind with large enough arrays (at least nfetchrows% elements) before calling SqlCursorFetchEx%.

When fetchtype% is FETCHFIRST%, an nfetchrows% value of 0 means that the new cursor position is set to before the beginning (first row) of the cursor results set.

When fetchtype% is FETCHLAST%, an nfetchrows% value of 0 means that the new cursor position is set to after the end (last row) of the cursor results set.

reserved&
Reserved for future use. Use 0.

Returns

succeed (1) or fail (0).

SUCCEED (1) is returned if every row was fetched successfully. Note that for a keyset cursor, a fetch that results in a missing row will not cause SqlCursorFetchEx% to FAIL (0).

FAIL (0) is returned if at least one of the following is true:

  • A fetchtype% of FETCHRANDOM% was used on a dynamic cursor.
  • A fetchtype other than FETCHFIRST%, FETCHNEXT%, or FETCHRELATIVE% (with a positive rownum%) was used on a forward-only dynamic cursor.
  • The SQL Server connection is broken or times out.
  • DB-Library is out of memory.

Remarks

After the fetch, the elements of the array of row status indicators (pstatus&() in SqlCursorOpen%) are filled with row status values, one for each row in the fetch buffer. Each row status value is a series of fetch status values ORed together. The following table shows the meaning of each row status value:

Fetch status | Description
FTCSUCCEED% | The row was successfully fetched. SqlCursorData$ will return valid data for the row.
FTCMISSING% | The row has been deleted or a unique index column of the row has been changed. Do not use the values returned by SqlCursorData$ for the row. For keyset cursors, this fetch status can appear at any time. For dynamic cursors, this fetch status can appear only after the current fetch buffer is refreshed.

A row status indicator of 0 means that the row is invalid, and SqlCursorData$ will not return valid data. This happens when the row is before the beginning (first row) or after the end (last row) of the cursor results set.

After the fetch, SqlCursorData$ returns:

  • Valid data for all rows with a fetch status of FTCSUCCEED%.
  • Invalid data for all rows without a fetch status of FTCSUCCEED%.

If no fetches have been performed on a cursor, the current cursor position is before the beginning (first row) of the cursor results set.

After a fetch is complete, the new explicit server cursor position is one of the following:

  • The first row of the new fetch buffer, as specified under fetchtype%, if the first row of the new fetch buffer stayed within the cursor results set.
  • Adjusted to the first row of the cursor results set if the first row of the new fetch buffer would have been before the first row of the cursor results set and the last row of the new fetch buffer would have stayed within the cursor results set.
  • Before the beginning of the cursor results set if all rows of the new fetch buffer are before the first row of the cursor results set, or if any backward fetch (FETCHPREV% or FETCHRELATIVE% with a negative rownum%) is performed when the first row of the current fetch buffer is the first row of the cursor results set.
  • After the end of the cursor results set if the first row (and thus all rows) of the new fetch buffer is after the last row of the cursor results set.

When the current cursor position is before the beginning of the cursor, a FETCHNEXT% operation is identical to a FETCHFIRST% operation. When the current cursor position is after the end of the cursor, a FETCHPREV% operation is identical to a FETCHLAST% operation.

Note This function works with explicit server cursors in SQL Server 6.0. Do not use both SqlCursorFetchEx% and SqlCursorFetch% with the same server cursor handle. Once one of these functions is used on a specific cursor handle, any attempt to use the other function will return fail (0).

Each call to SqlCursorFetch% leaves the connection available for use with no pending results.

See Also

SqlCursor%, SqlCursorColInfo%, SqlCursorClose, SqlCursorInfo%, SqlCursorOpen%


SqlCursorInfo%

Returns the number of columns and the number of rows in the keyset for a client cursor, a transparent server cursor, or an explicit server cursor. The SqlCursorInfoEx% function returns more detailed information.

Syntax

SqlCursorInfo% ( cursorhandle%, ncols%, nrows& )

where

cursorhandle%
Is the cursor handle created by SqlCursorOpen%.
ncols%
Is a program variable that will contain the number of columns in the cursor.
nrows&
Is a program variable that will contain the number of rows in a cursor results set.

Client cursor:

For a keyset cursor, this number is always valid. For a dynamic cursor, this number is valid only if the current fetch buffer contains the last row in the cursor results set; otherwise, - 1 is returned.

Transparent server cursor, explicit server cursor:

For a dynamic cursor, - 1 is returned.

For a keyset cursor, this value can be the number of rows populated if asynchronous population of the cursor results set is incomplete, or the total number of rows in the cursor results set. You can call SqlCursorInfoEx% to determine this.

Returns

SUCCEED (1) or FAIL (0).

Remarks

Call SqlCursorInfoEx% for more complete information about transparent server cursors and explicit server cursors.

See Also

SqlCursor%, SqlCursorClose, SqlCursorColInfo%, SqlCursorFetch%, SqlCursorInfoEx%, SqlCursorOpen%


SqlCursorInfoEx%

Returns information about a client cursor, a transparent server cursor, or an explicit server cursor.

Syntax

SqlCursorInfoEx%( cursorhandle%, cursorinfo )

where

cursorhandle%
Is a cursor handle returned by SqlCursorOpen%.
cursorinfo
Is a SqlCursorInfo structure that DB-Library will fill with information about the specified cursor.

The SqlCursorInfo structure is defined as follows:

Type SqlCursorInfo
    TotCols As Long
    TotRows As Long
    CurRow As Long
    TotRowsFetched As Long
    CursorType As Long
    Status As Long
End Type

The SqlCursorInfo fields are described below:
Field | Description
TotCols | Is the total number of columns in the cursor.
TotRows Is the total number of rows in the cursor results set.

Client cursor:

For a keyset cursor, this number is always valid. For a dynamic cursor, this number is valid only if the current fetch buffer contains the last row in the cursor results set; otherwise, - 1 is returned.

Transparent server cursor, explicit server cursor:

For a dynamic cursor, - 1 is returned.

For a keyset cursor, if the Status field is CU_FILLING, the asynchronous population of the cursor results set is incomplete, and this value indicates the number of rows populated. If the Status field is CU_FILLED, the cursor results set is completely populated, and this value indicates the total number of rows in the cursor results set.
CurRow Is the row number within the cursor results set of the current cursor position (first row of the fetch buffer). The first row of the cursor results set is number 1.

Client cursor:

This value will be 0.

Transparent server cursor, explicit server cursor:

For a keyset cursor, this value is always valid.

For a dynamic cursor, this value will always be 1 when the current position is within the cursor results set.

This value will be 0 if the current position is before the beginning of the cursor. This value will be - 1 if the current position is after the end of the cursor.
TotRowsFetched | Is the total number of valid rows in the current fetch buffer.
Type Is a bitmap of cursor type, scroll option, and concurrency control information. It is a series of the following values ORed together:

Type:

CU_CLIENT: Client cursor

CU_SERVER: Transparent server cursor or explicit server cursor

Scroll option:

CU_DYNAMIC: Dynamic cursor

CU_FORWARD: Forward-only dynamic cursor

CU_KEYSET: Keyset cursor

CU_INSENSITIVE: Insensitive keyset cursor

CU_MIXED: Mixed-mode cursor (provided for backward compatibility only)

Concurrency control:

CU_READONLY: Read-only concurrency

CU_LOCKCC: Intent to update concurrency

CU_OPTCC: Optimistic concurrency based on timestamp or values

CU_OPTCCVAL: Optimistic concurrency based on values
Status Bitmap of status information. It is a series of the following values ORed together:

Client cursor:

CU_FILLED: All cursors

Transparent server cursor, explicit server cursor:

CU_FILLING: Incomplete asynchronous population of a keyset transparent server cursor or keyset explicit server cursor results set

CU_FILLED: Incomplete asynchronous population of a keyset transparent server cursor or keyset explicit server cursor results set, or the cursor is a dynamic cursor

Returns

succeed (1) or fail (0).

Remarks

Before calling SqlCursorInfoEx%, set the SizeOfStruct field equal to the value returned by the C sizeof function for the SQLCURSORINFO% structure. The SqlCursorInfoEx% function fills the supplied SQLCURSORINFO% structure with information about the open server cursor.

See Also

SqlCursor%, SqlCursorClose, SqlCursorColInfo%, SqlCursorFetch%, SqlCursorInfoEx%, SqlCursorOpen%


SqlCursorOpen%

Opens a cursor. It is an explicit server cursor if you are connected to SQL Server 6.0 and SqlCursorFetchEx% is used for the first fetch. It is a transparent server cursor if you are connected to SQL Server 6.0 and SqlCursorFetch% is used for the first fetch. It is a client cursor if you are connected to SQL Server 4.2, or if the DBCLIENTCURSORS option is set, and only SqlCursorFetch% can be used to fetch rows.

Syntax

SqlCursorOpen% ( sqlconn%, stmt$, scrollopt%, concuropt%, nrows%, pstatus&() )

where

sqlconn%
Is the SQL Server connection returned by SqlOpen%.
stmt$
Is the SELECT statement that defines a cursor.

Client cursor:

This must be a single SELECT statement. All tables included in the FROM clause must have a unique index.

The SELECT statement cannot contain any of the following:

  • INTO
  • FOR BROWSE
  • COMPUTE
  • UNION
  • COMPUTE BY
  • aggregate function
  • Table alias

If scrollopt% is CURKEYSET%, the SELECT statement can contain the following keywords:

  • ORDER BY
  • HAVING
  • GROUP BY

If the SELECT statement includes a view, the FROM clause must include only a single view (no other tables or views). All base tables included in the FROM clause of the view definition must have a unique index, and the select list must include all unique index columns of the base tables.

Transparent server cursor, explicit server cursor:

This can be a single SELECT statement or the name of a stored procedure that contains only a single SELECT statement.

The SELECT statement (alone or in a stored procedure) cannot contain any of the following keywords:

  • INTO
  • FOR BROWSE
  • COMPUTE

The SELECT statement can contain an ORDER BY clause. If the columns in the ORDER BY clause match the columns of the unique indexes used by the cursor, the cursor will use the scrollopt% requested. If they do not match, SQL Server must generate a temporary table, and a CURKEYSET% cursor will be used if a scrollopt% of CURFORWARD% or CURDYNAMIC% is requested. This also occurs if the SELECT contains a subquery.

The cursor is automatically opened with a scrollopt% of CURINSENSITIVE% and a concuropt% of CURREADONLY% if the SELECT statement contains any of the following:

  • Table with no unique index
  • UNION
  • DISTINCT
  • GROUP BY
  • HAVING
  • aggregate function
  • Outer join

If a stored procedure is used, any input parameters must be constants. Declared variables cannot be used for input parameters. Any output parameters or return values from the stored procedure are ignored.

scrollopt%
Is one of the following requested scroll options:
scrollopt% Description
CURDYNAMIC% Dynamic cursor.

Client cursor, transparent server cursor:

The SqlCursorFetch% function will allow only a fetchtype% of FETCHFIRST%, FETCHNEXT%, or FETCHPREV%.

Explicit server cursor:

The SqlCursorFetchEx% function will allow all fetchtype% values except FETCHRANDOM%.
CURFORWARD% Forward-only dynamic cursor.

Client cursor, transparent server cursor:

The SqlCursorFetch% function will allow only a fetchtype% of FETCHFIRST% or FETCHNEXT%.

Explicit server cursor:

The SqlCursorFetchEx% function will allow only a fetchtype% of FETCHFIRST%, FETCHNEXT%, or FETCHRELATIVE% with a positive rownum%.
CURKEYSET% Keyset cursor.

The SqlCursorFetch% and SqlCursorFetchEx% functions will allow all fetchtype% values.
CURINSENSITIVE% Client cursor:

Not supported.

Transparent server cursor, explicit server cursor:

Insensitive keyset cursor. Use a concuropt% of READ_ONLY. SQL Server will generate a temporary table, so changes made to the rows by others will not be visible through the cursor.

The SqlCursorFetch% and SqlCursorFetchEx% functions will allow all fetchtype% values.
n > 1 Client cursor:

For backward compatibility with "mixed" client cursors.

Transparent server cursor, explicit server cursor:

Mapped to a CURKEYSET% cursor.

concuropt%
Is one of the following concurrency control options:
concuropt% | Description
CURREADONLY% | Read-only cursor. You cannot modify rows in the cursor results set.
CURLOCKCC% Intent to update locking.

Client cursor:

Places an exclusive lock on the data page that contains each row as it is fetched. The locks are maintained only if it is inside an open transaction block defined by BEGIN TRANSACTION; the locks are released when the transaction is closed by a COMMIT TRANSACTION or ROLLBACK TRANSACTION statement.

Transparent server cursor, explicit server cursor:

Places an update intent lock on the data page that contains each row as it is fetched. If not inside an open transaction, the locks are released when the next fetch is performed. If inside an open transaction, the locks are released when the transaction is closed.
CUROPTCC% | Optimistic concurrency control using timestamp or values. Changes to a row through the cursor succeed only if the row remains unchanged since the last fetch. Changes are detected by comparing timestamps or by comparing all non-text, non-image values if timestamps are not available.
CUROPTCCVAL% | Optimistic concurrency control using values. Changes to a row through the cursor succeed only if the row remains unchanged since the last fetch. Changes are detected by comparing all non-text, non-image values.

nrows%
Client cursor, transparent server cursor:

Is the number of rows in the fetch buffer filled by calls to SqlCursorFetch%.

Explicit server cursor:

Is the maximum number of rows in the fetch buffer. The nfetchrows% parameter of SqlCursorFetchEx% must be less than or equal to this value.

pstatus&()
Is an array of row status indicators. This array must contain nrows% long integer elements. A row status value is a bitmap of fetch status values ORed together. When passing a pstatus&() parameter to SqlCursorOpen%, pass the first element of the array, for example, mypstatus&(0).

Each row in the fetch buffer has a corresponding row status indicator. After a fetch, the status of every row in the fetch buffer is returned in the corresponding element of this array.

Client cursor, transparent server cursor:

For more information about fetch status values, see SqlCursorFetch%.

Explicit server cursor:

For more information about fetch status values, see SqlCursorFetchEx%.

Returns

A handle to the cursor if the cursor open succeeds. If it fails, 0 is returned. Several errors, such as the following, can cause the cursor to fail:

  • Not enough memory to complete the request. Reduce the number of rows in the keyset cursor results set by using a more limiting WHERE clause, use a dynamic cursor, or reduce the number of rows in the fetch buffer.
  • Tables did not have the required unique indexes.
  • A syntax error occurred or the SELECT statement failed.

Remarks

After SqlCursorOpen% returns a valid cursor handle, you can call SqlCursorInfoEx% and examine the Type field to determine the actual type of cursor that was opened.

With a dynamic cursor, membership of rows in the cursor results set is determined at fetch time, and it can change between each fetch. A row disappears from the cursor results set if it is deleted or if it is updated such that it no longer meets the WHERE clause criteria. A row appears in the cursor results set if it inserted or updated such that it meets the WHERE clause criteria.

With a keyset cursor, membership and order of rows in the cursor results set is fixed at open time. A row is marked as missing from the cursor results set if it is deleted or if it is updated such that it no longer meets the WHERE clause criteria. A row appears in the cursor results set only if it is inserted through a cursor based on a single table.

Multiple cursors (as many as the system's memory allows) can be opened using the same connection. When cursor functions are called, there should be no commands waiting to be executed or results pending in the connection.

See Also

SqlCursor%, SqlCursorClose, SqlCursorColInfo%, SqlCursorFetch%, SqlCursorInfo%, SqlCursorOpen%


Chapter 6 Stored Procedure Functions

Stored Procedure Functions

SqlHasRetStat%

SqlNumRets%

SqlRetData$

SqlRetLen&

SqlRetName$

SqlRetStatus&

SqlRetType%

SqlRpcExec%

SqlRpcInit%

SqlRpcParam%

SqlRpcSend%


SqlHasRetStat%

Determines whether a stored procedure or a remote stored procedure generated a return status number.

Syntax

SqlHasRetStat% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

SUCCEED (1) or FAIL (0).

Remarks

Status numbers are returned only by stored procedures running on SQL Server version 4.2 or later.

The server returns stored procedure information (including any return status and parameter values) immediately after returning all normal results for that stored procedure. Process the normal results, and then call SqlHasRetStat% after SqlResults% returns NOMORERPCRESULTS (for all stored procedures in a batch except the last one) or NOMORERESULTS (for a single stored procedure, or for the last stored procedure in a batch).

SqlRetStatus& actually retrieves the status number. Stored procedures that complete normally return a status number of 0.

The order in which the application processes the status number and any return parameter values is unimportant.

See Also

SqlNextRow%, SqlResults%, SqlRetData$, SqlRetStatus&


SqlNumRets%

Calculates the number of returned parameter values generated by a stored procedure or a remote stored procedure.

Syntax

SqlNumRets% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

The number of parameter values associated with the most recently executed stored procedure.

Remarks

For more information about stored procedure return parameters, see "SqlRetData$."

The server returns stored procedure information (including any return status and parameter values) immediately after returning all normal results for that stored procedure. Process the normal results, and then call SqlNumRets% after SqlResults% returns NOMORERPCRESULTS (for all stored procedures in a batch except the last one) or NOMORERESULTS (for a single stored procedure, or for the last stored procedure in a batch).

See Also

SqlNextRow%, SqlResults%, SqlRetData$, SqlRetLen&, SqlRetName$, SqlRetType%


SqlRetData$

Returns a return-parameter value generated by a stored procedure or a remote stored procedure.

Syntax

SqlRetData$ ( sqlconn%, retnum% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
retnum%
Is the number of the returned value of interest. The first return value is number 1. Values are returned in the same order as the parameters were originally specified in the stored procedure's CREATE PROCEDURE statement. (Note that the order is not necessarily the same as that specified in the remote stored procedure.) When specifying retnum%, non-return parameters are not counted. For example, if the second parameter in a stored procedure is the only return parameter, its retnum% is 1, not 2.

Returns

A string containing the value of the specified retnum%. If retnum% is out of range, SqlRetData$ returns an empty string. To determine whether the data really has a null value (and retnum% is not merely out of range), check for a return value of 0 from SqlRetLen&.

Remarks

The server returns stored procedure information (including any return status and parameter values) immediately after returning all normal results for that stored procedure. Process the normal results, and then call SqlRetData$ after SqlResults% returns NOMORERPCRESULTS (for all stored procedures in a batch except the last one) or NOMORERESULTS (for a single stored procedure, or for the last stored procedure in a batch).

Stored procedures can return values for specified parameters. If the value of one of these parameters is changed in a stored procedure, the new value is returned to the program that called the procedure. This action parallels the pass-by-reference facility available in some programming languages.

To function as a return parameter, a parameter must be declared as such:

  • When a stored procedure is created with CREATE PROCEDURE, the parameter must be declared as OUTPUT.
  • For a stored procedure executed using the Transact-SQL EXECUTE statement, the parameter must be declared as OUTPUT.
  • For a stored procedure executed using DB-Library functions (such as SqlRpcInit%), when the parameter is added using SqlRpcParam%, the status% bitmask must contain the SQLRPCRETURN option.

If a stored procedure is executed using DB-Library functions (such as SqlRpcInit%), the return parameter values are automatically available to the application. If a stored procedure is invoked with an EXECUTE statement, the return parameter values are available only if the command batch containing the EXECUTE statement uses Transact-SQL local variables, not constants, for the return parameters.

See Also

SqlNextRow%, SqlNumRets%, SqlResults%, SqlRetLen&, SqlRetName$, SqlRetType%


SqlRetLen&

Determines the length of a return-parameter value generated by a stored procedure or a remote stored procedure.

Syntax

SqlRetLen& ( sqlconn%, retnum% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
retnum%
Is the number of the returned value of interest. The first return value is number 1. Values are returned in the same order as the parameters were originally specified in the stored procedure's CREATE PROCEDURE statement. (Note that this is not necessarily the same order as that specified in the remote stored procedure.) When specifying retnum%, non-return parameters are not counted. For example, if the second parameter in a stored procedure is the only return parameter, its retnum% is 1, not 2.

Returns

The length of the specified returned value. If retnum% is out of range, SqlRetLen& returns -1. If the return value is null, SqlRetLen& returns 0.

Remarks

For more information about stored procedure return parameters, see "SqlRetData$."

The server returns stored procedure information (including any return status and parameter values) immediately after returning all normal results for that stored procedure. Process the normal results, and then call SqlRetLen& after SqlResults% returns NOMORERPCRESULTS (for all stored procedures in a batch except the last one) or NOMORERESULTS (for a single stored procedure, or for the last stored procedure in a batch).

See Also

SqlNextRow%, SqlNumRets%, SqlResults%, SqlRetData$, SqlRetName$, SqlRetType%


SqlRetName$

Returns the name of a return parameter of a stored procedure or a remote stored procedure.

Syntax

SqlRetName$ ( sqlconn%, retnum% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
retnum%
Is the number of the returned value of interest. The first return value is number 1. Values are returned in the same order as the parameters were originally specified in the stored procedure's CREATE PROCEDURE statement. (Note that this is not necessarily the same order as that specified in the remote stored procedure.) When specifying retnum%, non-return parameters are not counted. For example, if the second parameter in a stored procedure is the only return parameter, its retnum% is 1, not 2.

Returns

The name of the parameter of the specified return value. If retnum% is out of range, SqlRetName$ returns an empty string.

Remarks

For more information about stored procedure return parameters, see "SqlRetData$."

The server returns stored procedure information (including any return status and parameter values) immediately after returning all normal results for that stored procedure. Process the normal results, and then call SqlRetName$ after SqlResults% returns NOMORERPCRESULTS (for all stored procedures in a batch except the last one) or NOMORERESULTS (for a single stored procedure, or for the last stored procedure in a batch).

See Also

SqlNextRow%, SqlNumRets%, SqlResults%, SqlRetData$, SqlRetLen&, SqlRetType%


SqlRetStatus&

Returns the status number returned by a stored procedure or a remote stored procedure.

Syntax

SqlRetStatus& ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

The return status number for the stored procedure or remote stored procedure.

Remarks

Normally, completed stored procedures return a status number of 0. A RETURN statement in a stored procedure is used for application-specific return status numbers. If a RETURN statement is not used and an error occurs when the stored procedure is executed, SQL Server can return one of the following values:

Value | Description
-1 | Missing object
-2 | Datatype error
-3 | Process was chosen as deadlock victim
-4 | Permission error
-5 | Syntax error
-6 | Miscellaneous user error
-7 | Resource error, such as out of space
-8 | Nonfatal internal problem
-9 | System limit was reached
-10 | Fatal internal inconsistency
-11 | Fatal internal inconsistency
-12 | Table or index corrupt
-13 | Database is corrupt
-14 | Hardware error

Values -15 through -99 are reserved for future SQL Server expansion.

The SqlHasRetStat% function determines whether the most recently executed stored procedure generated a return status number.

The server returns stored procedure information (including any return status and parameter values) immediately after returning all normal results for that stored procedure. Process the normal results, and then call SqlRetStatus& after SqlResults% returns NOMORERPCRESULTS (for all stored procedures in a batch except the last one) or NOMORERESULTS (for a single stored procedure, or for the last stored procedure in a batch).

The order in which the application processes the status number and any returned parameter values is unimportant.

See Also

SqlHasRetStat%, SqlNextRow%, SqlResults%, SqlRetData$


SqlRetType%

Determines the datatype of a return parameter value generated by a stored procedure or a remote stored procedure.

Syntax

SqlRetType% ( sqlconn%, retnum% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
retnum%
Is the number of the returned value of interest. The first return value is number 1. Values are returned in the same order as the parameters were originally specified in the stored procedure's CREATE PROCEDURE statement. (Note that this is not necessarily the same order as that specified in the remote stored procedure.) When specifying retnum%, non-return parameters are not counted. For example, if the second parameter in a stored procedure is the only return parameter, its retnum% is 1, not 2.

Returns

A token value for the datatype of the specified return value, as shown here:

Column datatype | Returned constant
char | SQLCHAR
varchar | SQLCHAR
binary | SQLBINARY
varbinary | SQLBINARY
tinyint | SQLINT1
smallint | SQLINT2
int | SQLINT4
real | SQLFLT4
float | SQLFLT8
smallmoney | SQLMONEY4
money | SQLMONEY
decimal | SQLDECIMAL
numeric | SQLNUMERIC
smalldatetime | SQLDATETIM4
datetime | SQLDATETIME

If retnum% is out of range, -1 is returned.

Remarks

For more information about stored procedure return parameters, see "SqlRetData$."

The server returns stored procedure information (including any return status and parameter values) immediately after returning all normal results for that stored procedure. Process the normal results, and then call SqlRetType% after SqlResults% returns NOMORERPCRESULTS (for all stored procedures in a batch except the last one) or NOMORERESULTS (for a single stored procedure, or for the last stored procedure in a batch).

The SqlRetType% function actually returns an integer token value for the datatype (SQLCHAR, SQLFLT8, and so on). To convert the token value into a readable token string, use SqlPrType$. For a list of all token values and their equivalent token strings, see SQLPrType$.

See Also

SqlNextRow%, SqlNumRets%, SqlPrType$, SqlResults%, SqlRetData$, SqlRetLen&, SqlRetName$


SqlRpcExec%

Executes a single stored procedure, a single remote stored procedure, or a batch of stored procedures and/or remote stored procedures on SQL Server.

Syntax

SqlRpcExec% ( sqlconn% )

where

sqlconn%
A SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

succeed (1) or fail (0).

Remarks

After initializing and setting up each stored procedure using SqlRpcInit% and SqlRpcParam%, call SqlRpcExec% to execute the stored procedure or batch of stored procedures on SQL Server. Then call SqlOk% before processing the stored procedure results. SqlRpcExec% can be faster than SqlRpcSend% on some networks. For more information about executing stored procedures using DB-Library functions, see "SqlRpcInit%."

Note This function is one of the five (SqlNextRow%, SqlResults%, SqlRpcExec%, SqlExec%, SqlOk%) that do not return control to the application until after the server sends the required response. The application can be blocked for a considerable time if the server is waiting for a lock or is processing a large sort. If this is unacceptable, use SqlRpcSend% and SqlOk%, or set the DB-Library timeout to regain control periodically.

See Also

SqlNextRow%, SqlResults%, SqlRetData$, SqlRetStatus&, SqlRpcInit%, SqlRpcParam%


SqlRpcInit%

Initializes a stored procedure or a remote stored procedure.

Syntax

SqlRpcInit% ( sqlconn%, rpcname$, options% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
rpcname$
Is the name of the stored procedure to be invoked.
options%
Is a 2-byte bitmask of options for stored procedures. Specify 0 to indicate no options. The following options are available:
option | Description
SQLRPCRECOMPILE | Recompiles a stored procedure before it is executed.
SQLRPCRESET | Cancels a single stored procedure or a batch of stored procedures. If rpcname$ is specified, that new stored procedure is initialized after the cancel is complete.

Returns

SUCCEED or FAIL.

Remarks

An application can execute a single stored procedure, or it can execute a batch containing multiple stored procedures. To execute a single stored procedure, you can use DB-Library functions (such as SqlRpcInit%) or the Transact-SQL EXECUTE statement. To retrieve the status number and parameter values returned by each stored procedure in a batch, you must use DB-Library functions.

To execute a single stored procedure or a batch of stored procedures using DB-Library functions:
  1. Call SqlRpcInit% once to initialize a new stored procedure.
  2. Call SqlRpcParam% for each parameter of the stored procedure that does not have a default value.
  3. Repeat steps 1 and 2 for each stored procedure in the batch.
  4. Call SqlRpcSend% or SqlRpcExec% to send the entire stored procedure batch to SQL Server.
  5. Call SqlOk% to wait for SQL Server to start returning results.
  6. Call SqlResults% to process the results from each stored procedure.

    If SqlResults% returns SUCCEED, call SqlNextRow% until it returns NOMOREROWS to process the normal results from the stored procedure.

    If SqlResults% returns NOMORERPCRESULTS, and you want to retrieve status number and return parameter information returned by the stored procedure, follow the steps given below.

  7. Repeat step 6 until SqlResults% returns NOMORERESULTS.
  8. If you want to retrieve status number and return parameter information returned by the last stored procedure in the batch, follow the steps given below.

After SqlResults% returns NOMORERPCRESULTS (for all stored procedures in a batch except the last one) or NOMORERESULTS (for a single stored procedure, or for the last stored procedure in a batch), you can retrieve status number and return parameter information for a stored procedure.

To retrieve status number and return parameter information returned by a stored procedure using DB-Library functions:
  • Call SqlRetStatus& and SqlHasRetStat% to retrieve the return status number.
  • Call SqlNumRets% to determine the number of return parameters.
  • Call SqlRetData$, SqlRetType%, SqlRetLen&, and SqlRetName$ about retrieve information for each return parameter.

Executing stored procedures with DB-Library functions has some advantages over using an EXECUTE statement:

  • Using DB-Library functions to call a stored procedure causes DB-Library for Visual Basic to pass parameters in their native datatypes; using an EXECUTE statement passes them as ASCII characters. Calling stored procedures with DB-Library functions works faster and usually more efficiently than an EXECUTE statement because the server is not required to convert native datatypes into their ASCII equivalents.
  • Using DB-Library functions instead of an EXECUTE statement accommodates return parameters for stored procedures more quickly. With a remote stored procedure, the return parameters are always available to the application by calling SqlRetData$. (Note, however, that a return parameter must be specified as such when it is first added to the stored procedure through SqlRpcParam%.)

    When a stored procedure is called with an EXECUTE statement, the return parameter values are available only if the command batch containing the EXECUTE statement uses local variables, rather than constants, as the return parameters. This involves additional parsing each time the command batch is executed.

  • The client application can use DB-Library functions to issue a stored procedure call directly to an Open Data Services server application. The Open Data Services server application will detect this request as a remote stored procedure event. The Open Data Services server application is not required to parse the language buffer to find out what the client is requesting.

Stored procedures executed on the local SQL Server (using the sqlconn% connection) participate in transactions normally and can be rolled back. Remote stored procedures executed on a remote SQL Server cannot be rolled back.

See Also

SqlNextRow%, SqlResults%, SqlRetData$, SqlRetStatus&, SqlRpcParam%, SqlRpcSend%, SqlOk%


SqlRpcParam%

Adds a parameter to a stored procedure or a remote stored procedure.

Syntax

SqlRpcParam% ( sqlconn%, paramname$, status%, type%, maxlen&,
datalen&, value$ )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
paramname$
Is the name of the parameter to be invoked. This name must begin with the at symbol (@), as do all parameter names within stored procedures. As in the Transact-SQL EXECUTE statement, the name is optional. If the name is not used, it should be specified as an empty string. In that case, the order of the SqlRpcParam% calls determines the parameter to which each call refers.
status%
Is a 1-byte bitmask of parameter options for stored procedures. The only option currently available is SQLRPCRETURN, which signifies that an application designates this parameter as a return parameter. Specify 0 to indicate no options.
type%
Is the datatype of the value$ parameter (such as SQLINT1, SQLCHAR, and so on).
maxlen&
For variable-length return parameters (when type% is SQLCHAR, SQLBINARY, SQLTEXT, or SQLIMAGE), the maximum desired byte length for the value$ parameter returned from a stored procedure.

Set maxlen& to -1 in any of these cases:

  • For fixed-length return parameters (such as when type% is SQLINT4).
  • To pass a NULL fixed-length parameter value (such as when type% is SQLINT4) to the stored procedure.
  • For parameters that are not designated as return parameters.

Set maxlen to 0 to pass a NULL variable-length parameter value (when type% is SQLCHAR, SQLBINARY, SQLTEXT, or SQLIMAGE) to the stored procedure.

datalen&
For variable-length return parameters (when type% is SQLCHAR, SQLBINARY, SQLTEXT, or SQLIMAGE), datalen& is the actual byte length of the value$ parameter sent to the stored procedure. The byte length should not count any null terminator.

Set datalen& to - 1 for fixed-length parameters (such as when type% is SQLINT4).

Set datalen& to 0 to pass a NULL parameter value (fixed or variable length) to the stored procedure.

value$
Is a string containing the stored procedure parameter itself. DB-Library converts the string to its native datatype. You must use binary strings for binary parameters (when type% is SQLBINARY or SQLIMAGE.)

The following table summarizes the required maxlen& and datalen& values for each type of parameter.
Parameter | maxlen& | datalen&
Fixed-length | - 1 | - 1
Variable-length | Maximum desired length of return value | Length of input value
Fixed-length NULL | - 1 | 0
Variable-length NULL | 0 | 0

When specifying a NULL parameter, the actual contents of value$ is not used, and a NULL parameter is added to the stored procedure.

Returns

SUCCEED or FAIL.

Remarks

After initializing a stored procedure using SqlRpcInit%, you must call SqlRpcParam% once for each parameter of the stored procedure that does not have a default value. You specify default values for stored procedure parameters in the CREATE PROCEDURE statement. For more information about executing stored procedures using DB-Library functions, see "SqlRpcInit%."

See Also

SqlNextRow%, SqlOk%, SqlResults%, SqlRetData$, SqlRetStatus&, SqlRpcInit%, SqlRpcSend%


SqlRpcSend%

Sends a single stored procedure, a single remote stored procedure, or batch of stored procedures and/or remote stored procedures to SQL Server to be executed.

Syntax

SqlRpcSend% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

SUCCEED or FAIL.

Remarks

After initializing and setting up each stored procedure using SqlRpcInit% and SqlRpcParam%, call SqlRpcSend% to send the stored procedure or batch of stored procedures to SQL Server. Then call SqlOk% before processing the stored procedure results. For more information about executing stored procedures using DB-Library functions, see "SqlRpcInit%."

See Also

SqlNextRow%, SqlOk%, SqlResults%, SqlRetData$, SqlRetStatus&, SqlRpcInit%, SqlRpcParam%


Chapter 7 Text and Image Functions

Text and Image Functions

SqlMoreText%

SqlTxPtr$

SqlTxTimeStamp$

SqlTxTsNewVal$

SqlTxTsPut%

SqlUpdateText%

SqlWriteText%

SqlTextUpdate1Row%

SqlTextUpdateManyRows&


SqlMoreText%

Sends part of a large text or image value to SQL Server.

Syntax

SqlMoreText% ( sqlconn%, size&, text$ )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
size&
Is the size, in bytes, of the particular part of the text or image value sent to SQL Server. You cannot send more text or image bytes to SQL Server than are specified in the call to SqlWriteText% or SqlUpdateText%. The size& parameter cannot be larger than 32K.
text$
Is a string containing the text or image portion to be written.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlMoreText% is used in conjunction with SqlWriteText% or SqlUpdateText% to send a large text or image value to SQL Server in the form of a number of smaller chunks. This function is particularly useful with operating systems unable to allocate extremely long data buffers.

After calling SqlMoreText% for the last time, call SqlOk%.

For an example using SqlMoreText%, see "SqlWriteText%."

See Also

SqlTxPtr$, SqlTxTimeStamp$, SqlUpdateText%, SqlWriteText%


SqlTxPtr$

Return the identifier for a text or image column in the current row.

Syntax

SqlTxPtr$ ( sqlconn%, column% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
column%
Is the number of the column. The first column in a table is number 1.

Returns

The identifier for a text or image column in the current row. In the case of a NULL text or image value, the identifier value is an empty string.

Important Do not modify this identifier in any way. Modifying the identifier can cause unpredictable results.

Remarks

Every text or image column has an associated identifier that uniquely identifies the text or image value. This identifier is useful in conjunction with SqlWriteText%. The identifier returned by SqlTxPtr$ supplies the value for the textptr$ parameter of SqlWriteText%. Call SqlTxPtr$ only after SqlNextRow% or SqlGetRow% has returned regrow.

Text pointers are of fixed length and can be null when the text or image value is null.

Example

See the Windows-based programming example for SqlWriteText%, later in this chapter, which uses SqlTxPtr$.

See Also

SqlTxTimeStamp$ and SqlWriteText%


SqlTxTimeStamp$

Returns the identifier for the text timestamp for a column in the current row.

Syntax

SqlTxTimeStamp$ ( sqlconn%, column% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
column%
Is the number of the column. The first column in a table is number 1.

Returns

The identifier of the text timestamp for the column. This identifier can be an empty string.

Important Do not modify this identifier in any way. Modifying the identifier can cause unpredictable results.

Remarks

Every text or image column has an associated text timestamp that marks the time of the column's last modification. The text timestamp is useful in conjunction with SqlWriteText% to ensure that two competing users do not inadvertently wipe out each other's modifications in the database. The text timestamp is returned to the sqlconn% when a Transact-SQL SELECT statement is performed on a SQLTEXT or SQLIMAGE column.

The length of a non-NULL text timestamp is always SQLTXTSLEN (currently defined as eight bytes). Call SqlTxTimeStamp$ only after SqlNextRow% or SqlGetRow% has returned regrow.

Example

See the Windows-based programming example for SqlWriteText%, later in this chapter, which uses SqlTxTimeStamp$.

See Also

SqlTxPtr$ and SqlWriteText%


SqlTxTsNewVal$

Returns the identifier for the new value for a text timestamp after a call to SqlWriteText%.

Syntax

SqlTxTsNewVal$ ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

The identifier for the timestamp value for the text or image value modified by a SqlWriteText% operation. This identifier can be an empty string.

Important Do not modify this identifier in any way. Modifying the identifier can cause unpredictable results.

Remarks

Every text or image column has an associated text timestamp that is updated whenever the column's value is changed. The new text timestamp identifier, returned by SqlTxTsNewVal$, can be used in conjunction with SqlWriteText% to ensure that two competing users do not inadvertently wipe out each other's modifications in the database. It is returned to the sqlconn% when a Transact-SQL SELECT statement is performed on a SQLTEXT or SQLIMAGE column and can be examined by calling SqlTxTimeStamp$.

After each successful SqlWriteText% operation (which can include a number of calls to SqlMoreText%), SQL Server sends the updated value of timestamp$ back to DB-Library for Visual Basic. The application can then get the new value of timestamp$ with SqlTxTsNewVal$ and use SqlTxTsPut% to put that new value into the row buffer for future access through SqlTxTimeStamp$. This capability is particularly useful when the application does not need the new timestamp immediately because row buffering is turned on.

See Also

SqlMoreText%, SqlTxTimeStamp$, SqlTxTsPut%, SqlWriteText%


SqlTxTsPut%

Places the identifier for the new value for a text timestamp into a column of the current row in the row buffer.

Syntax

SqlTxTsPut% ( sqlconn%, newtxts$, column% )

where

sqlconn% ( )
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
newtxts$ ( )
Is the new text timestamp value, returned by SqlTxTsNewVal$.
column%
Is the number of the column to receive the new text timestamp. Column numbers start at 1.

Returns

SUCCEED (1) or FAIL (0).

Remarks

Every text or image column has an associated text timestamp that is updated whenever the column's value is changed. The text timestamp is useful in conjunction with SqlWriteText% to ensure that two competing users do not inadvertently wipe out each other's modifications in the database. It is returned to the sqlconn% when a Transact-SQL SELECT statement is performed on a SQLTEXT or SQLIMAGE column and can be examined by calling SqlTxTimeStamp$. Call SqlTxtsPut% only after SqlNextRow% or SqlGetRow% has returned regrow.

After each successful SqlWriteText% operation (which can include a number of calls to SqlMoreText%), SQL Server sends the updated text timestamp value back to DB-Library for Visual Basic. SqlTxTsNewVal$ enables the application to get this new timestamp value. The application can then use SqlTxTsPut% to place the new timestamp value in the row buffer for future access through SqlTxTimeStamp$. This is particularly useful when the application does not need the new timestamp immediately because row buffering is turned on.

See Also

SqlMoreText%, SqlTxTimeStamp$ and SqlTxTimeStamp&, SqlTxTsNewVal$, SqlWriteText%


SqlUpdateText%

Updates an existing text or image value. Unlike SqlWriteText% which replaces an entire text or image value, SqlUpdateText% can change only a portion of a text or image value in place.

Syntax

SqlUpdateText% ( sqlconn%, dest_object$, dest_textptr$, dest_timestamp$, update_type%, insert_offset&, delete_length&, src_object$, src_size&, src_text$ )

where

sqlconn%
A SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
dest_object$
Is the destination table and text or image column name (separated with a period) of the existing text or image value to be updated.
dest_textptr$
Is the text pointer of the existing text or image value to be updated. Call SqlTxPtr$ to get this value. This string cannot be empty.
dest_timestamp$
Is the timestamp of the existing text or image value to be updated. Call SqlTxTimeStamp$ to get this value. This string cannot be empty.
update_type%
The type of update operation to perform.

Use UTTEXT% to insert new data from a program variable specified in this call to SqlUpdateText%. You must specify an empty src_object$ string, a src_size& equal to the size in bytes of the new data value being inserted, and a non-empty src_text$ that contains the new data value being inserted.

Use UTMORETEXT% to insert new data from a program variable with later calls to SqlMoreText%. You must specify an empty src_object$ string, a src_size& equal to the total size in bytes of the new data value (that will be inserted by calls to SqlMoreText%), and an empty src_text$ string. Then call SqlMoreText% to insert the new data value in chunks.

Use UTTEXTPTR% to insert new data from a text or image column of an existing table. You must specify a non-empty src_object$ string that gives the table and column a src_size& of 0, and a non-empty src_text$ string that gives the text pointer (returned by SqlTxPtr$) of the new data value being inserted from the src_object$.

Use UTDELETEONLY% to only delete existing data. You must specify an insert_offset& value other than -1 and a non-zero delete_length& value. Specify that no new data will be inserted by using an empty src_object$ string, a src_size& of 0 and an empty src_text$ string.

By default, a SqlUpdateText% operation is not recorded in the transaction log. You can bitwise OR the UTLOG% bit flag with any of these update_type% values (for example UTTEXT% Or UTLOG%) to indicate that this operation will be recorded in the transaction log.

insert_offset&
Is the zero-based starting position, specified as the number of bytes (from the start of the existing text or image value) to skip before inserting the new data. The existing text or image data beginning at this zero-based starting position will be shifted to the right to make room for the new data. A value of 0 means that the new data will be inserted at the beginning of the existing data value. A value of -1 means that the new data will be appended to the existing data value.
delete_length&
Is the number of bytes to delete from the existing text or image value, starting at the insert_offset& position. A value of 0 means that no data will be deleted. A value of -1 means that all data from the insert_offset& position to the end of the existing text or image value will be deleted.
src_object$
Is the source table and text or image column name (separated with a period) that can be used as the source of the inserted data. If not empty, the src_size& and src_text$ parameters are ignored. If this string is empty, the src_size& and src_text$ parameters specify the data to be inserted.
src_size&
Is the total size, in bytes, of the source text or image value (specified by src_text$) to be inserted. Use this parameter only if the src_object$ parameter is empty.
src_text$
Is a pointer to the source data value to be inserted. Use this parameter only if the src_object$ parameter is empty.

Returns

succeed (1) or fail (0).

Remarks

The SqlUpdateText% function can be used to delete existing data and then insert new data, to delete only existing data, or to insert only new data.

To delete existing data and then insert new data, specify an update_type% other than UTDELETEONLY%, an insert_offset& value other than -1, a non-zero delete_length& value, and the new data to be inserted.

To delete only existing data, specify an update_type% value of UTDELETEONLY%, an insert_offset& value other than -1 and a non-zero delete_length& value. Do not specify any new data to be inserted.

To insert only new data, specify an update_type% other than UTDELETEONLY%, a delete_length& value of 0, and the new data to be inserted.

See Also

SqlMoreText%, SqlTxPtr$, SqlTxTimeStamp$, SqlTxTsNewVal$, SqlTxTsPut%


SqlWriteText%

Sends a text or image value to SQL Server.

Syntax

SqlWriteText% ( sqlconn%, objname$, textptr$, textptrlen%, timestamp$,
log%, size&, text$ )

where

sqlconn% ( )
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
objname$
Is the database table name and column name. The table name and the column name are separated by a period.
textptr$ ( )
Is the text or image value to be modified. This identifier can be obtained by calling SqlTxPtr$.
textptrlen%
Is a parameter. This parameter is included for future compatibility. For now, its value must be the constant SQLTXPLEN.
timestamp$ ( )
Is the text timestamp for the text or image value to be modified. This identifier can be obtained by calling SqlTxTimestamp$. The value changes whenever the text or image value itself is changed. This string cannot be empty.
log%
Is a Boolean value that specifies whether this SqlWriteText% operation should be recorded in the transaction log.
size&
Is the total size, in bytes, of the text or image value to be written.
text$
Is a string containing the text or image to be written. If this string is empty, DB-Library for Visual Basic expects the application to call SqlMoreText% one or more times until all size& bytes of data have been sent to SQL Server. No single data block can be larger than 64K.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlWriteText% is used to update text and image values, allowing an application to send long values to SQL Server without having to copy them into a Transact-SQL UPDATE statement. In addition, SqlWriteText% gives an application access to the text timestamp mechanism, which can be used to ensure that two competing users do not inadvertently wipe out each other's modifications in the database.

SqlWriteText% succeeds only if its timestamp$ parameter, usually obtained when the column's value is originally retrieved, matches the text column's timestamp in the database. If a match occurs, SqlWriteText% updates the text column and at the same time updates the column's timestamp. This has the effect of governing updates by competing applications ¾ an application's SqlWriteText% call fails if a second application has updated the text column between the time the first application retrieved the column and the time it made its SqlWriteText% call.

SqlWriteText% is similar to a Transact-SQL WRITETEXT statement. However, calling SqlWriteText% is usually more efficient than sending a WRITETEXT statement through the command buffer. (For information about WRITETEXT, see the Microsoft SQL Server Transact-SQL Reference.)

SqlWriteText% can be invoked with or without logging in, according to the value of the log% parameter. To use SqlWriteText% with logging turned off, the SQL Server option select into/bulkcopy must be set to TRUE by executing the following system procedure:

sp_dboption 'mbsql', 'select into/bulkcopy', 'true'

For more information about SQL Server options, see the Microsoft SQL Server Transact-SQL Reference and the Microsoft SQL Server Administrator's Companion.

SqlWriteText%, used in conjunction with SqlMoreText%, also enables an application to send a large text or image value to SQL Server in the form of a number of smaller chunks. This is particularly useful with operating systems that are unable to allocate extremely long data buffers.

When SqlWriteText% is used with SqlMoreText%, it locks the specified database text column, and the lock is not released until the final SqlMoreText% has sent its data. This ensures that a second application does not read or update the text column in the middle of the first application's update.

If the text$ string is not an empty string, SqlWriteText% executes the data transfer from start to finish, including any necessary calls to SqlOk% and SqlResults%. To send a text or image value in chunks rather than sending the whole value at once, set the text$ parameter to an empty string. SqlWriteText% returns control to the application immediately after notifying SQL Server that a text transfer is about to begin. The actual text is sent to SQL Server with SqlMoreText%, which can be called multiple times, once for each chunk.

Examples

The following code fragment uses SqlWriteText%:

A.    'Retrieve a record from the "abstract" text column.
    cmd$ = "SELECT abstract FROM articles"
    cmd$ = cmd$  " WHERE article_id = 1000"
    Result% = SqlCmd%(Sqlconn%, cmd$)
    Result% = SqlExec%(Sqlconn%)
    Result% = SqlResults%(Sqlconn%)
    Result% = SqlNextRow%(Sqlconn%)
    'Update the text column.
    Abstract$ = "A brand new text value."
    Result% = SqlWriteText%(UpdSqlconn%, "articles.abstract",_
       SqlTxPtr$(Sqlconn%, 1), SQLTXPLEN,_
       SqlTxTimestamp$(Sqlconn%, 1), 1,_
       LEN(Abstract$), Abstract$)

The following code fragment uses SqlWriteText% with SqlMoreText%. Notice the required calls to SqlOk% and SqlResults% between the call to SqlWriteText% and the first call to SqlMoreText% and after the final call to SqlMoreText%.

B.    'Retrieve a record from the "abstract" text column.
    cmd$ = "SELECT abstract FROM articles"
    cmd$ = cmd$  " WHERE article_id = 1000"
    Result% = SqlCmd%(Sqlconn%, cmd$)
    Result% = SqlExec%(Sqlconn%)
    Result% = SqlResults%(Sqlconn%)

    Result% = SqlNextRow%(Sqlconn%)

    'Update the text column.
    Abstr1$ = "A brand new text value."
    Abstr2$ = " This text value contains two sentences."
    Result% = SqlWriteText%(UpdSqlconn%, "articles.abstract",_
       SqlTxPtr$(Sqlconn%, 1), SQLTXPLEN,_
       SqlTxTimestamp$(Sqlconn%, 1), 1,_
       LEN(Abstr1$  Abstr2$), "")
    Result% = SqlOk%(UpdSqlconn%)
    Result% = SqlResults%(UpdSqlconn%)

    'Send the update value in chunks.
    Result% = SqlMoreText%(UpdSqlconn%, LEN(Abstr1$), Abstr1$)
    Result% = SqlMoreText%(UpdSqlconn%, LEN(Abstr2$), Abstr2$)
    Result% = SqlOk%(UpdSqlconn%)
    Result% = SqlResults%(UpdSqlconn%)

These examples specify datatypes for Windows.

See Also

SqlMoreText%, SqlTxPtr$, SqlTxTimeStamp$, SqlTxTsNewVal$, SqlTxTsPut%


SqlTextUpdate1Row%

Updates one row of results in a text column. All subsequent rows, if any, are removed from the results buffer.

Syntax

SqlTextUpdate1Row% ( sqlconn%, objname$, column%, text$ )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
objname$
Is the database table and column name. The table name and the column name are separated by a period.
column%
Is the number of the column. The first column in a table is number 1.
text$
Specifies a string containing the text or image replacing the current data on the server.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlTextUpdate1Row% is a utility function that performs several actions to reduce the number of steps for updating the data in a text or image column of a single row. SqlUpdate1Row% is equivalent to calling SqlTxPtr$, SqlTxTsPut%, and SqlWriteText%. The data is updated in the current row determined by a call to SqlNextRow%. You can call SqlTextUpdate1Row% any time after you call SqlNextRow%.

See Also

SqlTxPtr$, SqlTxTsPut%, SqlWriteText%, SqlTextUpdateManyRows&


SqlTextUpdateManyRows&

Updates all rows of results in a text or image column, starting from the current row.

Syntax

SqlTextUpdateManyRows& ( sqlconn%, usqlconn%, objname$, column%, text$ )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
usqlconn%
Is a SQL Server connection used only for updating the desired column. The value of usqlconn% is returned by SqlOpen%.
objname$
Is the database table and column name. The table name and the column name are separated by a period.
column%
Is the number of the column. The first column in a table is number 1.
text$
Is a string containing the text or image replacing the current data on the server.

Returns

The number of updated rows. If an error occurs, -1 is returned.

Remarks

SqlTextUpdateManyRows& replaces the text or image of all rows in a column, starting from the current row. It is usually used to change the text or image of an entire column, starting from the first row.

SqlTextUpdateManyRows& performs several actions that reduce the number of steps for updating the data in a text or an image column of a single row. This function is equivalent to calling SqlTxPtr$, SqlTxTsPut%, and SqlWriteText%. The data is updated in the current row, which is determined by a call to SqlNextRow%.

The usqlconn% connection must be clear ¾ that is, it cannot have any rows pending. After completing all the updates to the rows, immediately close the usqlconn% connection.

Call SqlTextUpdateManyRows& any time after you call SqlResults%. Updates begin on the next row from the current pending row or, if SqlNextRow% has not been called, updates begin on the first row.

See Also

SqlTxPtr$, SqlTxTsPut%, SqlTextUpdate1Row%, SqlWriteText%


Chapter 8 Browse Functions

Browse Functions

SqlColBrowse%

SqlColSource$

SqlQual$

SqlTabBrowse%

SqlTabCount%

SqlTabName$

SqlTabSource$

SqlTsNewLen%

SqlTsNewVal$ and SqlTsNewVal&

SqlTsPut%

SqlTsUpdate%


SqlColBrowse%

Indicates whether the source of a result column can be updated with the DB-Library for Visual Basic browse-mode facilities.

Syntax

SqlColBrowse% ( sqlconn%, column% )

where

sqlconn% ( )
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
column%
Is the number of the result column. The first column is number 1.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlColBrowse% is a DB-Library for Visual Basic browse-mode function. For a detailed discussion of browse mode, see DB-Library for Visual Basic Programming.

SqlColBrowse% determines whether the database column that is the source of a result column in a select list can be updated with the DB-Library for Visual Basic browse-mode facilities. SqlColBrowse% is useful for examining ad hoc queries. When a query has been hard-coded into the application, SqlColBrowse% is unnecessary.

You can call SqlColBrowse% any time after you call SqlResults%.

To determine the name of the source column, use SqlColSource$.

Example

Only a column derived from a table that has a unique index and a timestamp column can be updated. The column cannot be the result of a Transact-SQL expression. For example, in the following select list, result columns 1 and 2 (title and category) can be updated, but column 3 (wholesale) cannot because it is the result of an expression:

SELECT title, category=type, wholesale=(price * 0.6)
FROM inventory FOR BROWSE

See Also

SqlColSource$, SqlQual$, SqlTabBrowse%, SqlTabCount%, SqlTabName$, SqlTabSource$, SqlTsNewLen%, SqlTsNewVal$, SqlTsPut%


SqlColSource$

Returns the name of the database column from which a result column derives.

Syntax

SqlColSource$ ( sqlconn%, tabnum% )

where

sqlconn% ( )
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
tabnum%
Is the number of the table. The first table is number 1.

Returns

A string containing the name of the database column from which a specified result derives. SqlColSource$ returns an empty string if the column number is out of range or if the column is the result of a Transact-SQL expression, such as MAX(colname).

Remarks

SqlColSource$ is a DB-Library for Visual Basic browse-mode function. For a detailed discussion of browse mode, see DB-Library for Visual Basic Programming. SqlColSource$ is useful for ad hoc queries. When a query has been hard-coded into the application, SqlColSource$ is unnecessary. SqlColSource$ returns the underlying database column name. Don't confuse this column name with the optional column headings you can specify with a SELECT statement. For example, the following statement specifies a column header of "author" for the au_lname column:

SELECT author = au_lname FROM authors

When updating a table, use the database column name, not the header name. The following code fragment uses SqlColSource$ to get the underlying database column name:

Source$ = SqlColSource$(Sqlconn%, 1)

You can call SqlColSource$ any time after you call SqlResults%.

See Also

SqlColBrowse%, SqlQual$, SqlTabBrowse%, SqlTabCount%, SqlTabName$, SqlTabSource$, SqlTsNewLen%, SqlTsNewVal$ and SqlTsNewVal&, SqlTsPut%


SqlQual$

Returns a string containing the WHERE clause for the current row in a specified table. In a browsable table, this string can be used to update the current row.

Syntax

SqlQual$ ( sqlconn%, tabnum%, tabname$ )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
tabnum%
Specifies an integer to receive the number of the table. Tables are numbered in the order they are listed in the SELECT statement's FROM clause. Table numbers start at 1. If tabnum% is -1, tabname$ is used to identify the table.
tabname$
Identifies a string containing the name of a table specified in the SELECT statement's FROM clause. If tabname$ is an empty string, tabnum% is used to identify the table.

Returns

A string containing the WHERE clause for the current row in a specified table. If the specified table cannot be browsed, SqlQual$ returns an empty string. A browsable table has a unique index and a timestamp column.

Remarks

SqlQual$ is a DB-Library for Visual Basic browse-mode function. For a detailed discussion of browse mode, see DB-Library for Visual Basic Programming.

SqlQual$ provides a WHERE clause that can be used to update a single row in a browsable table. Columns from this row must have been previously retrieved through a browse-mode SELECT query.

The WHERE clause produced by SqlQual$ begins with the keyword WHERE and contains references to the row's unique index and timestamp column. You can simply append the WHERE clause to an UPDATE or DELETE statement; there is no need to examine it or manipulate it in any way.

The timestamp column indicates the time that a particular row was last updated. An update on a browsable table fails if the timestamp column in the WHERE clause that SqlQual$ generates is different from the timestamp column in the table. Such a condition, which generates SQL Server error message 532, indicates that another user updated the row since it was selected for browsing. Design your application to include the logic for handling an update failure.

SqlQual$ can construct WHERE clauses only for browsable tables. You can use SqlTabBrowse% to determine whether a table can be browsed. SqlQual$ is usually called after SqlNextRow%.

Example

The following code fragment illustrates one approach to updating a table in a multiuser environment using browse mode. The application attempts to update a record specified by the user. If the update fails, the application assumes that someone else already updated the same row and changed its timestamp. To handle this situation, the application simply repeats the process, retrieving the changed row for the user to examine and edit and allowing the user to decide whether to overwrite the change. A complete application examines the messages from the server to determine why the update failed.

DO
   'Retrieve the employee record from the database.
   'Assuming that "empid" is a unique index, the query
   'will return only one row.
   cmd$ = "SELECT * FROM employees WHERE empid ="
   cmd$ = cmd$  STR$(EmployeeId%)  " FOR BROWSE"
   Result% = SqlCmd%(Sqlconn%, cmd$)
   Result% = SqlExec%(Sqlconn%)
   Result% = SqlResults%(Sqlconn%)
   Result% = SqlNextRow%(Sqlconn%)

   'Assign returned data to variables.
   Name$ = SqlData$(Sqlconn%, 2)
   Salary# = VAL(SqlData$(Sqlconn%, 3))

   'Let user edit data.
   PRINT "Name: "; Name$
   PRINT "Salary: "; Salary#
   INPUT "New salary"; Salary#

'Get a WHERE clause and update the database. Sqlconn%
'is the connection used to query the database, while
'UpdSqlconn% is the connection used to update it.
Qual$ = SqlQual$(Sqlconn%, -1, "employees")
Result% = SqlNextRow%(Sqlconn%)
cmd$ = "UPDATE employees SET salary ="
cmd$ = cmd$  STR$(Salary#)  " "  Qual$
Result% = SqlCmd%(UpdSqlconn%, cmd$)
Result% = SqlExec%(UpdSqlconn%)

'If the update failed, try again.
LOOP WHILE SqlResults%(UpdSqlconn%) = FAIL
OR Result% = FAIL

Output:

Name: Charles Dickens
Salary: 76543.21
New salary? 80000.00

See Also

SqlColBrowse%, SqlColSource$, SqlTabBrowse%, SqlTabCount%, SqlTabName$, SqlTabSource$, SqlTsNewLen%, SqlTsNewVal$, SqlTsPut%


SqlTabBrowse%

Indicates whether a specified table can be updated with the DB-Library for Visual Basic browse-mode procedures.

Syntax

SqlTabBrowse% ( sqlconn%, tabnum% )

where

sqlconn% ( )
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
tabnum%
Is the number of the table as specified in the SELECT statement's FROM clause. Table numbers start at 1.

Returns

SUCCEED (1) or FAIL (0). If you drop a table's unique index while browsing, SqlTabBrowse% continues to return SUCCEED.

Remarks

SqlTabBrowse% is a DB-Library for Visual Basic browse-mode function. For a detailed discussion of browse mode, see DB-Library for Visual Basic Programming.

SqlTabBrowse% provides a way to identify browsable tables. A browsable table has a unique index and a timestamp column. SqlColBrowse% is useful when examining ad hoc queries prior to performing browse-mode updates based on them. When a query is hard-coded into the application, SqlTabBrowse% is unnecessary.

You can call SqlTabBrowse% any time after you call SqlResults%.

See Also

SqlColBrowse%, SqlColSource$, SqlQual$, SqlTabCount%, SqlTabName$, SqlTabSource$, SqlTsNewLen%, SqlTsNewVal$, SqlTsPut%


SqlTabCount%

Returns the number of tables included in the current SELECT statement.

Syntax

SqlTabCount% ( sqlconn% )

where

sqlconn% ( )
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

The number of tables, including SQL Server work tables, included in the current SELECT statement. If an invalid sqlconn% value is sent to SqlTabCount%, a value of -1 is returned.

Remarks

SqlTabCount% is a DB-Library for Visual Basic browse-mode function. For a detailed discussion of browse mode, see DB-Library for Visual Basic Programming.

A SELECT statement can generate a set of result rows whose columns are derived from several database tables. To perform browse-mode updates of the columns in a statement's select list, your application must know how many tables are involved in the query, because each table requires a separate UPDATE statement. SqlTabCount% can provide this information for ad hoc queries. When a query is hard-coded into the application, SqlTabCount% is unnecessary.

The count returned by SqlTabCount% includes any SQL Server work tables used in processing a query. SQL Server sometimes creates temporary internal work tables to process a query and deletes them by the time it finishes processing the statement. Work tables cannot be updated and are not available to your application. Therefore, design your application such that before it uses a table number, it verifies that the number does not belong to a work table. SqlTabName$ can be used to determine whether a particular table number refers to a work table.

You can call SqlTabCount% any time after you call SqlResults%.

See Also

SqlColBrowse%, SqlColSource$, SqlQual$, SqlTabBrowse%, SqlTabName$, SqlTabSource$, SqlTsNewLen%, SqlTsNewVal$, SqlTsPut%


SqlTabName$

Returns the name of a table based on its number.

Syntax

SqlTabName$ ( sqlconn%, tabnum% )

where

sqlconn% ( )
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
tabnum%
Is the number of a table. Table numbers start with 1. Use SqlTabCount% to find out the total number of tables involved in a particular statement.

Returns

A string containing the name of a specified table. This string is empty if the table number is out of range or if the specified table is a SQL Server work table. For a description of work tables, see SqlTabCount% .

Remarks

SqlTabName$ is a DB-Library for Visual Basic browse-mode function. For a detailed discussion of browse mode, see DB-Library for Visual Basic Programming.

A SELECT statement can generate a set of result rows whose columns are derived from several database tables. The database tables are specified by the FROM clause. SqlTabName$ provides a way for an application to determine the name of each table involved in an ad hoc query. When the query has been hard-coded into the application, SqlTabName$ is unnecessary.

You can call SqlTabName$ any time after you call SqlResults%.

See Also

SqlColBrowse%, SqlColSource$, SqlQual$, SqlTabBrowse%, SqlTabCount%, SqlTabSource$, SqlTsNewLen%, SqlTsNewVal$, SqlTsPut%


SqlTabSource$

Returns the name and number of the table from which a result column is derived.

Syntax

SqlTabSource$ ( sqlconn%, column%, tabnum% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
column%
Is the number of the result column. Column numbers start at 1.
tabnum%
Is an integer variable to receive the table number. Many DB-Library for Visual Basic functions that operate in browse mode accept either a table name or a table number. If SqlTabSource$ returns an empty string, tabnum% is set to -1.

Returns

A string containing the name of the table from which a result column derives. If an empty string is returned, it means one of the following:

  • The SQL Server connection is inactive. This is an error that invokes an application's error handler.
  • The SELECT statement does not contain the FOR BROWSE clause.
  • The column number is not in range.
  • The column is the result of an expression, such as MAX(colname).

Remarks

SqlTabSource$ is a DB-Library for Visual Basic browse-mode function. For a detailed discussion of browse mode, see DB-Library for Visual Basic Programming.

Use SqlTabSource$ to determine which tables provide the columns in the current set of result rows. This information is valuable when using SqlQual$ to construct WHERE clauses for UPDATE and DELETE statements based on ad hoc queries. When the query is hard-coded into the application, SqlTabSource$ is unnecessary. You can call SqlTabSource$ any time after you call SqlResults%.

See Also

SqlColBrowse%, SqlColSource$, SqlQual$, SqlTabBrowse%, SqlTabCount%, SqlTabName$, SqlTsNewLen%, SqlTsNewVal$, SqlTsPut%


SqlTsNewLen%

Returns the length of the new value of a timestamp column after a browse-mode update.

Syntax

SqlTsNewLen% ( sqlconn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

The length, in bytes, of the updated row's new timestamp value. SqlTsNewLen% returns -1 if no timestamp is returned to the application because the update was unsuccessful or because the UPDATE statement did not contain a WHERE clause returned by SqlQual$.

Remarks

SqlTsNewLen% is a DB-Library for Visual Basic browse-mode function. For a detailed discussion of browse mode, See DB-Library for Visual Basic Programming.

SqlTsNewLen% provides information about the timestamp column. The WHERE clause returned by SqlQual$ contains references to the row's unique index and timestamp column. When you use such a WHERE clause in an UPDATE statement, a new value is placed in the updated row's timestamp column and a new timestamp value is returned to the application (if the update is successful). With SqlTsNewLen%, the application saves the length of the new timestamp value, possibly for use with SqlTsPut%.

See Also

SqlColBrowse%, SqlColSource$, SqlQual$, SqlTabBrowse%, SqlTabCount%, SqlTabName$, SqlTabSource$, SqlTsNewVal$, SqlTsPut%


SqlTsNewVal$ and SqlTsNewVal&

Returns the identifier of the new value of a timestamp column after a browse-mode update.

Syntax

SqlTsNewVal$ ( sqlconn% )

where

sqlconn% ( )
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.

Returns

The identifier of the updated row's new timestamp value. The identifier is an empty string if no timestamp is returned to the application because the update was unsuccessful or because the UPDATE statement did not contain a WHERE clause returned by SqlQual$.

Important Do not modify the identifier in any way. Modifying the identifier can cause unpredictable results.

Remarks

SqlTsNewVal$ is a DB-Library for Visual Basic browse-mode function. For a detailed discussion of browse mode, see DB-Library for Visual Basic Programming.

SqlTsNewVal$ provides information about the timestamp column. When used in an UPDATE statement, the WHERE clause returned by SqlQual$ places a new value in the updated row's timestamp column and returns the new timestamp value to the application (if the update is successful). With SqlTsNewVal$, the application saves the new timestamp value, possibly for use with SqlTsPut%.

See Also

SqlColBrowse%, SqlColSource$, SqlQual$, SqlTabBrowse%, SqlTabCount%, SqlTabName$, SqlTabSource$, SqlTsNewLen%, SqlTsPut%


SqlTsPut%

Puts the new value of the timestamp column into a specified table's current row in the row buffer.

Syntax

SqlTsPut% ( sqlconn%, newts$, newtslen%, tabnum%, tabname$ )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
newts$
Is the new timestamp value. The new timestamp value is returned by SqlTsNewVal$.
newtslen%
Is the length of the new timestamp value. It is returned by SqlTsNewLen%.
tabnum%
Is the number of the table to receive the new timestamp. Table numbers start at 1. The tabnum% parameter must refer to a browsable table. Use SqlTabBrowse% to determine whether the table you specify can be browsed. If the table is browsable, tabname$ is used to identify the table.
tabname$
Is a string containing the table name. The tabname$ parameter must refer to a browsable table. If the string is empty, tabnum$ is used to identify the table. The value of tabname$ is returned by SqlTabSource$.

Returns

SUCCEED (1) or FAIL (0). The following conditions cause SqlTsPut% to return FAIL:

  • The application tries to update the timestamp of a nonexistent row.
  • The application tries to update the timestamp using an empty string as the new timestamp identifier (newts$ or newts&).
  • The specified table cannot be browsed.

Remarks

SqlTsPut% is a DB-Library for Visual Basic browse-mode function. For a detailed discussion of browse mode, see DB-Library for Visual Basic Programming.

SqlTsPut% manipulates the timestamp column. When used in an UPDATE statement, the WHERE clause returned by SqlQual$ places a new value in the updated row's timestamp column and returns the new timestamp value to the application (if the update is successful). If the same row is updated a second time, the UPDATE statement's WHERE clause must use the latest timestamp value. SqlTsPut% updates the timestamp in the row currently being browsed. Then, if the application has to update the row a second time, it calls SqlQual$ to formulate a new WHERE clause that uses the new timestamp. With SqlTsNewVal$, the application saves a new timestamp value, possibly for use with SqlTsPut%. Call SqlTsPut% only after SqlNextRow% or SqlGetRow% has returned regrow.

See Also

SqlColBrowse%, SqlColSource$, SqlQual$, SqlTabBrowse%, SqlTabCount%, SqlTabName$, SqlTabSource$, SqlTsNewLen%, SqlTsNewVal$


SqlTsUpdate%

Updates the value of a timestamp column in a specified table.

Syntax

SqlTsUpdate% ( sqlconn%, usqlconn%, tabnum%, tabname$ )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
usqlconn%
Is a SQL Server connection used only for updating the timestamp of the desired column. The value of usqlconn% is returned by SqlOpen%.
tabnum%
Is the number of the table to receive the new timestamp. Table numbers start at 1. The tabnum% parameter must refer to a browsable table. Use SqlTabBrowse% to determine whether the table can be browsed. If this value is 1, the tabname$ parameter is used to identify the table.
tabname$
Is a string containing the table name. The tabname$ parameter must refer to a browsable table. If the string is empty, tabnum% is used to identify the table. The value of tabname$ is returned by SqlTabSource$.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlTsUpdate% is equivalent to calling SqlTsNewVal$ and SqlTsPut%. Like those functions, it is designed for use in browse mode. SqlTsUpdate% can update the timestamp column if either tabnum% or tabname$ is provided. If neither is provided, calling SqlTsUpdate% results in an error.

The usqlconn% connection must be clear ¾ that is, it cannot have any rows pending. After completing all the updates to the timestamp column, immediately close the usqlconn% connection.

See Also

SqlTabBrowse%, SqlTabSource$, SqlTsNewVal$, SqlTsPut%


Chapter 9 Bulk-Copy Functions

Bulk-Copy Functions

SqlBCPColfmt%

SqlBCPColumns%

SqlBCPControl%

SqlBCPExec%

SqlBCPInit%

SqlBCPSetL%

SqlBCPColumnFormat%


SqlBCPColfmt%

Specifies the format of an operating-system file in a bulk copy into or out of SQL Server.

Syntax

SqlBCPColfmt% ( sqlconn%, fcolumn%, ftype%, fplen%, fclen&, fterm$, ftlen%, tcol% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
fcolumn%
Is the column number in the operating-system file whose format is being specified. The first column is number 1.
ftype%
Is the datatype of this column in the operating-system file. If the specified datatype is different from the datatype of the corresponding column in the database table (tcol%), the datatype is converted automatically. To specify the same datatype as in the corresponding column of the database table (tcol%), set this parameter to 0.

For a bulk copy out of SQL Server into a file, when ftype% is SQLDECIMAL or SQLNUMERIC:

  • If the source column is not decimal or numeric, the default precision and scale are used.
  • If the source column is decimal or numeric, the precision and scale of the source column are used.
fplen%
Is the length of the length prefix for this column in the operating-system file. Legal prefix lengths are 1, 2, and 4 bytes. To avoid using a length prefix, set this parameter to 0. So that DB-Library will determine whether to use a length prefix, set this parameter to -1. In that case, DB-Library uses a length prefix of whatever length is necessary if the database column length is variable.

If more than one means of specifying the column length of an operating-system file is used (such as a length prefix and a maximum column length, or a length prefix and a terminator sequence), DB-Library uses the one that results in the shortest amount of data being copied.

One valuable use of length prefixes is to simplify the specification of null data values in an operating-system file. For example, assume that you have a 1-byte length prefix for a 4-byte integer column. Ordinarily, the length prefix contains a value of 4 to indicate that a 4-byte value follows. However, if the value of the column is NULL, the length prefix can be set to 0 to indicate that 0 bytes follow.

fclen&
Is the maximum length of this column's data in the operating-system file, not including the length of any length prefix and/or terminator. Setting fclen& to 0 signifies that the data is NULL. Setting fclen& to -1 directs the system to ignore this parameter, indicating that there is no default maximum length.

For fixed-length datatypes such as integers, the length of the data is constant, except in the special case of null values. Therefore, for fixed-length datatypes, fclen& must always be -1 except when the data is NULL, in which case fclen& must be 0. For character, text, binary, and image data, fclen& can be
- 1, 0, or any positive value. When fclen& is -1, the system uses either a length prefix or a terminator sequence to determine the length of the data. (If both are supplied, the system uses the one that results in the shorter amount of data being copied.) If fclen& is -1 and neither a prefix length nor a terminator sequence is specified, the system returns an error message. If fclen& is 0, the system assumes the data is NULL. If fclen& is a positive value, the system uses fclen& as the maximum data length. However, if a positive fclen& and a prefix length and/or terminator sequence are provided, the system determines the data length by using the method that results in the shortest amount of data being copied.

fterm$
Is the terminator sequence to be used for this column. This parameter is useful primarily for character, text, binary, and image datatypes, because all other types are of fixed length. To avoid using a terminator, set this parameter to NULL. To set the terminator to NULL, set fterm$ to chr$(0). To make the tab character the terminator, set fterm$ to chr$(9). To make the newline character the terminator, set fterm$ to chr$(13) chr$(10).

If more than one means of specifying the column length of an operating-system file is used (such as a terminator and a length prefix, or a terminator and a maximum column length), DB-Library uses the one that results in the shortest amount of data being copied.

ftlen%
Is the length, in bytes, of the terminator sequence to be used for this column. To avoid using a terminator, set this value to 0.
tcol%
Is the corresponding column number in the database table. If this value is 0, this column is not copied. The first column number is column 1.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlBCPColfmt% specifies the format of the operating-system file for bulk copies. The format of a bulk-copy operation contains the following parts:

  • A mapping from the columns in the operating-system file to columns in the database.
  • The datatype of each column in the operating-system file.
  • The length of the optional-length prefix of each column.
  • The maximum length of the data in a column in the operating-system file.
  • The optional terminating-byte sequence in each column.
  • The length of the optional terminating-byte sequence in each column.

Each call to SqlBCPColfmt% specifies the format for one column in the operating system file. For example, when you have a table with five columns and want to change the default settings for three of those columns, first call SqlBCPColumns%(5), and then call SqlBCPColfmt% five times, with three of those calls setting your custom format. Set ftype% for the remaining two calls to 0 and fplen%, fclen&, and ftlen% to -1. These settings copy all five columns ¾ three with your customized format and two with the default format.

You must call SqlBCPColumns% before you call SqlBCPColfmt%.

You must call SqlBCPColfmt% once and only once for every column in the operating-system file, regardless of whether those columns use the default format or are skipped.

To skip a column, set tcol% to 0.

See Also

SqlBCPColumnFormat%, SqlBCPColumns%, SqlBCPControl%, SqlBCPExec%, SqlBCPInit%


SqlBCPColumns%

Sets the total number of columns in the operating-system file for a bulk copy into or out of SQL Server.

Syntax

SqlBCPColumns% ( sqlconn%, colcount% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
colcount%
Is the total number of columns in the operating-system file. Note that even when you are bulk-copying data from the operating-system file to a SQL Server table and do not intend to copy all the columns in the operating-system file, you must still set colcount% to the total number of columns in the operating-system file.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlBCPColumns% can be called only after you call SqlBCPInit% with a valid filename.

Call this function only when you intend to use a format for an operating-system file that differs from the default format. For a description of the default format for an operating-system file, see SqlBCPInit%.

After calling SqlBCPColumns%, you must call SqlBCPColfmt% colcount% times because you are defining a custom file format.

See Also

SqlBCPColfmt%, SqlBCPColumnFormat%, SqlBCPInit%


SqlBCPControl%

Changes the default settings for various control parameters for a bulk copy between a file and SQL Server.

Syntax

SqlBCPControl% ( sqlconn%, param%, value& )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
param%
One of the following:
BCPMAXERRS%
Specifies the number of errors allowed before terminating. The default is 10. Providing a value of less than 1 to this field resets it to its default value. If a value larger than 65,535 is specified, this field is set to 65,535.
BCPFIRST%
Specifies the first row to copy. The default is 1. Providing a value of less than 1 to this field resets it to its default value.
BCPLAST%
Specifies the last row to copy. The default is to copy all rows. Providing a value of less than 1 to this field resets it to its default value.
BCPBATCH%
Specifies the number of rows per batch. The default is 0. Providing a value of less than 1 to this field resets it to its default value.
BCPKEEPNULLS
Specifies whether empty data values in the file will be converted to NULL values in the SQL Server table. If this option is set before calling SqlBCPExec%, empty values will be converted to NULL values in the SQL Server table. The default is for empty values to be converted to the column's default value in the SQL Server table.
value&
Is the value for the specified param%.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlBCPControl% sets various control parameters for bulk-copy operations, including the number of errors allowed before ending an operation, the numbers of the first and last rows to copy, and the batch size.

These control parameters are meaningful only when you are copying between an operating-system file and a SQL Server table.

Example

'Initialize bcp.
Result% =
SqlBCPInit%(Sqlconn%,"condb..address", "address.add", "addr.err", DBIN%)
IF Result% = FAIL THEN
   SQLExit
   SQLWinExit
   End
END IF
'Set the number of rows per batch.
Result% = SqlBDPControl%(Sqlconn%, BCPBATCH%, 1000)
IF Result% = FAIL THEN
   PRINT "SqlBCPControl% failed to set batching behavior."
   PRINT
   SQLExit
   SQLWinExit
   End
END IF
'Set file column count.
Result% = SQLBCPColumns%(Sqlconn%, 1)
IF Result% = FAIL THEN
   PRINT "SqlBCPColumns% failed."
   PRINT
   SQLExit
   SQLWinExit
   End
END IF

'Set file format.
Result% = SqlBCPColfmt%(Sqlconn%, 1, 0, 0, -1, Chr$(13), 1, 1)
IF Result% = FAIL THEN
   PRINT "SqlBCPColfmt% failed."
   PRINT
   SQLExit
   SQLWinExit
   End
END IF

'Now, execute the bulk-copy.
Result% = SqlBCPExec%(Sqlconn%, RowsCopied&)
IF Result% = FAIL THEN
   PRINT "Incomplete bulk-copy. Only "; RowsCopied&; " rows copied."
   PRINT
   SQLExit
   SQLWinExit
   End
END IF

See Also

SqlBCPColfmt%, SqlBCPColumns%, SqlBCPExec%, SqlBCPInit%


SqlBCPExec%

Executes a bulk-copy of data between a database table and an operating-system file.

Syntax

SqlBCPExec% ( sqlconn%, rowscopied& )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
rowscopied&
Is the number of rows successfully copied.

Returns

SUCCEED (1) or FAIL (0). The SqlBCPExec% function returns SUCCEED only when all rows are copied. If some or none of the rows are copied, SqlBCPExec% returns FAIL. Check the rowscopied& parameter for the number of rows successfully copied.

Remarks

SqlBCPExec% copies data from an operating-system file to a database table or vice versa, depending on the value of the direction% parameter in SqlBCPInit%.

Before calling SqlBCPExec%, you must call SqlBCPInit% with a valid operating-system filename. Failure to do so results in an error.

Example

'Initialize bcp.
Result% =
SqlBCPInit%(Sqlconn%,"pubs..authors", "authors.sav", "", DBOUT%)
IF Result% = FAIL THEN
   SQLExit
   SQLWinExit
   End
END IF

'Now, execute the bulk-copy.
Result% =
SqlBCPExec%(Sqlconn%, RowsCopied&)
IF Result% = FAIL THEN
   PRINT "Incomplete bulk-copy. Only "; RowsCopied&; " rows copied."
   PRINT
   SQLExit
   SQLWinExit
   End
END IF

See Also

SqlBCPColfmt%, SqlBCPColumns%, SqlBCPControl%, SqlBCPInit%


SqlBCPInit%

Initializes a bulk-copy operation.

Syntax

SqlBCPInit% ( sqlconn%, tblname$, hfile$, errfile$, direction% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
tblname$
Is the name of the database table to copy. This name can also include the name of the database and the name of the database owner. For example, pubs.gracie.titles, pubs..titles, gracie.titles, and titles are all legal table names.

If direction% is DBOUT%, tblname$ can also be the name of a database view.

hfile$
Is the name of the operating-system file to bulk copy into or out of SQL Server.
errfile$
Is the name of the error file to be used. This error file contains progress messages, error messages, and copies of any rows that could not be copied from an operating-system file to a SQL Server table. If NULL is passed as errfile$, no error file is used.
direction%
Is the direction of the copy. This parameter must be one of two values: DBIN% or DBOUT%. DBIN% indicates a copy from an operating-system file into the database table; DBOUT% indicates a copy from a database table into an operating-system file.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlBCPInit% performs the initializations necessary to bulk-copy data between a workstation and SQL Server. It sets the default data formats for the operating-system file and examines the structure of the database table.

When you use an operating-system file to bulk-copy (see the description of the hfile$ parameter), the default native data formats are as follows:

  • The order, type, length, and number of the columns in the operating-system file are assumed to be identical to the order, type, length, and number of the columns in the database table.
  • If the data in a given database column is of fixed length, then the data column in the operating-system file is also of fixed length. If the data in a given database column is of variable length or can contain NULL values, the data column in the operating-system file is prefixed by a 4-byte length value for SQLTEXT and SQLIMAGE datatypes and a 1-byte length value for all other types.
  • There are no terminators between columns in the operating-system file.

You can override any of these defaults by calling SqlBCPColumns% and SqlBCPColfmt%.

To use the bulk-copy functions to copy data to a database table, you must do the following:

  • Call SqlBCPSetL% to make the server connection usable for bulk-copy purposes:
    login% = sqllogin%
SqlBCPSetL%(login%, TRUE)
  • If the table has no indexes, set the database option select into/bulkcopy to TRUE, use the database, and send the SQL Server CHECKPOINT statement:
    cmd$ = "sp_dboption 'mydb', 'select into/bulkcopy', 'true'"
Result% = SqlExec%(Sqlconn%)
Result% = SqlUse%(Sqlconn%, Database$)
cmd$ = "CHECKPOINT"
Result% = SqlExec%(Sqlconn%)

The SqlBCPInit% function must be called before any other bulk-copy functions. Failure to do so results in an error.

See Also

SqlBCPColfmt%, SqlBCPColumns%, SqlBCPControl%, SqlBCPExec%, SqlBCPSetL%


SqlBCPSetL%

Sets the loginrec% to enable bulk-copy operations.

Syntax

SqlBCPSetL% ( loginrec%, enable% )

where

loginrec%
Is a login record that is passed as a parameter to SqlOpen%. You get a login record by calling SqlLogin%.
enable%
Is a Boolean value, TRUE ( - 1 or 1) or FALSE (0), that specifies whether or not to enable bulk-copy operations for the resulting SQL Server connection. By default, SQL Server connections are not enabled for bulk-copy operations.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlBCPSetL% sets a field in the login record that tells SQL Server that the sqlconn% connection can be used for bulk-copy operations. For SqlBCPSetL% to be effective, you must call it before you call SqlOpen%. SqlOpen% is the function that actually allocates the SQL Server connection.

To keep users from initiating a bulk-copy sequence with SQL statements, avoid using this function in applications that permit ad hoc queries. Once a bulk-copy sequence begins, it cannot be stopped with an ordinary SQL statement.

See Also

SqlBCPInit%, SqlLogin%, SqlOpen%


SqlBCPColumnFormat%

Sets up the column format for the input file in a bulk-copy operation. This is a utility function that combines SqlBCPColumns% and SqlBCPColfmt% in one step.

Syntax

SqlBCPColumnFormat% ( sqlconn%, col( ), numcols% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
col( )
Is an array of a user-defined datatype (structure) defined as BCPColData, that contains the following elements:
ftype%
Is the datatype of this column in the operating-system file. If the datatype of this column is different from the datatype of the corresponding column in the database table (tcol%), the data is converted automatically. To specify the same data type as in the corresponding column in the database table (tcol%), set this parameter to 0.
fplen%
Is the length of the length prefix for this column in the operating-system file. Legal prefix lengths are 1, 2, and 4 bytes. To avoid using a length prefix, set this parameter to 0. So that the bcp utility will determine whether to use a length prefix, set this parameter to -1. In that case, the bcp utility uses a length prefix of whatever length is necessary if the database column length is variable.

When more than one means of specifying the column length of an operating-system file is used (such as a length prefix and a maximum column length, or a length prefix and a terminator sequence), the bcp utility uses the one that results in the shortest amount of data being copied.

One valuable use for length prefixes is to simplify the specifying of null data values in an operating-system file. For example, assume that you have a length prefix of 1 byte for a 4-byte integer column. Ordinarily, the length prefix contains a value of 4 to indicate that a 4-byte value follows. However, if the value of the column is an empty string, the length prefix can be set to 0 to indicate that 0 bytes follow.

fcollen&
Is the maximum length of this column's data in the operating-system file, not including the length of any length prefix and/or terminator. Setting fcollen& to 0 signifies that the data is an empty string. Setting fcollen& to - 1 directs the system to ignore this parameter, indicating that there is no default maximum length.

For fixed-length datatypes such as integers, the length of the data is constant, except for the special case of null values. Therefore, for fixed-length datatypes, fcollen& must always be -1 except when the data is an empty string, in which case fcollen& must be 0. For character, text, binary, and image data, fcollen& can be -1, 0, or any positive value. If fcollen& is -1, the system uses either a length prefix or a terminator sequence to determine the length of the data. (If both are supplied, the system uses the one that results in the shorter amount of data being copied.) If fcollen& is - 1 and neither a prefix length nor a terminator sequence is specified, the system returns an error message. If fcollen& is 0, the system assumes that the data is an empty string. If fcollen& is a positive value, the system uses fcollen& as the maximum data length. However, if a positive fcollen& and a prefix length and/or terminator sequence are provided, the system determines the data length by using the method that results in the shortest amount of data being copied.

fterm$
Is the terminator sequence to be used for this column. This parameter is useful for character, text, binary, and image datatypes, because all other types are of fixed length. To avoid using a terminator, set this parameter to an empty string. To set the terminator to null-terminated, set fterm$ to chr$(0). To make the tab character the terminator, set fterm$ to chr$(9). To make the newline character the terminator, set fterm$ to chr$(13) chr$(10). The length of fterm$ is limited to 30 characters.

When more than one means of specifying the column length of an operating-system file is used (such as a terminator and a length prefix, or a terminator and a maximum column length), the bcp utility uses the one that results in the shortest amount of data being copied.

ftlen%
Is the length, in bytes, of the terminator sequence to be used for this column. To avoid using a terminator, set this value to -1.
tcol%
Is the corresponding column in the database table. If this value is 0, the column in the database table is not copied. The first column is column 1.
numcols%
Is the total number of columns to be copied.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlBCPColumnFormat% is equivalent to calling SqlBCPColumns% (to set the number of columns) and repeated calls to SqlBCPColfmt% (to set the format).

The size of the col( ) array is equal to the number of columns (numcols%). To access an element of the col structure, you must use the point (.) notation. For example:

col.elementname

For example, the following statement sets the datatype of the column in the operating-system file:

Col.ftype% = SystemFileType%

See Also

SqlBCPColfmt%, SqlBCPColumns%


Chapter 10 Utility Functions

Utility Functions

SqlGetAltColInfo%

SqlGetColumnInfo%

SqlOpenConnection%

SqlSendCmd%


SqlGetAltColInfo%

Gets the column ID, datatype, maximum length, type of aggregate function, and aggregate type name of a specific column in the current set of results.

Syntax

SqlGetAltColInfo% ( sqlconn%, altcolumndata, computeid%, altcolumn% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
altcolumndata
Is a user-defined datatype (structure) defined as AltColumnData. It contains the following elements:
colid%
Is an integer value of the column identification number that the aggregate of the compute column applies to.
datatype%
Is the datatype of the compute column. See SqlAltType% for the list of datatype token values. If either the computeid% or the altcolumn% is invalid, this value is - 1.
maxlen&
The maximum length, in bytes, that the data in the column can be.
aggtype%
The type of aggregate operator of the compute column. See SqlAltOpt% for the list of aggregate function types.
aggopname$
A string containing the name of the aggregate operator used by SQL Server ¾ for example, SUM, AVG, and MAX.
computeid%
Is the compute ID. A SELECT statement can have multiple COMPUTE clauses, each of which can have a different number of aggregate operators and aggregate targets. The computeid% is returned by SqlNextRow% or SqlGetRow%.
altcolumn%
Is the number of the column. The first column returned is number 1.

Returns

SUCCEED (1) or FAIL (0). The column ID, datatype, maximum length, type of aggregate function, and name of the aggregate operator type are returned by the altcolumndata parameter.

Remarks

SqlGetAltColInfo% performs the actions of several other Visual Basic functions and puts the results of the functions in the corresponding elements of the altcolumndata parameter. SqlGetAltColInfo% is the equivalent of calling SqlAltColId%, SqlAltLen%, SqlAltOp%, and SqlAltType%. To access an element returned by altcolumndata, you must use the point (.) notation:

altcolumndata.elementname

For example, the following statement gets the column name returned by altcolumndata :

AggregateOperatorName$ = AltColumnData.AggOpName$

Example

Dim AltColDetails As AltColumnData
'Put commands into the command buffer.
cmd$ = "SELECT title_id, price, advance FROM titles"
cmd$ = cmd$  " COMPUTE SUM(price), MAX(advance)"
Result% = SqlCmd%(SqlConn%, cmd$)
'Send the command to SQL Server and start execution.
Result% = SqlExec%(SqlConn%)
Result% = SqlResults%(SqlConn%)

'Get the column ID, datatype, and name of the aggregate operator from
 compute columns and print the results.
IF Result% = SUCCEED THEN
   DO UNTIL SqlNextRow%(SqlConn%) = NOMOREROWS
      IF Result% = REGROW THEN
         PRINT "regular row returned."
         PRINT
      ELSE
         GetAltColInfo% = SqlGetAltColInfo%(SqlConn%, AltColDetails,
                        ComputeId%, AltColumn%)
         IF GetAltColInfo% = SUCCEED THEN
            AltColumnID% = AltColDetails.ColID%
            ColDatatype% = AltColDetails.Datatype%
            AggregateOperator$ = AltColDetails.AggOpName$
            PRINT "Column ID of compute column = "  AltColumnID%
            PRINT "Datatype of column = "  ColData type%
            PRINT "Aggregate Operator of column = "  AggregateOperator$
            PRINT
         END IF
      END IF
   LOOP

See Also

SqlAltColId%, SqlAltLen%, SqlAltOp%, SqlAltType%, SqlGetColumnInfo%


SqlGetColumnInfo%

Gets the type, length, name, and server datatype of a specific column in the current set of results.

Syntax

SqlGetColumnInfo% ( sqlconn%, columndata, column% )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
columndata
Is a user-defined datatype (structure), defined as ColumnData. It contains the following elements:
coltype%
Is an integer value for the datatype of a particular column. For the list of datatype token values, see "SqlColType%".
collen&
The maximum length of the column.
colname$
A string containing the name of a particular column. The string is 30 characters long.
colsqltype$
A string containing the name of the datatype used by SQL Server ¾ for example, int, smallint, and text. The string is 30 characters long.
column%
Is the number of the column. The first column is number 1.

Returns

SUCCEED (1) or FAIL (0). The column type, length, name, and SQL Server datatype are returned by the columndata parameter.

Remarks

SqlGetColumnInfo% performs the actions of several other DB-Library for Visual Basic functions and puts the results of those functions in the corresponding elements of the columndata parameter. SqlGetColumnInfo% is the equivalent of calling SqlColType%, SqlColLen%, and SqlColName$. To access the information about an element returned by columndata, you must use the point (.) notation:

columndata.elementname

For example, the following statement gets the column name returned by columndata:

ColumnName$ = columndata.colname$

You can call SqlGetColumnInfo% any time after you call SqlResults%.

Example

'Put command into the command buffer.
cmd$ = "SELECT title_id, price, advance FROM titles"
Result% = SqlCmd%(SqlConn%, cmd$)

'Send the command to SQL Server and start execution.
Result% = SqlExec%(SqlConn%)
Result% = SqlResults%(SqlConn)

'Get the column name, the datatype used by the server, and the maximum
'possible length of the data in the column and print the results.
IF Result% = SUCCEED THEN
   DO UNTIL Result% = NOMOREROWS
      Result% = SqlNextRow%(SqlColunn%)
       IF Result% = NOMOREROWS THEN Exit
 DO
       ELSE
          GetColumnInfo% = SqlGetColumnInfo%(SqlConn%,
         Dim ColDetail as ColumnData, Column%)
            IF GetColumnInfo% = SUCCEED THEN
               ColumnName$ = ColDetail.ColName$
               ColDatatype$ = ColDetail.ColSqlType$
               ColLength& = ColDetail.Collen&
               PRINT "Column name is "  ColumnName$
               PRINT "Datatype of column is "  ColDatatype$
               PRINT "Maximum possible length of data = "  ColLength&
               PRINT
            END IF
      END IF
   LOOP

See Also

SqlColLen%, SqlColType%, SqlColName$, SqlGetAltColInfo%


SqlOpenConnection%

Opens a login record, establishes a connection to the server, and then deallocates the login record.

Syntax

SqlOpenConnection% ( server$, loginid$, pwd$, workstation$, app$ )

where

server$
Is the name of the SQL Server you want to connect to.
loginid$
Is the login identification number sent to the server. The string can have as many as 30 characters.
pwd$
Is the password sent to the server. The string can have as many as 30 characters.
workstation$
Is the workstation name sent to the server. The string can have as many as 30 characters.
app$
Is the application name sent to the server. The string can have as many as 30 characters.

Returns

The identifier of a SQL Server connection. If the connection cannot be created, 0 is returned.

Remarks

SqlOpenConnection performs the actions required to open a login record, establish a connection to the server, and then free the memory allocated for the login record. It is the equivalent of combining calls to SqlLogin%, SqlSetLUser%, SqlSetLPwd%, SqlSetLApp%, SqlOpen%, and SqlFreeLogin.

Important Do not modify the identifier returned by SqlOpenConnection in any way. Modifying the identifier can cause unpredictable results.

See Also

SqlFreeLogin, SqlLogin%, SqlOpen%, SqlSetLApp%, SqlSetLPwd%, SqlSetLUser%


SqlSendCmd%

Sends Transact-SQL text from the command buffer and sets up the statement for processing. This utility combines several functions into a single call.

Syntax

SqlSendCmd% ( sqlconn%, cmd$ )

where

sqlconn%
Is a SQL Server connection. The value of sqlconn% is returned by SqlOpen%.
cmd$
Is a character string to be copied into the command buffer.

Returns

SUCCEED (1) or FAIL (0).

Remarks

SqlSendCmd% performs several actions that process the Transact-SQL statements in the command buffer. SqlSendCmd% is equivalent to calling SqlCmd%, SqlExec%, and SqlResults%. SqlSendCmd% prepares the command for processing the first set of results but does not retrieve the first data row.

Example

'Put commands into the command buffer.
cmd$ = "SELECT db_name(dbid), dbid, size FROM sysusages"
cmd$ = cmd$  " ORDER BY dbid"

'Send commands to SQL Server and start execution.
Result% = SqlSendCmd%(SqlConn%,Cmd$)

See Also

SqlCmd%, SqlExec%, SqlResults%


Appendix A DB-Library for Visual Basic Options

DB-Library for Visual Basic Options

The DB-Library for Visual Basic options described in this appendix give you additional control over SQL Server queries. Design your applications to set and clear these options using SqlSetOpt% and SqlClrOpt%. Although the Transact-SQL SET statement can set and clear some DB-Library for Visual Basic options, SqlSetOpt% and SqlClrOpt% provide a uniform interface for all the options. They also mean that your application can use SqlIsOpt% to check the status of an option.

Some of the DB-Library for Visual Basic options take parameters, and in these cases the parameters are included in the descriptions below. However, each time you use SqlSetOpt%, SqlClrOpt%, or SqlIsOpt%, you must include both an option and a parameter, whether the option takes a parameter or not.

For example, the sqlrowcount option requires a parameter to set the number of rows to be counted. To set row count to 100, use the following statement:

SqlSetOpt%(SqlConn%, SQLROWCOUNT, "100")

The sqlarithabort option does not require a parameter. To set this option, use an empty string as a parameter, as shown in the following statement:

SqlSetOpt%(SqlConn%, SQLARITHABORT, "")

For more information on SqlSetOpt%, SqlClrOpt%, and SqlIsOpt%, see Stored Procedure Functions.

sqlarithabort
Terminates a query when an overflow or divide-by-zero error occurs during query execution. If sqlarithabort is not set, SQL Server substitutes null values and returns a warning message after the query has been executed. The default setting is off.
sqlarithignore
Substitutes null values when an overflow or divide-by-zero error occurs during a query. No warning message is returned. If sqlarithignore is not set, SQL Server substitutes null values and returns a warning message after the query has been executed. The default setting is off.
sqlbuffer
Buffers result rows. sqlbuffer is required when you use SqlGetRow%. You can only set this option using DB-Library for Visual Basic; it cannot be set with the Transact-SQL SET statement. When you set sqlbuffer, supply a parameter for the number of rows you want buffered. The default setting is 0 (no row buffering).
Parameter | Description
Less than 0 | Buffer set to 100 rows.
0 | No result rows buffered.
1 | Not allowed.
2 - 32,767 | The number of rows to buffer.

For more information about row buffering, see SqlNextRow%, SqlGetRow%, and SqlClrBuf in Stored Procedure Functions.

SQLCLIENTCURSORS
Forces the use of client cursors. When this option is set, every cursor opened with SqlCursorOpen% will be a client cursor. Even when connected to SQL Server 6.0, server cursors will not be used.

This option can be enabled for a client running Windows by placing the line UseClientCursors=ON in the [SQLSERVER] section of WIN.INI.

sqlnoautofree
Causes the command buffer to clear only with a call to SqlFreeBuf. When sqlnoautofree is not set, the first call to SqlCmd% after a call to SqlExec% or SqlSend%, automatically clears the command buffer before new text is entered. The default setting is off.
sqlnocount
Stops returning information about the number of rows affected by each Transact-SQL statement. The default setting is off.
sqlnoexec
Processes a query through the compile step but does not execute it. You can use this option with sqlshowplan. Once sqlnoexec is set, no subsequent statements are executed until sqlnoexec is turned off. The default setting is off.
sqloffset
Indicates where SQL Server should return offsets to certain constructs in the query. This option takes a parameter that specifies the particular construct. Valid values of this parameter include:
select | order | procedure
from | compute | execute
table | statement | param

Note The value param refers to parameters of stored procedures.

For the internal types that correspond to these offset values, see the SqlGetOff% function description. Offsets are returned only if the batch contains no syntax errors.

sqlparseonly
Checks the syntax of a query and returns error messages to the workstation. The default setting is off.
sqlrowcount
Specifies a maximum number of regular rows to be returned for SELECT statements. sqlrowcount does not limit the number of compute rows returned.

When you set sqlrowcount, supply a parameter for the number of rows you want returned. The default setting is 0, which returns all rows determined by SELECT statements.
Parameter | Description
0 | Returns all rows generated by a SELECT statement.
1 - 2,147,483,647 | Defines the maximum number of regular rows to be returned for SELECT statements.

This option is different from the other options in that you can turn it off by using SqlClrOpt% or by using SqlSetOpt% to set it to 0.

sqlshowplan
Generates a description of the processing plan after compilation and continues executing the query. The default setting is off.
sqlstat
Returns performance statistics (CPU time, elapsed time, I/O) to the workstation after each query. DB-Library for Visual Basic receives these statistics in the form of informational messages, and applications can access them through a user-defined message handler.

When you set sqlstat, supply a parameter for the type of performance statistics you want. The default setting is off.
Parameter | Description
IO | Returns statistics about SQL Server's internal I/O: the number of scans, the number of logical reads (pages accessed), and the number of physical reads (disk accesses) for each table referenced in the query. Also displays the number of pages written for each statement.
TIME | Returns information about SQL Server parsing, compilation, and execution times. Times are given in milliseconds.

sqlstorprocid
Sends the stored procedure ID to the workstation before sending rows generated by the stored procedure.
sqltextlimit
Causes DB-Library for Visual Basic to limit the size of returned text or image values. When setting this option, supply a parameter that is the length, in bytes, of the longest text or image value your application can handle. DB-Library for Visual Basic reads but ignores any part of a text or image value that goes over this limit. In the case of very large text values, it may take some time for the entire text value to be returned over the network. To keep SQL Server from sending this extra text in the first place, use the sqltextsize option. The default setting is 4096.
Parameter | Description
0 - 32,768 | Size, in bytes, of the longest text or image value that your application can handle.

sqltextsize
Limits the size of text or image values SQL Server returns. When setting this option, supply a parameter that is the length, in bytes, of the longest text or image value that SQL Server returns. In applications that allow users to make ad hoc queries, the user can override this option with the Transact-SQL SET TEXTSIZE statement. To set a text limit that the user cannot override, use the sqltextlimit option instead. The default setting is 4096.
Parameter | Description
0 - 32,768 | Size, in bytes, of the longest text or image value that SQL Server returns.


Appendix B Error Messages

Error Messages

This appendix describes all errors of DB-Library for Visual Basic and their levels of severity. These values are passed to a user-defined error handler. For information on creating an error handler for your application, see Programming with DB-Library for Visual Basic.

The text of the DB-Library for Visual Basic error messages comes from the underlying DB-Library, which is a library for developing client applications in C. As a result, some of the messages are specific to the DB-Library. In these cases, a version of the message that more accurately describes the error for DB-Library for Visual Basic is included in the entry.

The following table lists the DB-Library for Visual Basic errors, providing the error number, the error constant, and the error message for each error. The constants are defined in the VBSQL.BAS file.

Number | Constant | Error message
10000 | SQLEMEM | Unable to allocate sufficient memory.
10001 | SQLENULL | NULL DBPROCESS pointer encountered. For Visual Basic: A sqlconn identifier with a value of 0 was encountered.
10002 | SQLENLOG | NULL LOGINREC pointer encountered. For Visual Basic: A loginrec% with a value of 0 was encountered.
10003 | SQLEPWD | Login incorrect.
10004 | SQLECONN | Unable to connect: SQL Server is unavailable or does not exist.
10005 | SQLEDDNE | DBPROCESS is inactive or not enabled. For Visual Basic: SQL Server connection is dead.
10006 | SQLNULLO | Attempt to log in with null LOGINREC. For Visual Basic: Attempt to log in with a loginrec value of 0.
10007 | SQLESMSG | General SQL Server error: Check messages from the SQL Server.
10008 | SQLEBTOK | Bad token from SQL Server: datastream processing out of sync.
10009 | SQLENSPE | Non-specific general error.
10010 | SQLEREAD | Read from SQL Server failed.
10011 | SQLECNOR | Column number out of range.
10012 | SQLETSIT | Attempt to call dbtsput with an invalid timestamp. For Visual Basic: Attempt to call SqlTsPut% with an invalid timestamp.
10013 | SQLEPARM | Invalid parameter in DB-Library function reference.
10014 | SQLEAUTN | Attempt to update the timestamp of a table that has no timestamp column.
10015 | SQLECOFL | Data-conversion resulted in overflow.
10016 | SQLERDCN | Requested data conversion does not exist.
10017 | SQLEICN | Invalid computeid or compute column number.
10018 | SQLECLOS | Error in closing network connection.
10019 | SQLENTXT | Attempt to get text point/timestamp from a non-text column. For Visual Basic: Attempt to get a text identifier or text timestamp from a non-text column.
10020 | SQLEDNTI | Attempt to use dbtxtsput to put a new text timestamp into a column whose datatype in neither SQLTEXT nor SQLIMAGE. For Visual Basic: Attempt to use SqlTxTsPut% to put a new text timestamp into a column whose datatype is neither text nor image.
10021 | SQLETMTD | Attempt to send too much TEXT data via the dbmoretext call. For Visual Basic: Attempt to send too much text data using SqlMoreText%.
10022 | SQLEASEC | Attempt to send an empty command buffer to SQL Server.
10023 | SQLENTLL | Name too long for LOGINREC field.
10024 | SQLETIME | SQL Server connection timed out.
10025 | SQLEWRIT | Write to SQL Server failed.
10026 | SQLEMODE | Network connection not in correct mode; invalid SQL Server connection.
10027 | SQLEOOB | Error in sending out-of-band data to SQL Server.
10028 | SQLEITIM | Illegal timeout value specified.
10029 | SQLEDBPS | Maximum number of DBPROCESSes already allocated. For Visual Basic: Invalid or out-of-range parameter to a Visual Basic option.
10030 | SQLEIOPT | Attempt to use invalid DBOPTION. For Visual Basic: Attempt to use invalid Visual Basic option.
10031 | SQLEASNL | Attempt to set fields in a null LOGINREC. For Visual Basic: Attempt to set fields in a login record with loginrec value of 0.
10032 | SQLEASUL | Attempt to set unknown LOGINREC field.
10033 | SQLENPRM | NULL parameter not allowed for this DBOPTION. For Visual Basic: This Visual Basic option cannot have a parameter that is an empty string.
10034 | SQLEDBOP | Invalid or out of range dbn option parameter. For Visual Basic: Invalid or out-of-range parameter to a Visual Basic option.
10035 | SQLENSIP | Negative starting index passed to dbstrcpy. For Visual Basic: Negative starting index passed to SqlStrCpy%.
10036 | SQLECNULL | NULL destination variable not allowed. For Visual Basic: You have used 0 as an identifier for a text timestamp.
10037 | SQLESEOF | Unexpected EOF from SQL Server.
10038 | SQLERPND | Attempt to initiate a new SQL Server operation with results pending.
10039 | SQLECSYN | Attempt to convert data stopped by syntax error in source field.
10040 | SQLENONET | DB-Library network communications layer not loaded.
10041 | sqlebtyp | Unknown bind type passed to DB-Library function.
10042 | sqleabnc | Attempt to bind to a non-existent column.
10043 | sqleabmt | User attempted a dbbind with mismatched column and variable types.
10044 | sqleabnp | Attempt to bind using NULL pointers.
10045 | sqleabncr | Attempt to bind user variable to a non-existent compute row.
10046 | slqeaamt | User attempted a dbaltbind with mismatched columns and variable datatypes.
10047 | SQLENXID | The server did not grant us a distributed-transaction ID.
10048 | sqleifnb | Illegal field number passed to bcp_control.
10049 | SQLEKBCO | 1000 rows successfully copied to host file.
10050 | SQLEBBCI | Batch successfully copied to SQL Server.
10051 | SQLEKBCI | 1000 rows sent to SQL Server.
10052 | SQLEBCWE | I/O error while writing a bcp datafile.
10053 | SQLEBCNN | Attempt to copy a null value into a server column that does not accept null values.
10054 | SQLEBCOR | Attempt to bulk copy an oversized row to SQL Server.
10055 | SQLEBCPI | Call BCPInit before any other BCP routines. For Visual Basic: Call SqlInit$ before any other BCP routines.
10056 | sqlebcpn | Use bcp_bind, bcp_collen, and bcp_colptr only after calling bcp_init with the copy direction set to DB_IN.
10057 | sqlebcpb | Do not use bcp_bind after bcp_init has been passed a non-null input filename.
10058 | SQLEVDPT | For bulk copy, all variable-length data must have either a length-prefix or a terminator specified.
10059 | SQLEBIVI | Use bcp_columns and bcp_colfmt only after bcp_init has been passed a valid input file. For Visual Basic: Use SqlBCPColumns% and SqlBCPColfmt% only after SqlInit$ has been passed a valid input file.
10060 | SQLEBCBC | Call bcp_columns before bcp_colfmt. For Visual Basic: Call SqlBCPColumns% before SqlBCPColfmt%.
10061 | SQLEBCFO | Host files must contain at least one column: bcp.
10062 | SQLEBCVH | Call bcp_exec only after bcp_init has been passed a valid host file. For Visual Basic: Call SqlBCPExec% only after SqlBCPInit% has been passed a valid host file.
10063 | SQLEBCUO | Unable to open host datafile: bcp.
10064 | SQLEBUOE | Unable to open error file: bcp.
10065 | SQLEBWEF | I/O error while writing bcp error file.
10066 | SQLEBTMT | Attempt to send too much text data with bcp_moretext.
10067 | SQLEBEOF | Unexpected EOF encountered in bcp datafile.
10068 | SQLEBCSI | Host-file columns can be skipped only when copying into the server.
10069 | sqlepnul | NULL program pointer encountered.
10070 | SQLEBSKERR | Cannot seek in data file.
10071 | SQLEBDIO | Bad bulk-copy direction.
10072 | SQLEBCNT | Attempt to use bulk copy with a nonexistent server table.
10073 | sqlemdbp | Attempt to set maximum number of DBPROCESSes lower than 1.
10075 | SQLCRSINV | Invalid cursor statement.
10076 | SQLCRSCMD | Attempt to call cursor functions when there are commands waiting to be executed.
10077 | SQLCRSNOIND | One of the tables involved in the cursor statement does not have a unique index.
10078 | SQLCRSDIS | Cursor statement contains one of the disallowed phrases COMPUTE, UNION, FOR BROWSE, or SELECT INTO.
10079 | SQLCRSAGR | Aggregate functions are not allowed in a cursor statement.
10080 | SQLCRSORD | Only fully keyset driven cursors can have ORDER BY, GROUP BY, or HAVING PHRASES.
10081 | SQLCRSMEM | Keyset or window scroll size exceeds the memory limitations of this machine.
10082 | SQLCRSBSKEY | Keyset cannot be scrolled backward in mixed cursors with a previous fetch type.
10083 | SQLCRSNORES | Cursor statement generated no results.
10084 | SQLCRSVIEW | A view cannot be joined with another table or a view in a cursor statement.
10085 | SQLCRSBUFR | Row buffering should not be turned on when using cursor functions.
10086 | SQLCRSFROWN | Row number to be fetched is outside valid range.
10087 | SQLCRSBROL | Backward scrolling cannot be used in a forward scrolling cursor.
10088 | SQLCRSFRAND | Fetch types RANDOM and RELATIVE can only be used within the keyset of keyset driven cursors.
10089 | SQLCRSFLAST | Fetch type LAST requires fully keyset driven cursors.
10090 | SQLCRSRO | Data locking or modifications cannot be made in a READONLY cursor.
10091 | SQLCRSTAB | Table name must be determined in operations involving data locking or modifications.
10092 | SQLCRSUPDTAB | Update or insert operations using bind variables require single table cursors.
10093 | SQLCRSUPDNB | Update or insert operations cannot use bind variables when binding type is NOBIND.
10094 | SQLCRSVIIND | The view used in the cursor statement does not include all the unique index columns of the underlying tables.
10095 | SQLCRSNOUPD | Update or delete operation did not affect any rows.
10096 | SQLCRSOS2 | Cursors are not supported for this server.
10097 | SQLEBCSA | The BCP hostfile %s contains only %ld rows. Skipping all of these rows is not allowed.
10098 | SQLEBCRO | Data locking or modifications cannot be made in a READONLY cursor.
10099 | SQLEBCNE | The table %s contains only %ld rows. Copying up to row %ld is not possible.
10100 | SQLEBCSK | The table %s contains only %ld rows. Skipping all of these rows is not allowed.
10101 | SQLEUVBF | Attempt to read unknown version of bcp format file.
10102 | SQLEBIHC | Incorrect host-column number found in bcp format file.
10103 | SQLEBWFF | I/O error while reading bcp format file.
10104 | SQLNUMVAL | The data stored in the DBNUMERIC/DBDECIMAL structure is invalid.
10105 | SQLEOLDVR | The SQL Server's TDS is obsolete with this version of DB-Library.


Error-Severity Levels

The following table lists the level of severity of Visual Basic errors and the corresponding constants. The constants are defined in the VBSQL.BAS file.

Severity level | Constant | Description
1 | EXINFO | Informational non-error.
2 | EXUSER | User error.
3 | EXNONFATAL | Nonfatal error.
4 | EXCONVERSION | Error in Visual Basic data conversion.
5 | EXSERVER | Server returned an error flag.
6 | EXTIME | Exceeded timeout period while waiting for a response from SQL Server. The SQL Server connection is still alive.
7 | EXPROGRAM | Coding error in user program.
8 | EXRESOURCE | Running out of resources. The SQL Server connection may be inactive.
9 | EXCOMM | Failure in communication with SQL Server. The SQL Server connection is inactive.
10 | EXFATAL | Fatal error. The SQL Server connection is inactive.
11 | EXCONSISTENCY | Internal software error. Notify your primary support provider.


Before You Begin

The programming components in Microsoft® SQL Server™ 6.0 enable you to develop sophisticated client/server applications that tap the power of Microsoft SQL Server from workstations running the Microsoft® Windows NT™, Microsoft® Windows®, and MS-DOS® operating systems.

Microsoft Open Data Services (ODS) is used to create server applications for client/server systems. It is compatible with the Microsoft C compiler and tools for Windows NT.

Note This book contains background information about Microsoft SQL Server and provides some information specific to SQL Server 6.0. For information about changes and enhancements specific to SQL Server 6.5, see the supplementary "What's New in SQL Server 6.5."


About Programming Open Data Services

Microsoft SQL Server Programming Open Data Services describes how to create Open Data Services server applications. It describes the Open Data Services application programming interface (API), provides details about building Open Data Services server applications, provides a directory of all Open Data Services functions and macros, and includes sample code.

This book is written for programmers who are using the C programming language to develop server applications that can interact with Microsoft SQL Server and with client computers running applications based on the DB-Library™ or Microsoft® Open Database Connectivity (ODBC) API.

This book assumes that you are familiar with DB-Library and/or ODBC. It also assumes that you are familiar with Transact-SQL™, the enhanced version of SQL (structured query language). For information about Transact-SQL, see the Microsoft SQL Server Transact-SQL Reference.


Finding Further Information

This book contains reference information to help you write Open Data Services server applications that will interact with Microsoft SQL Server. Information about Open Data Services and additional information about SQL Server 6.0 is available from the following sources, as well as from the Microsoft® Development Library and Microsoft® TechNet.

The Microsoft Developer Network provides in-depth information for developers. With Level 1 of the Developer Network, you get four quarterly releases of the Development Library, packed with inside information on programming for Microsoft Windows and Windows NT, plus other program benefits. With Level 2 of the Developer Network, you'll receive all the Level 1 benefits plus quarterly releases of the Development Platform, containing the latest Windows and Windows NT Workstation operating systems and API-level SDKs and DDKs from Microsoft. For ordering information, call (800) 759-5474.

Microsoft TechNet is the front-line resource for fast complete answers to technical questions on Microsoft desktop and system products. Through two monthly CDs, you get everything from crucial data on client/server and workgroup computing, systems platforms, and database products to the latest applications support for Microsoft Windows and the Apple® Macintosh®. For ordering information, call your reseller or (800) 344-2121.

ODS Online Help

To access online Help while using ODS, choose the ODS Help icon.

SQL Server Documentation

The documentation for SQL Server 6.0 is available online as part of the Microsoft® Development Library and as Microsoft SQL Server Books Online, which is part of Microsoft SQL Server and Microsoft® SQL Workstation.

Important SQL Server Books Online contains the most up-to-date information about SQL Server 6.0, including information that changed or was unavailable when the SQL Server 6.0 books were printed.

Microsoft SQL Server Setup
Provides instructions for installing SQL Server 6.0 servers and clients.
Microsoft SQL Server System Administrator's Companion
Incorporates configuration, administration, and troubleshooting topics. Describes server and client configuration. Explains system administration tasks, such as managing devices and databases, backing up and recovering data, performing replication, scheduling tasks, managing security, and monitoring performance. Describes error conditions and gives troubleshooting procedures.
Microsoft SQL Server Database Developer's Companion
Provides an overview of Transact-SQL, which is an enhanced version of SQL (structured query language). Discusses managing data and database objects, such as tables, views, indexes, stored procedures, defaults, rules, constraints, and user-defined datatypes.
Microsoft SQL Server Transact-SQL Reference
Explains how to use Transact-SQL statements and other features to access databases, and provides syntax and descriptions for Transact-SQL statements, system procedures, utility programs, and system tables.
Microsoft SQL Server Programming SQL Distributed Management Objects
Provides syntax and reference information for the SQL Distributed Management Objects, which are 32-bit OLE Automation objects for the Microsoft® Windows® 95 and Windows NT operating systems. These objects, properties, methods, and collections are used to write scripts and programs that can administer multiple SQL Servers distributed across a network.
Microsoft SQL Server Programming DB-Library for C
Provides syntax and reference information for the DB-Library application programming interface (API), which is used to write C/C++ client programs for the Windows, Windows 95, Windows NT, and MS-DOS operating systems.
Microsoft SQL Server Programming DB-Library for Visual Basic
Provides syntax and reference information for the DB-Library API, which is used to write Microsoft® Visual Basic® programming system-based client programs for the Windows operating system.


Chapter 1 Overview

Overview

Microsoft Open Data Services (ODS) provides a server-based application programming interface (API). The API consists of C functions and macros used for creating two types of server applications: applications that are initialized as Open Data Services servers and that support user connections and user queries, and applications called extended stored procedures that are added directly to SQL Server and accessed by making procedure calls to SQL Server. Applications created with Open Data Services can interact with SQL Server database clients, with SQL Server database servers, and with any other elements of a network environment that you define.

This interaction allows you to create powerful applications that can:

  • Provide extensions to SQL Server by integrating features from your network environment whenever certain events occur within SQL Server.

    For example, you can create extension functions that take specific actions based on updates to SQL Server tables, launch programs that are external to SQL Server, or exchange data with an application external to SQL Server. You can even make these functions transparent to SQL Server users.

  • Provide gateways to non - SQL Server database environments.

    Open Data Services server applications can connect to relational databases to perform general-purpose data access, or to non-relational data sources to perform application-specific tasks.

For Open Data Services server applications that provide extension functions, you can generally make the application available as a set of extended stored procedures that you add to SQL Server itself.

For Open Data Services server applications that provide gateway functions, you might not need to involve a SQL Server database at all; your application can accept connections from multiple local area network (LAN) clients directly, access an external data source on their behalf, and then return responses to the clients.

With the Open Data Services Library (ODS Library), an application runs as a server software process on the network, just like other server software processes such as SQL Server. The ODS Library automatically handles network communications with other elements of the SQL Server environment. Client communications are based on client connection requests. Server-to-server communications take place via SQL Server remote stored procedures.


Client Connections

With Open Data Services, your server application can maintain active connections with many client applications at one time, in a manner that is transparent to the client and is largely transparent to the server application. Open Data Services supports many types of client applications running on a variety of operating systems and includes support for simultaneous client connections over several types of local area network protocols.

When a client application requests data from an Open Data Services server application, Open Data Services passes the request to the application-defined event handler for that request type. After your event handler processes the request, Open Data Services returns the reply to the client application over the network. To the client, the reply looks the same as a reply from SQL Server.

Just as DB-Library, the SQL Server client-based API, allows you to design a variety of client applications that share a common database server, the Open Data Services server-based API supplies the foundation for a variety of server applications to share a common client interface. Any client application that can connect to a SQL Server database server can also connect to an Open Data Services server application.

A comparison with SQL Server helps to explain how Open Data Services operates. SQL Server can be described as having two logical components: the client manager and the data manager. The client manager coordinates requests from clients on the network. It handles such tasks as establishing a network session for each client connection, formatting data for transmission over the network, and managing multiple client threads. The data manager handles database requests from clients. It handles such tasks as parsing SQL requests, optimizing data access, establishing locks to control concurrency, and accessing data on the disk drives.

Think of the Open Data Services Library as a complete client manager, with "hooks" that allow you to define your own data management routines that you implement as a set of event handlers. The ODS Library handles all network communication with database clients; you determine what data to return in response to individual client requests. The ODS Library and the application-defined event handlers make up the primary components of an Open Data Services server application that can respond to multiple client connections, as shown in the following illustration.


Support for Multiple Clients

Open Data Services can maintain simultaneous connections with multiple clients. For each client that establishes a connection, Open Data Services maintains a separate SRV_PROC structure to contain client-specific information. Open Data Services functions concerned with client requests pass a pointer to this SRV_PROC structure when referring to the client.

Open Data Services can process active client requests using one thread per client connection, or optionally, using multiple threads from a thread pool, where multiple threads can service individual requests from multiple clients as each thread becomes available. The thread pooling option allows Open Data Services to process a large number of client requests with little overhead.

As described later in this chapter, a application-defined event handler need only respond to a well-defined set of requests; Open Data Services creates and manages multiple threads and their access to the application's event handlers. Thread management in Open Data Services includes thread protection provisions, allowing Open Data Services to operate on a Windows NT - based computer that uses multiple processors. For a complete discussion of processing threads, see the description of the srv_config function in Functions and Macros.


Supported Client Types

Open Data Services accepts connections from all DB-Library - based client applications, regardless of the operating system on which the client application is running. Support for DB-Library client functions is an integral component of Open Data Services. Open Data Services also accepts connections from client applications that adhere to the Open Database Connectivity (ODBC) client API. Support for ODBC clients is available via an Open Data Services gateway driver for ODBC. You can customize the Open Data Services gateway driver for ODBC clients for your Open Data Services gateway applications. For information, see ODBC Drivers for SQL Server and Open Data Services.

With support for Windows NT - based installable networks, Open Data Services accepts connections from clients on any network protocol for which an installable network driver, known as a Net-Library, is provided. Open Data Services can listen for connection requests (from clients and from servers) on multiple network protocols simultaneously.


Server Connections

Open Data Services server applications and SQL Server database servers communicate on the network using remote stored procedures. As with server-to-server communication between two SQL Server database servers, a remote stored procedure call establishes a network session between the two servers. The servers can communicate over any network protocol for which an installable Net-Library is provided, such as named pipes or sockets. When the Open Data Services server application is located on the same computer as SQL Server, a session is established in the same way, but, in the case of named pipes connections, communication takes place over a local named pipe.


Event Handler Interface

The Open Data Services API defines a small, powerful group of events within Open Data Services. Each event is initiated by a request from a server or a client in the SQL Server environment. Using the Open Data Services API, you supply a well-defined routine, called an event handler, for each event type. An Open Data Services server application, then, consists primarily of a set of event handlers that respond to events triggered by incoming requests. In a sense, the ODS Library "runs" the application by calling its event handlers at appropriate times. This style of programming is similar to that used in writing an application for a graphical user interface (GUI) such as the Microsoft Windows operating system. For example, Windows-based applications respond to events such as mouse clicks or key presses. Open Data Services server applications respond to events such as user login requests. In both cases, the application is responsible for taking appropriate actions when an event occurs.

Open Data Services server applications will generally be concerned with three major events:

  • Connect events, which occur each time a client connects to Open Data Services.
  • Language events, which occur each time a client sends a command string, such as a SQL statement, to Open Data Services for processing.
  • Remote stored procedure events, which occur each time a client or a SQL Server directs a remote stored procedure request to Open Data Services for processing.

Open Data Services also generates events based on certain client activities and application activities, allowing an Open Data Services server application to respond to changes to the status of the client connection or to changes to the status of the Open Data Services server application.

Each event causes Open Data Services to issue a call to the corresponding event handler, if one is provided. When writing code for event handlers, think of events as arriving one at a time, each complete with information that identifies the client and tells what the client is requesting.

You can write code for each Open Data Services event handler as if it deals with a single event in isolation, without worrying about blocking other clients by taking too long with a particular request. However, your event-handler code does need to protect global resources. For example, if your application uses a counter that applies to the server as a whole, you should ensure that the counter cannot be modified simultaneously by two separate threads.

In practice, client requests can arrive simultaneously. To deal with simultaneous client requests, the ODS Library allocates a separate area in memory and creates a separate SRV_PROC structure to contain connection information for each new client connection.

In an application servicing many clients, multiple instances of a single event handler can execute in response to multiple client requests through the use of separate processing threads. This multithreaded operation enables Open Data Services server applications to maintain a high level of performance and availability. It also enables Open Data Services server applications to transparently use multiple processors under Windows NT, since the operating system can schedule any thread on any available processor. Developing a server application that handles multiple clients is simple because Open Data Services itself handles all the complexity.

One of the sample applications provided with Open Data Services illustrates event handlers for all event types. The gateway sample application implements a pass-through gateway from one SQL Server to another database server (in this case, another SQL Server). The sample application implements a language event handler that issues a DB-Library dbsqlexec call against the back-end SQL Server, passing on the same command that the client sent to the gateway. Many potential Open Data Services server applications involve simple modifications of this sample gateway.


Connect Events

When a client requests a connection, Open Data Services establishes the connection and accepts login information from the client. It then generates a connect event that calls a connect event handler in the Open Data Services server application, if one is available, allowing the Open Data Services server application to perform additional functions as part of the client connection process. Because the client cannot execute any further requests until the connect event is complete, you can use a connect event handler to perform a set of operations before the client has connected (for example, to validate client logins).


Language Events

Open Data Services language event handlers can process database language requests on behalf of a client or a server. Language events are generated in one of two ways: when a client or a server directs a standard DB-Library language request to the Open Data Services server application, or when a client or a server issues a call to the sp_sqlexec remote stored procedure built in to Open Data Services.


Language Events and sp_sqlexec

Open Data Services includes a built-in remote stored procedure called sp_sqlexec that enables users to retrieve data from an external data source by making a remote stored procedure call to the Open Data Services server application. The user specifies the language request as an sp_sqlexec string argument.

When Open Data Services receives an sp_sqlexec procedure, Open Data Services first converts the contents of the string into a language statement and then directs the statement to the Open Data Services language event handler. To the language event handler, the request appears as a standard language request. The language event handler can pass the language statement directly to an external data source and retrieve the results. To the client, results are returned as remote stored procedure results.


Remote Stored Procedure Events

Remote stored procedure events deserve particular attention for their flexibility and ease of use. They are especially well-suited for enhancements to SQL Server applications that integrate clients and servers into existing environments.

Open Data Services remote stored procedure events correspond to SQL Server remote stored procedures. Remote stored procedures allow a client connected to one SQL Server to execute a stored procedure on another SQL Server without establishing a client connection to the second server. The server to which the client is connected accepts the client request and sends the request to the remote server on the client's behalf. The remote server processes the request and returns any results to the original server, which in turn passes those results to the client.

Remote stored procedure requests can be initiated by clients or servers. DB-Library and ODBC functions are available for calling remote stored procedures directly from a client. For more information about remote stored procedures, see ODBC Drivers for SQL Server and Open Data Services the Microsoft SQL Server Transact-SQL Reference, and Microsoft SQL Server Programming DB-Library for C.

Remote stored procedures are particularly powerful when combined with Open Data Services. SQL Server clients and servers can issue remote stored procedure calls to an Open Data Services server application. The following illustrations show a connection between a client, SQL Server, and Open Data Services using remote stored procedures.

To Open Data Services, requests from SQL Server clients and servers look the same ¾ they simply activate a remote stored procedure event ¾ so you can create a single event handler that responds to requests coming from a client or to requests coming from a SQL Server database server (as the result of a trigger, for example). Moreover, event handlers for remote stored procedure events are generally easier to write than language event handlers, since the incoming commands and parameters don't have to be parsed from a command string. For more information about event handlers for remote stored procedures, see Chapter 3, Open Data Services Programming.


Other Types of Events

Of the remaining event types, two are based on client activities and the rest are based on Open Data Services server activities:

  • Client requests can generate an attention event and a disconnect event, allowing you to provide an attention event handler and a disconnect event handler that act on the status of the client connection.
  • The Open Data Services server can generate a start event, a stop event, a sleep event, a restart event, or an exit event, allowing you to provide event handlers that act on the status of the Open Data Services server and your application.

For a complete list of all Open Data Services events, see Events and Event Types.

Because SQL Server itself handles the main event, extended stored procedures can include pre- and post-event handlers. Pre- and post-event handler functions are defined the same as standard event handler functions. First the pre-handler is called, then SQL Server handles the main event, then the post-handler is called. For more information about pre- and post-event handlers, see srv_pre_handle and srv_post_handle.


Types of Server Applications

This section discusses some of the potential applications for Open Data Services. Open Data Services provides sample code that illustrates the applications discussed. For some of the samples, executable versions are included so that you can use them without modification.


Applications for Extending SQL Server

Open Data Services offers a variety of ways to expand the capabilities of SQL Server. Open Data Services server applications can respond to updates in SQL Server tables, facilitate running external programs, and obtain data from an outside source.


Responding to SQL Server Updates

Client-server architecture assumes that when a client wants the latest data from the server, the client makes a request to the server. Therefore, SQL Server responds to client requests but never initiates the conversation. In some applications, however, a client must be notified when a key piece of data changes at the server. A stockbroker, for example, might want to know immediately if the price of a particular security changes by more than a certain percentage. With standard client-server architecture, the stockbroker's client application would need to query the server frequently to see whether the data had changed. This activity costs processing resources, both at the client and at the server.

The remote stored procedure capabilities of Open Data Services offer a simple solution to this problem. In SQL Server, you can place a trigger on the table of interest. When data in the table changes, the trigger activates a remote stored procedure call to an Open Data Services server application, passing the name of the client that needs notification as a parameter in the procedure call. Then, in the Open Data Services server application, the remote stored procedure event handler can call an external application that can notify a user of the update.

Example

The PROCSRV sample application, included with Open Data Services, shows how an Open Data Services server application can notify a client of a SQL Server update by triggering a process that is external to SQL Server, such as a LAN Manager net send command.


Triggering External Processes from SQL Server

Another common application requirement is to execute an external command or executable file when the value of a field in a particular table reaches a certain level. An inventory application, for example, might reorder stock when the quantity on hand falls below a certain reorder point. The reordering process could involve an existing mainframe or minicomputer application instead of being entirely implemented on SQL Server.

With Open Data Services, you can put a trigger on the table in question. The trigger compares the quantity on hand with the reorder point. When the quantity on hand falls below the reorder point, the trigger issues a remote stored procedure call to an Open Data Services server application, passing it the part number as a parameter. The remote stored procedure event handler then automatically executes the mainframe or minicomputer transaction that you have defined in your application, using the part number as an input parameter.

Example

The PROCSRV sample application provides a way to handle this type of SQL Server extension without any C programming. SQL Server can issue a remote stored procedure call to the PROCSRV sp_exec procedure. SQL Server passes the name of a command file or executable file on that server, along with any required input parameters. The sp_exec procedure automatically starts the requested command or executable file in response to the remote stored procedure event. SQL Server includes a similar extended stored procedure called xp_cmdshell.

Using this procedure, a SQL Server installation can draw on a set of simple command or executable files in any language to perform functions that are external to the SQL Server environment.


Capturing External Data

Some applications require SQL Server to reflect a current data value from the external environment. A currency-trading application, for example, might need to get a current exchange value from a wire service. With conventional client-server techniques, a client program would obtain this value and then update the server. Using Open Data Services, however, this value can be obtained by SQL Server, when required, from an Open Data Services server application. SQL Server calls the Open Data Services server application as a remote stored procedure, and then the Open Data Services server application sends the current value or values back to SQL Server in the form of return parameters. This value can then be stored in a table or incorporated into a Transact-SQL procedure as required.

Example

The PROCSRV and the XP.DLL sample applications demonstrate this type of application. When SQL Server calls the PROCSRV diskfree or the XP.DLL xp_diskfree remote stored procedure, passing a drive letter as a parameter to the procedure, the procedure returns the amount of free space on the drive.


Gateway Applications

Gateway applications focus on connecting local area network (LAN) clients to external data sources. Sometimes gateway applications also use SQL Server to store data. At other times a gateway application is simply a mechanism for delivering data from other systems to LAN clients. Because gateway applications based on Open Data Services can communicate with SQL Server clients, they can take advantage of the client platforms, front-end tools, and network support that SQL Server provides. Gateway applications are particularly useful in mixed database environments because they allow clients to connect to many data sources using a single access library (DB-Library or ODBC) and a single protocol (their LAN transport), limiting the cost and complexity of connecting to mainframe or minicomputer networks to that of a few powerful servers running gateways. Overhead is very low and differences in performance are usually negligible.

Gateways built with Open Data Services can connect to both relational and non-relational data sources. Relational database gateways are often general-purpose tools that allow clients to issue any type of supported SQL request against a back-end database. Gateways to non-relational data sources are often application-specific rather than general-purpose tools. Since a non-relational data source usually doesn't recognize SQL language requests, you can implement this type of gateway using the remote stored procedure facility of Open Data Services. Writing the gateway application simply involves defining a stored procedure for each of the data interactions with the external source that the application requires. These stored procedures can then be called by any client on the network.

Note Open Data Services does not support sending compute rows to the client. Also, if a row containing text or image data is sent to the client, the text pointer and text timestamp are not included. Pass-through gateway applications do not support SQL Server 6.0 server cursor operations.

Example

The PROCSRV sample application is a simple example of an application-specific gateway. PROCSRV responds to a call from a client to its scan_xbase function by returning the contents of a sample dBASE® file on the server. In addition, the PROCSRV sample includes a flexible way for clients to call its stored procedures as language events. This allows you to write one procedure handler to respond to clients that can make remote stored procedure requests as well as to clients that can make language requests only.


Extended Stored Procedures

Open Data Services server applications can be integrated as a set of extended stored procedures as part of SQL Server. Extended stored procedures provide a way to extend SQL Server via the Open Data Services API, without providing a separate Open Data Services server application.

Instead of running your application as a separate Open Data Services server application that uses the ODS Library as a base, you can include your application's dynamic-link library (DLL) file with the standard SQL Server DLL files and use SQL Server as a base. Each function within the DLL file can then be called as if it were a standard SQL Server stored procedure.

Example

The XP.DLL sample application provides a set of extended stored procedures.


Windows NT Services

You can install an Open Data Services server application as a Windows NT service that responds to Windows NT commands such as net start, net stop, and net pause. Windows NT services must use the Win32™ API to register with the Service Control Manager (SCM). For more information, see your Win32 API documentation.

The PROCSRV sample application demonstrates integration with the Service Control Manager, and the service application demonstrates installing a Windows NT service.


Chapter 2 System Requirements

System Requirements

This chapter describes the system requirements for using Microsoft Open Data Services. For information about installing a completed Open Data Services server application, see Network Setup Options for Open Data Services Server Applications.

Microsoft Open Data Services requires a computer that includes the following software components:

  • Microsoft Windows NT Workstation version 3.5 or later (version 3.51 or later is recommended)

    Or

    Microsoft Windows NT Server version 3.5 or later (version 3.51 or later is recommended)

  • Microsoft Visual C++ version 2.0 or later, or 100% compatible compiler and linker

Microsoft Open Data Services is available for computers with the following microprocessor architectures:

  • Alpha AXP™
  • Intel® 32-bit x86-based
  • MIPS®

The computer must meet all of the hardware requirements for Microsoft Windows NT and for a minimum version of Microsoft Visual C++, such as processor type, available disk space, and recommended RAM.

If the computer is also running Microsoft SQL Server, be sure to meet the hardware and software requirements described in the Microsoft SQL Server Setup.

Important Existing Open Data Services applications must be recompiled and rebuilt using Open Data Services 6.0. This is required because of changes to Open Data Services data structures, and because of the removal of certain constants, such as SRV_CONNECTSPERTHREAD, SRV_MINNETWORKTHREADS, and SRV_THREADPOOLING used by srv_config. Applications should not use LocalFree on the errtext and oserrtext parameters within the error handler (registered using srv_errhandle) because Open Data Services frees these now.


Chapter 3 Open Data Services Programming

Open Data Services Programming

In presenting Open Data Services programming topics, this chapter:

  • Provides a brief overview of the types of functions, the primary data structures, and all the include files that make up the Open Data Services API.
  • Provides a brief overview of memory management options, thread processing options, and security options that the Win32 API for Windows NT supports.
  • Describes how to respond to Open Data Services events by writing code for a set of event handlers and installing the handlers.
  • Describes how to respond to Open Data Services errors by writing code for the error handlers and installing the handlers.
  • Uses sections of sample code to illustrate the process of initializing Open Data Services server applications and to demonstrate the use of event handlers and error handlers.


Programming Tasks

Open Data Services server applications are event-driven — that is, they respond to a predefined set of events that the ODS Library generates in response to an incoming request or to an error.

The programming tasks that you need to complete when creating an Open Data Services server application are based on meeting the following requirements:

  • Initializing the Open Data Services server.
  • Installing a set of error handlers.
  • Installing a set of event handlers that will respond to the main Open Data Services event types by processing incoming requests and returning the results to the user. The main Open Data Services event types are as follows:
    • connect
    • language
    • remote stored procedure

For applications that provide access to a remote data source, the tasks include:

  • establishing a connection to the data source
  • passing user requests
  • receiving the results
  • returning the results to the user


Open Data Services Functions and Macros

Functions and Macros

This section groups the Open Data Services API functions and macros by category and describes each function and macro. For syntax and detailed functionality information on each Open Data Services API function and macro, see Functions and Macros.


Server Initialization and Configuration

Function/Macro | Description
srv_config | Sets server configuration parameters, such as the number of client connections and the Open Data Services log file. You must allocate a configuration structure with srv_config_alloc before using srv_config.
srv_config_alloc | Allocates an SRV_CONFIG structure that contains the Open Data Services configuration parameters.
SRV_GETCONFIG | Returns a pointer to an Open Data Services server application's configuration structure for a client connection. The returned pointer can be used to change configuration parameters with srv_config.
srv_init | Initializes Open Data Services. Use this function to initialize the server before starting the server with srv_run.
srv_run | Starts Open Data Services and allows event processing to begin.
SRV_TDSVERSION | Determines the tabular data stream (TDS) version being used for the client connection.


Data Retrieval

Function | Description
srv_getuserdata | Returns a pointer to private data space in an SRV_PROC structure. To access private data, set the pointer with srv_setuserdata.
srv_setuserdata | Sets a pointer to private data space in an SRV_PROC structure. This pointer can be used later with srv_getuserdata.
srv_pfield | Returns a field from an SRV_PROC structure.
srv_symbol | Converts an Open Data Services token value to a readable string. Use this function to return data, event, status, or error-severity token types.


Column and Row Processing

Function | Description
srv_describe | Defines a row's column name, number, and its source and destination data. Use this function to define all columns in a row before sending the row to the client requesting the data.
srv_sendrow | Transmits a row of data to the client connection. Use this function to send each row of data to the client.
srv_setcoldata | Specifies the current address for a column's data. Use this function after srv_describe if the address of the column data changes before a complete results set has been sent to the client.
srv_setcollen | Specifies the current length of a column's data. Use this function after srv_describe if the length of the column data changes before a complete results set has been sent to the client.
srv_setutype | Sets the user-defined datatype for a column in a row. Use this function if a user-defined datatype is to be sent to the client along with the actual datatype, or for encoding additional column information for ODBC and DB-Library clients.


Error and Message Handling

Function/Macro | Description
srv_errhandle | Installs a programmer-supplied error handler for an Open Data Services server application.
SRV_IODEAD | Determines whether an input and output connection to a client is open.
srv_log | Writes a message to the Open Data Services log file.
srv_senddone | Sends a results completion message to the client. Use this function after a results set has been sent by the server.
srv_sendmsg | Sends a message to the client.
srv_sendstatus | Sends a message or a status value to the client in response to a request. Use this function to send a value to the client indicating the status of a client request.
srv_sfield | Returns a pointer to a field in an SRV_SERVER structure. Use this function to obtain server configuration information, such as the number of allowable client connections.
srv_message_handler | Calls SQL Server from an extended stored procedure to log an error.


Data Conversion

Function | Description
srv_convert | Changes data from one datatype to another. Use this function to change data to any of the allowable Open Data Services datatypes.
srv_willconvert | Determines whether a specific datatype conversion is available within Open Data Services.


Event Management

Function/Macro | Description
srv_event | Causes an Open Data Services event to be activated.
SRV_EVENTDATA | Accesses the event handler data passed by srv_event. Use this macro to retrieve data supplied by an Open Data Services server application.
SRV_GETSERVER | Returns a pointer to the SRV_SERVER structure being used by the client.
SRV_GOT_ATTENTION | Determines whether an attention event has occurred.
srv_handle | Installs an event handler in an Open Data Services server application. Use this function to assign an event to an event handler other than the default event handler.
srv_impersonate_client | Impersonates the security context of a client connection.
srv_pre_handle | Installs a pre-event handler that is called before the standard event handler.
srv_post_handle | Installs a post-event handler that is called after the standard event handler.
srv_revert_to_self | Stops impersonation of the security context of a client connection, reverting to the original security context of the Open Data Services application.
srv_setevent | Activates an event outside the context of a client connection.
srv_terminatethread | Disconnects and exits a client thread.


Language Event Processing

Function | Description
srv_langcpy | Copies part of the language request buffer. Use this function to retrieve a part of the language command sent by the client.
srv_langlen | Returns the length of the language request buffer. Use this function with srv_langcpy when the entire language command is to be retrieved.
srv_langptr | Returns a pointer to the language request buffer.


Remote Stored Procedure Event Processing

Function | Description
srv_paramdata | Returns the value of a remote stored procedure parameter.
srv_paramlen | Returns the length of a remote stored procedure parameter.
srv_parammaxlen | Returns the maximum length of a remote stored procedure parameter.
srv_paramname | Returns the name of a remote stored procedure parameter.
srv_paramnumber | Returns the number of a remote stored procedure parameter.
srv_paramset | Sets the output value for a remote stored procedure parameter.
srv_paramstatus | Returns the status flags for a remote stored procedure parameter.
srv_paramtype | Returns the datatype of a remote stored procedure parameter.
srv_returnval | Defines an output parameter value for a language event.
srv_rpcdb | Returns the database name component for the current remote stored procedure.
srv_rpcname | Returns the procedure name component for the current remote stored procedure.
srv_rpcnumber | Returns the number component for the current remote stored procedure.
srv_rpcoptions | Returns the run-time options for the current remote stored procedure.
srv_rpcowner | Returns the owner name component for the current remote stored procedure.
srv_rpcparams | Returns the number of parameters for the current remote stored procedure.


Application Management

Function | Description
srv_clearstatistics | Resets the counters that collect statistics about the Open Data Services server application's workload.
srv_sendstatistics | Returns statistical information about the Open Data Services server application's workload.


Memory Management

These functions are provided for backward compatibility.

Function | Description
srv_alloc | Allocates memory dynamically.
srv_bmove | Copies bytes from one memory location to another.
srv_bzero | Sets the contents of a memory location to zero.
srv_free | Frees memory allocated with srv_alloc or srv_config_alloc.


Open Data Services Data Structures

Data Structures

The following table explains the purpose of each of the three primary data structures that Open Data Services uses to maintain information about the status of the Open Data Services server application and each connected client process.

Structure | Contains
SRV_CONFIG | Configuration information about the Open Data Services server application process, such as the maximum number of client connections to allow. This structure is examined when the Open Data Services server application is initialized using srv_init. SRV_CONFIG is similar to the DB-Library LOGINREC structure.
SRV_PROC | Information about the client process. The SRV_PROC structure holds information such as the client's current connection status, the version of the SQL Server tabular data stream (TDS) protocol being used, the client's login information, and the Open Data Services server application name. Each client connected to the Open Data Services server application has its own SRV_PROC structure. This structure corresponds to the DB-Library DBPROCESS structure. You can examine the contents of this structure using the srv_pfield function.
SRV_SERVER | Server-wide information for the Open Data Services server application. This structure includes the current status, the server name, and the event handler. You can examine the contents of this structure using the srv_sfield function.


Open Data Services Header Files

Header Files

The following table details the contents of each Open Data Services header file.

Header file | Contains
SRV.H | All of the header files listed below. This file is the only header file that developer-defined routines need to include.
SRVAPI.H | Function prototype definitions for all Open Data Services functions.
SRVCONST.H | Open Data Services constant definitions.
SRVDBTYP.H | DB-Library definitions.
SRVMISC.H | Open Data Services miscellaneous definitions.
SRVSTRUC.H | Open Data Services structure definitions.
SRVTOK.H | Open Data Services token definitions.
SRVTYPES.H | Open Data Services datatype definitions.


Taking Advantage of Win32 API Features

This section describes the memory management and thread management features of the Microsoft Win32 API. An Open Data Services server application can take advantage of the features described in the following topics:

  • Memory Management
  • Threads
  • Windows NT Security


Memory Management

The 32-bit linear virtual memory address space available to processes with the Win32 API simplifies memory management. This applies to Open Data Services programming as well as to all other programming for the Win32 API.

When you develop applications using the Win32 API, consider using the C run-time functions malloc and free to perform dynamic memory management. These functions are both safe and elegant with the Win32 API. In addition to the standard memory management functions (Global and Local, C run-time support), the Win32 API also provides heap and virtual memory management functions for applications that require specialized memory management.

The srv_alloc and srv_free Open Data Services functions are provided for backward compatibility.


Threads

The Win32 API supports 32-bit linear memory, greatly increasing the number of threads that an application can create per process.

Open Data Services uses a thread management technique called thread pooling to make threads available to active client connections faster in environments that support a large number of users. As soon as a thread completes a single request, it becomes available to the thread pool. Open Data Services manages thread processing transparently. However, you can increase or decrease the total number of active threads available to your application.

For more information about threads, refer to the srv_config function description in Functions and Macros.


Windows NT Security

Open Data Services provides the capability for a server application to act in the security context of a client that has connected to it. One potential use of this feature would allow an Open Data Services server application to handle user access entirely through Windows NT facilities, so that the Open Data Services application does not need to maintain a separate list of user IDs and passwords. Another potential use of this feature might involve implementing your own auditing procedures to track system usage during a client session.

An Open Data Services server application can act in the security context of a client through the use of the srv_impersonate_client function and the Windows NT Registry. The srv_impersonate_client function is available for client connections that use the named pipes or multi-protocol Net-Library.

Individual event handlers in an Open Data Services server application can act in the security context of clients. For example, if you want to restrict the execution of particular remote stored procedures requests based on the client user, your remote stored procedures event handler could use the srv_impersonate_client function to determine the user's authorization.

One method of restricting access to an Open Data Services server application based on the client security context is to create a special Registry key and set access permissions on the key. You can use the Windows NT regedt32 utility to set permissions on the key, or you can write a custom setup program that will do it. When the connect event handler is called, the code can impersonate the client and then attempt to access the Registry key.

In this way, the Open Data Services server application can control access based on the success or failure of this action. For example, if a client does not have permission to access the key, the Open Data Services server application can return a specific error to the client and then issue a disconnect event.

Call srv_revert_to_self to return to the original security context of the Open Data Services application.


Events and Event Handlers

Open Data Services defines a set of events that serve as the interface between client or server requests made to the ODS Library and the event handlers that you supply in your application to process those requests.

This section identifies Open Data Services event types, defines the actions that can generate an event, and describes how to associate a particular event handler with a particular event. In addition, this section illustrates a sample connect event from initiation to completion to demonstrate how Open Data Services processes incoming requests.

The following illustration shows the Open Data Services event-handling mechanism. In this example, the Open Data Services server application serves as a gateway between a SQL Server database client workstation and an external data source. A SQL Server database server or another Open Data Services server application making a remote stored procedure request would communicate with Open Data Services in a similar way.

Whenever the ODS Library accepts a request, it generates the appropriate event type and calls the corresponding event handler in the Open Data Services server application, if one is provided.

The Open Data Services server application responds to each event, returning results to the caller. If the caller is a client, Open Data Services returns results sets (using srv_describe and srv_sendrow), return values (using srv_sendstatus), and stored procedure output parameters (using srv_paramset or srv_returnval) to the calling client. If the caller is SQL Server, Open Data Services returns all results to SQL Server. Results sets flow through SQL Server to the client that initiated the activity. Return values and stored procedure output parameters can be captured by Transact-SQL commands or be returned directly to the client.


Event Types

These are the Open Data Services event types:

Event type | Description of event
SRV_ATTENTION | A client sends an interrupt request, or the network connection to the client is broken.
SRV_CONNECT | A client sends a connect request.
SRV_DISCONNECT | A client sends a disconnect request; or the Open Data Services server application calls the srv_event function to initiate a request to disconnect the current client thread.
SRV_LANGUAGE | A client sends a SQL Server language request; or a client or a server sends the sp_sqlexec remote stored procedure request.
SRV_RPC | A client or a server sends a remote stored procedure request.
SRV_EXIT | The Open Data Services server application calls the srv_event or srv_setevent function to initiate a request for an immediate shutdown.
SRV_START | The Open Data Services server application calls the srv_run function to initiate server startup and to set server status.
SRV_SLEEP | The Open Data Services server application calls the srv_setevent function to pause a started server.
SRV_RESTART | The Open Data Services server application calls the srv_setevent function to continue a paused server.
SRV_STOP | The Open Data Services server application calls the srv_event or srv_setevent function to initiate a request to terminate all client threads and then shut down.


Client-initiated Events

Most Open Data Services events are initiated by SQL Server client applications. The client applications use the same set of DB-Library functions to communicate with SQL Server database servers and with Open Data Services server applications.

Each Open Data Services event initiated by a client application has a corresponding DB-Library function. The following table shows the DB-Library client requests that activate Open Data Services events:

DB-Library call | Open Data Services event activated | Description of event
dbcancel | SRV_ATTENTION | Interrupt request
dbclose | SRV_DISCONNECT | Disconnect request
dbopen | SRV_CONNECT | Connect request
dbsqlexec | SRV_LANGUAGE | Language request
dbrpcsend | SRV_RPC | Remote stored procedure request

In addition, Open Data Services provides a built-in remote stored procedure, sp_sqlexec, that allows a server or a client to send a language request that is formatted for a non – SQL Server data source to the Open Data Services server application in the form of a remote stored procedure argument. When an sp_sqlexec request is received by Open Data Services, Open Data Services converts the sp_sqlexec string into a language request, allowing the server application's language event handler to pass the request to an alternate data source.

Remote stored procedure call | Event activated | Description of event
sp_sqlexec | SRV_LANGUAGE | Uses a remote procedure call to pass a string containing a language request to the language event handler, which then interprets the string as a language request.

For DB-Library client applications that run on Windows or Windows NT, if the client computer's AutoAnsiToOem setting is enabled, the client application will generate an SRV_LANGUAGE event immediately following the SRV_CONNECT event to determine which character set the server is using.

Open Data Services server applications should include code to handle this event without generating an error. The query calls the catalog stored procedure sp_server_info with a parameter of 18 to obtain the server's COLLATION_SEQ value. If the first 5 bytes of the resulting value is iso_1, it indicates that the server is returning string data in the ANSI code page, and DB-Library does not need to perform any character set conversions. If the resulting value is anything else, DB-Library assumes that the server is returning string data in an OEM code page (such as 437 or 850). In this case, DB-Library performs a character set conversion to convert all string data into the Windows ANSI code page, unless conversion is explicitly turned off in the client application. For more information about character set conversions in DB-Library, see the Microsoft SQL Server Programming DB-Library for C. For more information about catalog stored procedures, see the Microsoft SQL Server Transact-SQL Reference.

Alternatively, for any DB-Library clients that connect only to Open Data Services, you can disable this event by turning off the client computer's AutoAnswerToOem setting. This setting can be changed using the SQL Client Configuration Utility.


Server-initiated Events

SQL Server database servers and other Open Data Services server applications can initiate these events:

Server request | Event activated | Description of event
Any remote stored procedure call | SRV_RPC | Remote stored procedure request.
sp_sqlexec | SRV_LANGUAGE | Uses a remote procedure call to pass a string containing a language request to the language event handler, which then interprets the string as a language request.

Some events can be generated by Open Data Services itself. Open Data Services can generate the events described in the following table. You can provide your own event handlers for these events.

ODS action | Event activated | Description of event
Issues srv_event function with SRV_DISCONNECT argument. | SRV_DISCONNECT | Requests a disconnect for the current client thread.
Issues srv_event or srv_setevent function with SRV_EXIT argument. | SRV_EXIT | Requests an immediate shutdown.
Issues srv_setevent function with SRV_SLEEP. | SRV_SLEEP | Requests pausing a started server.
Issues srv_setevent function with SRV_RESTART. | SRV_RESTART | Requests continuing a paused server.
Issues srv_event or srv_setevent function with SRV_STOP argument. | SRV_STOP | Requests a graceful shutdown, first waiting for client threads to terminate and then shutting down.


Assigning Event Handlers to Events

For each event handler that your application supplies, the application must include a call to the srv_handle function to map the handler to an event. At run time, srv_handle installs the event handler, enabling the ODS Library to locate the event handler code, and assigns the handler to the event you specify.

Open Data Services includes default event handlers that are called when no event handler of the appropriate type has been installed in the Open Data Services server application. Currently, the default event handlers perform no processing and instead simply return to the calling function.


Connect Event Example

The following steps describe an Open Data Services connect event from its initiation, including the functions performed by the ODS Library and the functions performed by the Open Data Services server application:

  1. The client application calls the DB-Library function dbopen. The dbopen function sends parameters to the client's network layer. The client's network layer sends the connection information to the LAN.
  2. The Open Data Services network layer receives the client connection information. It creates and allocates an SRV_PROC structure containing the connection information and issues a connect event to the ODS Library.
  3. The ODS Library calls the connect event handler provided in the Open Data Services server application, as shown in the following illustration:

  4. The connect event handler provides whatever additional processing it defines.

    For example, if the Open Data Services server application provides a gateway, the connect event handler might respond to this event by establishing a connection to a remote database management system.

  5. The connect event handler returns connection information to the client, as shown in the following illustration:

This completes the processing for the connect event. At this point, the client is logged in. Open Data Services waits for additional requests from the client, at which point the ODS Library generates another event and calls the appropriate event handler.


Open Data Services Error Handling

Error Handling

You can provide an error handler to respond to errors generated by the ODS Library by including in your application a call to the srv_errhandle function. Open Data Services automatically supplies parameters to the error handler to identify the type and severity of the error. Open Data Services also supplies the error handler with a pointer to text that describes the error.

An example of an error condition that invokes a developer-defined error handler is insufficient memory for internal processing. If a language event is received from the client and there is too little available memory for the buffer space required to hold the client's SQL query string the error handler will be called. In this case, the error handler normally informs the user of the condition by displaying a message and by writing information to the error log file using the pointer to the text that describes the error.


Open Data Services Programming Examples

Programming Examples

Each of the programming steps listed in the topics listed below provide an example, using a section of code taken from the Open Data Services sample gateway application. Complete code and additional comments are available in the sample gateway application provided with Open Data Services or in the listing provided in Sample Application-Gateway Server.

The sample gateway application demonstrates how to access a remote data source on behalf of a client application. The gateway application accesses a SQL Server database as if it were a remote data source. To connect to this data source, the gateway application's event handlers use the data source's native client interface, which in this case is the DB-Library client API.

Now see the following:

Setting Up Open Data Services

Handling ODS Library Errors and Server Messages

Installing Event Handlers

Connecting to a Remote Database

Handling a Language Event

Handling a Remote Stored Procedure Event

Receiving Results from a Remote Database

When building your own application to access another data source, use other interfaces as appropriate, such as Windows NT – based client APIs for other relational database products or C-language routines to access custom data sources.


Setting Up Open Data Services

In the following example, the gateway application sets up Open Data Services.

  1. Specify a server process, define the configuration structure for the server, define a pointer for the server's Windows NT Registry key name, and define a pointer for the server name at the remote data source:
    SRV_SERVER *server;                  // The service process
SRV_CONFIG *config;                  // The configuration structure
DBCHAR *RegistryName = "Gateway";    // Registry lookup name
DBCHAR *SrvrName = "";               // Default remote server name
  2. Read the command-line argument to get the name of the remote server to use and send the remote server name to the gateway's DLL:
    // Read any command-line arguments.
getargs(argc, argv);

// Send the name retrieved to the gateway's DLL module.
set_remote_server_name(SrvrName);
  3. Allocate a configuration structure, initialize it to allow 20 client connections, and define the log file as GATEWAY.LOG:
    // Allocate a configuration structure that is used to initialize
// the Open Data Services server application.
config = srv_config_alloc();

// Allow 20 connections at a time.
srv_config(config, (DBINT)SRV_CONNECTIONS, "20", SRV_NULLTERM);

// Set the log file.
srv_config(config, (DBINT)SRV_LOGFILE, "gateway.log", SRV_NULLTERM);


Handling ODS Library Errors and Server Messages

The file GATECBS.C defines an error handler called chk_err to handle ODS Library errors and server messages. This example shows how to implement the chk_err function and install it using the srv_errhandle function.

  1. Create a prototype of the chk_err callback error handler function:
    int chk_err(
SRV_SERVER * server,  // Open Data Services application that got the
                      // error
SRV_PROC * srvproc,   // Error connection being used
int srverror,         // Error number
BYTE severity,        // Severity of the error
BYTE state,           // Error state
int oserrnum,         // Operating-system error number
DBHAR * errtext,      // Text of the error message
int errtextlen,       // Length of the error message
DBHAR * oserrtext,    // Pointer to the operating-system
                      // error message
int oserrtextlen);    // Length of the operating-system
                      // error message
  2. Use srv_errhandle to install the error handler chk_err:
    srv_errhandle (chk_err);
  3. Use the srv_init function to initialize the gateway server and save the server handle in the SERVER process structure so it can be used later:
    server = srv_init(config, RegistryName, SRV_NULLTERM);


Installing Event Handlers

This example shows the gateway application installing an SRV_START event. An SRV_START event occurs once (when srv_run is called) and starts the Open Data Services server application. The SRV_START event invokes the init_server callback function defined in GATECBS.C to initialize the remote server. The init_server function installs the remaining events required to run the gateway application.

  1. Add a prototype for the init_server function in the gateway callback program, GATECBS.C:
    int init_server (SRV_SERVER * server);
  2. Install an SRV_START event using srv_handle to call the init_server function when an Open Data Services server application is first started:
    srv_handle (server, (DBINT)SRV_START, init_server);
    • The init_server function installs an SRV_CONNECT event for connecting to the remote server in the init_remote function:
      srv_handle (server, (DBINT)SRV_CONNECT, init_remote);
    • The init_server function installs an SRV_LANGUAGE event for sending SQL statements to the remote server in the lang_execute function:
      srv_handle (server, (DBINT)SRV_LANGUAGE, lang_execute);
    • The init_server function installs an SRV_RPC event for sending SQL statements to the remote server in the rpc_execute function:
      srv_handle (server, (DBINT)SRV_RPC , rpc_execute);
    • The init_server function installs an SRV_DISCONNECT event to close the connection to the remote database in the exit_remote function:
      srv_handle (server, (DBINT)SRV_DISCONNECT, exit_remote);
    • The init_server function installs an SRV_ATTENTION event to process a dbcancel function call from a client in the attn_handler function:
      srv_handle (server, (DBINT)SRV_ATTENTION, attn_handler);
  3. Return the srv_continue constant to the Open Data Services server application to continue processing events:
    return (SRV_CONTINUE);


Connecting to a Remote Database

This example shows one method of connecting to a remote database, as used by the gateway sample application. Since the connection is to a SQL Server database, DB-Library structures and function calls are used to establish the connection and to communicate with the remote database.

  1. Declare a structure to hold connection information for accessing a remote database. This structure is passed to Open Data Services event handlers in the SRV_PROC structure:
    {
    LOGINREC * login     // Pointer to a LOGINREC structure
    DBPROCESS * dbproc;  // Pointer to a DBPROCESS structure
} REMOTE_DBMS

    where

    login
    Is a pointer to a LOGINREC structure. This structure is defined by the client and contains login and connection information to connect a client to a server.
    dbproc
    Is a pointer to a DBPROCESS structure. This structure is defined by Open Data Services and contains information to manage communications between the client and the server.
  2. Add the init_remote function to the gateway callback program, GATECBS.C:
    int init_remote (srvproc)
SRV_PROC * srvproc;
  3. Allocate a REMOTE_DBMS information structure, which holds the private data space associated with a remote database connection:
    // Private data area to keep track of remote database connection.

REMOTE_DBMS * remote;
remote = (REMOTE_DBMS *) srv_alloc ((DBINT)sizeof(*remote));
  4. Use the DB-Library call dblogin to allocate and return a pointer to a LOGINREC structure, which is used to make the connection to the remote server. Put the pointer to LOGINREC in remote->login:
    // Now we'll allocate our LOGINREC structure that
// we'll use to make connections to the
// remote server. We'll actually open the connection
// in the SRV_CONNECT handler.

remote->login = dblogin();
  5. Use the ODS Library srv_pfield function to copy the user name, password, application name, and language defined in the client's SRV_PROC structure to remote->login:
    // Set the user name, password, application name for the
// remote database.

DBSETLUSER (remote->login, srv_pfield(srvproc, SRV_USER, (int *)
NULL));

DBSETLPWD (remote->login, srv_pfield(srvproc, SRV_PWD, (int *)
NULL));

DBSETLAPP (remote->login, srv_pfield(srvproc, SRV_APPLNAME, (int *)
NULL));

DBSETLNATLANG(remote->login, srv_pfield(srvproc, SRV_NATLANG,
    (int *) NULL));
  6. Use the DB-Library dbopen function with the parameters in remote->login and the server name to connect to the host:
    // Try to open a connection to the remote database.

if ((remote->dbproc = dbopen(remote->login, remote_server))
== (DBPROCESS *) NULL)
{

//  Send a message to the Open Data Services client if the remote
//  connection cannot be made.

srv_sendmsg    (srvproc,
               SRV_MSG_ERROR,
               (DBINT)REMOTE_FAIL,
               (DBTINYINT)0,
               (DBTINYINT)0,
               NULL,
               0,
               0,
               "Login to remote DBMS failed.",
               SRV_NULLTERM);

//  Deallocate remote structure and set the user data pointer in
//  the SRV_PROC connection structure to NULL so that the
//  disconnect handler won't try to disconnect from the remote
//  database.
srv_free (remote);
srv_setuserdata (srvproc, (BYTE *) NULL);
  7. After the connection is made, save the remote data structure in the SRV_PROC connection structure so that it will be available to the other handlers using srv_setuserdata and dbsetuserdata, and return the SRV_CONTINUE constant:
    // Connection to the remote database is successful. Save remote
// data structure in the SRV_PROC connection structure so that it
// will be available to the other handlers. Map the remote
// database connection to the SRV_PROC connection structure.

srv_setuserdata(srvproc, (VOID *)remote);
dbsetuserdata(remote->dbproc, (VOID *)srvproc);


Handling a Language Event

This example describes the lang_execute event handler provided in the sample gateway application. This event handler is implemented as a callback function that sends a client's language command to the SQL Server example remote database, receives the results, and returns the results to the client.

  1. Define the lang_execute function and the following parameters:
    int lang_execute(srvproc)
SRV_PROC *srvproc;
{
REMOTE_DBMS *rmt_dbms;        // Remote database pointer
DBPROCESS *rmtproc;            // Open Data Services DBPROCESS pointer
DBCHAR *query;                // Pointer to language buffer
int query_len;                // Length of query
int status;                    // Status of DB-Library calls
  2. Get the remote DBPROCESS pointer *rmtproc in the SRV_PROC connection structure with srv_getuserdata. This is a pointer that was saved using srv_setuserdata after the client connected to a remote database.
    rmt_dbms = (REMOTE_DBMS *)srv_getuserdata(srvproc);
rmtproc = rmt_dbms->dbproc;
  3. Get the pointer to the client's language request command buffer using the srv_langptr function, and put the pointer in the DBPROCESS structure of the SQL Server database:
    // Get the pointer to the client language request command buffer.

query = srv_langptr (srvproc);

// Place the pointer in the remote DBPROCESS pointer rmtproc.

status = dbcmd (rmtproc, query);
  4. Send the SQL command to the remote database using the DB-Library dbsqlexec function if the previous DB-Library dbcmd function call was successful:
    if (status == SUCCEED)    // Previous DB-Library call successful
    status = dbsqlexec (rmtproc);
else

  // If an attention event was issued or if the previous DB-Library
  // call was not successful, acknowledge and send a results
  // completion message to the client.

    srv_senddone (srvproc, SRV_DONE_FINAL, (DBUSMALLINT) 0,
         (DBINT) 0);
  5. Get the remote database results and pass them back to the client using the handle_results function:
    handle_results (rmtproc, srvproc);

    (For more information about this function, see Receiving Results from a Remote Database.

  6. Return the srv_continue constant to continue processing events:
    return (SRV_CONTINUE);


Handling a Remote Stored Procedure Event

This example shows how the rpc_execute callback function in GATECBS.C sends a remote stored procedure to, and receives results from, a remote database.

  1. Define the rpc_execute function and the following parameters:
    DBPROCESS *rmtproc;     // DBPROCESS pointer
int i;                  // Index variable
short params;
short retparam;
short *paramarray;
DBCHAR complete_rpc_name[4 * (MAXNAME  1)];//Database.owner.name;#
  2. Get the remote DBPROCESS pointer *rmtproc in the SRV_PROC connection structure with srv_getuserdata. This is a pointer that was saved using srv_setuserdata after the client connected to a remote database.
    rmtproc = ((REMOTE_DBMS *)srv_getuserdata(srvproc))->dbproc;
paramarray = ((REMOTE_DBMS *)srv_getuserdata(srvproc))->retparams;
  3. Get the remote stored procedure name and initialize the remote stored procedure to the remote database management system:
    dbrpcinit(rmtproc, complete_rpc_name,
    (DBUSMALLINT)srv_rpcoptions(srvproc));

// Set up any RSP parameters.

params = srv_rpcparams(srvproc);
retparam = 1;
for (i = 1; i <= params; i+)
{
    rpc_paramname = srv_paramname(srvproc, i, (int *)NULL);
    if (!strlen(rpc_paramname))
        rpc_paramname = NULL;
    rpc_paramstatus = (BYTE)srv_paramstatus(srvproc, i);
    rpc_paramtype = srv_paramtype(srvproc, i);
    rpc_parammaxlen = srv_parammaxlen(srvproc, i);
    rpc_paramlen = srv_paramlen(srvproc, i);
    rpc_paramdata = srv_paramdata(srvproc, i);
    dbrpcparam(rmtproc,rpc_paramname,rpc_paramstatus,rpc_paramtype,
        rpc_parammaxlen,rpc_paramlen, rpc_paramdata);

// Not all parameters are return parameters. Map each return
// parameter to its original parameter to later reset the return
// value of the correct return parameters in "handle_results()".

if((BYTE)srv_paramstatus(srvproc, i) & SRV_PARAMRETURN) {
      paramarray[retparam] = i;
      retparam+;
}
  4. Send the remote stored procedure to the remote database using the DB-Library dbrpcsend function:
    dbrpcsend(rmtproc);
dbsqlok(rmtproc);
  5. Get the remote database results and pass them back to the client using the handle_results function:
    handle_results(rmtproc, srvproc);
return (SRV_CONTINUE);


Receiving Results from a Remote Database

This example uses the handle_results callback function, which processes results from the remote database and sends them to the client.

  1. Define the function and the function parameters for handle_results:
    int handle_results (rmtproc, srvproc)
DBPROCESS   FAR * rmtproc;    // DBPROCESS handle
                              // to the remote database
SRV_PROC    FAR * srvproc;    // Process handle to send
                              // results to the client

{
    short    cols;            // Data columns returned
    int      i;               // Index variable
    DBINT    rows;            // Number of rows sent
    BOOL     results_sent;    // Number of results sets sent
    BOOL     gotcompute;      // COMPUTE row indicator
    short *  paramarray;      // Return parameters
    RETCODE  returnvalue;     // Value returned from
                              // DB-Library calls
  2. Use the DB-Library dbresults callback function to loop through each results set. Since a command can consist of multiple commands or a single command that has multiple results sets, use a WHILE loop to process each results set:
    // Process the results from the remote database.

while (TRUE)
{
       returnvalue = dbresults (rmtproc);
       if (returnvalue == NO_MORE_RESULTS)
           break;
}
  3. Get the number of data columns in the row using the DB-Library dbnumcols function, and describe each column in the row using the srv_describe function:
    cols = dbnumcols (rmtproc); // How many data columns
                            // are in the row?
for (i = 1; i <= cols; i+) // Call srv_describe for each column

{
     srv_describe (srvproc,
                   i,
                   dbcolname (rmtproc, i),
                   SRV_NULLTERM,
                   (DBINT)dbcolntype (rmtproc, i),
                   dbcollen (rmtproc, i),
                   (DBINT)dbcolntype (rmtproc, i),
                   dbcollen (rmtproc, i),
                   (BYTE *)NULL);
}

    You may also need to use srv_setutype to set the user-defined datatype information for a column. For more information, see the GATEWAY sample application.

  4. Set the address of the column data using srv_setcoldata and the length of the column data using srv_setcollen. Move the row from the remote database to the client using the srv_sendrow function:
    rows = 0;  // Initialize a counter for the row number.
while (TRUE)

{
       returnvalue = dbnextrow (rmtproc);
       if (returnvalue == NO_MORE_ROWS)   // No more rows so exit
                                          // loop, set the DONE
                                          // status, and exit.
            break;

       // Move the row from the remote database to the client.

       for (i = 1; i <= cols; i+)

       {
            srv_setcollen (srvproc, i,
                 (short)dbdatlen (rmtproc, i));
            srv_setcoldata (srvproc, i, dbdata(rmtproc, i));
        }

        // Send the row to the client.

       if (srv_sendrow (srvproc) == SUCCEED)
           rows+;                        // Go to the next row.
}
  5. Determine if the count value in the remote database is relevant and, if so, pass it to the client. Send a completion message for the current results set:
    if (dbnumcols (rmtproc) > 0)
    rows = DBCOUNT(rmtproc)  0L ? 0L: rows;
else
{
    rows = DBCOUNT (rmtproc);

   // Now set the flag so a completion message is sent for the
   // current results set.
   results_sent = TRUE;

}

// Send the final done packet for the execution of the command
// batch. The previous batch was one that might have returned
// rows, so set the DONE status accordingly.
if (rows > 0)
    srv_senddone (srvproc,
              SRV_DONE_COUNT | SRV_DONE_FINAL,
              (DBUSMALLINT) 0,
              rows);
else
    srv_senddone (srvproc,
              SRV_DONE_FINAL,
              (DBUSMALLINT) 0,
              (DBINT) 0);
  6. Once a set of results has been retrieved from the remote database, a completion message must be sent to the client for the last results set retrieved. This must be done before another set of results can be obtained.
    // If this is the second time through the loop, send a completion
// message to the client for the previous results set sent.
    if (results_sent == TRUE)
      {  // If the previous batch returned rows, set
         // the DONE status accordingly.
         if (rows > 0)
              srv_senddone (srvproc,
                        SRV_DONE_MORE | SRV_DONE_COUNT,
                        (DBUSMALLINT)0,
                        rows);
         else
              srv_senddone (srvproc,
                        SRV_DONE_MORE,
                        (DBUSMALLINT)0,
                        (DBINT) 0);
         }


Chapter 4 Functions and Macros

Functions and Macros

srv_alloc

srv_bmove

srv_bzero

srv_clearstatistics

srv_config

srv_config_alloc

srv_convert

srv_describe

srv_errhandle

srv_event

SRV_EVENTDATA

srv_free

SRV_GETCONFIG

SRV_GETSERVER

srv_getuserdata

SRV_GOT_ATTENTION

srv_handle

srv_impersonate_client

srv_init

SRV_IODEAD

srv_langcpy

srv_langlen

srv_langptr

srv_log

srv_message_handler

srv_paramdata

srv_paramlen

srv_parammaxlen

srv_paramname

srv_paramnumber

srv_paramset

srv_paramstatus

srv_paramtype

srv_pfield

srv_post_handle

srv_pre_handle

srv_returnval

srv_revert_to_self

srv_rpcdb

srv_rpcname

srv_rpcnumber

srv_rpcoptions

srv_rpcowner

srv_rpcparams

srv_run

srv_senddone

srv_sendmsg

srv_sendrow

srv_sendstatistics

srv_sendstatus

srv_setcoldata

srv_setcollen

srv_setevent

srv_setuserdata

srv_setutype

srv_sfield

srv_symbol

SRV_TDSVERSION

srv_terminatethread

srv_willconvert


srv_alloc

Allocates memory dynamically.

Syntax

void * srv_alloc ( DBINT size );

where

size
Specifies the number of bytes to allocate.

Returns

A pointer to the newly allocated space. If size bytes cannot be allocated, a null pointer is returned.

Remarks

Use the srv_free function to free memory allocated by srv_alloc. The srv_alloc function is provided for backward compatibility with earlier versions of Open Data Services. It is equivalent to the Win32 GlobalAlloc function. Normal Win32 or C run-time memory management functions can be used in an Open Data Services application.

See Also

This entry | For information about
srv_bmove | Copying bytes to memory
srv_bzero | Setting memory contents to zero
srv_errhandle | Listing Open Data Services errors
srv_free | Freeing allocated memory
srv_getuserdata | Getting a pointer to private data space in a server process


srv_bmove

Copies bytes from one memory location to another.

Syntax

int srv_bmove (
void * from,
void * to,
DBINT count );

where

from
Is a pointer to the source of the data to be copied.
to
Is a pointer to the destination of the data to be copied.
count
Specifies the number of bytes to copy from the source to the destination.

Returns

SUCCEED if the move was successful; otherwise, FAIL.

Remarks

The values for from and to must be valid non-null pointers. Only count bytes are moved and no null-terminator is added. The srv_bmove function is provided for backward compatibility with earlier versions of Open Data Services. It is equivalent to the memcpy function.

See Also

This entry | For information about
srv_alloc | Allocating memory dynamically
srv_bzero | Setting memory contents to 0


srv_bzero

Sets the contents of a memory location to 0.

Syntax

int srv_bzero (
void * location,
DBINT count );

where

location
Is a pointer to the source of the data to be set to 0.
count
Specifies the number of bytes to set to 0.

Returns

SUCCEED if the memory was successfully set to 0; otherwise, FAIL.

Remarks

The memory location must be a valid non-null pointer. The srv_bzero function is provided for backward compatibility with earlier versions of Open Data Services. It is equivalent to the memset function.

See Also

This entry | For information about
srv_bmove | Copying bytes to memory


srv_clearstatistics

Clears the statistical counters kept by Open Data Services and resets them to 0.

Syntax

srv_clearstatistics ( SRV_PROC * srvproc );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection. The srvproc parameter contains the information that the Open Data Services Library uses to manage communication and data between the application and the client.

Returns

SUCCEED if the statistical counters were cleared; otherwise, FAIL.

See Also

This entry | For information about
srv_sendstatistics | Reporting Open Data Services statistics


srv_config

Sets server configuration parameters.

Syntax

int srv_config (
SRV_CONFIG * config,
DBINT option,
DBCHAR * value,
int valuelen );

where

config
Is a pointer to the SRV_CONFIG structure, which contains the values for the configuration options used by the Open Data Services application. Before issuing srv_config, config must first be allocated with srv_config_alloc.
option
Specifies which of the following configuration parameters to set:
SRV_ANSI_CODEPAGE
Specifies how Open Data Services handles character conversion for srv_sendrow and srv_sendmsg. Specify "FALSE" to convert all character data from ANSI to OEM (using the AnsiToOem function) before sending it to the client. Specify "TRUE" to not convert the data before sending it to the client. The default is "TRUE". These conversions do not affect English language characters but can affect extended characters (character positions 128-255) used in many languages.

It is recommended that extended stored procedures do not adjust this option, and always call srv_sendrow and srv_sendmsg with ANSI character strings. Open Data Services will handle any necessary character conversions to be consistent with the character set of SQL Server.

It is recommended that pass-through gateways to SQL Server set SRV_ANSI_CODEPAGE to "TRUE" to avoid any character conversion. DB-Library clients and SQL Server will handle any necessary character conversions.

For standalone Open Data Services applications with data that is already in ANSI form, and when you need to connect clients running MS-DOS, it is recommended that you set SRV_ANSI_CODEPAGE to "FALSE". ODS will convert your ANSI data to OEM before sending it to the client. Clients running MS-DOS will do no conversion, and clients running Windows and Windows NT can turn on AutoANSItoOEM. If your clients are running Windows and Windows NT only (none running MS-DOS), you can set SRV_ANSI_CODEPAGE to "TRUE" in your Open Data Services application, and turn off AutoANSItoOEM on the clients to avoid converting from ANSI to OEM at the server, and then from OEM back to ANSI at the client.

For standalone Open Data Services applications with data that is already in OEM form, it is recommended that you set SRV_ANSI_CODEPAGE to "TRUE" to avoid invalid character conversion. Clients running Windows and Windows NT can turn on AutoANSItoOEM.

For more information about DB-Library character set conversion and the AutoANSItoOEM client option, see Appendix A of the Microsoft SQL Server Programming DB-Library for C.

srv_connections
The maximum number of client connections that the server will accept. This value must be a positive integer; the default is 10.
SRV_DEFAULT_PACKETSIZE
The default TDS packet size used by the Open Data Services application and the client connection if the client did not request a specific TDS packet size.
srv_logfile
The name of the log file to which the server will write Open Data Services messages. The default name is SRV.LOG. Messages are added to the log file when an srv_log function is issued. To stop adding messages and close the open log file, set value to " " and valuelen to 0.
SRV_MAX_PACKETS
The maximum number of tabular data stream (TDS) packets that Open Data Services will read for each incoming client or server request. The default value is 128 packets, allowing for 64K of data per request when using the default TDS packet size of 512 bytes. If clients or servers receive error messages that some requests are too large, increase this value. (This is most likely to occur for remote stored procedure requests that pass a large amount of information.)
srv_max_packetsize
The maximum TDS packet size that Open Data Services will use for all Net-Library connections. This value can be from 512 to 65535; the default is 512. DB-Library clients that request a large TDS packet size via DBSETLPACKET will use either the requested TDS packet size or the value specified by srv_max_packetsize, whichever is smaller. A larger packet size allows the ODS Library to execute large client requests and server responses with fewer network operations.
srv_maxworkingthreads
The maximum number of working threads that can actively process client requests on the server at one time. This value must be a positive integer between 1 and 65535; the default is 255. This parameter limits the size of the active thread pool, not the number of client connections. (To limit client connections, see the SRV_CONNECTIONS option.)
srv_minworkingthreads
The minimum number of worker threads available to process client requests when the application is idle. This value must be a positive integer between 1 and 65535; the default is 32.
SRV_REMOTE_ACCESS
Must be set to "TRUE" to allow SYBASE®- and OS/2-based SQL Servers to access the Open Data Services server application; the default is "TRUE". Specify "FALSE" to deny access to these types of servers.
SRV_REMOTE_CONNECTIONS
The maximum number of individual remote stored procedure requests that the Open Data Services server application will accept from SYBASE- and OS/2-based SQL Server sites at one time; the default is 20. Each SYBASE- or OS/2-based SQL Server site that establishes a session with Open Data Services can send multiple remote stored procedure requests. This parameter limits the total number of simultaneous, requests from all sites.
SRV_REMOTE_SITES
The maximum number of active sessions that the Open Data Services server application can establish with individual SYBASE- and OS/2-based SQL Server sites at one time; the default is 10. Each SYBASE- or OS/2-based SQL Server site can establish a single session with Open Data Services. This parameter limits the total number of simultaneous sessions.
srv_stacksize
The stack space size to be allocated for each new connect event. The default is 4096 bytes. For each new client connection, the ODS Library allocates a separate stack, reserving an area for client connection information and for client callback functions. Normally the default stack size is sufficient. However, some developer-defined callback functions might require a larger stack space in order to operate properly. SRV_STACKSIZE allows you to adjust the stack size allocated to each client connection thread.
SRV_THREADPRIORITY
The thread priority (within a priority class) of every Open Data Services thread. It must be one of the following values:

SRV_PRIORITY_LOW: 2 points below normal priority

SRV_PRIORITY_NORMAL: Normal thread priority

SRV_PRIORITY_HIGH: 2 points above normal priority

SRV_PRIORITY_REALTIME: Highest possible priority

The default value is SRV_PRIORITY_NORMAL.

srv_threadtimeout
The number of minutes that worker threads and networking threads can remain idle before they time out and exit. This value must be a positive integer between 1 and 65535; the default is 15. A thread is forced to exit if it remains idle for the specified time-out value. This parameter allows a decrease in network and worker threads during idle processing.
value
Is a character string that provides the value for the configuration option. Specifying 0 sets option to its default value.
valuelen
Indicates the length, in bytes, of the value string. If valuelen is SRV_NULLTERM, then the value string is expected to be null terminated and valuelen is ignored.

Returns

SUCCEED or FAIL.

Remarks

All configuration options have default values. The srv_config function is not required unless configuration option values differ from the default values. The log file can be changed at any time by calling srv_config with the log file option and specifying a new filename for value. Open Data Services sets the valuelen to 0 and uses the string in value.

All thread configuration parameters can be changed at any time by calling SRV_GETCONFIG and then srv_config again, specifying new values, which take effect immediately. Changes to SRV_CONNECTIONS, SRV_MAX_PACKETS, SRV_REMOTE_ACCESS, SRV_REMOTE_CONNECTIONS, and SRV_REMOTE_SITES do not take effect until you re-start the Open Data Services application.

The options SRV_REMOTE_ACCESS, SRV_REMOTE_CONNECTIONS, and SRV_REMOTE_SITES apply only when the Open Data Services server application is servicing incoming requests from SYBASE SQL Server or Microsoft SQL Server for OS/2. Because these servers can make multiple requests in a single session, option parameters are provided to prevent one or more servers from consuming the resources of the Open Data Services server application. With Microsoft SQL Server for Windows NT, individual remote stored procedure requests are handled by Open Data Services as separate client sessions, eliminating the potential for resource contention problems.

Open Data Services uses a pool of working threads to process client requests.

At least one worker thread must be available to process active client requests. If the number of client connections exceeds the maximum number of available worker threads specified with SRV_MAXWORKINGTHREADS, Open Data Services will continue to accept client connections by placing them in a queue until they can be serviced by available threads from the thread pool. Threads are subject to time-outs and will exit if they are idle beyond the specified time-out value, in order to minimize processing overhead when the application is idle.

See Also

This entry | For information about
srv_config_alloc |  | Allocating an Open Data Services server configuration structure
srv_event |  | Activating an event
SRV_GETCONFIG |  | Accessing an Open Data Services server configuration structure
srv_init |  | Initializing an Open Data Services server application
srv_log |  | Writing a message to the Open Data Services server log file
srv_run |  | Starting an Open Data Services server application


srv_config_alloc

Allocates and initializes a SRV_CONFIG structure.

Syntax

SRV_CONFIG * srv_config_alloc ( );

Returns

A pointer to a SRV_CONFIG structure, or NULL if insufficient memory is available.

Remarks

The SRV_CONFIG structure contains configuration parameters for the Open Data Services server application. Once an SRV_CONFIG structure is allocated, configuration parameters can be set with srv_config.

The SRV_CONFIG structure is needed only when initializing the Open Data Services server application with srv_init. Once srv_init uses this structure, the SRV_CONFIG structure can be freed with srv_free.

See Also

This entry | For information about
srv_config | Setting the server configuration parameters
srv_free | Freeing allocated memory
srv_init | Initializing an Open Data Services server application


srv_convert

Changes data from one datatype to another.

Syntax

int srv_convert (
SRV_PROC * srvproc,
int srctype,
void * src,
DBINT srclen,
int desttype,
void * dest,
DBINT destlen );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection. The structure contains all the control information that Open Data Services uses to manage communications and data between the Open Data Services server application and the client. If the srvproc handle is supplied, it is passed to the Open Data Services error handler function when an error occurs.
srctype
Specifies the datatype of the data to be converted. This parameter can be any of the Open Data Services datatypes.
src
Is a pointer to the data to be converted. This parameter can be any of the Open Data Services datatypes.
srclen
Specifies the length, in bytes, of the data to be converted. If srclen is 0, srv_convert places a null value in the destination variable. Unless it is 0, this parameter is ignored for fixed-length datatypes, in which case the source data is assumed to be NULL. For data of the SRVCHAR datatype, a length of -1 indicates that the string is null-terminated.
desttype
Specifies the datatype to convert the source to. This parameter can be any of the Open Data Services datatypes.
dest
Is a pointer to the destination variable that receives converted data. If this pointer is NULL, srv_convert calls the user-supplied error handler (if any) and returns FAIL.

If desttype is SRVDECIMAL or SRVNUMERIC, the dest parameter must be a pointer to a DBNUMERIC or DBDECIMAL structure with the precision and scale fields of the structure already set to the desired values. You can use DEFAULTPRECISION to specify a default precision and DEFAULTSCALE to specify a default scale.

destlen
Specifies the length, in bytes, of the destination variable. This parameter is ignored for fixed-length datatypes. For a destination variable of type srvchar, the value of destlen must be the total length of the destination buffer space. A length of -1 for a destination variable of type srvchar or srvbinary indicates that there is sufficient space available. For a destination variable of type srvchar, a length of -1 causes the character string to be null-terminated.

Returns

The length of the converted data, in bytes, if the datatype conversion succeeds. When srv_convert encounters a request for a conversion that it doesn't support, it calls the developer-supplied error handler (if any), sets a global error number, and returns FAIL.

Remarks

Conversion to and from all Open Data Services datatypes is supported, except for conversion from SRVDATETIME or SRVDATETIME4 to these datatypes, and from these datatypes to SRVDATETIME or SRVDATETIME4:

  • SRVINT1, SRVINT2, SRVINT4
  • SRVFLT4, SRVFLT8
  • SRVBIT
  • SRVMONEY, SRVMONEY4
  • SRVDECIMAL, SRVNUMERIC

The srv_willconvert function determines whether a particular conversion is allowed.

Converting to the approximate numeric datatypes SRVFLT4 or SRVFLT8 can result in some loss of precision. Converting from the approximate numeric datatypes SRVFLT4 or SRVFLT8 to SRVCHAR or SRVTEXT can also result in some loss of precision.

Converting to SRVFLTx, SRVINTx, SRVMONEY, SRVMONEY4, SRVDECIMAL, or SRVNUMERIC can result in overflow if the number is larger than the destination's maximum value, or in underflow if the number is smaller than the destination's minimum value. If overflow occurs when converting to SRVCHAR or SRVTEXT, the first character of the resulting value contains an asterisk (*) to indicate the error.

When converting SRVCHAR to SRVBINARY, srv_convert interprets SRVCHAR as hexadecimal, whether or not the string contains a leading 0. When converting SRVBINARY to SRVCHAR, srv_convert creates a hexadecimal string without a leading 0. In all other cases, a conversion to or from the SRVBINARY datatype is a straight bit-copy.

In certain cases, it can be useful to convert a datatype to itself. For example, converting SRVCHAR to SRVCHAR with a destlen of -1 adds a null terminator to a string.

The srv_convert function can fail for several reasons:

  • the requested conversion is not available
  • the conversion resulted in truncation, overflow, or loss of precision in the destination variable
  • a syntax error occurred while converting a character string to a numeric datatype.

See Also

This entry | For information about
srv_describe | Describing a result row column
srv_errhandle | Listing Open Data Services errors
srv_setutype | Setting datatypes columns in rows
srv_willconvert | Determining available datatype conversions
Datatypes | Open Data Services datatypes


srv_describe

Defines a row's column name, and source and destination datatypes.

Syntax

int srv_describe (
SRV_PROC * srvproc,
int colnumber,
DBCHAR * columnname,
int namelen,
DBINT desttype,
DBINT destlen,
DBINT srctype,
DBINT srclen,
void * srcdata );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the client that is sending the row). The structure contains all the information that the Data Services Library uses to manage communications and data between the Open Data Services server application and the client.
colnumber
Is currently not supported. Columns must be described in order. All columns must be described before srv_sendrow is called.
columnname
Specifies the name of the column to which the data belongs. This parameter can be NULL, since a column is not required to have a name.
namelen
Specifies the length, in bytes, of columnname. If namelen is SRV_NULLTERM, then the columname string must be null-terminated.
desttype
Specifies the datatype of the destination row column (the datatype sent to the client). The datatype must be specified even if the data is NULL (see Datatypes.)
destlen
Specifies the length, in bytes, of the data to be sent to the client. For fixed-length datatypes that don't allow null values, destlen is ignored. For variable-length datatypes and fixed-length datatypes that allow null values, destlen specifies the maximum length that the destination data can be.
srctype
Specifies the datatype of the source data.
srclen
Specifies the length, in bytes, of the source data. This value is ignored for fixed-length datatypes.
srcdata
Provides the source data address for a particular column. When srv_sendrow is called, it looks for the data for colnumber at srcdata. The source data address can be changed between calls to srv_sendrow by using srv_setcoldata.

If desttype is SRVDECIMAL or SRVNUMERIC, the srcdata parameter must be a pointer to a DBNUMERIC or DBDECIMAL structure with the precision and scale fields of the structure already set to the desired values. You can use DEFAULTPRECISION to specify a default precision and DEFAULTSCALE to specify a default scale.

Returns

The number of the column that has been described. The first column is column 1. If an error occurs, returns 0.

Remarks

The srv_describe function must be called once for each column in the row before the first call to srv_sendrow. The columns of a row can be described in any order.

To change the location and length of the source data in column rows before the complete results set has been sent, use srv_setcoldata and srv_setcollen, respectively.

The ODS Library automatically performs data conversion between srctype and desttype.

See Also

This entry | For information about
srv_convert | Converting datatypes and supported conversions
srv_sendrow | Sending rows to a client
srv_setcoldata | Setting the address for a column's data
srv_setutype | Setting datatype columns in rows and datatypes that are available


srv_errhandle

Installs a developer-supplied error handler for Open Data Services errors.

Syntax

SRV_ERRHANDLE_PROC srv_errhandle ( SRV_ERRHANDLE_PROC handler );

where

handler
Is a pointer to the function that is called whenever an Open Data Services error occurs (for example, when memory is insufficient during processing). The ODS Library can use a default error handler or a developer-supplied error handler. If the Open Data Services server application uses a developer-supplied error handler, a set of predefined parameters must be used. For a list of these parameters, see the "Remarks" section later in this entry.

Returns

A pointer to the previously installed error-handling function.

Remarks

When an error occurs, Open Data Services automatically calls the error handler installed by srv_errhandle. The error handler determines the Open Data Services server application's response to errors. For example, it can tell the Open Data Services server application whether to continue, to return an error, or to terminate the connection.

If no error handler is installed, then a default error handler is used. The default error handler writes messages to the standard error output and to the Open Data Services log file.

If the severity of the error is 1 through 9, then an informational message is assumed and the default error handler returns SRV_CONTINUE (continue processing). If the severity of the error is 10 through 18, then an error condition is assumed and the default error handler returns SRV_CANCEL (and returns FAIL to the invoking function). If the severity of the error is 19 or higher, then some form of fatal error is assumed, and the default error handler returns SRV_EXIT, which terminates the thread associated with this client connection. (Error numbers and severities are defined in the Open Data Services header file SRVCONST.H.)

A developer-supplied error handler is invoked with the following parameters defined. These parameters are provided by the ODS Library whenever it detects an internal error:

Parameter | Meaning
server | The affected Open Data Services server application process.
srvproc | The affected client process.
srverror | The Open Data Services error number.
severity | The severity of the error: informational (SRV_INFO), fatal for the client process (SRV_FATAL_PROCESS), or fatal for the Open Data Services server application (SRV_FATAL_SERVER).
state | The state of the error.
oserr | The operating-system error number.
errtext | A printable description of the Open Data Services error.
errtextlen | The length of the Open Data Services error string errtext.
oserrtext | A printable description of the operating-system error string oserr.
oserrtextlen | The length of the operating-system error string oserr.

One of the following values should be returned by a developer-supplied error handler:

Return value | Meaning
SRV_CONTINUE | Pass a non-fatal error or an information message from the Open Data Services server application to the client and continue processing.
SRV_CANCEL | Return SRV_FAIL from the Open Data Services function that caused the error.
SRV_EXIT | Print an error message and terminate the client connection thread.

A developer-defined error handler can be installed at any time. The new handler automatically replaces an existing handler. To remove an existing error handler and install the default error handler, use srv_errhandle with a null parameter.

See Also

This entry | For information about
srv_convert | Converting datatypes
srv_sendmsg | Sending Open Data Services errors to the client


srv_event

Activates a client event.

Syntax

int srv_event (
SRV_PROC * srvproc,
int event,
void * data );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection. The structure contains all the information that the Data Services Library uses to manage communications and data between the Open Data Services server application and the client.
event
Indicates the event to activate. This value can be SRV_DISCONNECT, SRV_EXIT, or SRV_STOP.
data
Is a pointer to data supplied by the Open Data Services developer. The data is available in the event handler for the specified event when srv_event is called. It is accessed with SRV_EVENTDATA. The pointer can be NULL.

Returns

The value of the requested event, or -1 if an error occurs.

Remarks

Events are usually activated automatically based on client and server requests. However, events can be activated from within an Open Data Services server application by using srv_event.

Only these events can be invoked using srv_event:

  • SRV_DISCONNECT, which disconnects the specified srvproc client connection, regardless of whether additional client events are pending.
  • SRV_STOP, which disables new logins and then waits until all users have exited before shutting down the ODS server. The necessary server information is obtained from srvproc.
  • SRV_EXIT, which shuts down the ODS server immediately, regardless of whether further client events are pending. The necessary server information is obtained from srvproc.

The srv_handle function specifies which event handler to call when an event occurs. If no handler is defined for a particular event, the Open Data Services server application's default event handler is called.

Data can be passed to event handlers or to any event. The data is made available with the SRV_EVENTDATA macro.

To activate an ODS event without a SRV_PROC client connection, call the srv_setevent function.

See Also

This entry | For information about
SRV_EVENTDATA | Accessing event-handler data
srv_handle | Installing an event handler
srv_setevent | Activating a global ODS event


SRV_EVENTDATA

Accesses event-handler data passed by srv_event.

Syntax

void * SRV_EVENTDATA ( SRV_PROC * srvproc );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the event).

Returns

A pointer to the event data area in the SRV_PROC structure being passed data by srv_event. The pointer can be NULL.

Remarks

Sometimes an event contains data supplied by the Open Data Services developer. A pointer to this data can be made available to the event handler using SRV_EVENTDATA. This data can be passed to event handlers for any event supported by the srv_event function.

See Also

This entry | For information about
srv_event | Activating an event


srv_free

Frees memory allocated with srv_alloc or srv_config_alloc.

Syntax

int srv_free ( void * ptr );

where

ptr
Is a pointer to the source of the data to be freed.

Returns

SUCCEED if the memory was successfully freed; otherwise, FAIL.

Remarks

Memory allocated with srv_alloc or srv_config_alloc is not freed unless you free it using srv_free. The srv_free function is provided for backward compatibility with earlier versions of Open Data Services. It is equivalent to the Win32 GlobalFree function.

See Also

This entry | For information about
srv_alloc | Allocating memory dynamically
srv_config_alloc | Allocating an SRV_CONFIG structure


SRV_GETCONFIG

Accesses an Open Data Services server application's configuration structure.

Syntax

SRV_CONFIG * SRV_GETCONFIG ( SRV_SERVER * server );

where

server
Is a pointer to the SRV_SERVER structure associated with the desired SRV_CONFIG element.

Returns

A pointer to the Open Data Services server application's SRV_CONFIG structure. If insufficient memory or an invalid server is specified, returns NULL.

Remarks

The SRV_CONFIG structure configures the Open Data Services server application on initialization. A copy of that structure is found in the SRV_SERVER structure. The SRV_GETCONFIG macro returns a pointer to this SRV_SERVER copy of the SRV_CONFIG structure.

The pointer to SRV_CONFIG can be passed to srv_config to change configuration parameters.

See Also

This entry | For information about
srv_config | Setting Open Data Services configuration parameters
SRV_GETSERVER | Returning a pointer to the server being used by a client


SRV_GETSERVER

Returns a pointer to the SRV_SERVER structure being used by a client.

Syntax

SRV_SERVER * SRV_GETSERVER ( SRV_PROC * srvproc );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection.

Returns

A pointer to SRV_SERVER. If srvproc is not valid, returns NULL.

Remarks

Every client process has an SRV_PROC structure that contains client login information, the Open Data Services server application name, the event list, and a pointer to the SRV_SERVER structure.

The SRV_GETSERVER macro accesses the pointer to the SRV_SERVER structure within the SRV_PROC structure.

See Also

This entry | For information about
SRV_GETCONFIG | Accessing a server's configuration structure
srv_sfield | Returning a field from an SRV_SERVER structure


srv_getuserdata

Returns a pointer to private data space in an SRV_PROC structure.

Syntax

void * srv_getuserdata ( SRV_PROC * srvproc );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection. The structure contains all of the necessary control information that the Open Data Services server application uses to manage communications and data between the Open Data Services server application and the client.

Returns

A generic pointer to the private data space in the SRV_PROC structure. If an error occurs or if nothing is set with srv_setuserdata, returns NULL.

Remarks

Events associated with a client connection's SRV_PROC are activated either by a client request or by an Open Data Services request. A pointer to the activating event can be set by the srv_setuserdata function. This pointer to private data can be retrieved with srv_getuserdata.

Open Data Services server applications should be reentrant and avoid using global or static variables. Using private data eliminates the need for global or static variables.

See Also

This entry | For information about
srv_setuserdata | Saving a pointer to private data space in an SRV_PROC structure


SRV_GOT_ATTENTION

Determines whether an attention event has occurred.

Syntax

BOOL SRV_GOT_ATTENTION ( SRV_PROC * srvproc );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle receiving an attention event).

Returns

TRUE if an attention event is received; otherwise, FALSE.

Remarks

Attention events are serviced as soon as they are detected. The handler for the attention event is called automatically when an attention event is detected.

When a client sends an attention event to an Open Data Services server application, an attention flag is set in the receiving SRV_PROC structure. This flag is normally set as a result of a client call to the DB-Library function dbcancel. The attention flag is cleared when srv_senddone is called.

See Also

This entry | For information about
srv_handle | Installing an event handler


srv_handle

Installs a standard event handler for an ODS application.

Syntax

SRV_HANDLE_PROC srv_handle (
SRV_SERVER * server,
DBINT event,
SRV_HANDLE_PROC handler );

where

server
Is a pointer to the SRV_SERVER structure. Use srv_init to get this pointer.
event
Specifies the event that is assigned to handler. All ODS events are valid. For a list of ODS events, see Appendix B, "Events and Event Types."
handler
Is a pointer to the function that is called when the event defined by event occurs. This function is global to the ODS application and will be called every time event occurs.

This function should be defined as returning an int and taking a single parameter. This parameter should be defined as SRV_SERVER * when event is one of the following:

  • SRV_EXIT
  • SRV_START
  • SRV_SLEEP
  • SRV_RESTART
  • SRV_STOP

and should be defined as SRV_PROC * when event is one of the following:

  • SRV_ATTENTION
  • SRV_CONNECT
  • SRV_DISCONNECT
  • SRV_LANGUAGE
  • SRV_RPC

This function must return one of the following values:
Return value | Description
SRV_CONTINUE | Continue normal processing
SRV_DISCONNECT | Fires a disconnect event to close the client connection
SRV_EXIT | Fires a disconnect event to close the client connection

Returns

A pointer to the previously defined event-handling function.

Remarks

When an event occurs, ODS calls the following functions in this order:

  1. The pre-event handler (installed by srv_pre_handle)
  2. The standard event handler (installed by srv_handle)
  3. The post-event handler (installed by srv_post_handle)

Each ODS event has a default standard event handler which returns SRV_CONTINUE. Installing a standard event handler with srv_handle replaces the default handler with one supplied by the application.

You can install standard event handlers dynamically. The new standard event handler is called when the next event occurs. An ODS application can have one standard event handler for each event. Open Data Services will automatically remove the event handler when necessary; your program should not attempt to do this.

See Also

This entry | For information about
srv_event | Adding an event request
srv_pre_handle | Installing a pre-event handler.
srv_post_handle | Installing a post-event handler.


srv_impersonate_client

Impersonates the security context of a client connection.

Syntax

int srv_impersonate_client ( SRV_PROC * srvproc );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection. The srvproc parameter contains the information that the Open Data Services Library uses to manage communication and data between the application and the client.

Returns

SUCCEED if the security context of the client connection was impersonated; otherwise, FAIL.

Remarks

After calling srv_impersonate_client, the Open Data Services application can perform operations on a client's behalf, using the security context of the client connection. This is called "pass-through" security. To stop impersonating the client connection, call srv_revert_to_self.

Using srv_impersonate_client for "pass-through" security simplifies the setup and administration of security procedures because:

  • The Open Data Services application can rely on existing Windows NT security measures.
  • The Open Data Services application does not need to maintain a separate security system.
  • The network administrator needs to be concerned about security only between the Open Data Services client and the resource the Open Data Services application is using on that client's behalf.

The srv_impersonate_client function currently supports impersonating client connections that use the named pipes or multi-protocol Net-Library.

See Also

This entry | For information about
srv_revert_to_self | Stopping impersonation of the security context of the client connection


srv_init

Initializes an Open Data Services server application.

Syntax

SRV_SERVER * srv_init (
SRV_CONFIG * config,
DBCHAR * servername,
int namelen );

where

config
Is a pointer to the SRV_CONFIG structure that contains the values for the configuration options used by the Open Data Services server application.
servername
Specifies the Registry key:

HKEY_LOCAL_MACHINE\
SOFTWARE\
Microsoft\
MSSQLServer\
servername

where Open Data Services can find the Windows NT Registry ListenOn value with the appropriate connection string data for this server application process. If no ListenOn multi-string value has been entered at the specified registration key or if servername is null, Open Data Services then looks in the registration key:

HKEY_LOCAL_MACHINE\
SOFTWARE\
Microsoft\
MSSQLServer\
Server

If this key also has no ListenOn value, then, by default, Open Data Services loads the named pipes server Net-Library DLL (SSNMPNTW.DLL) only, using the default named pipe \\.\pipe\sql\query.

The following example shows connection string data that might appear for a Windows NT ListenOn multi-string value:

SSNMPN60,\\.\PIPE\SQL\APPNAME
SSMSSO60,1433

The first connection string is an instruction to load the named pipes server Net-Library (SSNMPN60.DLL) with the pipe name \pipe\sql\appname. The second connection string is an instruction to load the TCP/IP sockets server Net-Library (SSMSSO60.DLL) with the TCP/IP port number 3180. You can use the Windows NT - based program regedt32 to view and edit the entries in the Windows NT Registry.

namelen
Specifies the length, in bytes, of servername. If the namelen parameter is SRV_NULLTERM, then the servername string must be null-terminated.

Returns

A pointer to an SRV_SERVER structure. If the server can't be initialized, returns NULL.

Remarks

The initialization process consists primarily of allocating the necessary data structures for the server and initializing the server state.

To use values other than the defaults, use the srv_config function before calling srv_init.

A server must be initialized before being started with srv_run.

See Also

This entry | For information about
srv_config | Setting the server configuration parameters
srv_config_alloc | Allocating an SRV_CONFIG structure
srv_run | Starting an Open Data Services server application


SRV_IODEAD

Determines whether an SRV_PROC input and output connection to a client is open.

Syntax

BOOL SRV_IODEAD ( SRV_PROC * srvproc );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that has the input and output connection to be tested).

Returns

TRUE if the client input and output connection's SRV_PROC structure is still open; otherwise, FALSE.

Remarks

This function is useful in error handling situations when you need to determine whether you can send an error message to a client.

In an SRV_DISCONNECT handler, SRV_IODEAD always returns TRUE.

See Also

This entry | For information about
srv_sendmsg | Sending a row to the client


srv_langcpy

Copies part of the language request buffer.

Syntax

long srv_langcpy (
SRV_PROC * srvproc,
long start,
long nbytes,
DBCHAR * buffer );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the language request). The structure contains the information that the ODS Library uses to manage communication and data between an Open Data Services server application and the client.
start
Indicates where to start copying characters from the request buffer. Command buffer characters are numbered beginning with 0.
nbytes
Specifies the number of bytes to copy. If nbytes is -1, srv_langcpy copies the number of bytes available in the request buffer. If there are less than nbytes bytes available to copy, srv_langcpy copies all the bytes in the request buffer.
buffer
Provides a DBCHAR pointer to the developer-supplied buffer in which to copy the bytes.

Returns

The number of bytes copied. If there is no current language request from the client, returns -1.

Remarks

The srv_langcpy function null-terminates the part of the language request buffer copied into buffer. This function assumes that buffer is large enough to handle (bytes 1) bytes. The request buffer can contain an ASCII string.

See Also

This entry | For information about
srv_langptr | Returning a pointer to the language request buffer
srv_langlen | Returning the length of the language request buffer


srv_langlen

Returns the length of the language request buffer.

Syntax

long srv_langlen ( SRV_PROC * srvproc );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the language request). The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.

Returns

The length, in bytes, of the language request buffer received from the client. If there is no current language request from the client, returns -1.

Remarks

All or part of the request buffer can be accessed using srv_langcpy.

See Also

This entry | For information about
srv_langcpy | Copying part of the language request buffer
srv_langptr | Returning a pointer to the language request buffer


srv_langptr

Returns a pointer to the language request buffer.

Syntax

void *srv_langptr ( SRV_PROC * srvproc );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the language request). The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.

Returns

A pointer to the beginning of the language buffer. If there is no language request, returns NULL.

Remarks

The language request buffer can contain an SQL string or an ASCII string. The Open Data Services server application determines which type of string is present and what to do with it.

See Also

This entry | For information about
srv_langcpy | Copying part of the language request buffer
srv_langlen | Returning the length of the language request buffer


srv_log

Writes a message to the Open Data Services log file.

Syntax

int srv_log (
SRV_SERVER * server,
BOOL datestamp,
DBCHAR * msg,
int msglen );

where

server
Is a pointer to the SRV_SERVER server structure being accessed by the Open Data Services server application.
datestamp
Specifies prefixes on each log message to mark the current date and time if the log message is TRUE. If FALSE, log messages do not get a date and time stamp.
msg
Contains the actual text of the message. Note that the newline character is added to the end of msg.
msglen
Specifies the length, in bytes, of msg. If msglen is SRV_NULLTERM, the msg string is expected to be null-terminated and msglen is ignored.

Returns

SUCCEED or FAIL.

Remarks

The default name of the log file is SRV.LOG. The name of the log file can be set with srv_config; the name of the log file can be found with srv_sfield.

The log file can be changed at any time. If the log file is changed, the current log file, if any, is closed and a new log file is opened.

Messages are always added to a log file if one exists.

See Also

This entry | For information about
srv_config | Setting the server configuration parameters
SRV_GETSERVER | Accessing a client's Open Data Services structure
srv_sfield | Returning a field from an SRV_SERVER structure


srv_message_handler

Calls the installed Open Data Services message handler. This function is usually used to call SQL Server from an extended stored procedure to log an error (defined by the extended stored procedure) in the SQL Server error log file and/or the Windows NT event log.

Syntax

int srv_message_handler (
SRV_PROC * srvproc,
int errornum,
BYTE severity,
BYTE state,
int oserrnum,
char * errtext,
int errtextlen,
char * oserrtext,
int oserrtextlen );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection. The srvproc parameter contains the information that the Open Data Services Library uses to manage communication and data between the application and the client.
errornum
Is an error number defined by the extended stored procedure. This number must be from 50,001 through 2,147,483,647. You can OR this error number with the following values to adjust the event type recorded in the Windows NT event log:
Value | Windows NT event type
0x40000000 | Informational
0x80000000 | Warning
0xC0000000 | Error

severity
Is a standard SQL Server severity value for the error. This number must be from 0 through 24.
state
Is a SQL Server state value for the error.
oserrnum
Is the operating-system error number.
errtext
Is the description of the extended stored procedure error errornum.
errtextlen
Is the length of the extended stored procedure error string errtext.
oserrtext
Is the description of the operating-system error oserrnum.
oserrtextlen
Is the length of the operating-system error string oserrtext.

Returns

SUCCEED or FAIL.

Remarks

The srv_message_handler function enables an extended stored procedure to integrate with the centralized error logging and reporting features of SQL Server. SQL Server alerts can be established for events from extended stored procedures, and SQLExecutive will monitor for these alert conditions.

See Also

This entry | For information about
srv_errhandle | Installing a developer-supplied error handler


srv_paramdata

Returns the value of a remote stored procedure call parameter.

Syntax

void * srv_paramdata (
SRV_PROC * srvproc,
int n );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the remote stored procedure call). The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
n
Indicates the number of the parameter. The first parameter is number 1.

Returns

A pointer to the parameter value. If the nth parameter is NULL, or if there is no nth parameter, or if there is no remote stored procedure, returns NULL.

Remarks

If you know the parameter name, you can use srv_paramnumber to get the parameter number. To determine whether a parameter is NULL, use srv_paramlen.

When a remote stored procedure call is made with parameters, the parameters can be passed by name or they can be passed by position (unnamed). If the remote stored procedure call is made with some parameters passed by name and some passed by position, an error occurs. If an error occurs, the SRV_RPC handler is still called, but it appears as if there were no parameters, and srv_rpcparams returns 0.

See Also

This entry | For information about
srv_paramlen | Returning the data length of a remote stored procedure parameter
srv_parammaxlen | Returning the maximum data length of a remote stored procedure parameter
srv_paramname | Returning the name of a remote stored procedure parameter
srv_paramnumber | Returning the number of a remote stored procedure parameter
srv_paramstatus | Returning the status of a remote stored procedure parameter
srv_paramtype | Returning the datatype of a remote stored procedure parameter
srv_rpcparams | Returning the number of parameters in a remote stored procedure


srv_paramlen

Returns the data length of a remote stored procedure call parameter.

Syntax

int srv_paramlen (
SRV_PROC * srvproc,
int n );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the remote stored procedure call). The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
n
Indicates the number of the parameter. The first parameter is 1.

Returns

The actual length, in bytes, of the parameter data. If there is no nth parameter or there is no remote stored procedure, returns -1. If the nth parameter is NULL, returns 0.

Remarks

Each remote stored procedure parameter has an actual and a maximum data length. For standard fixed-length datatypes that don't allow null values, the actual and maximum lengths are the same. For variable-length datatypes, the lengths can vary. For example, a parameter declared as varchar(30) can have data that is only 10 bytes long. The parameter's actual length is 10 and its maximum length is 30. The srv_paramlen function gets the actual data length, in bytes, of a remote stored procedure. To obtain the maximum data length of a parameter, use srv_parammaxlen.

When a remote stored procedure call is made with parameters, the parameters can be passed either by name or by position (unnamed). If the remote stored procedure call is made with some parameters passed by name and some passed by position, an error occurs. The SRV_RPC handler is still called, but it appears as if there were no parameters and srv_rpcparams returns 0.

See Also

This entry | For information about
srv_paramdata | Returning the value of a remote stored procedure parameter
srv_parammaxlen | Returning the maximum data length of a remote stored procedure parameter
srv_paramname | Returning the name of a remote stored procedure parameter
srv_paramnumber | Returning the number of a remote stored procedure parameter
srv_paramset | Setting the value of a remote stored procedure return parameter
srv_paramtype | Returning the datatype of a remote stored procedure parameter
srv_rpcparams | Returning the number of parameters in a remote stored procedure


srv_parammaxlen

Returns the maximum data length of a remote stored procedure call parameter.

Syntax

int srv_parammaxlen (
SRV_PROC * srvproc,
int n );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the remote stored procedure call). The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
n
Indicates the number of the parameter. The first parameter is 1.

Returns

The maximum length, in bytes, of the parameter data. If there is no nth parameter or if there is no remote stored procedure, returns -1.

Remarks

Each remote stored procedure parameter has an actual and a maximum data length. For standard fixed-length datatypes that don't allow null values, the actual and maximum lengths are the same. For variable-length datatypes, the lengths can vary. For example, a parameter declared as varchar(30) can have data that is only 10 bytes long. The parameter's actual length is 10 and its maximum length is 30. The srv_parammaxlen function gets the maximum data length of a remote stored procedure. To obtain the actual length of a parameter, use srv_paramlen.

When a remote stored procedure call is made with parameters, the parameters can be passed either by name or by position (unnamed). If the remote stored procedure call is made with some parameters passed by name and some passed by position, an error occurs. The SRV_RPC handler is still called, but it appears as if there were no parameters, and srv_rpcparams returns 0.

See Also

This entry | For information about
srv_paramdata | Returning the value of a remote stored procedure parameter
srv_paramlen | Returning the data length of a remote stored procedure parameter
srv_paramname | Returning the name of a remote stored procedure parameter
srv_paramnumber | Returning the number of a remote stored procedure parameter
srv_paramset | Setting the value of a remote stored procedure return parameter
srv_paramtype | Returning the datatype of a remote stored procedure parameter
srv_rpcparams | Returning the number of parameters in a remote stored procedure


srv_paramname

Returns the name of a remote stored procedure call parameter.

Syntax

DBCHAR * srv_paramname (
SRV_PROC srvproc,
int n,
int len );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the remote stored procedure). The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
n
Indicates the number of the parameter. The first parameter is 1.
len
Provides a pointer to an int variable that contains the length, in bytes, of the parameter name. If len is NULL, the length of the remote stored procedure parameter name is not returned.

Returns

A pointer to a null-terminated character string that contains the parameter name. The length of the parameter name is stored in len. If there is no nth parameter or if there is no remote stored procedure, returns NULL, len is set to -1, and an informational error message is sent. If the parameter name is NULL, len is set to 0 and a null-terminated empty string is returned.

Remarks

This function gets the name of a remote stored procedure call parameter. When a remote stored procedure call is made with parameters, the parameters can be passed either by name or by position (unnamed). If the remote stored procedure call is made with some parameters passed by name and some passed by position, an error occurs. The SRV_RPC handler is still called, but it appears as if there were no parameters, and srv_rpcparams returns 0.

See Also

This entry | For information about
srv_paramdata | Returning the value of a remote stored procedure parameter
srv_paramlen | Returning the data length of a remote stored procedure parameter
srv_parammaxlen | Returning the maximum data length of a remote stored procedure parameter
srv_paramnumber | Returning the number of a remote stored procedure parameter
srv_paramset | Setting the value of a remote stored procedure return parameter
srv_paramtype | Returning the datatype of a remote stored procedure parameter
srv_rpcparams | Returning the number of parameters in a remote stored procedure


srv_paramnumber

Returns the number of a remote stored procedure call parameter.

Syntax

int srv_paramnumber (
SRV_PROC * srvproc,
DBCHAR * name,
int namelen );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the remote stored procedure call). The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
name
Is a pointer to the parameter name.
namelen
Specifies the length of name. If name is null-terminated, set namelen to SRV_NULLTERM.

Returns

The parameter number of the named parameter. The first parameter is 1. If there is no parameter named name or if there is no remote stored procedure, 0 is returned and a message is generated.

Remarks

When a remote stored procedure call is made with parameters, the parameters can be passed either by name or by position (unnamed). If the remote stored procedure call is made with some parameters passed by name and some passed by position, an error occurs. The SRV_RPC handler is still called, but it appears as if there were no parameters, and srv_rpcparams returns 0.

See Also

This entry | For information about
srv_paramdata | Returning the value of a remote stored procedure parameter
srv_paramlen | Returning the data length of a remote stored procedure parameter
srv_parammaxlen | Returning the maximum data length of a remote stored procedure parameter
srv_paramname | Returning the name of a remote stored procedure parameter
srv_paramset | Setting the value of a remote stored procedure return parameter
srv_paramtype | Returning the datatype of a remote stored procedure parameter
srv_rpcparams | Returning the number of parameters in a remote stored procedure


srv_paramset

Sets the value of a remote stored procedure call return parameter.

Syntax

int srv_paramset (
SRV_PROC * srvproc,
int n,
void * data,
int len );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the remote stored procedure call). The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
n
Indicates the number of the parameter to set. The first parameter is 1.
data
Is a pointer to the data value to be sent back to the client as the remote stored procedure return parameter.
len
Specifies the actual length of the data to be returned. If the datatype of the parameter is one that is of a constant length and doesn't allow null values (for example, srvbit or srvint1), len is ignored.

Returns

SUCCEED if the parameter value was successfully set; otherwise, FAIL. FAIL is returned when there is no current remote stored procedure, when there is no nth remote stored procedure parameter, when the parameter is not a return parameter, and when the len argument isn't legal.

If len is 0, returns NULL. Setting len to 0 is the only way to return NULL to the client.

Remarks

Parameters contain data that is passed between clients and the Open Data Services server application with remote stored procedures. The client can specify certain parameters as return parameters. These return parameters can contain values that the Open Data Services server application passes back to the client. Using return parameters is analogous to passing parameters by reference.

You cannot set the return value for a parameter that wasn't invoked as a return parameter. You can use srv_paramstatus to determine how the parameter was invoked.

This function sets the return value for a parameter but it doesn't actually send the return value to the client. All return parameters, whether their return values have been set with srv_paramset or not, are automatically sent to the client when srv_senddone is called with the status flag SRV_DONE_FINAL set.

The srv_paramset function provides the only way to reset return parameters when the current client command is a remote stored procedure.

When a remote stored procedure call is made with parameters, the parameters can be passed either by name or by position (unnamed). If the remote stored procedure call is made with some parameters passed by name and some passed by position, an error occurs. The SRV_RPC handler is still called, but it appears as if there were no parameters, and srv_rpcparams returns 0.

See Also

This entry | For information about
srv_paramdata | Returning the value of a remote stored procedure parameter
srv_paramlen | Returning the data length of a remote stored procedure parameter
srv_parammaxlen | Returning the maximum data length of a remote stored procedure parameter
srv_paramname | Returning the name of a remote stored procedure parameter
srv_paramnumber | Returning the number of a remote stored procedure parameter
srv_paramstatus | Returning the status of a remote stored procedure parameter
srv_paramtype | Returning the datatype of a remote stored procedure parameter


srv_paramstatus

Returns the status of a particular remote stored procedure call parameter.

Syntax

int srv_paramstatus (
SRV_PROC * srvproc,
int n );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the remote stored procedure call). The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
n
Indicates the number of the parameter. The first parameter is number 1.

Returns

An int that contains status flags for the parameter. Currently, there is only one flag: If bit 0 is set to 1, the parameter is a return parameter. If there is no nth parameter or if there is no remote stored procedure, returns -1.

Remarks

This routine returns the status flags for a remote stored procedure call parameter.

Parameters contain data that is passed between clients and the Open Data Services server application with remote stored procedures. The client can specify certain parameters as return parameters. These return parameters can contain values that the Open Data Services server application passes back to the client.

Currently, the only status flag is one that indicates whether the parameter is a return parameter.

Open Data Services can use srv_paramset to set the value of a return parameter.

When a remote stored procedure call is made with parameters, the parameters can be passed either by name or by position (unnamed). If the remote stored procedure call is made with some parameters passed by name and some passed by position, an error occurs. If an error occurs, the SRV_RPC handler is still called, but it appears as if there were no parameters, and srv_rpcparams returns 0.

See Also

This entry | For information about
srv_paramdata | Returning the value of a remote stored procedure parameter
srv_paramlen | Returning the data length of a remote stored procedure parameter
srv_parammaxlen | Returning the maximum data length of a remote stored procedure parameter
srv_paramname | Returning the name of a remote stored procedure parameter
srv_paramnumber | Returning the number of a remote stored procedure parameter
srv_paramset | Setting the value of a remote stored procedure return parameter
srv_rpcparams | Returning the number of parameters in a remote stored procedure


srv_paramtype

Returns the datatype of a remote stored procedure call parameter.

Syntax

int srv_paramtype (
SRV_PROC * srvproc,
int n );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the remote stored procedure call). The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
n
Indicates the number of the parameter. The first parameter is 1.

Returns

A token value for the datatype of the parameter. A readable description for the value is available using srv_symbol. For a list of datatypes, see Datatypes. If there is no nth parameter or if there is no remote stored procedure, returns - 1.

Remarks

When a remote stored procedure call is made with parameters, the parameters can be passed either by name or by position (unnamed). If the remote stored procedure call is made with some parameters passed by name and some passed by position, an error occurs. The SRV_RPC handler is still called, but it appears as if there were no parameters, and srv_rpcparams returns 0.

See Also

This entry | For information about
srv_paramdata | Returning the value of a remote stored procedure parameter
srv_paramlen | Returning the data length of a remote stored procedure parameter
srv_parammaxlen | Returning the maximum data length of a remote stored procedure parameter
srv_paramname | Returning the name of a remote stored procedure parameter
srv_rpcparams | Returning the number of parameters in a remote stored procedure
srv_symbol | Converting a token value to a readable string


srv_pfield

Returns a field from an SRV_PROC structure.

Syntax

DBCHAR * srv_pfield (
SRV_PROC * srvproc,
int field,
int * len );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection. The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
field
Specifies the srvproc field to return. The following list provides the possible values for field and what these values return:
Field value | Returns
SRV_APPLNAME | The application name that the client supplied when it logged in to the Open Data Services server application.
SRV_BCPFLAG | A flag that is TRUE if the client is preparing for a bulk copy operation; otherwise, FALSE.
SRV_CLIB | The name of the library that enables the client to talk to a server.
SRV_CPID | The process ID of the client process on the client's source machine.
SRV_EVENT | The current event for srvproc.
SRV_HOST | The host name used by the srvproc client application when it logged on to the Open Data Services server application.
SRV_LIBVERS | The version of the client library.
SRV_LSECURE | A flag. TRUE if client connection is a trusted connection; otherwise, FALSE. For a gateway, TRUE if the client requested a trusted connection (for example, when a DB-Library client uses DBSETLSECURE). For an extended stored procedure, TRUE if SQL Server established a trusted connection.
SRV_NETWORK_MODULE | The name of the Net-Library DLL used for the current srvproc connection.
SRV_NETWORK_VERSION | The version of the Net-Library DLL used for the current srvproc connection.
SRV_NETWORK_CONNECTION | The connection string passed to the Net-Library DLL used for the current srvproc connection.
SRV_PIPEHANDLE | A string containing the pipe handle of a connected client, or NULL if the client is connected on a network that does not use named pipes. To use this handle as a valid pipe handle with Windows NT, convert this string to an integer.
SRV_PWD | The user password used by the srvproc client application when it logged on to the Open Data Services server application.
SRV_RMTSERVER | The server from which the client process is logged on. If the logon is from a client, this value will be an empty string.
SRV_ROWSENT | The number of rows already sent by srvproc for the current set of results.
SRV_SPID | The server thread ID of the srvproc. For extended stored procedures, this value is the same as the kpid column of sysprocesses, and it can change over time.
SRV_STATUS | The current status of srvproc.
SRV_TDS | The version of the tabular data stream (TDS) used by the client. Use SRV_TDSVERSION instead of this value.
SRV_TYPE | The connection type of srvproc. If "server" is returned, srvproc is from a SQL Server. If "client" is returned, srvproc is from a DB-Library or ODBC client.
SRV_USER | The user name used by the srvproc client application when it logged on to the Open Data Services server application.

len
Is a pointer to an integer variable that contains the length of the returned field value. If len is NULL, the length of the string isn't returned.

Returns

A pointer to a null-terminated string containing the current value for the specified field in the SRV_PROC structure. If the field is empty, a valid pointer to an empty string is returned and len contains 0. If the field is unknown, NULL is returned and len contains the value -1.

Remarks

This function returns a pointer to a null-terminated string containing the current value for the required field in the SRV_PROC structure. It also returns the length of the string.

See Also

This entry | For information about
srv_sfield | Returning a field from an SRV_SERVER structure
srv_symbol | Converting an Open Data Services token value to a readable string
SRV_TDSVERSION | Returning TDS version information for a client


srv_post_handle

Installs a post-event handler for an extended stored procedure that is called after the standard event handler.

Syntax

int srv_post_handle (
SRV_SERVER * server,
SRV_PROC * srvproc,
DBINT event,
SRV_POST_HANDLE_PROC handler,
BOOL remove );

where

server
Is a pointer to the SRV_SERVER structure. Use srv_init to get this pointer. If you provide a server value, you must provide a NULL srvproc value.
srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection. The srvproc parameter contains the information that the Open Data Services Library uses to manage communication and data between the application and the client.

If you provide a srvproc value, you must provide a NULL server value.

event
Specifies the event assigned to handler. If you provide a server value, all events are valid. If you provide a srvproc value, the following client-generated events are valid:
  • SRV_ATTENTION
  • SRV_CONNECT
  • SRV_DISCONNECT
  • SRV_LANGUAGE
  • SRV_RPC

When a SRV_DISCONNECT event occurs, the srvproc passed to the post-event handler is valid, but the connection is disconnected.

handler
Is a pointer to the function that is called after the standard event handler (installed by srv_handle) when the event defined by event occurs.

If a server value is provided, this function is global to the Open Data Services application and will be called (after the standard event handler) every time event occurs.

If a srvproc value is provided, this function will be called (after the standard event handler) only when event is generated by the srvproc client connection.

This function should be defined as returning an int and taking a single parameter. This parameter should be defined as SRV_SERVER * when event is one of the following:

  • SRV_EXIT
  • SRV_START
  • SRV_SLEEP
  • SRV_RESTART
  • SRV_STOP

and defined as SRV_PROC * when event is one of the following:

  • SRV_ATTENTION
  • SRV_CONNECT
  • SRV_DISCONNECT
  • SRV_LANGUAGE
  • SRV_RPC

This function must return one of the following values:
Return value | Description
SRV_CONTINUE | Continue normal processing.
SRV_DISCONNECT | Fire a disconnect event to close the client connection.
SRV_EXIT | Fire a disconnect event to close the client connection.

remove
Is a boolean flag that determines if the specified handler should be installed or removed. Use FALSE to install a new handler for event. Use TRUE to remove an existing handler for event.

Returns

SUCCEED, FAIL, or SRV_DUPLICATE_HANDLER. SRV_DUPLICATE_HANDLER is returned if you attempt to install the same post-event handler function multiple times for the same event.

Remarks

When an event occurs, Open Data Services calls the following functions in this order:

  1. The pre-event handler (installed by srv_pre_handle)
  2. The standard event handler (installed by srv_handle)
  3. The post-event handler (installed by srv_post_handle)

You can install post-event handlers dynamically. The new post-event handler is called when the next event occurs. For each event, an extended stored procedure application can have multiple global post-event handlers, and multiple post-event handlers per client connection, but you cannot install the same post-event handler function multiple times for the same event. Open Data Services will automatically remove the post-event handler when necessary; your program should not attempt to do this.

See Also

This entry | For information about
srv_handle | Installing a standard event handler
srv_pre_handle | Installing a pre-event handler


srv_pre_handle

Installs a pre-event handler for an extended stored procedure that is called before the standard event handler.

Syntax

int srv_pre_handle (
SRV_SERVER * server,
SRV_PROC * srvproc,
DBINT event,
SRV_PRE_HANDLE_PROC handler,
BOOL remove );

where

server
Is a pointer to the SRV_SERVER structure. Use srv_init to get this pointer. If you provide a server value, you must provide a NULL srvproc value.
srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection. The srvproc parameter contains the information that the Open Data Services Library uses to manage communication and data between the application and the client.

If you provide a srvproc value, you must provide a NULL server value.

event
Specifies the event assigned to handler. If you provide a server value, all events are valid. If you provide a srvproc value, the following client-generated events are valid:
  • SRV_ATTENTION
  • SRV_DISCONNECT
  • SRV_LANGUAGE
  • SRV_RPC
handler
Is a pointer to the function that is called before the standard event handler (installed by srv_handle) when the event defined by event occurs.

If a server value is provided, this function is global to the Open Data Services application and will be called (before the standard event handler) every time event occurs.

If a srvproc value is provided, this function will be called (before the standard event handler) only when event is generated by the srvproc client connection.

This function should be defined as returning an int and taking a single parameter. This parameter should be defined as SRV_SERVER * when event is one of the following:

  • SRV_EXIT
  • SRV_START
  • SRV_SLEEP
  • SRV_RESTART
  • SRV_STOP

and defined as SRV_PROC * when event is one of the following:

  • SRV_ATTENTION
  • SRV_DISCONNECT
  • SRV_LANGUAGE
  • SRV_RPC

This function must return one of the following values:
Return value | Description
SRV_CONTINUE | Continue normal processing.
SRV_DISCONNECT | Fire a disconnect event to close the client connection.
SRV_EXIT | Fire a disconnect event to close the client connection.
SRV_SKIP | Skip execution of the standard event handler. The post-event handler is still executed.

remove
Is a boolean flag that determines if the specified handler should be installed or removed. Use FALSE to install a new handler for event. Use TRUE to remove an existing handler for event.

Returns

SUCCEED, FAIL, or SRV_DUPLICATE_HANDLER. SRV_DUPLICATE_HANDLER is returned if you attempt to install the same pre-event handler function multiple times for the same event.

Remarks

When an event occurs, Open Data Services calls the following functions in this order:

  1. The pre-event handler (installed by srv_pre_handle)
  2. The standard event handler (installed by srv_handle)
  3. The post-event handler (installed by srv_post_handle)

You can install pre-event handlers dynamically. The new pre-event handler is called when the next event occurs. For each event, an extended stored procedure application can have multiple global pre-event handlers, and multiple pre-event handlers per client connection, but you cannot install the same pre-event handler function multiple times for the same event. Open Data Services will automatically remove the post-event handler when necessary; your program should not attempt to do this.

See Also

This entry | For information about
srv_handle | Installing a standard event handler
srv_post_handle | Installing a post-event handler


srv_returnval

Defines an output parameter value for a language event.

Syntax

int srv_returnval (
SRV_PROC * srvproc,
DBCHAR * valuename,
int len,
BYTE status,
DBINT type,
DBINT maxlen,
DBINT datalen,
BYTE * value );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection. The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
valuename
Is the name of the return value. It can be NULL, since a return value is not required to have a name.
len
Indicates the length, in bytes, of valuename. If valuename is null-terminated, set len to SRV_NULLTERM.
status
Specifies the status of the return value. Currently, there is only one legal status, SRV_PARAMRETURN.
type
Specifies the datatype of the return value to be sent back to the client. The appropriate datatype must be specified even if the data is NULL. For a list of Open Data Services datatypes, see Datatypes.
maxlen
Indicates the maximum length of the value, in bytes. For fixed-length datatypes that don't allow null values (for example, srvint4 or srvmoney), maxlen is ignored. For fixed-length datatypes that allow null values (for example, srvintn or srvmoneyn), maxlen must be the size of the datatype when it is not NULL. For variable-length datatypes, maxlen is the maximum length that the datatype can be.
datalen
Indicates the actual length, in bytes, of value. This parameter is ignored for fixed-length datatypes.

If datalen is 0, then a null value is returned.

value
Is a pointer to the program variable that contains the return value. The return value data is copied into the private srvproc space when srv_returnval is called. The return value data is sent when srv_senddone is called.

Returns

SUCCEED or FAIL.

Remarks

Usually, output parameters are returned by an SRV_RPC event handler and are handled with the srv_paramset function. However, it is possible for an Open Data Services server application to return values from an SRV_LANGUAGE event handler when an explicit remote stored procedure call is not involved. In this case, srv_returnval is used to define the datatype and value of the return value.

Multiple output parameter values can be sent to a client in a set of results, but srv_returnval must be called once for each parameter. The return values are sent back automatically when srv_senddone is called. The output parameters are sent back in the order in which they were defined with srv_returnval.

To send a null value, set datalen to 0.

When srv_returnval is called, the data at location value is copied into the SRV_PROC private data space. This copying makes it safe to use value later for other purposes.

See Also

This entry | For information about
srv_paramset | Setting the value of a remote stored procedure return parameter
srv_senddone | Sending a results completion message to the client.


srv_revert_to_self

Stops impersonation of the security context of a client connection, reverting to the original security context of the Open Data Services application.

Syntax

int srv_revert_to_self ( SRV_PROC * srvproc );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection. The srvproc parameter contains the information that the Open Data Services Library uses to manage communication and data between the application and the client.

Returns

SUCCEED if the original security context of the Open Data Services application was restored; otherwise, FAIL.

Remarks

Call this function to stop the impersonation started by srv_impersonate_client.

See Also

This entry | For information about
srv_impersonate_client | Impersonating the security context of a client connection


srv_rpcdb

Returns the database name component for the current remote stored procedure.

Syntax

DBCHAR * srv_rpcdb (
SRV_PROC srvproc,
int len );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection. The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
len
Is a pointer to an integer variable that receives the length of the database name. If len is NULL, the length of the database name isn't returned.

Returns

A DBCHAR pointer to the null-terminated string for the database name part of the current remote stored procedure. If there is no current remote stored procedure, NULL is returned and the len parameter is set to - 1.

Remarks

This function returns only the database component of the remote stored procedure's object name. It doesn't include the optional specifiers for owner, remote stored procedure name, and remote stored procedure number.

See Also

This entry | For information about
srv_rpcname | Returning the name for the current remote stored procedure.
srv_rpcnumber | Returning the number for the current remote stored procedure
srv_rpcparams | Returning the number of parameters for the current remote stored procedure
srv_rpcoptions | Returning the run-time options for the current remote stored procedure
srv_rpcowner | Returning the owner component for the current remote stored procedure


srv_rpcname

Returns the procedure name component for the current remote stored procedure.

Syntax

DBCHAR * srv_rpcname (
SRV_PROC * srvproc,
int * len );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the remote stored procedure). The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
len
Is a pointer to an integer variable that receives the length of the database name. If len is NULL, the length of the remote stored procedure name isn't returned.

Returns

A DBCHAR pointer to the null-terminated string for the remote stored procedure name component of the current remote stored procedure. If there isn't a current remote stored procedure, NULL is returned and len is set to -1.

Remarks

This function returns only the name of the remote stored procedure. It doesn't include the optional specifiers for owner, database name, and remote stored procedure number.

Since it's legal to call srv_rpcname when there isn't a remote stored procedure, (no informational error occurs), this function provides a method for determining whether a remote stored procedure exists.

See Also

This entry | For information about
srv_rpcdb | Returning the database name for the current remote stored procedure
srv_rpcnumber | Returning the number for the current remote stored procedure
srv_rpcparams | Returning the number of parameters for the current remote stored procedure
srv_rpcoptions | Returning the run-time options for the current remote stored procedure
srv_rpcowner | Returning the owner for the current remote stored procedure


srv_rpcnumber

Returns the number component for the current remote stored procedure call.

Syntax

int srv_rpcnumber ( SRV_PROC * srvproc )

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the remote stored procedure). The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.

Returns

The number component for the current remote stored procedure. If the client does not use a number component when running the remote stored procedure or if there is no current remote stored procedure, returns - 1.

Remarks

This function returns only the number component of the remote stored procedure. It doesn't include the optional specifiers for owner, remote stored procedure name, and database name.

See Also

This entry | For information about
srv_rpcdb | Returning the database name for the current remote stored procedure
srv_rpcname | Returning the name for the current remote stored procedure
srv_rpcparams | Returning the number of parameters for the current remote stored procedure
srv_rpcoptions | Returning the run-time options for the current remote stored procedure
srv_rpcowner | Returning the owner for the current remote stored procedure


srv_rpcoptions

Returns run-time options for the current remote stored procedure.

Syntax

DBUSMALLINT srv_rpcoptions ( SRV_PROC * srvproc );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the remote stored procedure). The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.

Returns

A bitmap that contains the run-time flags ORed together for the current remote stored procedure. If there isn't a current remote stored procedure, 0 is returned and a message is generated.

Remarks

The following table describes each run-time flag:

Run-time flag | Description
SRV_NOMETADATA | The client has requested results without metadata information. This flag is only used when the client is communicating with SQL Server. An Open Data Services application cannot omit the metadata information.
SRV_RECOMPILE | The client has requested to recompile the remote stored procedure before executing it. This flag might or might not apply to an Open Data Services application.

See Also

This entry | For information about
srv_rpcdb | Returning the database name for the current remote stored procedure
srv_rpcname | Returning the name for the current remote stored procedure
srv_rpcnumber | Returning the number for the current remote stored procedure
srv_rpcowner | Returning the owner of the current remote stored procedure
srv_rpcparams | Returning the number of parameters for the current remote stored procedure


srv_rpcowner

Returns the owner component for the current remote stored procedure.

Syntax

DBCHAR * srv_rpcowner (
SRV_PROC * srvproc,
int * len );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the remote stored procedure). The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
len
Is a pointer to an integer variable that receives the length of the owner name. The parameter len can be NULL, in which case the length of the owner component isn't returned.

Returns

A DBCHAR pointer to the null-terminated owner component for the current remote stored procedure. If there is no current remote stored procedure, NULL is returned and len is set to - 1.

Remarks

This function returns only the owner component of the remote stored procedure. It doesn't include the optional specifiers for name, remote stored procedure name, and remote stored procedure number.

See Also

This entry | For information about
srv_rpcdb | Returning the database name for the current remote stored procedure
srv_rpcname | Returning the name for the current remote stored procedure
srv_rpcnumber | Returning the number for the current remote stored procedure
srv_rpcparams | Returning the number of parameters for the current remote stored procedure
srv_rpcoptions | Returning the run-time options for the current remote stored procedure


srv_rpcparams

Returns the number of parameters for the current remote stored procedure.

Syntax

int srv_rpcparams ( SRV_PROC * srvproc );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the remote stored procedure). The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.

Returns

The number of parameters in the remote stored procedure. If there are no parameters in the remote stored procedure or if there isn't a current remote stored procedure, -1 is returned and an information error occurs.

Remarks

This function returns the number of parameters in the current remote stored procedure. It is usually called from the remote stored procedure.

When a remote stored procedure call is made with parameters, the parameters can be passed either by name or by position (unnamed). If the remote stored procedure call was made with some parameters passed by name and some passed by position, an error occurs. When this error occurs, the remote stored procedure handler is called, but it does not receive the parameters and srv_rpcparams returns 0.

See Also

This entry | For information about
srv_rpcdb | Returning the database name for the current remote stored procedure
srv_rpcname | Returning the name for the current remote stored procedure
srv_rpcnumber | Returning the number for the current remote stored procedure
srv_rpcoptions | Returning the run-time options for the current remote stored procedure
srv_rpcowner | Returning the owner of the current remote stored procedure


srv_run

Starts an Open Data Services server application.

Syntax

int srv_run ( SRV_SERVER * server );

where

server
Is a pointer to the SRV_SERVER structure. Use srv_init to get this pointer.

Returns

SRV_STOP for a stopped server. It returns FAIL if the server cannot be run.

Remarks

Once started, the server waits for a client request, calls the appropriate event handler to process the request, and then continues waiting. The srv_run function does not return until the server has been stopped by an SRV_STOP event.

If a server has stopped, you must use srv_init to re-initialize it before you can restart it.

See Also

This entry | For information about
srv_config | Configuring an Open Data Services server application
srv_init | Initializing an Open Data Services server application


srv_senddone

Sends a results completion message to the client.

Syntax

int srv_senddone (
SRV_PROC * srvproc,
DBUSMALLINT status,
DBUSMALLINT info,
DBINT count );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the language request). The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
status
Is a 2-byte bit field for various status flags. Multiple flags can be set by using the AND and OR operators with status flag values. Here is a list of the possible status flags:
Status | Description
SRV_DONE_FINAL | The current set of results is the final set of results.
SRV_DONE_MORE | The current set of results isn't the final set of results.
SRV_DONE_COUNT | The count parameter contains a valid count.
SRV_DONE_ERROR | The current client command received an error.
SRV_DONE_RPC_IN_BATCH | The current set of results is the last set of the currently executing remote stored procedure. This value is used when multiple remote stored procedures are executed in a single batch.

info
Is a reserved, 2-byte field. Set this value to 0.
count
Is a 4-byte field used to indicate a count for the current results set. If the SRV_DONE_COUNT flag is set in the status field, count holds a valid count.

Returns

SUCCEED or FAIL.

Remarks

A client request can cause the server to execute a number of commands and to return a number of results sets. For each results set, srv_senddone must return a results completion message to the client.

To indicate that there are more results for the current request, the Open Data Services server application must set the status field to SRV_DONE_MORE. To indicate that there are no more results for the current request, the Open Data Services server application must set the status field to SRV_DONE_FINAL. However, when an application function is installed as a SQL Server extended stored procedure instead of as a separate Open Data Services server application, use SRV_DONE_MORE. With extended stored procedures, SQL Server itself sends SRV_DONE_FINAL.

The count field indicates the number of rows affected by a command. If the count field contains a count, the SRV_DONE_COUNT bit should be set in the status field. This setting allows the client to distinguish between a count of 0 and an unused count field.

Do not call srv_senddone from the SRV_CONNECT handler.

See Also

This entry | For information about
srv_sendmsg | Sending a message to the client
srv_sendrow | Sending a row to the client
srv_sendstatus | Sending a status value to the client


srv_sendmsg

Sends a message to the client.

Syntax

int srv_sendmsg (
SRV_PROC * srvproc,
int msgtype,
DBINT msgnum,
DBTINYINT class,
DBTINYINT state,
DBCHAR * rpcname,
int rpcnamelen,
DBUSMALLINT linenum,
DBCHAR * message,
int msglen );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the language request). The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
msgtype
Is either SRV_MSG_INFO or SRV_MSG_ERROR, depending on whether the server is sending an informational message or an error message.
msgnum
Is a 4-byte message number.
class
Specifies the severity of the error. A severity less than or equal to 10 is considered an informational message.
state
Provides the error state number for the current message. The error state number provides information about the context of the error. Valid state numbers are 1 through 127.
rpcname
Is currently not supported.
rpcnamelen
Is currently not supported.
linenum
Is the line number in the language command batch where the message applies. Line numbers start at 1. If linenum does not apply to the message, set it to 0.
message
Is a pointer to the character string that is to be sent to the client.
msglen
Specifies the length, in bytes, of message. If message is null-terminated, set msglen to SRV_NULLTERM.

Returns

SUCCEED or FAIL.

Remarks

This function sends error or other messages to the client. It is called once for each message to be sent.

Messages sent with srv_sendmsg can be sent to the client in any order before or after all rows, if any, have been sent with srv_sendrow. All messages, if any, must be sent to the client before the completion status is sent with srv_senddone.

See Also

This entry | For information about
srv_errhandle | Defining Open Data Services error handlers
srv_senddone | Sending a results completion message to the client
srv_sendrow | Sending a row to the client
srv_sendstatus | Sending a status value to the client


srv_sendrow

Transmits a row of data to the client.

Syntax

int srv_sendrow ( SRV_PROC * srvproc );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the language request). The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.

Returns

SUCCEED or FAIL.

Remarks

The srv_sendrow function is called once for each row sent to the client. All rows must be sent to the client before any messages, status values, or completion statuses are sent with srv_sendmsg, srv_status, or srv_senddone.

Sending a row that hasn't had all its columns defined with srv_describe causes the Open Data Services server application to raise an informational error message and return FAIL to the client. In this case, the row is not sent.

Note Open Data Services does not support sending compute rows to the client. Also, if a row containing text or image data is sent to the client, the text pointer and text timestamp are not included.

See Also

This entry | For information about
srv_describe | Describing a result row column
srv_senddone | Sending a results completion message to the client
srv_sendmsg | Sending a message to the client
srv_setcollen | Specifying the current length of a column's data


srv_sendstatistics

Sends Open Data Services statistics to the client in table format.

Syntax

int srv_sendstatistics ( SRV_PROC * srvproc );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection. The structure contains the information that the Open Data Services Library uses to manage communication and data between the application and the client.

Returns

SUCCEED or FAIL.

Remarks

The srv_sendstatistics function returns statistics about the Open Data Services server application's workload. The statistics are returned in table format with the first column listing the statistic name and the second column showing its value. The following table describes the statistics returned:

Statistic name | Return value
max worker threads | The highest number of worker threads servicing the command queue since the Open Data Services server application was started or since the last time an srv_clearstatistics call was issued.
network reads | The total number of reads from the network device.
network writes | The total number of writes from the network device.
worker threads | The current number of worker threads servicing the command queue.

See Also

This entry | For information about
srv_clearstatistics | Resetting the statistical counters


srv_sendstatus

Sends a status value to the client in response to a request.

Syntax

int srv_sendstatus (
SRV_PROC * srvproc,
DBINT value );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle that received the language request). The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
value
Indicates the status of the request; 0 indicates that the request completed normally.

Returns

SUCCEED or FAIL

Remarks

When a request is received, a developer-supplied event handler function is called to service it. Part of the response to a request can be to return a status value.

A status value can be sent after all rows, if any, have been sent to the client with srv_sendrow and before the completion status is sent with srv_senddone. Only one status value can be sent for each set of results. This is equivalent to the Transact-SQL RETURN command.

See Also

This entry | For information about
srv_errhandle | Defining Open Data Services error handlers
srv_senddone | Sending a results completion message to the client
srv_sendmsg | Sending a message to the client
srv_sendrow | Sending a row to a client


srv_setcoldata

Specifies the current address for a column's data.

Syntax

int srv_setcoldata (
SRV_PROC * srvproc,
int column,
void * data );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection. The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
column
Indicates which column the address is being specified for. The first column is 1.
data
Is a pointer for a column's data.

Returns

SUCCEED or FAIL.

Remarks

Each column of the row must be defined first with srv_describe. Column data addresses are initially set with srv_describe. If the address of the column data changes, srv_setcoldata must be called to specify the new address of the data and srv_setcoldata must be called separately for each changed
column.

Null data is represented by setting the column's length to 0 with srv_setcollen, then the data address is ignored.

See Also

This entry | For information about
srv_describe | Describing a result row column
srv_setcollen | Specifying the current length of a column's data


srv_setcollen

Specifies the current data length in bytes of a variable-length column or a column that allows null values.

Syntax

int srv_setcollen (
SRV_PROC * srvproc,
int column,
int len );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection. The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
column
Indicates which column the data length is being specified for. The first column is 1.
len
Indicates the length, in bytes, of the column data. A length of 0 means the column data value is NULL.

Returns

SUCCEED or FAIL.

Remarks

Each column of the row must first be defined with srv_describe. The column data length is set by the last call to srv_describe or srv_setcollen. If variable-length data (null-terminated data) changes for a row, srv_setcollen must be used to set it to the new length before calling srv_sendrow. For a column that allows null values, srv_describe must have been called with desttype set to a datatype that allows nulls (like srvintn) and null data is specified by calling srv_setcollen with len set to 0.

Note that when the datatype of the column is variable-length, len is not checked for reasonableness. This function will return fail if called for a fixed-length column.

See Also

This entry | For information about
srv_describe | Describing a result row column
srv_setcoldata | Specifying the current address for a column's data


srv_setevent

Activates an Open Data Services event outside the context of a client connection.

Syntax

int srv_setevent (
SRV_SERVER * server,
int event );

where

server
Is a pointer to the SRV_SERVER structure. Use srv_init to get this pointer.
event
Indicates the event to activate. This value can be one of the following:
Event | Description
SRV_EXIT | Shuts down the server immediately, regardless of whether further client events are pending
SRV_RESTART | Continues the server after it has been paused
SRV_SLEEP | Pauses the server; no new connections are allowed
SRV_STOP | Disables new connections and then waits until all users have exited before shutting down the server

Returns

SUCCEED or FAIL.

Remarks

The srv_setevent function is usually used to shut down, pause, or continue the server in response to a Windows NT Service Control Manager request, or inside a ctrl+c handler. Unlike srv_event, srv_setevent does not require a SRV_PROC client connection handle.

See Also

This entry | For information about
srv_event | Activating a client event


srv_setuserdata

Saves a pointer to private data space in an SRV_PROC structure.

Syntax

int srv_setuserdata (
SRV_PROC * srvproc,
void * ptr );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection. The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
ptr
Is a pointer to the private data space for Open Data Services processes.

Returns

SUCCEED or FAIL.

Remarks

The ODS Library passes the current SRV_PROC structure to most event handlers. A pointer to user data can be saved in the SRV_PROC structure by using srv_setuserdata. This pointer to user data allows Open Data Services server applications to access private data without using global or static variables to hold private data. Open Data Services programs can then be reentrant.

The ptr pointer is not manipulated in any way by the ODS Library. It is provided only for the convenience of Open Data Services developers. The data that ptr points to can be allocated at connect time and accessed later with srv_getuserdata.

See Also

This entry | For information about
srv_getuserdata | Getting a pointer to private data space in a server process


srv_setutype

Sets the user-defined datatype for a column in a row.

Syntax

int srv_setutype (
SRV_PROC * srvproc,
int column,
DBINT usertype );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection. The structure contains the information that the ODS Library uses to manage communication and data between the Open Data Services server application and the client.
column
Indicates which column to set. The first column is 1.
usertype
Specifies the user-defined datatype code.

Returns

SUCCEED or FAIL. Returns FAIL if the column doesn't exist.

Remarks

A column has two types: its actual datatype and its user-defined datatype code. The user-defined datatype is used by SQL Server to store the actual user-defined datatype of the column (if any), and to store column description information (such as nullability and updatability) for the column. For more information on how a pass-through gateway should set this column information, see the the GATEWAY sample application.

The user-defined datatype is used to return ODBC column description information to the Open Data Services ODBC driver. For more information on how a pass-through gateway should set this ODBC column information, see ODBC Drivers for SQL Server and Open Data Services.

The srv_setutype function can be called any time that column has been defined with srv_describe and before the last row has been sent.

See Also

This entry | For information about
srv_describe | Describing a result row column


srv_sfield

Returns a field from an SRV_SERVER structure.

Syntax

DBCHAR * srv_sfield (
SRV_SERVER * server,
int field,
int * len );

where

server
Is a pointer to an SRV_SERVER structure. Use srv_init to get this pointer.
field
Specifies which server field to return. srv_sfield supports all configuration options supported by srv_config. srv_sfield also supports the following additional server fields:
SRV_SERVERNAME
The name of the Open Data Services server application server. This name is set with srv_init.
SRV_VERSION
Returns a string representing the version of Open Data Services in use. The version string has the format xx.xx.xx.xx (for example, 6.00.01.02). The first two sets of digits represent the internal version number. The final set of digits is a level identifier. Applications can check the version of the ODS Library, OPENDS60.DLL, at run time, to ensure that its version information is equal to or greater than the version used to develop the application.

For more information about supported configuration options, see srv_config.

len
Specifies a pointer to an integer variable that contains the length of the value for field. If len is NULL, the length of the string is not returned.

Returns

A DBCHAR pointer to a null-terminated string containing the field value. The string length is returned in len. If the field is empty, a valid DBCHAR pointer to an empty string is returned and len is set to 0. If the field is unknown, NULL is returned and len is set to -1.

Remarks

This function returns a pointer to a null-terminated string containing the current value for the field in the server structure.

See Also

This entry | For information about
srv_config | Setting Open Data Services configuration parameters
SRV_GETSERVER | Accessing a client's Open Data Services data structure
srv_init | Initializing an Open Data Services server application
srv_log | Writing a message to the Open Data Services log file
srv_pfield | Returning a field from an SRV_PROC structure
srv_symbol | Converting an Open Data Services token value to a readable string


srv_symbol

Converts an Open Data Services token value to a readable string.

Syntax

DBCHAR * srv_symbol (
int type,
int symbol,
int * len );

where

type
Is the type of the symbol token. The following token type values are valid:
Value (type) | Token (symbol)
SRV_DATATYPE | An Open Data Services datatype token returned by the Open Data Services function srv_paramtype (SRVCHAR for example) or a DB-Library datatype token returned by functions like dbcoltype (SQLCHAR for example).
SRV_EVENT | An event token passed to srv_handle (SRV_CONNECT for example).
SRV_DONE | A "done" status token passed to srv_senddone (SRV_DONE_FINAL for example).
SRV_ERROR | An error-severity token passed to the Open Data Services application's error handler installed by srv_errhandle (SRV_INFO for example).

symbol
Is the actual Open Data Services or DB-Library token value.
len
Is a pointer to an integer variable that contains the length of the returned string.

Returns

A pointer to a null-terminated character string that is a readable translation of an Open Data Services token value. If type or symbol is unknown, the function returns NULL and sets len to -1. The returned pointer points to space that is never overwritten, so it is safe to call this function more than once in the same statement. To free memory allocated by a call to srv_symbol, you must call the Windows NT function LocalFree.

Remarks

This function returns a pointer to a null-terminated string that describes an Open Data Services token value.

See Also

This entry | For information about
srv_pfield | Returning a field from an SRV_PROC structure
srv_sfield | Returning a field from an SRV_SERVER structure


SRV_TDSVERSION

Determines the tabular data stream (TDS) version being used in the client connection for the SRV_PROC structure.

Syntax

int SRV_TDSVERSION ( SRV_PROC * srvproc );

where

srvproc
Is a pointer to the SRV_PROC structure that is the handle for a particular client connection (in this case, the handle for which the TDS version is requested).

Returns

The TDS version used by the specified client connection. The following table lists the TDS version constants that can be returned:

Constant | Version
srv_tds_4_0 | The version used by SQL Server 4.2 and by Open Data Services version 4.2.
srv_tds_6_0 | The version used by SQL Server 6.0 and by Open Data Services version 6.0.

Remarks

The macro SRV_TDSVERSION returns more useful information than the srv_pfield function. Using SRV_TDSVERSION you can determine if the client connection supports SRVDECIMAL and SRVNUMERIC data. If SRV_TDSVERSION returns SRV_TDS_6_0 then the client supports SRVDECIMAL and SRVNUMERIC data. If SRV_TDSVERSION returns SRV_TDS_4_0 then the client does not support SRVDECIMAL and SRVNUMERIC data, and the Open Data Services application should convert SRVDECIMAL and SRVNUMERIC data into SRVFLT8 before sending it to the client.

See Also

This entry | For information about
srv_pfield | Returning a field from an SRV_PROC structure


srv_terminatethread

Disconnects and exits the client thread associated with the SRV_PROC structure.

Syntax

srv_terminatethread ( SRV_PROC * srvproc );

where

srvproc
Is a pointer to the Open Data Services thread to terminate. The structure parameter contains the information that the Open Data Services Library uses to manage communication and data between the application and the client.

Returns

SUCCEED or FAIL.

Remarks

By passing in the srvproc pointer that refers to a thread, this function can be used to kill any thread that is executing a user request from anywhere in your Open Data Services server application. To use srv_terminatethread to kill a thread other than the one that is executing the current client request, your application must provide a way of tracking active threads and of referring to them using the srvproc pointer. For example, if your application implements its own monitoring thread to determine the status of an active thread, the monitoring thread can use srv_terminatethread to terminate that thread.

The srv_terminatethread function does not terminate the thread immediately. When you issue the srv_terminatethread function, it sets an appropriate status in the SRV_PROC structure that instructs the client to clean up and exit. Open Data Services checks the SRV_PROC structure for termination status at common entry points and, if present, activates exit processing. If the client thread is currently processing an event, it will continue processing and wait until the event handler issues a return before exiting.


srv_willconvert

Determines whether a specific datatype conversion is available within the ODS Library.

Syntax

BOOL srv_willconvert (
int srctype,
int desttype );

where

srctype
Indicates the datatype of the data to be converted. This parameter can be any of the Open Data Services datatypes.
desttype
Indicates the datatype that the source data is converted to. This parameter can be any of the Open Data Services datatypes.

Returns

TRUE if the datatype conversion is supported; FALSE if the datatype conversion is not supported.

Remarks

The following table shows the datatype conversions that srv_willconvert checks for. The source datatypes are listed on the left, and the destination datatypes are listed across the top. For brevity, the prefix "srv" has been eliminated from each datatype. T (True) indicates that the conversion is allowed; F (False) indicates that the conversion is not allowed.

Conversion to and from all Open Data Services datatypes is supported, except for conversion from SRVDATETIME or SRVDATETIME4 to these datatypes, and from these datatypes to SRVDATETIME or SRVDATETIME4:

  • SRVINT1, SRVINT2, SRVINT4
  • SRVFLT4, SRVFLT8
  • SRVBIT
  • SRVMONEY, SRVMONEY4
  • SRVDECIMAL, SRVNUMERIC

For a description of each datatype, see Datatypes.

See Also

This entry | For information about
srv_convert | Converting datatypes


Chapter 5 Building Server Applications

Building Server Applications

This chapter describes how to build and then install Open Data Services server applications for the Windows NT operating system.

This chapter describes how to precompile, link, and run the sample server applications, GATEWAY, PROCSRV, and XP.DLL, included with Microsoft Open Data Services. The necessary header files, along with a makefile and a build file, are provided in the package. You will use a similar process to compile and link the Open Data Services server applications that you develop.


Required Files

To build the sample Open Data Services server applications, use the Microsoft C/C++ compiler for Windows NT with the Open Data Services subdirectory tree described here:

C:\SQL60\OPENDS\INCLUDE

File | Description
SRV.H | Main header file that includes all other header files
SRVAPI.H | Open Data Services API macro definitions and function prototypes
SRVCONST.H | Open Data Services constant definitions
SRVDBTYP.H | DB-Library definitions (checks to see whether they have already been defined)
SRVMISC.H | Miscellaneous Open Data Services definitions
SRVSTRUC.H | Open Data Services structure definitions
SRVTOK.H | Open Data Services token definitions
SRVTYPES.H | Open Data Services datatype definitions

C:\SQL60\OPENDS\LIB

File | Description
OPENDS60.LIB | The Open Data Services library definition file

C:\SQL60\OPENDS\SAMPLES\GATEWAY\BUILD

File | Description
BUILD.CMD | The build file used to make the sample gateway
MAKEFILE | The makefile used to create GATEWAYEXE

C:\SQL60\OPENDS\SAMPLES\GATEWAY\SRC

File | Description
GATECBS.C | Source code for callback functions used in the sample gateway
GATEWAY.C | Source code for the sample gateway application

C:\SQL60\OPENDS\SAMPLES\PROCSRV\BUILD

File | Description
BUILD.CMD | The build file used to create the sample gateway
MAKEFILE | The makefile used to create PROCSRV.EXE
SALES.DBF | A sample non - SQL Server database file

C:\SQL60\OPENDS\SAMPLES\PROCSRV\SRC

File | Description
PROCCBS.C | Source code for callback functions used in the sample procedure server application
PROCSRV.C | Source code for the sample procedure server application

C:\SQL60\OPENDS\SAMPLES\XPDLL\BUILD

File | Description
BUILD.CMD | The build file used to create the sample gateway
MAKEFILE | The makefile used to create XPDLL
XP.DEF | The DLL definition file
XP.DLL | The XPDLL executable file

C:\SQL60\OPENDS\SAMPLES\XPDLL\SRC

File | Description
XP.C | Source code for the sample extended stored procedure application

For a list of ODBC sample files, see ODBC Drivers for SQL Server and Open Data Services.


Libraries

Open Data Services server applications require the following libraries:

Library | Description | Setup
OPENDS60.DLL * | A dynamic-link library that contains Open Data Services functions for the Win32 API. | Set the PATH environment variable to include the directory in which OPENDS60.DLL resides.
OPENDS60.LIB | Contains the import definitions that Open Data Services server applications use. | Set the LIB environment variable to include the directory in which OPENDS60.LIB resides.
* For information about the OPENDS60.DLL library, see Installing an Open Data Services Server Application.

By default, the OPENDS60.DLL file is located in the C:\SQL60\DLL directory.


Include Files

SRV.H is the only Open Data Services include file that you must include in your application source code. This file includes all other header files.

Add the include file directory to the path argument of the INCLUDE environment variable. Or use the /I compile-line switch to point to the include file directory.


Compiling and Linking the Sample Applications

This section describes how to compile and link the Open Data Services sample applications.

PROCSRV.C

GATEWAY.C

XP.C


PROCSRV.C

The PROCSRV sample application subdirectory contains a makefile and a build file that allow you to build a custom version of PROCSRV.EXE, the PROCSRV executable file.

The makefile contains the compile and link statements that create PROCSRV.EXE. The build file sets the appropriate paths and runs the makefile. Before using the build command, edit BUILD.CMD to make the INCLUDE path and the LIB path conform to your environment. You need to edit the MAKEFILE only if you want to use a drive other than C.

To build an executable file
  • Enter

    build

This BUILD.CMD command file uses the information in MAKEFILE to create the PROCSRV executable file. It also builds the service utility, used to install PROCSRV as a Windows NT service.


GATEWAY.C

The GATEWAY sample application subdirectory contains a makefile and a build file that allow you to build a custom version of GATEWAY.EXE, the GATEWAY executable file.

The makefile contains the compile and link statements that create GATEWAY.EXE. The build file sets the appropriate paths and runs the makefile. Before using the build command, edit BUILD.CMD to make the INCLUDE path and the LIB path conform to your environment. You need to edit MAKEFILE only if you want to use a drive other than C.

To build an executable file
  • Enter

    build

This BUILD.CMD command file uses the information in MAKEFILE to create the GATEWAY executable file.


XP.C

The XP extended stored procedure sample application works with SQL Server. This file and its build environment are located under \SQL60\OPENDS\SAMPLES\XPDLL. The build tools include a makefile and a build file that allow you to build a custom version of XP.DLL, the XP dynamic-link library.

The makefile contains the compile and link statements that create XP.DLL. The build file sets the appropriate paths and runs the makefile. Before using the build command, edit BUILD.CMD to make the INCLUDE path and the LIB path conform to your environment. You need to edit MAKEFILE only if you want to use a drive other than C.

To build the dynamic-link library
  • Enter

    build

This BUILD.CMD command file uses the information in MAKEFILE to create the XP executable file. The build directory also includes also contains the Transact-SQL script INSTXP.SQL used to register the extended stored procedures with SQL Server.


Installing an Open Data Services Server Application

You can install an Open Data Services server application on a separate computer (that is, a computer not running a SQL Server process), or you can install it on the same computer as SQL Server. This section describes the special requirements for both cases.

Check the license information that comes with Open Data Services for details on licensing requirements for deploying or reselling an Open Data Services application.


Installing on the Same Computer as SQL Server

To install an Open Data Services server application on the same computer as SQL Server, copy the application to a directory and include that directory in your path. For example, if you plan to use the sample applications, you could copy the files PROCSRV.EXE and GATEWAY.EXE to \SQL60\BINN.

When two server processes, such as SQL Server and Open Data Services, share a single computer, they cannot use the same process identifier to listen for connection requests. If your network uses named pipes or sockets, you must assign a unique process identifier to each of them. In addition, you must add the alternate connection information to any computer that needs direct access to that server process. For more information, see Network Setup Options for Open Data Services Server Applications.


Installing on a Separate Computer from SQL Server

When all Open Data Services server applications and SQL Server processes are installed on separate computers on the network, they can use the same process identifier to listen for connection requests. No extra configuration steps are required for servers or clients. For more information, see Network Setup Options for Open Data Services Server Applications.


Installing Extended Stored Procedures on SQL Server

To install an extended stored procedures application created with Open Data Services, copy the DLL application file to the SQL Server directory \SQL60\DLL.

The SQL Server system administrator can then add each of the DLL's application functions to SQL Server as extended stored procedures and can grant users access to the procedures. For more information, see Sample Application-Extended Stored Procedures.


Chapter 6 Network Setup Options for Open Data Services Server Applications

Network Setup Options for Open Data Services Server Applications

This chapter discusses options for making an Open Data Services server application available for use on the network. It describes configuration requirements for the Open Data Services server application, for SQL Server, and for DB-Library clients.

Your configuration requirements will depend on:

  • The type of network you are using.
  • Whether the Open Data Services server application is installed on the same computer as SQL Server or on a separate computer.
  • Whether you want to provide clients with direct access or remote access to the Open Data Services server application.

Each software process on a network must have a unique set of identifiers that distinguishes it from all others. The connection information each computer requires depends on the type of network protocol that the Open Data Services server application uses to accept connections from other software processes on the network. In some cases, you can take advantage of SQL Server default values to eliminate some configuration steps.

Open Data Services for Windows NT can accept requests from clients and servers across multiple network protocols simultaneously. Open Data Services supports multiple network protocols though the use of loadable network drivers, known as Net-Libraries. Open Data Services supports the same server Net-Libraries as SQL Server. For specifics, see Microsoft SQL Server Setup.

This chapter discusses Net-Library configuration options.

Each Net-Library uses a two-part identifier to uniquely locate server processes in a SQL Server environment: a node identifier and a process identifier. The node identifier indicates the computer on which the software process resides. The process identifier locates a specific software process on that computer.

For networks that use named pipes, the node identifier is specified as a computer name, for example, \\svr_name, and the process identifier is specified as a pipe name, for example, \pipe\sql\query.

For networks that use TCP/IP socket addresses, the node identifier is specified as a numeric IP address, for example, 11.1.4.68, and the process identifier is specified as a socket number, for example, 1433.

When Open Data Services server applications and SQL Server are installed on separate computers on the network, they can use the same process identifiers. When an Open Data Services server application and SQL Server are installed together on a single computer, they share the same node identifier, requiring you to assign an alternate process identifier to one of them. In addition, any computer that requires direct access to that process must be configured to refer to it by its alternate process identifier.


Client Access to an Open Data Services Server Application

SQL Server database clients can access an Open Data Services server application remotely or directly, as follows:

  • Clients can access the Open Data Services server application remotely, via the SQL Server remote stored procedure facility.

    To enable this type of access, you must configure SQL Server as described in Server Access to an Open Data Services Server Application. You do not need to make any configuration changes to the client computers.

    Clients can then make remote stored procedure calls to the Open Data Services server application as if it were a remote SQL Server. This can include the use of the Open Data Services sp_sqlexec remote stored procedure, which allows the use of remote stored procedures as a vehicle for sending language queries.

  • Clients can access the Open Data Services server application directly, via a direct connection to the Open Data Services server application.

    To enable this type of access, no special configuration is required if the Open Data Services server application is on a network type that supports address resolution at connect time (such as named pipes) and uses the default process identifier. Otherwise, you must use the SQL Client Configuration Utility to configure the client to connect to the node and process identifiers used by the Open Data Services server application.

    The client can connect to the Open Data Services server application and send language queries or stored procedure calls in exactly the same way the client would connect to and communicate with a SQL Server on the network.

For some custom applications, clients can access SQL Server indirectly via Open Data Services. The Open Data Services server application implements a pass-though server function that directs client requests to SQL Server. For an example of a pass-through server application, see the GATEWAY sample application.

The network configuration requirements for a pass-through server are somewhat different from the other types of configurations discussed in this chapter. Clients must have a direct connection to the Open Data Services server application and not to SQL Server. The Open Data Services server application must be configured to connect to SQL Server as a client of SQL Server.

For Open Data Services server application functions that are installed on SQL Server as extended stored procedures, there are no special configuration issues. Clients use these functions by making standard stored procedure calls to SQL Server. For more information, see Sample Application-Extended Stored Procedures.


Server Access to an Open Data Services Server Application

SQL Server database servers communicate with Open Data Services server applications by using remote stored procedure calls, the same method used to communicate with other SQL Servers. When making a remote stored procedure call, SQL Server automatically initiates a server-to-server connection with Open Data Services, as a client of the Open Data Services remote server.

SQL Server can access an Open Data Services server application as a remote server in the following ways:

  • A SQL Server stored procedure can include a call to a remote stored procedure in an Open Data Services server application. For example, a client can execute a stored procedure on SQL Server, causing the client-initiated procedure to execute a remote stored procedure.
  • A SQL Server table can contain a trigger that calls a remote stored procedure in an Open Data Services server application. For example, a client update to the table might fire a trigger, causing the trigger to execute a remote stored procedure.
  • SQL Server can receive a remote stored procedure call from a client application in which the client specifies a server name that refers to an Open Data Services server application. SQL Server forwards the request to the Open Data Services server application.

In all these cases, the client initiates the action taken by SQL Server. Any returned data is sent by the Open Data Services server application to SQL Server. SQL Server, in turn, passes all results sets on to the client. A SQL Server trigger or stored procedure can retain the values of any returned stored procedure output parameters for later use.

To enable this type of access, you must:

  • Configure the computer on which SQL Server is running to connect to the Open Data Services server application as a client of the application. Use the SQL Client Configuration Utility to do this. Use the Advanced option of the SQL Client Configuration Utility if the Open Data Services application is using a non-default process identifier.
  • Configure SQL Server itself by using standard SQL Server administrative procedures (such as sp_addserver) to add the Open Data Services server application as a SQL Server remote server.

For Open Data Services functions that are added to SQL Server as extended stored procedures, there are no special configuration issues. For information on the SQL Server system procedures that install extended stored procedures, see the Microsoft SQL Server Administrator's Companion.


Configuration Guidelines

Explicit configuration of one or more computers is required in order to enable access to an Open Data Services server application in all of the following cases:

  • When an Open Data Services server application shares a single computer with SQL Server, you must assign an alternate process identifier to either the Open Data Services server application or to SQL Server. Then appropriately configure any computer that requires direct access to that alternate process identifier.
  • For SQL Server to communicate with an Open Data Services server application (sending remote stored procedure calls to an Open Data Services remote server) you must perform SQL Server administrative tasks (such as sp_addserver) to identify the Open Data Services server application as a remote server. You must also add client connection information to the computer on which SQL Server is installed (unless the Open Data Services server application is using a default process identifier).
  • For DB-Library clients or SQL Servers to access multiple instances of an Open Data Services server application that is installed on a single computer, each instance must use a different process identifier. The configuration requirements are the same as when SQL Server and Open Data Services share the same computer.


Understanding Client-Server Configuration

Before you begin setting up a network with specific values, you should be familiar with this general configuration information:

  • To accept requests from clients and servers, servers use "Listen On" values that specify a network type and a process identifier. The server accepts requests that are directed to that process identifier. An Open Data Services server application can listen on multiple network types and process identifiers simultaneously.
  • To enable communication with a particular server, clients and servers use "Connect To" values that specify a network type, a node identifier, and a process identifier for each server.
  • Remote server information for SQL Server is entered via two SQL Server stored procedures, sp_addserver and sp_configure. Note that when you identify an Open Data Services server application as a remote server, you use the same procedure that you use when identifying another SQL Server as a remote server. For more information, see the Microsoft SQL Server Administrator's Companion.
  • The server names you choose are case-sensitive for some types of clients and servers on the network.

Not all computers on your network are necessarily of the same network type. SQL Server and Open Data Services allow you to use mixed networks.

For more information about configuring Open Data Services clients and using the SQL Client Configuration Utility, see Microsoft SQL Server Setup.


Chapter 7 Sample Application-Extended Stored Procedures

Sample Application–Extended Stored Procedures

This chapter describes the XP.DLL extended stored procedure sample application. It describes extended stored procedures, discusses special programming considerations for using the Open Data Services API to create extended stored procedures, tells how to add extended stored procedures to SQL Server and make them available for use, and describes how to use extended stored procedures.

For the most current version of the sample code, refer to the version that shipped with your Open Data Services package.


Creating Extended Stored Procedures

Microsoft SQL Server for Windows NT supports extended stored procedures, allowing functions that you develop using the Open Data Services API to be integrated into SQL Server as a dynamic component of SQL Server, instead of providing them as part of a separate server application. Users call these procedures in the same way that they call standard SQL Server stored procedures.

Extended stored procedures extend SQL Server by providing functions that are similar to those of an Open Data Services server application, such as accessing data or running commands that exist outside of the standard SQL Server environment.

You create extended stored procedures using your own C application code with the Open Data Services API in the same way as you would create a separate Open Data Services server application. Rather than responding to a series of requests from connected clients, however, extended stored procedures use the Open Data Services API to respond to procedure calls from individual clients and servers and then return the appropriate results.

Integrating your Open Data Services server application functions directly into SQL Server as extended stored procedures offers the following advantages:

  • Ease of use.

    For the SQL Server user, executing an extended stored procedure is similar to executing a stored procedure.

  • Ease of administration.

    For the SQL Server system administrator, adding and dropping extended stored procedures is similar to adding and dropping stored procedures.

  • Performance advantages.

    Extended stored procedures are implemented as a dynamic-link library (DLL) that runs as part of SQL Server, sharing the SQL Server address space and security privileges.

Note Only a SQL Server system administrator can add extended stored procedures to SQL Server. The administrator should thoroughly test these procedures before installation due to the potential for any process that shares the same address space in system memory to affect normal SQL Server processing. Although SQL Server uses an exception handler to catch memory access violations, it is not always possible to detect cases in which an extended stored procedure corrupts a portion of memory that is being used by SQL Server.

The alternative to running extended stored procedures in the same address space as SQL Server is to provide these functions as a separate Open Data Services server application. For more information, see Sample Application-Procedure Server.

The XP.DLL sample application provides the following extended stored procedures, which can be called either from a client or from SQL Server.

Extended stored procedure | Description
xp_diskfree | Accepts a drive letter as an argument and returns the amount of available disk space as a return parameter.
xp_disklist | Returns a list of available disk drives and the amount of available disk space for each one as a relational results set.
xp_echo | Accepts an input parameter as an argument and returns the same value as an output parameter.
xp_proclist | Returns a list of available extended stored procedures.
xp_scan_xbase | Returns the contents of a dBASE® file as if it were a SQL Server query results set, performing the equivalent of a SELECT * from tablename statement.


Programming Considerations

This section describes some programming considerations that you will need to keep in mind when writing Open Data Services routines that users will access as extended stored procedures in SQL Server (as opposed to routines that users will access on an Open Data Services server).

When standard stored procedures are added to SQL Server, an administrator defines their expected parameters so that the system can validate user-specified parameters and return syntax errors. With extended stored procedures, it is up to the application to validate any user-specified parameters.

When using the srv_senddone function to send a results completion message to the client, always set the completion status flag to SRV_DONE_MORE instead of to SRV_DONE_FINAL. The client receives SRV_DONE_FINAL from SQL Server.

Each extended stored procedure function that you create should follow these recommendations for accepting and responding to user input:

  1. Check that the caller of the procedure has provided all of the required parameters and that each parameter is of the appropriate datatype. Return an appropriate message if not.
  2. Define the columns for returning a result set.
  3. Create each record for returning to the caller.
  4. Set up any output parameters and return statuses used by the procedure.
  5. When finished returning results, send the results completion message using srv_senddone with the SRV_DONE_MORE status flag.
  6. Return from the procedure with the desired Transact-SQL return status.

A single DLL file can contain multiple extended stored procedures. And SQL Server supports the use of multiple DLL files.


Adding Extended Stored Procedures to SQL Server

A DLL application file that contains extended stored procedure functions forms an extension to SQL Server itself. To install the DLL file, copy the file to the same directory as the standard SQL Server DLL files. As with other DLL files, once the extended stored procedure DLL is placed in the appropriate directory and the appropriate paths are set, you can make its functions available to users immediately ¾ it is not necessary to restart the server.

For each function provided in an extended stored procedure DLL, a SQL Server system administrator must run the sp_addextendedproc system procedure, specifying the name of the function and the name of the DLL in which that function resides. This registers the function with the SQL Server master database and updates the SQL Server system tables by adding the name of the DLL to the syscomments table and adding the specified function name to the sysobjects table as an extended stored procedure with X as the object type. For example:

sp_addextendedproc 'xp_proclist', 'xp.dll'

This command registers the function xp_proclist, located in the file XP.DLL, as a SQL Server extended stored procedure.

To drop individual extended stored procedures, a system administrator uses the system procedure sp_dropextendedproc.

SQL Server loads an extended stored procedure DLL as soon as a call is made to one of the DLL's functions. The DLL remains loaded until the server is shut down or until the system administrator uses the DBCC command to unload it. For example:

DBCC xp(FREE)

This command unloads XP.DLL, allowing the system administrator to copy in a newer version of this file without shutting down the server.

For more information about the administrative tasks described in this section, see the Microsoft SQL Server Administrator's Companion.


Running Extended Stored Procedures

Once a system administrator has added an extended stored procedure, users can find out what new functions are available by using the system procedure sp_helpextendedproc. When used without an argument, sp_helpextendedproc displays all extended stored procedures that are currently registered with the master database. If you specify an extended stored procedure name as an argument, sp_helpextendedproc verifies whether that function is currently available.

SQL Server and database clients can use extended stored procedures in the same way as they use standard stored procedures. For example, SQL Server can call an extended stored procedure as the result of a trigger, or a user can issue the EXECUTE command, specifying the name of the extended stored procedure and supplying any parameters required by that extended stored procedure. Both SQL Server and database clients can access extended stored procedures on a remote server by specifying the remote server name when calling the procedure.


Debugging Extended Stored Procedures

Extended stored procedures can be debugged using Microsoft Visual C++. For more information on how to debug a DLL, see your documentation for Visual C++.


Using the Sample Extended Stored Procedures

To use the sample extended stored procedures, a SQL Server system administrator must make the procedures in XP.DLL available as SQL Server extended stored procedures, either by using the methods described in Adding Extended Stored Procedures to SQL Serveror by running the XP.DLL installation script, INSTXP.SQL, that is provided with SQL Server. The INSTXP.SQL script registers each of the XP.DLL procedures as SQL Server extended stored procedures and gives all users EXECUTE permission to the procedures.

To run the XP.DLL extended stored procedures, you can log in to SQL Server and issue the EXECUTE statement, specifying the name of the extended stored procedure to use and any valid arguments defined by that procedure (described in the following sections).

Like standard stored procedures, extended stored procedures support return status values and support the use of input and output parameters. Parameters are used in some of the following examples. For information about passing parameters in a stored procedure, see the Microsoft SQL Server Transact-SQL Reference.


Using xp_proclist

The XP.DLL extended stored procedure xp_proclist displays the name and expected arguments, if any, for each extended stored procedure implemented in XP.DLL. This procedure demonstrates a method for providing syntax help to extended stored procedure users. For example:

execute xp_proclist

This command displays usage information for all the extended stored procedures implemented in XP.DLL.


Using xp_diskfree

The XP.DLL extended stored procedure xp_diskfree accepts a user-specified drive letter and returns the number of bytes of free space for that drive as an output parameter. To save the return parameter, the caller of the procedure must initialize a variable of datatype int, according to standard SQL Server stored procedure syntax. For example:

declare @outvar int
execute xp_diskfree @drive = 'c' @space = @outvar OUTPUT
select @outvar

When the EXECUTE statement completes, the @outvar variable contains the value returned by the xp_diskfree procedure. If the first three lines in this example were part of a stored procedure in SQL Server itself, the @outvar return value could then be used in subsequent statements.

The xp_diskfree sample code also demonstrates how to implement a default parameter. If the caller executes xp_diskfree without specifying a drive letter parameter, xp_diskfree returns a data row showing free space for the drive on which SQL Server is installed.


Using xp_disklist

The XP.DLL extended stored procedure xp_disklist returns data obtained from the external environment as a results set. Specifically, it returns a two-column results set listing all the local and network-attached drives (excluding floppy-disk drives) that are available to the computer on which SQL Server is installed. It also lists the space available on each drive. For example:

execute xp_disklist

The caller of this procedure receives disk space information about server disk drives as a two-column SQL Server results set.


Using xp_echo

The XP.DLL extended stored procedure xp_echo is an example of how to use input and output parameters to pass information to and from an extended stored procedure, in the same way as you would pass information to and from a standard SQL Server stored procedure. The xp_echo extended stored procedure accepts a user-specified input parameter and returns the value of the input parameter as an output parameter. For example:

declare @out char(4)
declare @in int
select @in=999
execute xp_echo @in, @param=@out output
select @out

In this example, the caller first declares the parameters to be used. The EXECUTE statement passes the value of @in to the xp_echo procedure and then saves the value that the procedure returns as @out, using standard SQL Server stored procedure syntax for passing the input value and for saving the return parameter.


Using xp_scan_xbase

The XP.DLL extended stored procedure xp_scan_xbase accesses a dBASE III® - or dBASE IV® - based file and returns the contents as a relational results set. This procedure is an example of how to access data that is not held in a relational database and how to return results in a form that can be used by a SQL Server client. The xp_scan_xbase extended stored procedure takes as an argument the full pathname of the database file, enclosed in quotation marks. For example:

declare @retstatus int
@retstatus=execute xp_scan_xbase
    "c:\sql\opends\samples\procsrv\build\sales.dbf"
select @retstatus

This example accesses the specified file and returns its contents as a relational results set. By declaring and using a return status variable, this example also shows how to access the return values from extended stored procedures.

The xp_scan_xbase sample code demonstrates the use of a default parameter in an extended stored procedure. If the caller does not specify a parameter, this procedure accesses a sample dBASE-formatted file that is included with the sample for the purposes of demonstration.


Chapter 8 Sample Application-Procedure Server

Sample Application–Procedure Server

This chapter describes the PROCSRV.EXE sample application that is provided with your Open Data Services package. It describes programming considerations for creating your own procedure server applications, explains how to use the features of the PROCSRV sample application, and includes a listing of the PROCSRV source code. For the most current version of the sample code, refer to the version that shipped with your software.

The PROCSRV sample application demonstrates how to implement stored procedures in an Open Data Services server application. PROCSRV provides the following procedures for use by clients and servers in the SQL Server environment:

PROCSRV procedure | Function
diskfree | Allows the caller to specify a drive letter as a stored procedure output parameter and returns the amount of available disk space as a stored procedure return value.
disklist | Obtains a list of available disk drives from the operating-system environment in which the Open Data Services server application is running and returns the available disk space for each drive as a SQL Server relational results set.
proclist | Returns a list of the procedures available in PROCSRV.
scan_xbase | Returns the contents of a dBASE-format file as a SQL Server relational results set.
sp_exec | Executes any command string in the operating-system environment in which the Open Data Services server application is running.

The procedures in the PROCSRV sample application implement many of the features described in Overview. The procedures are similar to the extended stored procedures covered in Sample Application¾Extended Stored Procedures. Note, however, that PROCSRV runs as a separate network server application; extended stored procedures run as part of SQL Server.

Open Data Services includes two versions of the PROCSRV application:

  • A compiled version that you can use without modification
  • The source code to use as a model if you are writing an Open Data Services server application that provides similar functionality

PROCSRV implements both a remote stored procedure event handler and a language event handler:

  • The remote stored procedure event handler allows database clients to call procedures directly, using the DB-Library dbrpc functions. It also allows SQL Server to call the PROCSRV procedures as if they were remote stored procedures on another SQL Server.

    The event handler checks for the existence of the procedure name, runs the appropriate routine, and returns results to the caller.

  • The language event handler provides a mechanism for DB-Library clients that do not use the DB-Library dbrpc functions to access the PROCSRV procedures by using language statements.

    The event handler parses the language statement to extract the procedure call and the appropriate parameters. It processes the appropriate routine and returns results to the caller. This allows access from any type of database client that can send user-defined SQL statements, such as the isql utility.

    To execute the PROCSRV procedures by using language statements, the database client must be directly connected to the PROCSRV application server.


Programming Considerations

This section describes some programming considerations that you will need to keep in mind when writing an Open Data Services server application that uses the PROCSRV sample application as a model.

With standard stored procedures, an administrator can define a set of user-specified parameters that will be validated by SQL Server. When creating procedures using the Open Data Services API, the application must validate any user-specified parameters.

Each function in your application should follow these recommendations for accepting and responding to user input:

  1. Check that the caller of the procedure has provided in all the required parameters and that each parameter is of the appropriate datatype. Return an appropriate message if not.
  2. Define the columns for returning a results set.
  3. Create each record for returning to the caller.
  4. Set up any output parameters and return statuses used by the procedure.
  5. When finished returning results, send the results completion message using srv_senddone with the SRV_DONE_FINAL status flag.


Running the PROCSRV Sample Application

After you install Open Data Services and the sample applications, you can start the PROCSRV sample application.

To start the PROCSRV sample application from an operating-system prompt
  • At the operating-system prompt, enter

PROCSRV

You can minimize this window after PROCSRV starts.

You can also use the service utility to install the PROCSRV application as a Windows NT service. Once PROCSRV is installed as a Windows NT service, you can control PROCSRV using:

  • The net start and net stop commands
  • The SQL Service Manager utility
  • The Services utility in the Windows NT Control Panel

When you start the PROCSRV application, it runs as a separate server application process in the SQL Server environment. SQL Servers and database clients can access PROCSRV in the same way as they access stored procedures on another SQL Server on the network.

The PROCSRV sample application listens for connection requests on the connection information specified in the Windows NT Registry. For details, see Network Setup Options for Open Data Services Server Applications.

Now see the following:

Server Access to the PROCSRV Server

Client Access to the PROCSRV Server

Executing the PROCSRV Procedures


Server Access to the PROCSRV Server

The Open Data Services setup program installs the PROCSRV sample application on the same computer as SQL Server. Before you can use PROCSRV, you need to set up PROCSRV and SQL Server as described below.

SQL Server can communicate with PROCSRV using remote stored procedure calls in the same way it communicates with other SQL Servers on the network. When SQL Server communicates with the PROCSRV application, it uses client connection values to locate and connect to the application. Be sure that SQL Server is configured for the appropriate client connection values. For more information, see Network Setup Options for Open Data Services Server Applications.

On the SQL Server, use sp_addserver and sp_configure to identify the PROCSRV application as a remote server in the same way you would identify a SQL Server as a remote server. For example:

sp_addserver SERVNAME

provides SQL Server with remote access to the Open Data Services server application SERVNAME. For more information about sp_addserver, see the Microsoft SQL Server Administrator's Companion. For more information about sp_configure, see Microsoft SQL Server Setup.


Client Access to the PROCSRV Server

Database clients can communicate with a PROCSRV server using remote stored procedure calls, in the same way they communicate with a remote SQL Server. The client executes the procedure, specifying PROCSRV as the remote server name.

A client can also connect to a PROCSRV server directly. For clients that are directly connected to PROCSRV, the client application can execute the PROCSRV procedures as language statements (using dbsqlexec, for example) or as stored procedure calls (using dbrpcsend and related calls).

For information about setting up direct client connections to an Open Data Services server application, see Network Setup Options for Open Data Services Server Applications.


Executing the PROCSRV Procedures

This section contains examples of running each of the procedures that the PROCSRV sample application provides. To use these procedures, log in to SQL Server as a client and issue the EXECUTE statement, specifying PROCSRV as the remote server name, and specifying any valid arguments that are defined by the procedures.

Like standard stored procedures, the PROCSRV procedures support return status values and support the use of input and output parameters. Parameters are used in some of the examples.

For more information about using EXECUTE to invoke remote stored procedures and for information about passing parameters in stored procedures, see the Microsoft SQL Server Transact-SQL Reference.

Now see the following:

Using proclist to Display Help Information

Using sp_exec to Access External Processes

Using diskfree to Retrieve a Data Value from the External Environment

Using disklist to Retrieve a Results Set from the External Environment

Using scan_xbase to Access a dBASE-format file


Using proclist to Display Help Information

The PROCSRV procedure proclist is an example of how to provide syntax Help to users of an Open Data Services server application. For example:

execute PROCSRV...proclist

This displays the name and expected arguments, if any, for each procedure implemented in the PROCSRV application.


Using sp_exec to Access External Processes

The PROCSRV procedure sp_exec executes any command string in the operating-system environment in which PROCSRV is running, including batch files and other utilities. A string of parameters can be passed with the command. For example, if you have a mechanism for sending an automated electronic mail message from a batch file named SENDMAIL.CMD and the batch file takes the recipient's email name as a parameter, you can invoke the batch file from within SQL Server by issuing the following statement:

execute PROCSRV...sp_exec 'sendmail johndoe'

In this example, sendmail is the name of the external process (a command file), and johndoe is the parameter required by the external process. In SQL Server terms, these constitute one parameter of the sp_exec procedure, which then returns the results to the caller as a SQL Server results set.


Using diskfree to Retrieve a Data Value from the External Environment

The PROCSRV procedure diskfree is an example of the use of output parameters in an Open Data Services stored procedure. The diskfree procedure returns the number of bytes of free space for the drive letter passed to it as a parameter. To use diskfree, you must declare and initialize a variable to hold the return parameter and use the OUTPUT keyword when calling the procedure, as follows:

declare @outvar int
execute PROCSRV...diskfree @drive = 'c', @space = @outvar OUTPUT
select @outvar

Return parameters in PROCSRV are treated in the same way as standard SQL Server stored procedure parameters. For example, when the EXECUTE statement completes, the @outvar variable contains the return value from the PROCSRV procedure. If the three lines in this example were part of a stored procedure in SQL Server itself, the return value of @outvar could then be used in subsequent statements.

The diskfree procedure also accepts a default parameter. If you execute diskfree without specifying a drive-letter parameter, diskfree returns a data row showing free space for the drive on which PROCSRV is installed.

For more information about using return parameters in stored procedures, see the Microsoft SQL Server Transact-SQL Reference.


Using disklist to Retrieve a Results Set from the External Environment

The PROCSRV procedure disklist shows an Open Data Services server application that returns a results set from the external environment in response to a remote stored procedure request. This procedure returns a two-column results set of all the local and network-attached drives (excluding floppy-disk drives) and the space free on each. For example:

execute PROCSRV...disklist

The results set from a remote stored procedure is always returned to the client that made the call.


Using scan_xbase to Access a dBASE-format File

The PROCSRV procedure scan_xbase returns the entire contents of a
dBASE III - or dBASE IV - formatted file as a relational results set. This procedure is an example of the ability of Open Data Services to access data that is not held in a relational database and to return results in a form that can be used in the SQL Server database environment. For example:

execute PROCSRV...scan_xbase 'c:\sql\opends\samples\procsrv\build\sales.dbf'

The parameter enclosed in quotation marks is the fully qualified path to the dBASE-format file.


Chapter 9 Sample Application-Gateway Server

Sample Application–Gateway Server

The GATEWAY sample application provides an Open Data Services server application that serves as a gateway from the SQL Server environment to an alternate data source.

For purposes of illustration, the GATEWAY sample application connects to SQL Server as an alternate data source. It accesses the alternate data source by using the standard interface to that data source (in this case, the DB-Library client interface to SQL Server), and returns results to the caller.

The GATEWAY sample also serves to demonstrate a "pass-through" application. Pass-through applications can be used for auditing or security purposes, since they allow the Open Data Services server application to intercept and examine all requests before the Open Data Services server application sends the request on to SQL Server.

The programming examples earlier in this book use segments from the GATEWAY sample application code to illustrate how to implement event handlers. For more information about this application, see Open Data Services Programming.

For the most current version of the sample code, refer to the version that shipped with your package.


Running the GATEWAY Sample Application

To run the GATEWAY application

At the operating-system prompt, enter

gateway -r registry_key_name -s servername

where

registry_key_name
Is the name of the Registry key under which Open Data Services can find the Windows NT Registry ListenOn value. Open Data Services looks for this key in the following location:

HKEY_LOCAL_MACHINE\
Software\
Microsoft
MSSQLServer\
registry_key_name

servername
Is the name of the SQL Server GATEWAY connects to.

The GATEWAY sample application connects the database client to a SQL Server database.

For information about setting up network access to an Open Data Services server application, see Network Setup Options for Open Data Services Server Applications.


Appendix A Errors

Errors

This appendix lists and describes Open Data Services error messages.

The following error values are returned by Open Data Services.

Number | Description
17801 | Unknown internal error value.
17802 | Creation of server event thread failed.
17803 | Insufficient memory available.
17804 | Invalid 'nbytes' value.
17805 | Invalid buffer received from client.
17806 | Invalid event specification.
17807 | Invalid event '%l!ld!'.
17808 | Invalid starting position specified.
17809 | Unable to connect. The maximum number of '%l!ld!' users are currently connected.
17810 | Unable to set up named pipe.
17811 | Requested data conversion does not exist.
17812 | Data conversion resulted in overflow.
17813 | Attempt to convert data stopped by syntax error in source field.
17814 | Invalid function parameter.
17815 | No longer waiting for client connections using '%1'.
17816 | No active RPC or parameter value out of range.
17817 | No active RPC or no parameters.
17818 | No active RPC or parameter name not found.
17819 | No active RPC.
17820 | Invalid datatype parameter.
17821 | Unable to setup subchannel.
17822 | Unable to load ListenOn Net-Library '%1'.
17823 | Unable to read from ListenOn connection.
17824 | Unable to write to ListenOn connection '%1', loginname '%2', hostname '%3'.
17825 | Unable to close ListenOn connection.
17826 | Unable to set up ListenOn connection '%1'.
17827 | The maximum number of '%1!ld!' remote connections are currently in use.
17828 | Unable to read from local subchannel named pipe.
17829 | Unable to copy buffer to subchannel thread, subchannel closed.
17830 | A subchannel protocol error has occurred.
17831 | Unable to load ListenOn Net-Library '%1' version '%2'. Need Net-Library version '%3' or greater.
18732 | Unable to read login packet(s).
18733 | ListenOn connection '%1' is already in use.
17834 | Using '%1' version '%2' to listen on '%3'.
17835 | Configured for local access only.
17836 | Unable to create IO completion port.


Appendix B Events and Event Types

Events and Event Types

This appendix lists all the events supported by Open Data Services. Events can be activated by a SQL Server database client through calls to DB-Library functions or by a SQL Server database server that makes remote stored procedure calls as a result of a client-initiated activity. Each event is read from the network connection and extracted from the SQL Server tabular data stream (TDS).

For more information about events and event handlers, see Open Data Services Programming.

Event type | Description
SRV_ATTENTION | A client sends an interrupt request, or the network connection to the client is broken.
SRV_CONNECT | A client sends a connect request.
SRV_DISCONNECT | A client sends a disconnect request, or the Open Data Services server application calls the srv_event function to initiate a request to disconnect the current client thread.
SRV_LANGUAGE | A client sends a SQL Server language request, or a client or a server sends the sp_sqlexec remote stored procedure request.
SRV_RPC | A client or a server sends a remote stored procedure request.
SRV_EXIT | The Open Data Services server application calls the srv_event or srv_setevent function to initiate a request for immediate shutdown.
SRV_START | The Open Data Services server application calls the srv_run function to initiate server startup and to set server status.
SRV_SLEEP | The Open Data Services server application calls the srv_setevent function to pause a started server.
SRV_RESTART | The Open Data Services server application calls the srv_setevent function to continue a paused server.
SRV_STOP | The Open Data Services server application calls the srv_event or srv_setevent function to initiate a request to terminate all client threads and then shut down.


Appendix C Datatypes

Datatypes

This appendix lists the Open Data Services datatypes. To use these datatypes, include the SRV.H header file in your program.

With Open Data Services, you can describe and return data of text and image datatypes. However, because Open Data Services does not support pointers, it can not support DB-Library functions that require pointers (for example, dbmoretext, dbwritetext, and dbtxtptr). DB-Library clients can bind and receive data of these types as long as they receive them using the non-text DB-Library functions.

SQL Server can send the following datatypes to an Open Data Services server application as part of a remote stored procedure call:

  • srvdatetimn
  • srvfltn
  • srvintn
  • srvmoneyn
  • srvnull
  • srvvarbinary
  • srvvarchar
  • srvdecimal
  • srvnumeric

A hard-coded NULL passed to a remote stored procedure parameter or an extended stored procedure parameter is received by an Open Data Services application with the datatype SRVNULL. In the following example, the second parameter of the remote stored procedure p1 is received as a parameter of type SRVNULL to the Open Data Services rmt_srv application:

exec rmt_srv...p1 'arg1',null,'arg3'

A NULL value stored in a local variable and passed to a remote stored procedure parameter or an extended stored procedure parameter is received by an Open Data Services application with the datatype of the local variable. In the following example, the second parameter of the remote stored procedure p1 is received as a parameter of type SRVINTN by the Open Data Services rmt_srv application:

declare @v1 int
select @v1 = NULL
exec rmt_srv...p1 'arg1',@v1,'arg3'

For a detailed description of SQL Server datatypes, see the Microsoft SQL Server Transact-SQL Reference; for a detailed description of DB-Library datatypes, see the Microsoft SQL Server Programming DB-Library for C.

These are the Open Data Services datatypes:

Datatype | Description
SRVCHAR | Character datatype
SRVVARCHAR | Variable-length character datatype
SRVBINARY | Binary datatype
SRVVARBINARY | Variable-length binary datatype
SRVINT1 | 1-byte tinyint datatype
SRVINT2 | 2-byte smallint datatype
SRVINT4 | 4-byte int datatype
SRVINTN | Tinyint, smallint, or int datatype, null values allowed
SRVBIT | Bit datatype
SRVDECIMAL | Decimal datatype
SRVDECIMALN | Decimal datatype, null values allowed
SRVNUMERIC | numeric datatype
SRVNUMERICN | numeric datatype, null values allowed
SRVMONEY4 | 4-byte smallmoney datatype
SRVMONEY | 8-byte money datatype
SRVMONEYN | Smallmoney or money datatype, null values allowed
SRVFLT4 | 4-byte real datatype
SRVFLT8 | 8-byte float datatype
SRVFLTN | Real or float datatype, null values allowed
SRVDATETIM4 | 4-byte smalldatetime datatype
SRVDATETIME | 8-byte datetime datatype
SRVDATETIMN | Smalldatetime or datetime datatype, null values allowed
srvimage | Image datatype
srvtext | Text datatype
SRVNULL | null

Open Data Services applications also use the same datatype definitions as DB-Library functions. For more information, see the Microsoft SQL Server Programming DB-Library for C.


Appendix D Using the sp_sqlexec Built-in Stored Procedure

Using the sp_sqlexec Built-in Stored Procedure

The sp_sqlexec built-in stored procedure for Open Data Services provides a convenient way for SQL Server database clients and servers to send a language statement of any format to an Open Data Services server application.

The sp_sqlexec stored procedure call uses the following syntax:

sp_sqlexec "query_string"

where

query_string
Is a single database query that you want to send to a destination data source that is connected to an Open Data Services server application. The string can have a maximum of 256 characters, and must be of a char or varchar datatype. You must enclose the string in quotation marks.

The sp_sqlexec built-in stored procedure accepts a user-specified string as a stored procedure argument. SQL Server can pass the stored procedure call to a remote Open Data Services server without performing any processing on the string.

When Open Data Services receives the sp_sqlexec request, it converts the request into a language statement so that the string is handled by the Open Data Services language event handler, allowing the Open Data Services server application to pass the string directly to a back-end data source for processing as a language statement.

Many back-end databases cannot process remote stored procedure calls directly. The sp_sqlexec procedure allows the Open Data Services server application to function as a translator, accepting a remote stored procedure from a client or server in the SQL Server environment, and passing it to another data source as a language statement. In this way, SQL Server handles the request as a remote stored procedure, passing it to the Open Data Services server application without interpreting its contents. Any SQL Server - based client application can use sp_sqlexec to send data to or retrieve data from a gateway application, even when the client application is connected to a SQL Server and is not directly connected to the Open Data Services gateway application. Any SQL Server can call sp_sqlexec as a result of a trigger or from within another stored procedure, allowing SQL Server to send a language statement using its standard method of server-to-server remote stored procedure communication.

The following example sends a remote stored procedure call to an Open Data Services server application called odsapp, which has previously been defined as a remote server in the SQL Server sysservers table:

odsapp...sp_sqlexec "select au_lname, au_fname, phone from
    authors where au_id = '427-17-2319'"

In this example, odsapp could be an Open Data Services gateway to a DB2® database. The sp_sqlexec procedure causes the odsapp language event handler to issue the SELECT statement to the DB2 back-end database and retrieve the results of the query.


Appendix E ODBC Drivers for SQL Server and Open Data Services

ODBC Drivers for SQL Server and Open Data Services

Microsoft Open Data Services includes a set of Open Database Connectivity (ODBC) client drivers. These drivers allow ODBC client applications to establish direct connections to and exchange information with SQL Server databases and Open Data Services gateways. They are intended for use by client computers running database applications developed with the ODBC Software Development Kit.

The toolkit provides these drivers:

  • ODBC client driver for SQL Server (SQLSRVR.DLL and SQLSRV32.DLL) which connects an ODBC client application (Win16 or Win32) to Microsoft SQL Server.
  • ODBC client driver for Open Data Services gateways (ODSGATE.DLL and ODSGAT32.DLL) which is a version of the SQL Server driver designed specifically to connect an ODBC client application (Win16 or Win32) to Open Data Services gateway applications.

The ODBC driver for Open Data Services gateways works as part of a three-tier connectivity solution that includes a Windows- or Windows NT - based client, the Open Data Services gateway application, and a back-end data source (usually a relational DBMS). An Open Data Services developer can adapt the Open Data Services ODBC driver to match the characteristics of the back-end data source so that it presents the appropriate data formats and database capabilities information to ODBC client applications.

This appendix describes the architecture of the Open Data Services ODBC driver and its interaction with Open Data Services gateway applications. It addresses Open Data Services gateway developers who want to adapt the Open Data Services ODBC driver to their Open Data Services server gateway applications.

Open Data Services includes sample files for customizing the Open Data Services gateway ODBC driver. For more information about these files, see the README.TXT file provided in the C:\SQL60\OPENDS\SAMPLES\ODSODBC directory.


The Open Data Services Gateway ODBC Driver

Open Data Services applications and SQL Servers support the same data stream protocol, a format for sending commands and receiving structured result data over a network, called the Tabular Data Stream (TDS) protocol. SQL Server client libraries use this protocol for communicating and exchanging data with Open Data Services applications and SQL Servers over a network, so that for the client application, Open Data Services applications look like SQL Servers on the network.

Open Data Services gateways, however, generally do not support the exact same features as SQL Server. This means that the standard SQL Server ODBC driver does not work transparently against most Open Data Services gateways, since it expects all SQL Server features to be supported.

The Open Data Services ODBC driver is a three-tier version of the SQL Server ODBC driver, designed to connect to a back-end data source via an intermediate Open Data Services gateway. It is also designed to adapt to the features of the back-end data source.

The goal of the Open Data Services ODBC driver is to expose as much of the character of the back-end data source to the ODBC client application as possible. For example, if the back-end data source supports the DECIMAL datatype, the Open Data Services ODBC driver at the client computer performs the role of enabling the ODBC client application to use this datatype. The Open Data Services ODBC driver does not attempt to make the gateway look like SQL Server to the client, because that would result in a "lowest-common denominator" approach.

Customizing the Open Data Services ODBC driver offers an alternative to building a two-tier ODBC driver that connects directly to the back-end data source. A three-tier approach that uses an Open Data Services gateway application in the middle includes these advantages:

  • The Open Data Services ODBC driver is based on established, well-tested SQL Server driver code. Any new code to support the back-end data source is developed for the Windows NT - based server instead of for Win16 and Win32 clients. This consolidates the development process and reduces the complexity of providing connectivity.
  • The Open Data Services ODBC driver and Open Data Services share the SQL Server Net-Library layers, allowing network-independent support for popular LAN protocols such as IPX/SPX and named pipes. This is especially important for connecting to back-end data sources that do not directly support the LAN protocols used by the client computers. For example, few mainframe data sources directly support IPX/SPX communication.
  • Gateways based on Open Data Services can also support the DB-Library client interface, thus broadening the set of potential tools that can connect to the data source.

The following diagram shows the architecture of the Open Data Services ODBC driver:

Even though the Open Data Services ODBC driver and the SQL Server ODBC driver have the same basic architecture, the Open Data Services ODBC driver must be able to act as a "chameleon." An ODBC client application expects the Open Data Services ODBC driver to report datatypes and capabilities that are available from the back-end data source, not from SQL Server. To support communication between an ODBC client and a back-end data source, the gateway developer adapts the Open Data Services gateway at the server and customizes the Open Data Services ODBC driver for the client.


Supporting the Open Data Services ODBC Driver at the Server

At the server, the Open Data Services gateway application must be able to pass dynamic information about the back-end data source to the Open Data Services ODBC driver in an expected format. This type of information includes system catalog information (such as available tables and indexes) and result set information (such as column names and datatypes).

To return system catalog information, the Open Data Services gateway must adapt the catalog stored procedures that are defined for SQL Server. These catalog stored procedures are used in the same way that the SQL Server catalog stored procedures are used: They obtain schema information which can only be determined by interrogating the underlying system tables. To pass information back to the Open Data Services ODBC driver about the datatypes in the columns of a results set, the gateway can use a special encoding of the SQL Server user-defined datatype field.


Catalog Stored Procedures

ODBC supports a number of APIs that return system catalog information in a standard way. In order to support these APIs, the Open Data Services ODBC driver calls the following catalog stored procedures:

Procedure | Returns
sp_column_privileges | Information about column privileges for the specified table or tables.
sp_columns | Information about columns for the specified table or tables.
sp_databases | A list of databases.
sp_datatype_info | Information about the datatypes (used only by the Open Data Services ODBC driver if the resources DLL does not contain this information).
sp_fkeys | Information about foreign keys.
sp_pkeys | Information about primary keys.
sp_server_info | A list of attribute names and matching values for the server (only attributes 1, 2, and 500 are used by the Open Data Services ODBC driver).
sp_special_columns | Information for a single table about columns in the table that have special attributes.
sp_sproc_columns | Column information for a stored procedure.
sp_statistics | A list of indexes for a single table.
sp_stored_procedures | A list of stored procedures.
sp_table_privileges | Information about table privileges for the specified table or tables.
sp_tables | A list of objects that can be queried.

The Open Data Services ODBC driver calls these catalog stored procedures as SRV_RPC events if the IDS_FEATURE_RPC_SUPPORT flag is set to Y in the gateway resources DLL; otherwise, it calls them as srv_language events. Note that the sp_server_info and sp_datatype_info procedures are used only in a limited way, because much of this information is stored in the gateway resources DLL file instead. For more information about catalog stored procedures, see the Microsoft SQL Server Transact-SQL Reference.


Datatype Mapping

The SQL Server ODBC driver implements SQLDescribeCol and SQLColAttributes using the metadata information returned in the TDS header for that result set. Normally, an Open Data Services gateway application sets this metadata information via the srv_describe call, using SQL Server datatype codes, so that the Open Data Services ODBC driver maps the SQL Server datatype to the ODBC datatype and returns the information to the client.

This method of datatype mapping is valid whenever there is a one-to-one correspondence between the datatype supported by the data source, by SQL Server, and by the ODBC client (as with integer and floating-point datatypes). However, this method is not valid when an ODBC datatype is supported by the data source but has no corresponding SQL Server datatype (and therefore no underlying TDS protocol support).

For example, the TIMESTAMP datatype creates mapping incompatibilities between the three systems. Open Data Services gateways could convert TIMESTAMP data to character data using the default ODBC conversion, and then describe the data as SRVVARCHAR using srv_describe. It is important to note that if the only datatype information passed to the Open Data Services ODBC driver is the SQL Server SRVVARCHAR datatype, the driver has no way of knowing the original datatype. Thus, without additional datatype information, the SQLDescribeCol and SQLColAttributes calls made by the driver cannot return a TIMESTAMP datatype to the ODBC application.

Open Data Services gateway applications can convey lost information about the original datatype to the Open Data Services ODBC driver by filling in the Open Data Services usertype descriptor. To set this user-defined datatype field, use the srv_setutype call. The gateway should encode a user-defined datatype for all fields of a result set, regardless of whether there is an exact match to a SQL Server datatype. If the gateway does not set a usertype descriptor, the Open Data Services ODBC driver assumes that the data source supports SQL Server datatypes.

The following information about the original datatype must be conveyed in the user datatype field:

  • Datatype code ¾ the ODBC-defined encoding of the original datatype. The Open Data Services ODBC driver uses this code to look up the datatype name and other attributes.
  • Case Sensitivity ¾ whether a character column is case sensitive. In some DBMS implementations, case sensitivity can be set on a database, table, or column basis. Valid values are TRUE and FALSE.
  • Nullability ¾ whether a character column is "nullable." This information is conveyed in the TDS metadata for numeric datatypes only, so it would be lost if it were not put in the user datatype field. Valid values are TRUE and FALSE.
  • Updateability ¾ whether a column can be updated. Valid values are SQL_ATTR_READONLY, SQL_ATTR_WRITE 1, and SQL_ATTR_READWRITE_UNKNOWN 2 (from the ODBC header file SQLEXT.H).
  • Datatype lookup key (fNew) ¾ whether the datatype code described above refers to an ODBC datatype or to a gateway-defined datatype. Valid values are NEWODBCTYPE and NEWUSERTYPE.
  • Precision ¾ the length of the particular data value being described. For non-numeric datatypes, precision is an SWORD that holds the length of the actual data at the source. For numeric datatypes, precision is a BYTE that combines with the Scale value described below to form the num structure.
  • Scale ¾ the scale of the source column data. Used only for numeric datatypes.

To convey this extra information in the 4 bytes that are provided for a user datatype, the user datatype field returned in the TDS metadata is formatted using the following structure:

typedef struct odsusertype
{
    CHAR    fType;
        BYTE fNullable:1,
            fCaseSensitive:1,
            fUpdateable:2,
            fUnused:2,
            fNew:2;
        union
        {
            struct
            {
                BYTE cbPrecision;
                BYTE ibScale;
            } num;
            SWORD    cbPrecision;
        };
    } ODSUSERTYPE;
    #define NEWODBCTYPE 1
    #define NEWUSERTYPE 2


fType and fNew Values

The most important information in the ODSUSERTYPE data structure is the fType value. In most cases, this should be an ODBC datatype code, as defined in the Microsoft ODBC 2.0 Programmer's Reference and SDK Guide. (The datatype constants themselves are defined in the ODBC header files SQL.H and SQLEXT.H.)

When fType refers to an ODBC datatype code, fNew should be set to NEWODBCTYPE. The Open Data Services ODBC driver will then look up additional information about the datatype in the gateway resources DLL file, such as its native name and its use in a search clause. In the sample resources DLL file shipped with this toolkit, these datatype definitions are defined in the LOCAL.RC source file, starting with IDS_DATATYPE_OFFSET+0. The Open Data Services ODBC driver will find the first datatype definition whose DATA_TYPE value (second column) matches the fType set by the gateway.

The IDS_DATATYPE_OFFSET strings include values for NULLABLE and CASE SENSITIVE that apply to a datatype as a class. If these values indicate that a datatype can be null or is case sensitive, the Open Data Services ODBC driver will use the values of the fNullable and fCaseSensitive flags to determine if a given column instance of the datatype can contain null values or is case sensitive.

For some data sources, there may be more than one source datatype that matches an ODBC datatype. For example, a data source might support both a MONEY datatype and a DECIMAL datatype, both of which map to the ODBC datatype SQL_DECIMAL. To distinguish between the different source datatypes in this case, set the fNew flag to NEWUSERTYPE. The Open Data Services ODBC driver will then interpret the fType code as a USER_TYPE (last column) when looking up the datatype attributes in the resources DLL.


Setting Precision and Scale

The cbPrecision value (for non-numeric datatypes) and the num.cbPrecision and num.ibScale values should reflect the actual precision and scale of the source data for the column. The ODBC interpretation of these values is described in the Microsoft ODBC 2.0 Programmer's Reference and SDK Guide. For fixed-length datatypes, the cbPrecision value should match the precision value (column 3) coded in the resources DLL and the precision value returned by sp_columns for that datatype. For variable-length datatypes, cbPrecision should always be less than or equal to the precision value in the resources DLL and equal to the precision value in sp_columns.


Guidelines for Datatypes Not Supported in SQL Server TDS

The following are the specific cases in which the Open Data Services ODBC driver employs special strategies to avoid losing information when converting data to SQL Server TDS datatypes:

SQL_TIMESTAMP
The SQL Server DATETIME datatype limits the fractional part of the seconds to a precision of 1/300 second (about 3 milliseconds). Some DBMSs allow greater precision. The Open Data Services ODBC driver converts TIMESTAMP values sent as CHAR or VARCHAR data in ISO format (yyyy-mm-dd.hh.mm.ss.fffffffff) with fractional seconds of up to nine digits (the ODBC limit of precision). For example, this is done when the TDS datatype is a form of character but the ODBC datatype in the metadata is SQL_TIMESTAMP. DBMS DATE and TIME datatypes don't have this problem because they can be represented exactly by the SQL Server DATETIME datatype.
SQL_BIGINT
SQL Server does not have a native datatype to exactly represent a SQL_BIGINT. The Open Data Services ODBC driver converts BIGINT values sent as character data without loss of significance. This is done when the TDS datatype is a form of character and the ODBC datatype is SQL_BIGINT. The Open Data Services application could also convert SQL_BIGINT values to SRVDECIMAL values with a precision of 19.

These conversions are usually specified by SET statements in the initialization strings, either in the resources DLL or in ODBC.INI.


Example

The following code fragment sets the ODSUSERTYPE structure for a few common cases:

#define odstype ODSUSERTYPE
//***********************************************************
//  Initialize ODSUSERTYPE
//***********************************************************
if (col_p-> fNullAllowed)
        odstype.fNullable = TRUE;
else
        odstype.fNullable = FALSE;
odstype.fCaseSensitive = TRUE;
odstype.fUpdateable = SQL_ATTR_READWRITE_UNKNOWN;
odstype.fUnused = 0
odstype.fNew = NEWODBCTYPE;
odstype.cbPrecision = 0;

//***********************************************************
//  Switch based on column type
//***********************************************************
switch (col_p->uiType)
{
        //*******************************************************
        //  fixed-length character
        //*******************************************************
        case GW_FIXCHAR:
            odstype.cbPrecision = col_p->uiLen;
            odstype.fType = SQL_CHAR;
            break;

        //*******************************************************
        //  variable-length character
        //*******************************************************
        case GW_VARCHAR:
            odstype.cbPrecision = col_p->uiLen;
            odstype.fType = SQL_VARCHAR;
            break;

        //*******************************************************
        //  integer
        //*******************************************************
        case GW_INT:
            odstype.fCaseSensitive = FALSE;
            odstype.num.cbPrecision = 10;
            odstype.fType = SQL_INTEGER;
            break;

        //*******************************************************
        //  decimal
        //*******************************************************
        case GW_DECIMAL:
            odstype.fCaseSensitive = FALSE;
            odstype.num.cbPrecision = (BYTE)col_p->uiPrecision;
            odstype.num.ibScale = (BYTE)col_p->uiScale;
            odstype.fType = SQL_DECIMAL;
            break;

        //*******************************************************
        //  float
        //*******************************************************
        case GW_FLOAT:
            odstype.fCaseSensitive = FALSE;
            odstype.num.cbPrecision = 15;
            odstype.fType = SQL_FLOAT;
            break;


Customizing the Open Data Services ODBC Driver

There are two places in which you can customize the behavior of the Open Data Services ODBC driver to suit your gateway application: the gateway resources DLL and the ODBC.INI file.

The gateway resources DLL at the client computer contains information about the gateway's capabilities. These capabilities include:

  • the datatypes that are supported by the back-end DBMS
  • gateway support for the various ODBC escapes
  • support for transaction isolation levels
  • support for scalar functions
  • support for SQL Server statement preparation optimizations

The capabilities information is stored as a Windows string resource, with one string for each capability.

In addition, a new section in ODBC.INI or Registry has been added to those required by the SQL Server driver, specifying the file path of the resources DLL and optional initialization strings.


The Gateway Resources DLL

The gateway resources DLL encodes specific information about the capabilities of a gateway and its data source. This information is used by the Open Data Services ODBC driver to determine the handling of prepared statements, transaction commit/rollback, isolation levels, and other features of the ODBC interface.

For more information about the sample source code for a resources DLL, see the README.TXT file provided in the C:\SQL60\OPENDS\SAMPLES\ODSODBC directory. This sample is coded to allow the Open Data Services ODBC driver to connect directly to Microsoft SQL Server 6.0.


Adapting the Gateway Resources DLL

The sample resources DLL consists of four files:

  • SAMP.RC, which encodes the language-independent features of the gateway and data source. Except where noted, the customization values described below are found in this file. In almost every case, these values correspond to attributes set or returned by the ODBC API. See the comments in this file for additional descriptions of individual values.
  • LOCAL.RC, which includes the localizable strings used by the Open Data Services ODBC driver. If the customized Open Data Services ODBC driver is offered in multiple languages, only this file should need to change between languages.
  • LIBMAIN.C, which is the shell program for the resources DLL. This should not be changed.
  • ODSRC.H, which is the header file used by both the Open Data Services ODBC driver and the gateway resources DLL. This should not be changed.


SQLGetInfo Values

The IDS_INFO_OFFSET values form a one-to-one mapping with the fInfoType values defined for SQLGetInfo in the Microsoft ODBC 2.0 Programmer's Reference and SDK Guide. Some of the values for IDS_INFO_OFFSET are actually SELECT statements that are executed when SQLGetInfo is called. This allows flexibility for data sources where the values might be dependent on the installation or on the individual user.

The IDS_SPROC_VERSION string is used to validate that the gateway's catalog stored procedures are the proper version. The Open Data Services ODBC driver gets the gateway's version by using sp_server_info 500. If the version in the resource is greater than the gateway's version, a warning message is returned when the connection is complete.


Datatypes

The Open Data Services ODBC driver uses strings in the resource DLL to provide the results for the SQLGetTypeInfo function. The IDS_DATATYPE_OFFSET strings in LOCAL.RC contain the DBMS-supported datatypes and their various attributes. These strings are also used for certain metadata information that does not vary by column definition, such as an unsigned attribute. For a description of how the Open Data Services ODBC driver uses these values in conjunction with metadata, see Datatype Mapping.

If the first string is empty, the Open Data Services ODBC driver executes the sp_datatype_info procedure to obtain the datatypes supported.


Initialization

The IDS_INITIALIZATION_OFFSET strings are the set of initialization commands sent to the gateway after each connection has been established. These typically set the gateway to a "raw" SQL conversion mode, set various datatype conversions, set gateway defaults to ODBC defaults, and so on. Each string is sent as one language event. If the gateway can support multiple statements, it is more efficient to put them in a single string so that they are sent to the gateway as a single language event.


Feature Support Flags

The Open Data Services ODBC driver uses these flags to determine the capability of the gateway to handle SQL Server - specific features:

IDS_FEATURE_FMTONLY_SUPPORT
This flag is set to Y if the gateway can handle the SET FMTONLY ON/OFF statement. The Open Data Services ODBC driver sends a SET FMTONLY ON statement when a statement has been prepared (SQLPrepare called) and metadata (SQLDescribeCol, SQLColAttributes, or SQLNumResultCols) is required before it has been executed (SQLExecute). The driver sets FMTONLY on, sends the SQL statement, and then sets FMTONLY off. It is expected that the gateway will return only the metadata, without any rows of data.

If this flag is set to N, the Open Data Services ODBC driver tries to add a WHERE 1=2 clause to a SELECT statement and then executes it to get the metadata. This will work only for a SELECT statement in which there is a single statement in the batch or when multiple statements are separated by semicolons. This fallback behavior may not work or may not be efficient, depending on the particular query involved and the type of back-end data source.

IDS_FEATURE_NOEXEC_SUPPORT
This flag is set to Y if the gateway can handle the SET NOEXEC ON/OFF statement. The Open Data Services ODBC driver sends a SET NOEXEC ON statement when a statement is to be prepared (SQLPrepare called). It is expected that the gateway will return any errors found in processing but not execute the statement. If the DBMS supports a true prepare model, the statement should be prepared and the plan held for later execution. For more information, see Prepare/Execute Handling.
IDS_FEATURE_HOLDLOCK_SUPPORT
This feature is set to Y if the gateway supports the HOLDLOCK keyword of the SQL Server SELECT statement to hold locks for the duration of the transaction. When SQLConnectOption SQL_TXN_ISOLATION is set to SQL_TXN_SERIALIZABLE, the Open Data Services ODBC driver adds a HOLDLOCK keyword after each table name in the select statement.

If set to N, the HOLDLOCK keyword is never added. For more information, see Transaction Handling and Isolation Levels.

IDS_FEATURE_NOTNULL_DEFAULT
This flag is set to Y if the gateway has a default of NOT NULL for the column definition in a CREATE TABLE or ALTER TABLE statement. The ODBC default is NULL. If neither NOT NULL nor NULL is specified, the Open Data Services ODBC driver adds NOT NULL after each column name. If this flag is set to N, these statements are unchanged.
IDS_FEATURE_TEXTPTR_SUPPORT
This flag is used by the Open Data Services ODBC driver to determine the level of text pointer support supported by the gateway. The following settings are supported:
Flag Setting | Description
N | No text pointer support
R | READTEXT
W | WRITETEXT
U | UPDATETEXT
B | READTEXT and WRITETEXT
A | READTEXT, WRITETEXT, and UPDATETEXT

The Open Data Services ODBC driver currently uses WRITETEXT to send LONG VARCHAR or LONG VARBINARY data that is longer than 64K to the gateway. If the data is shorter than 64K, it is treated normally. If the gateway does not support text pointers, set the flag to N. This restricts the ODBC application from sending data that is longer than 64K to LONG VARCHAR/VARBINARY columns. Currently, the Open Data Services ODBC driver does not use READTEXT, so output data from these columns is only included in the normal result set. The Open Data Services ODBC driver uses UPDATETEXT when an update of a long data column affects multiple rows.

IDS_FEATURE_RPC_SUPPORT
The following flag settings are supported:
Flag
setting
Description
Y | The gateway supports execution of procedures through the RPC mechanism in addition to a language event. The Open Data Services ODBC driver will use the RPC invocation for execution of the catalog stored procedures and canonical procedure invocation. This is advantageous since the data is presented in binary form and there is no SQL statement to parse. RPC can also be used for prepare/execute, if supported. For more information, see Prepare/Execute Handling.
N | The Open Data Services ODBC driver will execute any procedure invocation using SQL statements as a language event. The IDS_AUX_RPC_TEXT string contains the text added as a prefix to the function name.
B | Executing multiple RPCs in a single batch is supported.

IDS_FEATURE_STRIP_SEPARATORS
This flag is set to Y if the gateway does not support semicolons between statements in a batch. The Open Data Services ODBC driver changes the separators to blanks.

This flag is set to N if the gateway or DBMS supports the semicolon statement separator.

IDS_FEATURE_TSQL_OJ_SUPPORT
This flag is set to Y if the gateway supports the SQL Server outer join syntax (*= or =*). The Open Data Services ODBC driver converts a canonical outer join to the SQL Server syntax.

This flag is set to N if the gateway does not support the SQL Server outer join syntax. In this case, the Open Data Services ODBC driver will send the canonical form through to the gateway for it to handle. If the gateway does not support either the SQL Server or canonical form, the SQLGetInfo SQL_OUTER_JOINS option should be set to N.

IDS_FEATURE_EXEC_THRU_PROC
This flag is set to Y if the gateway wants the Open Data Services ODBC driver to create a procedure and execute it for the prepare/execute model. If set to N, execution of a prepared statement will have the SQL statement sent with each execution. For more information, see Prepare/Execute Handling.
IDS_FEATURE_KEEP_PARM_MARKERS
This flag is set to Y if the gateway wants the parameter markers (question marks) to be retained when the statement is sent for preparation. If this flag is set to N, the Open Data Services ODBC driver substitutes dummy data of the proper type for the parameter markers.
IDS_FEATURE_AS_ALIAS
This flag is set to Y to tell the ODBC driver to keep the AS keyword ('column_name AS column_alias') in a SQL statement. If this flag is set to N, the ODBC driver removes the AS keyword.
IDS_FEATURE_ASC_INDEX
This flag is set to Y to tell the ODBC driver to keep the ASC and DESC keywords in a CREATE INDEX statement. If this flag is set to N, the ODBC driver removes these keywords.
IDS_FEATURE_CURSOR_SUPPORT
This flag is set to Y if the gateway supports the Microsoft SQL Server 6.0 cursor extended stored procedures. This allows the gateway to expose scrollable, updateable cursors to the client application. If this flag is set to N, the gateway does not support these cursor extended stored procedures.
IDS_FEATURE_DECNUM_SUPPORT
This flag is set to Y if the gateway supports data in the Open Data Services SRVDECIMAL and SRVNUMERIC format. If this flag is set to N, the gateway does not support these datatypes.


Prepare/Execute Handling

The Open Data Services ODBC driver supports three prepare/execute models:

  • The gateway supports creation and execution of SQL Server stored procedures. By setting the IDS_FEATURE_EXEC_THRU_PROC string to Y, the Open Data Services ODBC driver creates a stored procedure (using SQL Server syntax) when SQLPrepare (or SQLExecute, if all parameters were not set at SQLPrepare time) is called. It then executes that stored procedure as an RPC (IDS_FEATURE_RPC_SUPPORT = Y) or language event every time the application calls SQLExecute. The stored procedure is dropped when the cursor is dropped or re-used. If this process is not supported by the gateway and DBMS, or if procedure creation is inefficient, it should not be used.
  • The gateway supports NOEXEC. The Open Data Services ODBC driver sends the SQL statement with parameter markers or dummy data, depending on the IDS_FEATURE_KEEP_PARM_MARKERS string, with the SET NOEXEC ON statement as a prefix and followed by a SET NOEXEC OFF in the same batch. The gateway can prepare the statement and keep the plan available. When the application calls SQLExecute, the Open Data Services ODBC driver resends the SQL statement with the real data replacing the parameter markers or dummy data. The gateway can then extract the real data and execute the plan with it.
  • None of the above. The Open Data Services ODBC driver sends the SQL statement with the real data whenever the application calls SQLExecute. Nothing is done at SQLPrepare time.


Transaction Handling

The ODBC specification supports both autocommitting of transactions and explicit committing of transactions. For information, see the sections on transactions in both "Developing Applications" and "Developing Drivers" in the Microsoft ODBC 2.0 Programmer's Reference and SDK Guide. The default for the driver is autocommit mode with a default transaction isolation specified.

The Open Data Services ODBC driver supports three transaction models:

  • The DBMS implicitly starts a transaction and an explicit COMMIT/ABORT type statement ends it. DB2 behaves this way.
  • The DBMS automatically commits the statement after each execution, an explicit BEGIN TRANSACTION type statement starts an explicit transaction and an explicit COMMIT/ABORT type statement ends the explicit transaction. SQL Server behaves this way.
  • The DBMS supports both autocommit and explicit transactions. The AS/400® behaves this way.

The first transaction model requires either the Open Data Services ODBC driver or the gateway itself to issue explicit commits after each SQL statement to simulate autocommit mode. When autocommit is off, the DBMS implicitly starts the transaction and the ODBC application explicitly ends the transaction. If the IDS_AUTOCOMMIT_OFFSET strings are not empty, the Open Data Services ODBC driver sends the appropriate string to the gateway to turn autocommit on or off in the gateway. In this case, the gateway issues its own commits after each SQL statement. If these strings are empty, the Open Data Services ODBC driver assumes responsibility for issuing an explicit commit (see the IDS_TRANSACT_OFFSET string) after each SQL statement when autocommit is turned on. If the gateway is performing the autocommit and if the default for the gateway can be configured to set autocommit off, be sure to include the proper initialization string to set autocommit on in the gateway. For more information, see Gateway Initialization.

The second transaction model requires either the Open Data Services ODBC driver or the gateway itself to issue explicit transaction starts before the first SQL statement after an explicit commit/rollback when the ODBC application is not in autocommit mode. If the IDS_AUTOCOMMIT_OFFSET strings are not empty, the Open Data Services ODBC driver sends the appropriate string to the gateway to turn autocommit on or off in the gateway. In this case, the gateway issues the explicit transaction start before the first SQL statement. If these strings are empty, the Open Data Services ODBC driver issues a transaction start (see the IDS_BEGINTRAN string) before the first SQL statement. If the default for the gateway can be configured to set autocommit off, be sure to include the proper initialization string to set autocommit on in the gateway. For more information, see Gateway Initialization.

The third transaction model has the DBMS doing most of the work. The Open Data Services ODBC driver sends the appropriate string to turn autocommit on or off (see IDS_AUTOCOMMIT_OFFSET strings). If autocommit support is implemented in the DBMS as one of the transaction isolation levels, the gateway is responsible for correctly setting the previous isolation level when autocommit is turned off.

When autocommit is turned off and the application ends a transaction (SQLTransact), the appropriate string to commit or terminate is sent to the gateway. If the SQLTransact option is SQL_COMMIT, the IDS_TRANSACT_OFFSET+SQL_COMMIT string is sent. If the SQLTransact option is SQL_ROLLBACK, the IDS_TRANSACT_OFFSET+SQL_ROLLBACK string is sent.


Isolation Levels

ODBC supports five isolation levels. For information about ODBC isolation levels, see SQLSetConnectOption in the Microsoft ODBC 2.0 Programmer's Reference and SDK Guide. The Open Data Services ODBC driver sends the appropriate string from the IDS_ISOLATION_OFFSET section when the SQLSetConnectOption SQL_TXN_ISOLATION option is set.

If the string is empty, a SQL_ERROR with a SQL State of S1C00 is returned. The value of the SQL_TXN_ISOLATION_OPTION string in the SQLGetInfo section needs to match the IDS_ISOLATION_OFFSET strings that are not empty. The value of the SQL_DEFAULT_TXN_ISOLATION string needs to match the default isolation level of the DBMS. If the default isolation level can be configured on the gateway or DBMS and can't be obtained using SQL statements, be sure to include the proper initialization string to set the default to the value specified in SQL_DEFAULT_TXN_ISOLATION. For more information, see Gateway Initialization.

Some DBMSs have a single isolation level or have a configurable single isolation level. In this case, the SQL_DEFAULT_TXN_ISOLATION string needs to return that level. The SQL_TXN_ISOLATION_OPTION would return 0, since the application cannot change levels and the IDS_ISOLATION_OFFSET strings would be empty.

If IDS_FEATURE_HOLDLOCK_SUPPORT is set to Y, none of the IDS_ISOLATION_OFFSET strings are used. In this case, the Open Data Services ODBC driver behaves as if it were connected to SQL Server, adding the HOLDLOCK keyword after table names when the SQLSetConnectOption SQL_TXN_ISOLATION option is set to SQL_TXN_SERIALIZABLE.


Read-Only Mode

ODBC supports the concept of a read-only connection. For information about ODBC read-only connections, see SQLSetConnectOption in the Microsoft ODBC 2.0 Programmer's Reference and SDK Guide. If the gateway or DBMS supports a read-only connection, IDS_ACCESS_MODE_OFFSET strings should be set to the appropriate SQL statement.

If these strings are empty, the SQLSetConnectOption SQL_ACCESS_MODE option is ignored by the Open Data Services ODBC driver. Note that the ODBC definition of read-only connections is not necessarily intended to preclude non-selects, but is intended to optimize locking for selects only. An error can be returned on non-selects if the gateway or DBMS needs to return an error, but it is not required.


Multiple Language Support

The Open Data Services ODBC driver has the capability of exposing support for multiple languages in the DBMS. If multiple languages are supported, the IDS_LANGUAGE_QUERY string is the SQL statement used to fill in a list box of the supported languages. The user can then select one of these languages during SQLDriverConnect.

The initial selection of the list box is set to the language returned from the IDS_DEF_LANGUAGE_QUERY string. The language is set by the Open Data Services ODBC driver sending the IDS_AUX_LANGUAGE string, with the language appended to the gateway for processing. The language can also be set during DSN setup or can be passed to SQLDriverConnect using the LANGUAGE keyword. If the IDS_LANGUAGE_QUERY string is empty, the language control in the dialog boxes is disabled and the LANGUAGE keyword in the connection string is ignored.


Qualifiers/Databases

The Open Data Services ODBC driver has the capability of exposing support for user selection of default qualifiers or databases. The concept of a default qualifier is the ability of the DBMS to set a default that automatically qualifies any table name by that default.

For example, SQL Server uses a default qualifier to assign a default database to a user as a result of the user login. Any table reference must be in that database unless an explicit qualifier is specified. This default qualifier can be either the first part (ODBC qualifier) or second part (ODBC ownerid) of the three-part table name. If user selection of a default qualifier is supported, the IDS_DATABASE_QUERY string contains the SQL statement used to fill in a list box of the supported qualifiers. The user can then select one of these qualifiers during SQLDriverConnect.

The initial selection of the list box is set to the qualifier returned from the IDS_DEF_DATABASE_QUERY string. The qualifier is set by the Open Data Services ODBC driver sending the IDS_AUX_USE string with the qualifier appended to the gateway for processing. The qualifier can also be set during DSN setup or can be passed to SQLDriverConnect using the database keyword. If the IDS_DATABASE_QUERY string is empty, the database control in the dialog boxes is disabled and the DATABASE keyword in the connection string is ignored.


Row Count

If the gateway or DBMS has support for limiting the number of rows returned in a single result set, the IDS_AUX_SETROWCOUNT string contains the SQL statement sent to the gateway with the count appended. If the IDS_AUX_SETROWCOUNT string is empty, the SQLSetStmtOption SQL_MAX_ROWS option returns SQL_ERROR with a SQL State of S1C00. If there is a non-infinite default that limits the number of rows returned, be sure to include the proper initialization string to set an infinite row count in the gateway. For more information, see Gateway Initialization.


Text Size

If the gateway or DBMS has support for limiting the length of the data returned from a LONG VARCHAR or LONG VARBINARY column, the IDS_AUX_SETTEXTSIZE string contains the SQL statement sent to the gateway with the size appended. If the IDS_AUX_SETTEXTSIZE string is empty, the SQLSetStmtOption SQL_MAX_LENGTH option returns SQL_ERROR with a SQL State of S1C00. If there is a non-infinite default that limits the size of long columns, be sure to include the proper initialization string to set no limit in the gateway. For more information, see Gateway Initialization.


Dialog Boxes

The Open Data Services ODBC driver contains two dialog boxes that can be customized using strings in the gateway resources DLL. These are the DSN setup and SQLDriverConnect dialog boxes. Both contain similar fields and descriptions. The definitions for all of these fields except IDS_GTWYNAME are found in the LOCAL.RC source file.

The IDS_LOGIN_DIALOG_CAPTION string is used for the title bar at the top of the SQLDriverConnect dialog box.

The following strings are used for the text fields next to the associated control in both dialog boxes:

  • IDS_LOGIN_DIALOG_USERTERM
  • IDS_LOGIN_DIALOG_PASSWORDTERM
  • IDS_LOGIN_DIALOG_DATABASETERM
  • IDS_LOGIN_DIALOG_LANGUAGETERM

These strings also contain the ampersands (&) for the accelerators, so be sure that you don't duplicate accelerator keys of other controls in each dialog box. The database and language controls may be disabled. For more information, see Multiple Language Support and Qualifiers/Databases.

The IDS_GTWYNAME string in the SAMP.RC file is used during driver setup. The list box of gateway types is filled in from this string in each ODS*.DLL in the \WINDOWS\SYSTEM directory.


Canonical Functions

The ODBC specification supports various SQL functions that can be executed in a canonical method. For more information about passing the canonical form through a gateway without modification, see the comments in the SAMP.RC file. The Open Data Services ODBC driver supports a limited capability for parsing and converting the canonical form into a DBMS-specific format. The IDS_AUX_FUN_PINFO strings drive the parser/converter. The comments in the SAMP.RC file specify the string format.

The major restriction in the Open Data Services ODBC driver converter is that parameters cannot be duplicated or reordered. There is one string for each ODBC canonical function. If the gateway does not support the canonical form and the string is empty, the appropriate bit in the value of the SQL_xxxx_FUNCTIONS string must be zero, meaning that the canonical function is not supported.

If the canonical CONVERT function is supported, the values of the SQL_CONVERT_xxxx strings must correspond to the set of conversions supported for that datatype. See SQLGetInfo in the Microsoft ODBC 2.0 Programmer's Reference and SDK Guide for more information.


Canonical Date/Time Conversions

The ODBC specification supports canonical forms of date, time, and timestamps for input to the server as character literals and parameters. The Open Data Services ODBC driver uses the strings IDS_AUX_ECODE_PARSE_INFO1, IDS_AUX_ECODE_PARSE_INFO2, and IDS_AUX_ECODE_PARSE_INFO3 to convert canonical dates, times, and timestamps respectively into a DBMS-specific string specified by IDS_AUX_ECODE_TEMPLATE_xxxx strings. The format used for the DBMS input should be order-insensitive to prevent month/day/year ordering problems. The IDS_AUX_ECODE_FORMAT_xxxx strings are used to convert SQL_C_DATE, SQL_C_TIME, and SQL_C_TIMESTAMP parameters into character literals. These normally use the same DBMS format as the IDS_AUX_ECODE_TEMPLATE_xxxx strings.


Canonical Procedure Invocations

The ODBC specification supports invoking a stored procedure through a canonical method. If IDS_FEATURE_RPC_SUPPORT is set to Y, the stored procedure is executed as an RPC. If there is a batch of multiple canonical stored procedure invocations and IDS_FEATURE_RPC_SUPPORT is set to B, the batch is executed as a single batched RPC. In all other cases, the procedure is executed as a language event. The IDS_AUX_RPC_TEXT string is used as the verb for the language event. The IDS_AUX_RPC_SEP is a 3-character string which is used to map the ODBC parameter separators "(,)".


Miscellaneous

The IDS_HOSTDBMS string contains the name of the target DBMS. This is used in the Open Data Services ODBC driver for special cases. Currently the only defined use of this value is for IDS_HOSTDBMS=DB2. When the Open Data Services ODBC driver detects this value, it saves the default database as specified in the data source definition or in the ODBC SQLDriverConnect call. The Open Data Services ODBC driver uses this default database name in the SQLGetInfo call to provide the qualifier for the DB2 system catalogs. It is also used for the database name in a DB2 Create Table IN DATABASE clause.


ODBC.INI Entries for Gateway Customization

The ODBC.INI file contains some additional entries for the Open Data Services ODBC driver. At a minimum, the ODBC.INI file must specify the gateway resources DLL. The Initialization entry is optional.


Resource DLL Name

The Open Data Services ODBC driver must know where to find the resources DLL for each data source. The GatewayResource keyword in ODBC.INI gives the file path to the specific DLL to use. If the gateway resource filename is of the form ODS*.DLL, and if it is found in the \WINDOWS\SYSTEM directory, the Open Data Services ODBC setup program will know to list the gateway as a choice during setup.


Gateway Initialization

Even though a gateway initialization section is provided in the gateway resource DLL, the Open Data Services ODBC driver allows the client installation to override or add additional initialization commands. This is provided through the Initialization keyword in ODBC.INI. The Initialization section is a set of commands, delimited by semicolons, that the driver executes after the resources DLL default initialization commands and before any user-initiated statements.


Example

An Open Data Services gateway to Rdb might use a resource file named ODSRDB.DLL. Also, this gateway might be able to interpret the Transact-SQL USE command to set the default schema for a user differently from the default used by the gateway instance. The ODBC.INI file might look like this for a data source pointing to this gateway:

[RdbGate]
Driver=C:\WIN31\SYSTEM\odsgate.dll
Description=SQL Server gateway for Rdb
OemToAnsi=No
GatewayResource=c:\win31\system\odsrdb.dll
Initialization=USE sys$sysdevice:[user.fred]personnel


Error Messages

Error messages produced by the data source or by the gateway must be mapped to corresponding ODBC errors. Error mapping can be accomplished directly by the gateway or by the Open Data Services ODBC driver. Gateways that do not support ODBC error mapping use SQL Server driver error code mapping, which causes the gateway to map native errors to SQL Server error codes, and the driver to then map those codes to ODBC errors.

In order to map ODBC more directly to the underlying DBMS, gateways can perform the mapping directly. All mapping from gateway or remote DBMS errors to ODBC error codes is represented in the message text string passed to the client. Gateways construct the srv_message string to contain both the ODBC error code mapping and the gateway or DBMS error text. The error message consists of parts, delimited by brackets, using the following format:

[SQLSTATE code][vendor id][native error number][gateway name] [remote DBMS ID]:error text

where

SQLSTATE code
Is the ODBC code that maps to the gateway error or DBMS error. The ODBC driver for the gateways strips off this section and passes it to the client in the szSQLState return parameter for the ODBC SQLError API. If the DBMS returns SQLSTATE as part of its native error system, the gateway must map any DBMS SQLSTATE extensions to the appropriate ODBC SQLSTATE.
vendor ID
Is a code for the gateway vendor. This code is chosen by the gateway developer.
native error number
Is the ASCII representation of the "native" error number from a remote DBMS. This number is returned in the pfNativeError return parameter for the ODBC SQLError API. The native error number corresponds to a numeric DBMS-specific error code. For example, for a DB2 error, the SQLCA.SQLCODE would be returned in this section. This section is empty when the error is related to the gateway or does not represent a DBMS error.
gateway name
Is the name of the gateway component, for example, Rdb Gateway.
remote DBMS ID
In cases where a DBMS-specific error is returned, this section contains the name of the DBMS being accessed, such as DB2 or SQL/400®.
error text
Is the text of the error message.


Examples

DBMS Error

[SGS00][XYZ][-1][Rdb Gateway][Rdb]:%SQL-F-RELNOTDEF, Table FOO is not defined in schema.

Gateway Error

[08004][Acme][][Acme Oracle Gateway][]:Cannot connect: gateway user limit has been reached.


Glossary

aggregate functions
Functions that calculate summary values, such as averages and sums, from the values in a particular column, and that return a single value for each set of rows to which the function applies.

Aggregate functions often appear with GROUP BY, which partitions a table into groups. These functions calculate a single value for each group. Without GROUP BY, an aggregate function in the select list produces a single value as a result, whether it is operating on all the rows in a table or on a subset of rows defined by a WHERE clause.

alerts
By creating alerts, you can set up SQL Enterprise Manager to respond automatically to SQL Server events, either by executing a task that you have defined or by sending an e-mail and/or a pager message to a specified operator.
alias
A database username that is shared by several login IDs. An alias allows more than one person to be treated as the same user inside a database, giving all the designated users the same permissions. A common use for aliases is to allow several users to assume the role of database owner (DBO).
allocation page
The first page of an allocation unit that describes how the remaining pages within the allocation unit are used. SQL Server uses three units of data storage:
  • The page (2K in size)
  • The extent (8 continuous pages)
  • The allocation unit (32 extents, or 256 pages)

Each fragment of storage for a database must be at least 1 allocation unit¾0.5 MB, or 256 contiguous 2K pages. The first of the 256 pages is the allocation page. It contains an array that shows how the other 255 pages are used; unlike all other pages, it does not contain database rows.

allocation unit
A unit of data storage consisting of 32 extents, or 256 pages. DBCC NEWALLOC returns a listing for each allocation unit of the number of extents currently reserved for use by objects, the number of pages marked as being used by objects, and the actual number of pages being used by objects. An allocation unit can hold, at most, 32 database objects. An allocation unit is 512K (0.5 MB) made up of 32 extents (8, 2K pages). From this, 512K/16K results in 32 objects. The used pages value and the ref pages value should be equivalent for most, if not all, allocation units. A difference of 7 is possible due to the transaction log. A slightly larger difference is acceptable when text or image data exists within the database.

The number of extents tells you whether or not you can create new objects on that allocation unit. To estimate the amount of space reserved by database objects (tables and indexes), multiply the total number of extents by 16K. To estimate the amount of that space being used by data or index information, multiply the total number of used pages by 2K.

American National Standards Institute (ANSI)
ANSI-standard SQL offers limited support. Microsoft® addresses this problem with Transact-SQL™, an enhanced version of the SQL language for SQL Server.
ANSI
See American National Standards Institute.
ANSI to OEM conversion
The AutoANSItoOEM entry controls the default conversion behavior when you connect to a server. If AutoANSItoOEM is set to ON, conversion is turned on in the following cases:
  • ANSI clients to OEM servers (Windows and Windows NT)
  • OEM clients to ANSI servers (Windows NT)

The Automatic ANSI to OEM option enables DB-Library to convert characters from OEM to ANSI when communicating with SQL Server, and from ANSI to OEM when communicating from SQL Server to the client. By default, this option is set on.

For Windows-based clients, the SQL Client Configuration Utility includes the Automatic ANSI to OEM option. By default, the setting for the Automatic ANSI to OEM option is set off.

application log
The Windows NT application log is a special file that records new events. It can be viewed only by using the Windows NT Event Viewer. When SQL Server is configured to use the Windows NT application log, each SQL Server session writes new events to that log. (Unlike the SQL Server error log, a new application log is not created each time you start SQL Server.)
application programming interface (API)
An API is a set of routines available in an application, such as DB-Library, for use by software programmers when designing an application interface.
API
See application programming interface.
argument
A switch supported by a function that allows you to specify a particular behavior. An argument is sometimes called an option.
article
The basic unit of replication. An article contains data originating from a table that has been marked for replication. One or more articles are grouped within a publication.
attribute
A qualifier of an entity or a relation describing its character quantity, quality, degree, or extent. For example, column headings are usually considered to be attributes.
auto-start options
By default, the setup program installs SQL Server and SQL Executive to run as manually started Windows NT services. Optionally, each can be configured to run as an automatically started service. For each service, this choice is called the auto-start option.
automated server restart
If SQL Executive detects that the MSSQLServer service has stopped unexpectedly, it will automatically attempt up to three times to restart MSSQLServer. This automated restart behavior can be adjusted by modifying values in the Windows NT Registry.
automatic recovery
Recovery that occurs every time SQL Server is restarted. Automatic recovery protects your database in the event of system failure.

In each database, the automatic recovery mechanism looks at the transaction log. If the log has committed transactions not yet written out to the database, it performs those transactions again. This action is known as rolling forward.

Automatic recovery begins with the master database, goes on to model, clears out the tempdb temporary database, recovers msdb, recovers pubs, recovers distribution (if the server is configured as a replication distributor), and finally, recovers user databases. Users can log in to SQL Server as soon as the system databases have been recovered, but they can't access a user database while recovery is in progress on it.

automatic synchronization
Synchronization that is accomplished automatically by SQL Server. A snapshot is taken of the table data, and along with the table schemas that snapshot is written to files for transfer. The job to copy the table schema and data is transferred, as is any other replication job, via the distribution database. No operator intervention is required.
back end
In the context of SQL Server, a term applied to the database server level where processing, data storage, and data retrieval occurs.
back up
To create a copy of a database or transaction log on another device (a dump device). Backups are accomplished using SQL Enterprise Manager or the DUMP statement. Also called dump.
backup domain controller (BDC)
In a Windows NT domain, a server that receives a copy of the domain's security database from the primary domain controller and shares the user login authentication load.
base datatype
One of the system datatypes, which include the length for char, varchar, binary, and varbinary.
base object
See underlying object.
base table
A table from which a view is derived. A view can have one or more underlying tables. (A view can have underlying views.) Also called underlying table.
batch
A set of SQL statements submitted together and executed as a group. A script is often a series of batches submitted one after the other. A batch is compiled only once as a whole and is terminated by an end-of-batch signal (GO).
BCP
See bulk copy program.
binary datatype
Datatypes for bit patterns (not for hexadecimal data). Conversions and calculations of hexadecimal numbers stored as binary data can be unreliable.

When specifying the length of a binary datatype, every two characters count as one. A length of 10 signifies that 10 two-character groupings will be entered.

These are the binary datatypes:

binary[(n)]
Is a datatype that holds as many as 255 bytes of fixed-length binary data. Specify the maximum byte length with n. The binary datatype can contain 0 bytes, but when specified, n must be a value from 1 through 255. Storage size is n regardless of the actual length of the entry. Choose binary when you think the data entries in the column will be consistently close to the same size. Columns of type binary are accessed somewhat faster than varbinary columns because they use a fixed storage length (n).
varbinary[(n)]
Is a variable-length binary datatype that holds a maximum of 255 bytes of variable-length binary data. Specify the maximum byte length with n. A varbinary datatype can contain 0 bytes, but when specified, n must be a value from 1 through 255. Storage size is the actual length of the data entered, not n. Choose varbinary when you expect null values or a variation in data size.
binding
Associating a default or rule with a column or datatype. The sp_bindefault system stored procedure binds a default to a column or to a user-defined datatype.

The sp_bindrule system stored procedure binds a rule to a column or to a user-defined datatype.

bit datatype
Special datatype that holds 1 or 0. Integer values other than 1 or 0 are accepted but always interpreted as 1. Storage size is 1 byte. Multiple bit types in a table can be collected into bytes. Use bit for true/false or yes/no types of data.
blocks
A series of statements enclosed by BEGIN and END. You can nest BEGIN...END blocks within other BEGIN...END blocks.
bldmastr
A utility provided in earlier releases of SQL Server, used to build or rebuild the master database. SQL Server 6.0 does not need (nor does it support) a bldmastr utility or an INSTMSTR.SQL script.

The bldmastr utility has been replaced by the SQL Setup graphical user interface. All options previously available only through bldmastr have been moved or have been enhanced in SQL Setup.

Books Online
An online version of the SQL Server documentation set, it is presented as an installation option by the setup program. If installed, the Books Online icon is added to the SQL Server 6.0 program group. By choosing that icon you can view SQL Server user documentation on your computer screen. A particular benefit of Books Online is the full text search capability, which allows you to very rapidly search a book or set of books for all instances of a word or phrase.
Boolean expression
An expression that returns true or false.
browse mode
Functions that allow an application to handle ad hoc queries. Several browse-mode functions return information that an application can use to examine the structure of a complicated ad hoc query.
built-in functions
Functions provided by SQL Server that help you perform certain operations quickly and easily. These functions fall into the following categories:
  • System functions, most of which return information from the system tables
  • String functions, for manipulating char, varchar, binary, and varbinary values
  • Text and image functions, for manipulating text and image values
  • Mathematical functions, for trigonometry, geometry, and other number handling
  • Date functions, for manipulating datetime and smalldatetime values
  • A conversion function (CONVERT), for converting expressions from one datatype to another and for formatting dates in a wide variety of styles
bulk copy program (bcp)
A command-line utility that copies SQL Server data to or from an operating-system file in a user-specified format.
bulk data copy
You can break up large transactions when using bcp to bulk copy data into a database. If you use bcp without specifying a batch size, the entire operation is performed as a single logical transaction.

Even if another user process does a DUMP TRANSACTION statement, the log records associated with the bulk copy operation remain in the log until the entire operation completes or another DUMP TRANSACTION statement is executed. This is one of the most common causes of the error 1105. You can avoid the problem by splitting the bulk copy operation into batches.

business integrity
An organizational standard operating procedure that requires that certain policies (rules) be followed to ensure a correctly run business. For example: no debit without corresponding credit, no active customers to be deleted, no additional credit for those whose payments are past due. Business rules ensure that the database maintains its accuracy and integrity in a business sense.
business rules
See business integrity.
cache
A buffer used to hold data during input/output (I/O) transfers between disk and random access memory (RAM).
cached pages
Pages (one page is 2K of data) that are held in cache.
call-level interface (CLI)
The interface used by ODBC for use by an application.
Cartesian product
All the possible combinations of the rows from each of the tables. The number of rows in a Cartesian product of two tables is equal to the number of rows in the first table times the number of rows in the second table. Forming the Cartesian product is the first step in processing a join.
cascading delete
A delete that deletes all related database rows or columns.
cascading updates
An update that updates all related database rows or columns.
changeable value
A value in a table that may vary over time. Values in most tables are changeable.
char datatype
A character datatype that holds a maximum of 255 characters. Specify the maximum length with n. The char datatype can contain 0 characters, but when specified, n must be a value from 1 through 255. Storage size is n regardless of the actual length of the entry. Choose char when you think the data entries in the column will be consistently close to the same size. Columns of type char are accessed somewhat faster than varchar columns because they use a fixed storage length (n).
character set
A set of 256 letters, numbers, and symbols specific to a country of a language. The selected character set determines the types of characters that SQL Server recognizes in the databases. The printable characters of the first 128 values are the same for all character sets. The last 128 characters, sometimes referred to as extended characters, are different. During installation it is critical that you select the appropriate character set. If you later need to change it, you must rebuild your databases and reload your data.
CHECK constraints
Specify data values that are acceptable in a column. You can apply CHECK constraints to multiple columns, and you can apply multiple CHECK constraints to a single column.

When a table is dropped, all CHECK constraints are also dropped.

checkpoint
The point at which all data pages that have been changed are guaranteed to have been written to the disk.
CLI
See call-level interface.
client
A front-end application that uses the services provided by a server. The computer that hosts the application often is referred to as the client computer. SQL Server client software enables computers to connect to a SQL Server over the network.
client/server computing
A system of computing in which two or more computers share processing across a network. The server computer manages a shared resource, such as a database, and responds to requests from clients for use of this resource. The client computer interacts with a user and makes requests for use of a shared resource. Client/server computing separates the functions of an application into two distinct parts: a "front end" component and a "back end" component. The client application presents and manipulates data on the workstation; and the server stores, retrieves, and protects data.
clustered index
An index in which the logical (indexed) order of the key values is the same as the physical order in which the corresponding rows (that contain the key values) exist in the table.
Code page
A character set that determines the types of characters that SQL Server recognizes in databases. SQL Server 6.0 supports the following two Code page character sets:
  • ISO 8859-1

    The default character set. Also known as Latin 1 or ANSI character set, it is compatible with the ANSI characters used by the Windows NT and Windows operating system.

  • Code page 850

    Includes all characters for most languages of European, North American, and South American countries.

  • Code page 437

    The most commonly used character set in the United States. Includes many graphics characters not usually stored in databases. Unless you have an overriding reason to select this character set, choose code page 850, which provides more compatibility with languages other than United States English. (Setup, Chap 3, Server Options, Character Set)

collection (OLE)
A group of objects of the same type contained within a parent object.
column
The set of all rows in a table that have a common attribute (for example, the firstname column in the authors table of the pubs database). Contains an individual data item within a row or a record.
column-level constraints
A restriction used to enforce data integrity on a column (column-level constraints) or on a table (table-level constraints¾usually multicolumn constraints). You define constraints by using SQL Enterprise Manager or by specifying various options of the CREATE TABLE statement. SQL Server provides the following types of constraints: CHECK, DEFAULT, FOREIGN KEY REFERENCE, PRIMARY KEY, UNIQUE.
COM
See component object model
common key
A key created to make explicit a logical relationship between two tables in a database. See also primary key; foreign key.
complex relationship
A relationship between more than two entities, subsets, dependencies, or relations.
component object model (COM)
The model upon which SQL distributed management objects (SQL-DMO) is based.
composite index
An index that uses from 2 to 16 columns.
composite key
A key composed of two or more columns. A drawback of composite keys is that they introduce more complex join processing.
concatenation
The linking together of binary or character expressions, combining two or more character or binary strings, character or binary data, or a combination of them.
concurrency
The ability to allow several clients to access the same table, row or column at the same time (concurrently) without creating a collision.
concurrency control
Control by cursors, through several options, concurrent access (when more than one user accesses and updates the same data at the same time). With concurrent access, data would soon become unreliable without some kind of control.
concurrent access
The situation in which more than one user accesses and updates the same data at the same time.
connections
The number of logins or attempted logins to a SQL Server.
connectivity
A general term that refers to the ability of different classes of computers to communicate with one another.
consistent
A consistent database contains correct and non-conflicting information.
console utility
Displays backup and restore messages when dumping or loading to or from diskette dump devices. The console command-line utility is used by the person responsible for dumping and loading a database.
constant expression
Specifies an expression that contains only constant values (it does not include the names of any columns or other database objects). You can use any constant, built-in function, mathematical expression, or global variable. The default value must be compatible with the datatype of the column.
constant value
Any constant, built-in function, mathematical expression, or global variable. It cannot include the names of any columns or other database objects.
constraint
A restriction placed upon the value that can be entered into a column or a row. For example, age cannot be < 0 or > 110. SQL Server provides these constraints: CHECK, DEFAULT, FOREIGN KEY, REFERENCE, PRIMARY KEY, UNIQUE.
context-sensitive permission
In addition to protecting data based on a selection of rows and/or columns, you can use views for context-sensitive permission. For example, you can create a view that gives a data entry clerk permission to access only those rows that he or she has added or updated.
control-break report
A report whose summary values are controlled by the groupings, or breaks, that you specify.
control-of-flow language
Programming-like constructs (IF, ELSE, WHILE, etc.) provided by Transact-SQL so that the user can control the flow of execution of Transact-SQL statements.
controlled access protocols
On a publication-by-publication basis, you can control the access that subscription servers have to a publication by marking the publication as either unrestricted or restricted.
  • unrestricted¾visible to and can be subscribed to by any subscription server known to the publication server.
  • restricted ¾visible to only those subscription servers authorized for access. Servers not authorized for access cannot subscribe to the publication; they cannot even see it. As a result, users setting up subscriptions at servers not authorized for access will not even know of a restricted publication. At those servers, it will not appear in any list.

See also ownership chains.

correlated subquery
Many queries can be evaluated by executing the subquery once and substituting the resulting value or values into the WHERE clause of the outer query. In queries that include a correlated subquery (also known as a repeating subquery), the subquery depends on the outer query for its values. This means that the subquery is executed repeatedly, once for each row that might be selected by the outer query.
CPU busy
A SQL Server statistic, reporting the time, in milliseconds, that the CPU spent on SQL Server work.
creation script
An option, that when selected, adds object-creation statements to the script. creation_script is the path and name of an article schema script used to create target tables.
cursor
Database objects with which applications manipulate data by rows instead of by sets. Using cursors, multiple operations can be performed row by row against a results set with or without returning to the original table. In other words, cursors conceptually return a results set based on tables within the database(s). For example, a cursor can be generated to include a list of all user-defined table names within a database. After the cursor has been opened, movement (fetching) through the results set can include multiple operations against each table by passing each table name as a variable. Cursors are extremely powerful when combined with stored procedures and the EXECUTE statement (to dynamically build strings).
data
The coded representation of information for use in a computer. Data has attributes, such as type and length.
data definition
The process of setting up databases and creating database objects, such as tables, indexes, constraints, defaults, rules, procedures, triggers, and views.
data definition language (DDL)
A language for modeling the structure (rather than the contents) of a database. The ability to create, modify, and remove databases and database objects.
data dictionary
System tables containing descriptions of the database objects and how they are structured.
data integrity
Accuracy and reliability of data. Data integrity is important in both single-user and multiuser environments. In multiuser environments, where data is shared, both the potential for and the cost of data corruption is high. In large scale DBMS environments, data integrity becomes one of the primary concerns and focuses.
data manipulation language (DML)
The subset of the SQL language used to retrieve and manipulate data.
data modification
Adding, deleting or changing information in the database (using the INSERT, DELETE, and UPDATE statements).
data sharing
The ability to transparently share across different applications individual pieces of data from a database.
data synchronization
Before a new subscriber can receive replicated transactions from a publication, the publication and destination tables must contain the same schema and data. The process that accomplishes this is called initial synchronization.
data transfer
The process of copying data to or from a SQL Server.
database
A collection of information, data tables, and other objects that are organized and presented to serve a specific purpose, such as facilitation of searching, sorting, and recombination of data. Databases are stored on devices.
database catalog
The underlying tables to a database. System tables are tables used to store information about the system (the system catalog) or an individual database (the database catalog). The system catalog consists of system tables found only in the master database. The database catalog consists of system tables found in every database.
database consistency checker (DBCC)
Statement used to check the logical and physical consistency of a database, check memory usage, decrease the size of a database, check performance statistics, and so on. DBCC helps ensure the physical and logical consistency of a database, but it is not corrective.
database device
A file that databases are stored on. One database can be stored on several devices.
database language
The language used for accessing data in, querying, updating, and managing relational database systems. SQL is a widely used database language. With SQL, you can retrieve data from a database, create databases and database objects, add data, modify existing data, and perform other complex functions. You can also change the server configuration, modify database or session settings, and control data and access statements. Many of these capabilities are implemented by using one of three SQL categories: Data Definition Language (DDL), Data Manipulation Language (DML), and Data Control Language (DCL).
database management system (DBMS)
A repository for the collection of computerized data files, enabling users to perform a variety of operations on those files, including retrieving, appending, editing, updating, and generating reports.
database model
When SQL Server is installed, the setup program creates the MASTER database device. One of the databases it creates and places on that device is model. The model database provides the template or prototype on which new user databases are based. Each time a database is created, SQL Server makes a copy of the model database and then extends it to the creation size requested. The model database contains the system tables required for each user database. It can be modified to customize the structure of newly created databases so that every change you make to model is reflected in each new database.
database name
Must correspond to the rules for identifiers and can have as many as 30 characters (for example, SALES or PAYROLL91).
database object
One of the components of a database: a table, index, trigger, view, key, constraint, default, rule, user-defined datatype, or stored procedure. Anything that has a name and consumes space in a database.
database object owner
The designated owner of a database object (tables, indexes, views, defaults, constraints, triggers, rules, and procedures). The user who creates a database object is the database object owner and is automatically granted all permissions on it. The database object owner can grant permission to other users to use that object. Database object ownership cannot be transferred.
database owner (DBO)
The creator of the database. There is only one DBO. The DBO has full privileges inside that database and determines the access and capabilities provided to other users. In his or her own database, the user is recognized as the DBO; in other databases, the database owner is known by his or her database username. DBO status can be reassigned to a different user. Only one login ID can be the DBO login ID, although other login IDs can be aliased to the DBO.
database query
See query.
database scripts
A collection of statements used to create database objects. Transact-SQL scripts are saved as files, usually ending with the SQL filename extension.
datatype
An identifier that specifies what type of information a column holds and how the data is stored. System-supplied datatypes are provided by SQL Server; user-defined datatypes can also be created.
date functions
Functions used to display information about dates and times. They manipulate datetime and smalldatetime values, performing arithmetic operations on them. Date functions can be used in the select list, in the WHERE clause, or wherever an expression can be used.
datetime datatype
A SQL Server system datatype. A datetime datatype is stored in 8 bytes of two 4-byte integers: 4 bytes for the number of days before or after the base date of January 1, 1900, and 4 bytes for the number of milliseconds after midnight. The date segments of datetime values representing dates prior to the base date are stored as negative values.
DB-Library
A series of high level language (including C) libraries that provide the application programming interface for the client in a client/server system. DB-Library calls send requests from a client to a server. DB-Library allows the developer to incorporate Transact-SQL statements into an application to retrieve and update data in a SQL Server database.
DBCC
See database consistency checker.
DBMS
See database management system.
DBO
See database owner.
DDL
See data definition language.
deadlock
A situation that arises when two users, each having a lock on one piece of data, attempt to acquire a lock on the other's piece. Each user waits for the other to release their lock. SQL Server detects deadlocks and kills one user's process. See also livelock.
decision support
In the context of SQL Server, a use of data where users access and exploit computing capabilities for decision analysis and other decision making. Decision support typically requires read-only access to data. Compare to on-line transaction processing.
declarative referential integrity (DRI)
The SQL Server built-in capacity that checks the data integrity of a specific related table.
default
The database object that enables SQL Server to insert a value into a column if the user does not explicitly enter one. In a relational database management system, every data element (a particular column in a particular row) must contain some value, even if that value is NULL. Since some columns do not accept null values, some other value must be entered, either by the user or by SQL Server. Defaults specify what value SQL Server will insert when a user does not enter a value (in either a NULL or NOT NULL column). For example, you can create a default that has the value "???" or the value "fill in later", and then instruct SQL Server to enter it if a user does not make an entry.
default database
The database a user is connected to when first logging in to SQL Server.
default device
The device on which a user's database is automatically stored (unless another device is specified).
default language
The language (for example, French, German, or English) used to communicate with the server. Once the default language is set, the user is automatically logged in as using that language.
delimiter
The character used for separating elements of a list.
demand lock
A lock that prevents any more shared locks from being set on a data resource (table or data page). Any new shared lock request has to wait for the demand lock request to finish.
dependencies
The views and procedures that depend on the specified table or view, and the tables and views that are depended on by the specified view or procedure.
destination database
In replication, the subscribing database. The database that receives tables and data replicated from a publication database.
destination server
See subscription server.
destination table
In replication, the subscribing table, created as a replicated image of a published table. A destination table in a destination database is synchronized with and contains data derived from the published table in a publication database.
device
A file in which databases are stored. One database can be stored on several devices. There are two types of devices: database devices, which store databases, and dump devices, which store backups of a database.
device fragment
If the dumped database uses segments to store particular tables or indexes, for the LOAD statement to work correctly the new database must include devices of the same size and page order for these segments and their related data. Execute the sp_helpdb system stored procedure with the database name to see the size and fragments. Select from the sysusages system table to determine the order of the device fragments.

The device fragments that a new database uses for data and for the log must appear in the same order and have the same amount of space as the fragments in the original database. For example, if the original database had 10 MB of data (on any number of fragments), followed by 3 MB of log, followed by 6 MB more of space for data, the new database must have the same order by space and usage: 10 MB for data, 3 for log, and 6 (or more) for data. In this case, the total size of the destination database must be at least as large and have at least as many fragments (assigned in the same order and have the same uses) as the load.

direct response mode
The mode in which SQL Server statistics are gathered separately from the SQL Server Statistics display. Data is available immediately to SQL Performance Monitor and response time is good; however, the statistics displayed are one period behind the statistics retrieved. This is the default mode.
dirty pages
Cached pages that have been modified since the last checkpoint.
dirty read
Reads that contain uncommitted data. For example, transaction1 changes a row. Transaction2 reads the changed row before transaction1 commits the change. If transaction1 rolls back the change, transaction2 will have read a row that is considered to have never existed.
disk mirroring
The process that protects against media failure by maintaining a fully redundant copy of a partition on another disk.
distribute
In replication, to move transactions from the distribution database tables to subscription servers, where they are applied to the destination tables in the destination databases.
distributed database
A database implemented on a network, in which the component partitions are distributed over various nodes of the network. Depending on the specific update and retrieval traffic, distributing the database can significantly enhance overall performance.
distributed processing
Data processing in which some or all of the processing, storage and control functions, in addition to input/output functions, are situated in different places and connected by transmission facilities. The transparent access of both applications and data by programs and end users is an important goal of distributed processing systems.
distribution database
In replication, a store-and-forward database that holds all transactions that are waiting to be distributed to subscription servers. The distribution database receives transactions sent to it from the publication server by the log reader process and holds them until the distribution process moves them to the subscription servers.
distribution process
In replication, the process that moves transactions from the distribution database tables to subscription servers, where they are applied to the destination tables in the destination databases. The distribution process is a subsystem of the scheduling engine in SQL Executive.
distribution server
In replication, the server containing the distribution database. The distribution server receives all changes to published data, stores the changes in its distribution database, and when appropriate (depending on scheduling and other variables), transmits them to subscription servers. The distribution server can be the same computer that is acting as the publication server, or a different computer. Also referred to as a distributor. See also local distribution server, remote distribution server.
distributor
See distribution server.
DLL
See dynamic link library.
DML
See data manipulation language.
DMO
Distributed Management Object
domain
In Windows NT security, a collection of computers that are grouped for viewing and administrative purposes, and that share a common security database.
domain integrity
Integrity that enforces valid entries for a given column. Domain integrity is enforced by restricting the type (through datatypes), the format (through CHECK constraints and rules), or the range of possible values (through REFERENCE and CHECK constraints, and rules).
DRI
See declarative referential integrity.
dump device
A file that stores backups of databases.
dumps
Also known as backup. Backing up a database creates a copy of its tables, data, and user-defined objects.
dynamic backup
A backup performed while the database is active.
dynamic dump
A backup, or dump, of a database or a transaction log made while the database is active. The dynamic dump makes backups as convenient and continuous an operation as possible. However, because the dynamic dump slows SQL Server somewhat, it is best to execute it when the database is not being heavily updated.
dynamic link library (DLL)
Executable routines, generally serving a specific function or set of functions to be stored separately in files (with the .DLL extension) and loaded on demand when needed by the program that calls them.
dynamic recovery
The process that detects and/or attempts to correct software failures and losses of data integrity within a DBMS.
element
Synonymous with "field." In a table, where a row and a column meet.
entity integrity
Defines a row as a unique entity for a particular table. Usually enforces the primary key of a table (through indexes, UNIQUE constraints, or PRIMARY KEY constraints).
equijoin
A join in which the values in the columns being joined are compared for equality, and all columns in the tables being joined are included in the results.
error log
File that records error information from SQL Server. The error log can be viewed using SQL Enterprise Manager or any text editor. When SQL Server is configured to use its error log, each SQL Server session creates a new log, and SQL Server retains the last six logs created.
error state number
Provides information about the context of an error. Valid error state numbers are 1 through 127. An error state number that identifies the source from which the error was issued (if the error can be issued from more than one place).
event log
File that contains SQL Server error messages as well as messages for all activities on the computer.
exclusive lock
A lock that prevents any other transaction from acquiring a lock until the original lock is released at the end of a transaction. An exclusive lock is always applied during an update operation (INSERT, UPDATE, or DELETE).
explicit transaction
A grouping of SQL statements surrounded by the transaction delimiters BEGIN TRANSACTION and COMMIT TRANSACTION, and optionally, one of the following statements:

BEGIN TRANSACTION
COMMIT TRANSACTION
ROLLBACK TRANSACTION
SAVE TRANSACTION

extended stored procedure
SQL Server-provided way to dynamically load and execute a function within a dynamic-link library (DLL) in a manner similar to a stored procedure, allowing you to seamlessly extend SQL Server functionality. Actions outside of SQL Server can be easily triggered and external information returned to SQL Server. Return status codes and output parameters (identical to their counterparts in regular stored procedures) are also supported.
extent
Space allocated upon creation of a table or index. In SQL Server, an extent is 8 continuous pages. Disk space is allocated to individual SQL Server objects (for example, a particular table or index) in groups of 8 logically adjacent pages. These groups of 8 pages are known as extents. Whenever the last row is deleted from a page, it will be marked as "free" (at transaction commit time). However, in general the page will only be available for reuse by the same database object. Only when all 8 pages of an extent are marked as free is the occupied disk space released for use by other database objects.
extent lock
A lock on 8 pages of memory (one page equals 2K of RAM) allocated as a single unit.
forwarding server
A remote server (the Unhandled SQL Server Event Forwarding Server) to whose event log any unhandled SQL Server events on the local server (events for which there are no locally defined alerts) will be sent.
FAT file system
A method for managing disk storage. A file allocation table (FAT) file system is used by an operating system (for example, by Microsoft MS-DOS) to keep track of the status of various segments of disk space used for file storage.
fatal errors
Problems that generate error messages with severity levels 19 and higher. Contact your primary support provider when these errors occur.
field
A single item of information contained within a row or a record. The logical equivalent of a column.
file system
The portion of an operating system that translates requests for file operations from an application program into low-level, sector-oriented tasks that can be understood by the drivers that control the disk drives. SQL Server is usually installed on disk drives that are formatted for the NTFS or FAT file systems. It can be installed on a compressed NTFS volume but at a performance penalty.
fillfactor
Option that specifies how full SQL Server should make each index page. The amount of empty space on an index page is important because when an index page fills up, the system must take time to split it to make room for new rows.
filtering
In replication, the method by which only selected rows or only selected columns of a table are designated for replication. The method by which partitioning is accomplished. See also partitioning.
FK
See foreign key.
float datatype
A SQL Server system datatype. It is a floating-point column that holds positive or negative floating-point numbers. This column has 15-digit precision. The range of values is approximately 1.7E - 308 to 1.7E 308. Storage size is 8 bytes. All the arithmetic operations except modulo are available with float.

Data of type float can include an optional exponent. For float data with an exponential component, enter a number (with or without a decimal point and a positive or negative sign), followed by "e" or "E", followed by an optionally signed integer. The value represented by a float is the product of the first number and 10 to the power of the second number.

foreign key (FK)
The column or combination of columns whose values match the primary key (PK) of some other table. A foreign key does not have to be unique; in fact, foreign keys are often in a many-to-one relationship to a primary key. Foreign key values should be copies of the primary key values; no value in the foreign key except NULL should ever exist unless the same value exists in the primary key. A foreign key may be NULL; if any part of a composite foreign key is NULL, the entire foreign key must be NULL.
front end
Software used by a user to access any database or capture input data.
gateway
A network software product that allows computers or networks running dissimilar protocols to communicate, providing transparent access to a variety of foreign database management systems. A gateway moves specific database connectivity and conversion processing from individual client computers to a single server computer. Communication is enabled by translating up one protocol stack and down the other. Gateways usually operate at the session layer.
gateway server
A network server on which a gateway application resides.
global variable
System-supplied, predeclared variables. Global variables are distinguished from local variables by having two at symbols (@@) preceding their names.
group
A set of database users. Groups provide a convenient way to grant or revoke permissions to more than one user. All users belong to the group public by default.
group name
A name of a group of database users. A group name can have as many as 30 characters and must be unique within the database. The characters can be alphanumeric, but the first character must be a letter or the symbols # or _ (for example, DATAOPS or OPERS8).
guest
Creating a user named guest in a database enables any user with a login ID for SQL Server to access the database as a guest user. If a user attempts to access the database but does not have a username (his or her username is not found in the database's sysusers table), SQL Server looks for a user named guest. If there is one, the user is allowed to use the database, under the permissions assigned to guest.
horizontal filtering
See horizontal partitioning.
horizontal partitioning
In replication, the process of creating an article that replicates only selected rows from the base table. Subscription servers receive only that horizontally partitioned subset of data.
identifier
The name of a database object. An identifier can be from 1 to 30 characters long. The first character must be a letter or the symbols underscore (_), at sign (@), or pound sign (#). An identifier beginning with # denotes a temporary table. An identifier beginning with @ denotes a variable. Embedded spaces are not allowed.
IDENTITY property
Property that enables columns to contain system-generated values that uniquely identify each row within a table. When inserting values into a table that has an identity column, SQL Server automatically generates the next identifier based on the last used identity value (incremented by adding rows) and the increment value specified during column creation.
idle time
The time, in milliseconds, that SQL Server has been idle.
image datatype
A SQL Server system datatype of variable-length and holding between 0 and 2,147,483,647 bytes of binary data. The image datatype cannot be used for variables or parameters in stored procedures. Conversions and calculations of hexadecimal numbers stored as binary can be unreliable.
implicit transaction
A transaction in which each single SQL statement is considered an atomic unit.
index
A set of pointers that are logically ordered by the values of a key. An index is a database object that provides access to data in the rows of a table, based on key values. Indexes provide quick access to data and can enforce uniqueness on the rows in a table. SQL Server supports clustered and nonclustered indexes. In a clustered index, data is stored in the same order as the index; in a nonclustered index, data is stored differently from the index.
initial synchronization
See synchronization.
inner join
Process of joining two existing tables, producing a third table that consists of all possible ordered concatenations (joinings) of records from the first table with records from the second for which certain specified criteria on the data values from the two tables are met.
installation path
The drive and directory into which the SQL Server files will be copied. The default is C:\SQL60, although this can be set at installation time. After installation, this is often referred to as the SQL Server root directory.
int datatype
A SQL Server system datatype that is an integer column that holds whole numbers between 231 -1 (that is, 2,147,483,647) and -231 (that is, -2,147,483,648), inclusive. You cannot enter -2,147,483,648 in an integer column, but you can enter -2,147,483,647 - 1. You can store this number or it can be the result of a calculation. Storage size is 4 bytes.
integrated security
Security that allows a SQL Server to use Windows NT authentication mechanisms to validate logins for all connections. Only trusted (multiprotocol or named pipes) connections are allowed.
intent lock
Lock that indicates the intention to acquire a shared or exclusive lock on a data page. (An intent lock prevents another transaction from acquiring an exclusive lock on the table containing that page.)
interactive structured query language (ISQL)
An interactive command-line utility provided with SQL Server that allows users to execute Transact-SQL statements or batches from a server or a workstation and view the results returned.
International Standards Organization (ISO)
An international body based in Paris that is responsible for developing national and international data communication standards.
interprocess communication (IPC)
A system that lets threads and processes transfer data and messages among themselves. IPC is used to offer services to and receive services from other programs.
IO busy
The time, in milliseconds, that SQL Server spent doing input and output operations.
IPC
See interprocess communication.
ISO
See International Standards Organization.
isolation level
Option that allows you to customize locking for an entire SQL Server session by setting the session's isolation level. When you set the isolation level, you specify the default locking behavior for all SELECT statements in your SQL Server session.
ISQL
See interactive structured query language.
ISQL/w
A SQL Server utility that allows you to enter Transact-SQL statements and system procedures in a graphical query interface. ISQL/w also provides the capability for graphically analyzing queries.
join
Database table operation that creates a resultant entry in another table for each entry in one table whose key column matches that of an entry in the other.
kernel
The essential core component of the server that handles several functions such as task scheduling, disk caching, locking, and executing compiled queries.
key
A field used to identify a record, often used as the index field for a table.
keyword
Words reserved by the server to be used to define, manipulate, and access database objects.
latency
In replication, the amount of time that elapses between a transaction being logged on the publication server and being successfully delivered to the destination database on the subscription server. Latency consists of two components: duration in the transaction log, and duration in the distribution database.
leaf level
The bottom level of a clustered or nonclustered index. In a clustered index, the leaf level contains the actual data pages of the table. In a nonclustered index, the leaf level points to data pages rather than containing the data itself.
livelock
A request for an exclusive lock that is repeatedly denied because a series of overlapping shared locks keeps interfering. SQL Server detects the situation after four denials and refuses further shared locks. A situation in which read transactions can monopolize a table or page, forcing a write transaction to wait indefinitely. See also deadlock.
local distribution server
In replication, when a publication server also acts as its own distribution server, it is sometimes called a local distribution server. In this case, the publication database and the distribution database reside on the same computer. Compare with remote distribution server.
local login ID
See local login identification.
local login identification
The login identification (login ID) a user must use to log in to a local server. A login ID can have as many as 30 characters. The characters can be alphanumeric, but the first character must be a letter (for example, CHRIS or TELLER8).
local server
The server(s) the user is logged in to. If remote servers are set up for the local server, users can access remote servers from their local server.
local variable
User-defined entities that are assigned values. A local variable is defined with a DECLARE statement, assigned an initial value with a SELECT statement, and used within the statement batch or procedure in which it was declared.
lock
A restriction on access to a resource in a multiuser environment. SQL Server automatically locks users out of a specific record, field, or file to maintain security or prevent concurrent data manipulation problems.
log device
Device that contains a database's transaction log.
log reader process
In replication, the process of moving transactions from the publication server transaction log into the distribution database. The log reader process is a subsystem of the scheduling engine in SQL Executive.
logical name
A name used by SQL Server to identify a device. A logical name for a device must correspond to the rules for identifiers and can have as many as 30 characters (for example, ACCOUNTING or LIBRARY).
logical operators
The operators AND, OR, and NOT. The logical operators AND and OR are used to connect search conditions in WHERE clauses.
login
See login identification.
login ID
See login identification.
login identification
login ID. The unique name a user uses to log in to SQL Server. A login ID can have as many as 30 characters and must be unique for that server. The characters can be alphanumeric, but the first character must be a letter or the symbols # or _. With integrated security for Windows NT, you do not need to maintain a separate login ID for SQL Server.
login security mode
Security mode that determines the manner in which a SQL Server validates a login request. There are three types of login security: integrated, standard, and mixed.
loose consistency
A replication model that allows a time lag between the moment original data is altered and the replicated copies of that data are updated¾it does not guarantee that all copies will be constantly identical to the original. An advantage of loose consistency is that it supports LANs, WANs, fast and slow communication links, and intermittently connected databases. It also allows better database availability and scales much better in its implementation as compared to tight consistency. SQL Server 6.0 replication is based on a loose consistency model.
lost update
An update situation in which two transactions read and update the same data item.
manual synchronization
Synchronization that is accomplished by a user. As with automatic synchronization, the publication server produces files containing the schema and a snapshot of the data from the published table, but with manual synchronization, it is applied to the subscriber manually, using tape or another medium.
MAPI
An e-mail application programming interface (API).
master database
Database that controls the user databases and the operation of SQL Server as a whole. It is automatically installed with SQL Server and keeps track of such things as user accounts, remote user accounts, remote servers that this server can interact with, ongoing processes, the configurable environment variables, system error messages, the databases on SQL Server, the storage space allocated to each database, the tapes and disks available on the system, and the active locks.
MASTER device
The device that is automatically installed with SQL Server and used to store the master, model and tempdb system databases and transaction logs, and the pubs sample database and transaction log.
message number
A number that uniquely identifies an error message.
method
A function that performs an action using a SQL-DMO object.
Microsoft ODBC
See Microsoft Open Database Connectivity.
Microsoft Open Data Services
A SQL Server programming component used for building powerful client/server integration with external application systems and data sources.
Microsoft Open Database Connectivity (ODBC)
A database-neutral connectivity API for Microsoft Windows-based applications. ODBC is designed to allow any database vendor to write a driver that supports the API.
mirror name
A name for a mirrored device. Must correspond to the rules for identifiers and can have as many as 30 characters.
mirroring
Continuous duplication of the information on one SQL Server device to another. Mirroring can provide continuous recovery in the event of media failure.
mixed security
Security mode that allows login requests to be validated using either integrated or standard security. Trusted connections (as used by integrated security) and nontrusted connections (as used by standard security) can be established.
model database
SQL Server-supplied database that provides a template or prototype for new user databases. Each time a database is created, SQL Server makes a copy of the model database and then extends it to the creation size requested. A new database can never be smaller than the model database. The model database contains the system tables required for each user database. It can be modified to customize the structure of newly created databases so that every change you make to model is reflected in each new database.
modulo
An arithmetic operator that provides the integer remainder after a division involving two integers.
money datatype
A SQL Server system datatype. Money is a column that stores monetary values between +922,337,203,685,477.5807 and -922,337,203,685,477.5808 with accuracy to a ten-thousandth of a monetary unit. Money values are represented as double-precision integers. Storage size is 8 bytes.
multithreaded server application
An application that creates multiple threads within a single process to service multiple user requests at the same time.
multiuser
The ability of a computer to support many users operating at the same time, while providing to each user the full range of capabilities of the computer system.
named pipe
An interprocess communication (IPC) mechanism that SQL Server and Open Data Services use to provide communication between clients and servers. Named pipes permit access to shared network resources.
nested query
A SELECT statement that contains one or more subqueries.
Net-Library
A library of functions for managing network connections and routing. Each Net-Library allows a computer to use a particular network protocol.
nonclustered index
An index in which the logical order of the index does not match the physical order of the rows on disk. Clustered indexes usually provide faster access to data than nonclustered indexes.
normalization rules
According to the rules of database design (called normalization rules), each table should describe one type of entity¾a person, place, event, or thing.
NTFS
An advanced method for managing disk storage, designed for use specifically with the Windows NT operating system. It supports long filenames (but maintains shorter filenames for compatibility with computers running operating systems using the FAT file system). It also provides full security for access control, file system recovery, and extremely large storage media. It supports object-oriented applications by treating all files as objects with user- and system-defined attributes.
NULL
In Transact-SQL, an entry that has no explicitly assigned value. NULL is not equivalent to zero or blank. A value of NULL is not considered to be greater than, less than, or equivalent to any other value, including another value of NULL.
nullability
The capability that determines whether or not a column can allow null values (NULLs) for the data in that column.
object
One of the components of a database: a table, index, trigger, view, key, constraint, default, rule, user-defined datatype, or stored procedure. Also called a database object.
object dependencies
The views and procedures that depend on a table or view, and the tables and views that are depended on by a view or procedure.
object owner
The user who owns the object, usually the creator of the object. Also called database object owner.
object permissions
The permissions that regulate the use of certain statements (data modification statements) on certain database objects. Permissions can be granted or revoked by the owner of the object.
ODBC
See Microsoft Open Database Connectivity.
ODBC driver
A dynamic-link library (DLL) that an ODBC-enabled application, such as Microsoft Excel, can use to gain access to a data source. Each database management system (DBMS), such as Microsoft SQL Server, requires a driver.
ODS
See Open Data Services.
OLE
Microsoft component object technology and extensible service architecture.
OLE automation controller
A programming environment (for example, Visual Basic) that can drive OLE automation objects.
OLE automation objects
A Component Object Model (COM) object that provides automation compatible interfaces.
OLE automation server
An OLE custom component that provides programmable OLE automation objects.
OLTP
See online transaction processing.
online transaction processing (OLTP)
The high end of transaction-oriented DBMS applications, commonly used (for example) in financial transfers, airline reservations, and automatic teller (ATM) operations.
open data services (ODS)
An application programming interface (API) for the server portion of a client/server system that makes data sources or data services appear to a client as a SQL Server. Open Data Services provides a network interface that handles network protocol processes and a set of server routines that provide the application programming interface.
Open Database Connectivity
See Microsoft Open Database Connectivity.
operator
Symbols used to perform mathematical computations and/or comparisons between columns or variables.
optimizer
See query optimizer.
outer join
Joins that include all rows regardless of whether there is a matching row (*= and =*).
ownership chain
Views can depend on other views and/or tables. Procedures can depend on other procedures, views, and/or tables. These dependencies can be thought of as an ownership chain.
packet errors
The number of errors that SQL Server detected while reading and writing packets.
packets received
The number of input packets that SQL Server has read.
packets sent
The number of output packets that SQL Server has written.
page
In a virtual storage system, a fixed-length block of contiguous virtual addresses copied as a unit from memory to disk and back during paging operations. SQL Server allocates database space in pages. In SQL Server, a page is 2K in size.
page lock
A lock on 2K of RAM (one page) that is allocated as a single unit.
partitioning
In replication, creating an article that replicates only selected information from the base table. Subscription servers receive only that subset of data from the source table. Sometimes referred to as filtering. See also horizontal partitioning, vertical partitioning.
Performance Monitor
Windows NT functionality that provides a status about system performance.
permissions
Authorization to enforce database security. The SQL Server permissions system specifies which users are authorized to use which Transact-SQL statements, views, and stored procedures. The ability to assign permissions is determined by each user's status. There are two types of permissions: object permissions and statement permissions.
physical name
The path where a device or a mirrored device is located. For a device, the default is the path of the MASTER.DAT file followed by the first eight characters of the device's logical name. For example, if ACCOUNTING is the logical name, and the MASTER.DAT file is located in SQL60\DATA, the default physical name is SQL60\DATA\ACCOUNTI.DAT. For a mirrored device, the default is the path of the MASTER.MIR file followed by the first eight characters of the mirror device's logical name. For example, if MACCOUNT is the name of the mirror device, and the MASTER.MIR file is located in SQL60\DATA, the default physical name is SQL\DATA\MACCOUNT.MIR.
physical reads
Reads and writes of the data done by the database page.
polling interval
The option that sets how often the state of the service (SQL Server or SQL Executive) is checked.
precision
The maximum total number of decimal digits that can be stored, both to the left of and to the right of the decimal point.
primary domain controller (PDC)
In a Windows NT domain, a server that maintains the domain's security database and authenticates user logons. It also provides a copy of the domain's security database to backup domain controllers (BDCs), which share the user login authentication load.
primary key (PK)
The column or combination of columns that uniquely identifies a table. It must always be non-null and must always have a unique index. A primary key is used for joins with foreign keys (matching non-primary keys) in other tables.
projection
Process of extracting data from less than all available columns in a table or set of tables.
protocol
A set of rules or standards designed to enable computers to connect with one another and exchange information.
publication
In replication, a group of tables that have been made available for replication as a unit. A publication can contain one or more published tables¾articles¾from one user database. Each user database can have one or more publications.
publication database
In replication, a database that is the source of replicated data or a database containing tables that have been made available for replication.
publication server
In replication, a server that has made data available for replication. A publication server maintains publication databases, makes published data from those databases available for replication, and sends copies of all changes to the published data to the distribution server. Also referred to as a publisher.
publish
To make data available for replication.
publisher
See publication server.
pubs database
A sample database provided with Microsoft SQL Server. The pubs database can be helpful when you are learning to use SQL Server 6.0. All Microsoft SQL Server 6.0 documentation uses the pubs sample database as the basis for examples.
pull subscription
In replication, a subscription performed while administrative focus is set on the subscription server. A subscription is created by "pulling" in a publication or an article from a publication server.
push subscription
In replication, a subscription performed while administrative focus is set on the publication server. As part of the process of creating or managing a publication, subscriptions are created by "pushing" out an article to one or more subscription servers.
query
A specific request for data retrieval, modification, or deletion.
query optimizer
The SQL Server component responsible for generating the optimum execution plan for a query.
RDBMS
See relational database management system.
real datatype
A SQL Server system datatype, it is a floating-point column similar to float. This column has 7-digit precision. The range of values is approximately 3.4E - 38 to 3.4E 38. Storage size is 4 bytes.
record
A group of related fields (columns) of information treated as a unit. The logical equivalent of a row.
recovery interval
The interval that determines checkpoint frequency by specifying the amount of time it should take the system to recover.
referential integrity (RI)
Integrity mechanism that ensures that vital data in a database¾such as the unique identifier for a given piece of data¾remains accurate and usable as the database changes. Referential integrity involves managing corresponding data values between tables when the foreign key of a table contains the same values as the primary key of another table.
relational data model
A finite collection of two-dimensional, column-and-row tables that represents a situation.
relational database
A collection of information organized in tables that can be queried by using data in specified columns of one table to find additional data in another table. Relational databases differ from non-relational databases in that there are no system dependencies stored within the data; in contrast, hierarchical databases are not relational because they contain pointers to other data. SQL Server databases are relational.
relational database management system (RDBMS)
A system that organizes data into related rows and columns. A DBMS that is based on the relational model. SQL Server is an RDBMS.
remote distribution server
In replication, when a publication server does not act as its own distribution server, but instead is configured to send transactions that are marked for replication to a distribution database on another computer. Compare with local distribution server.
remote login ID
See remote login identification.
remote login identification
The login identification (login ID) assigned to a user for accessing remote procedures on a remote server. This can be the same as the user's local login ID. A remote login ID can have as many as 30 characters. The characters can be alphanumeric, but the first character must be a letter (for example, CHRIS or TELLER8).
remote procedure call (RPC)
The invocation of a stored procedure on a remote server from a procedure on another server.
remote server
A SQL server on the network that can be accessed through a user's local server. The setup program can install, upgrade, or configure remote servers.
remote stored procedure
A collection of SQL statements and optional control-of-flow statements stored under a name on a remote server. Remote stored procedures can be called by clients or by SQL Server.
replication
Duplication of table schema and data from a source database to a destination database, usually (but not necessarily) on separate servers.
replication topology
The Replication Topology window provides a convenient way to view the replication relationships of a server, to add subscription servers, and to open the replication management dialog boxes that are provided by SQL Enterprise Manager.
report generator
A software component that supports the production of formatted output from a database.
restrict
In replication, to allow replication to only selected servers. A publication marked Unrestricted is visible to and can be subscribed to by any subscription server. A publication marked Restricted is visible only to those subscription servers that have been marked for access.
restricted
In replication, specifies who can access a publication.
restricted publication
In replication, a publication marked restricted is displayed to and can be subscribed to by only those servers that have been granted access. See also unrestricted publication.
restriction clause
In replication, to partition the article horizontally, so that only selected rows are replicated, type a WHERE clause in the Restriction Clause box.
retention
In replication, the period of time that a transaction is maintained in the distribution database after it has been successfully delivered to the destination database on the subscription server.
RI
See referential integrity.
roll back
The ability to remove uncompleted or partially completed transactions after a database or other system failure.
roll forward
The ability to recover from major disasters such as media failure by reading the transaction log and reapplying all readable and complete transactions.
row
In a table, a set of related fields of information (columns) that are treated as a unit and that describe a specific entity. The logical equivalent of a record.
row aggregate function
Generates summary values that appear as additional rows in the query results (unlike the aggregate function results, which appear as new columns). Allows you to see detail and summary rows in one set of results. Row aggregate functions (SUM, AVG, MIN, MAX, and COUNT) are used in a SELECT statement with the COMPUTE clause.
rule
A database object that is bound to a column or to a user-defined datatype and that specifies what data can be entered in that column. Every time a user enters or modifies a value (with an INSERT or UPDATE statement), SQL Server checks it against the most recent rule that has been bound to the specified column. No table lookups are possible, but limit checking and list checking are. Data entered prior to the creation and binding of a rule is not checked.
SA
See system administrator.
savepoint
A marker that the user puts inside a user-defined transaction. When transactions are rolled back, they are rolled back only to the savepoint.
scalar aggregate
Functions that are applied to all the rows in a table (producing a single value per function). An aggregate function in the select list with no GROUP BY clause applies to the whole table and is one example of a scalar.
scheduled backup
A backup operation automatically accomplished by SQL Executive as defined and scheduled by an administrator.
scheduled table refresh
In replication, specifies that at scheduled intervals all articles in the publication will be refreshed. Each time refresh occurs, all data (and optionally, the table schemas) will be applied to all destination tables. No data changes are sent between the scheduled refresh intervals. Transaction-based replication does not occur.
schema
A description of a database the DBMS generated using the data definition language.
schema script
See table schema script.
script
A collection of statements used to create database objects. Transact-SQL scripts are saved as files usually ending with the .SQL filename extension.
segment
A named collection of disk pieces, a subset of a device that is available to a particular database to store objects on. A segment name can have as many as 30 characters. The characters can be alphanumeric, but the first character must be a letter (for example, FASTSEG2).
SELECT
The Transact-SQL statement used to request a selection, projection, join, query, and so on, from a SQL Server database.
selection
Extraction of data from a subset of all of the rows of a table or set of tables.
self-join
Joins that compare values within the same column of one table.
sequential file
A file whose records are arranged in the order in which they are placed in the file.
server name
Name of the SQL Server, it is taken from the computer's name. Must be a valid SQL identifier. The first character must be a letter or an underscore (_). Characters following can include letters, numbers, or the symbols #, $, or _. Embedded spaces are not allowed.
server state polling
Specifies the polling interval, which is used to set how often the state of the service (SQL Server or SQL Monitor) is checked.
setup initialization file
A text file, using regular Windows .INI file format, that stores configuration information and allows SQL Server 6.0 to be installed without a user having to be present to respond to prompts for information from the setup program.
severity level number
Represents the severity level of an error. Valid levels are 1 through 25. Only the system administrator can add a message with a severity level of 19 through 25.
shared lock
A lock created by nonupdate (read) operations. Other users can read the data concurrently, but no transaction can acquire an exclusive lock on the data until all the shared locks have been released.
SHOWPLAN
An option of ISQL/w and SQL Enterprise Manager. Shows the query execution plan for a query.
single-user mode
A startup mode that restricts connections. Only a single user can connect, and the CHECKPOINT mechanism, which guarantees that completed transactions are regularly written from the disk cache to the database device, is not started.
smalldatetime datatype
A SQL Server system datatype, a column that holds dates and times of day less precisely than datetime. Storage size is 4 bytes, consisting of one small integer for the number of days after January 1, 1900, and one small integer for the number of minutes past midnight. Dates range from January 1, 1900, to June 6, 2079, with accuracy to the minute.
smallint datatype
A SQL Server system datatype, a tiny integer column that holds whole numbers between 215 - 1 (32,767) and -215 (-32,768), inclusive. Storage size is 2 bytes.
smallmoney datatype
A SQL Server system datatype, a column that stores monetary values between +214,748.3647 and -214,748.3648 with accuracy to a ten-thousandth of a monetary unit. Storage size is 4 bytes. When smallmoney values are displayed, they are rounded up to two places. All the arithmetic operations except modulo are available with smallmoney. With smallmoney, you can store monetary values other than U.S. dollars, but SQL Server does not provide any form of conversion.
SMP
See symmetric multiprocessor.
sort order
A set of rules that determines how SQL Server collates and presents data in response to database queries. The sort order determines the order in which data is presented in response to SQL Server statements involving GROUP BY, ORDER BY, and DISTINCT. The sort order also determines how certain queries are resolved, such as queries involving WHERE and DISTINCT.
source database
See publication database.
SPID
See server process ID.
SQL
See structured query language.
SQL Client Configuration Utility
A SQL Server utility provided with SQL Server for Windows NT version 4.2x, which sets the default Net-Library and sets up server connection information on clients. The utility is also used to display the current DB-Library version number. In SQL Server 6.0 this functionality is provided by the SQL Enterprise Manager.
SQL-DMF
SQL Distributed Management Framework. An integrated framework of objects, services, and components used to manage Microsoft SQL Server. SQL-DMF provides a flexible and scaleable management framework that is adaptable to specific needs. SQL-DMF lessens the need for user-attended maintenance tasks¾such as database backup and alert notification¾by providing services that interact directly with SQL Server. At its most basic level, SQL-DMF provides direct access to the SQL Server engine and services from the command line through Transact-SQL. The second tier of the framework is a set of distributed management objects (DMOs) that provides an object interface to the SQL Server engine and services. The top level of the framework is a graphical administration tool, SQL Enterprise Manager, which provides you with an easy way to manage a multiple-server environment. The framework also provides services for replication, scheduling, and alerting.
SQL Enterprise Manager
A graphical application that allows for easy enterprise-wide configuration and management of SQL Server and SQL Server objects. SQL Enterprise Manager provides a powerful scheduling engine, administrator alert capability, drag-and-drop control operations across multiple servers, and a built-in replication management interface. You can also use SQL Enterprise Manager to manage logins, permissions, and users; create scripts; manage devices and databases; back up databases and transaction logs; and manage tables, views stored procedures, triggers, indexes, rules, defaults, and user-defined datatypes.

SQL Enterprise Manager is installed by the setup program as part of the server software on Windows NT-based computers, and as part of the client software on Windows NT- and Microsoft® Windows 95™-based computers. Because SQL Enterprise Manager is a 32-bit application, it cannot be installed on computers running 16-bit operating systems.

SQL Executive
A component of SQL Enterprise Manager, SQL Executive provides powerful scheduling capabilities that enable replication and additionally allow you to schedule other SQL Server events, including backups, DBCC operations, and other administrative maintenance tasks. SQL Executive replaces SQL Monitor, which was included in earlier releases of SQL Server.
SQLMail
Capability of Microsoft SQL Server that includes extended stored procedures that allow SQL Server to send and receive mail messages through the built-in mail application programming interface (MAPI) client interface in Windows NT. A mail message can consist of short text strings, the output from a query, or an attached file. This SQL Server mail capability is called SQLMail.
SQL Performance Monitor Integration
Integration of Windows NT Performance Monitor with SQL Server, providing up-to-the-minute activity and performance statistics.
SQL scripts
See script.
SQL Security Manager
A SQL Server utility provided with SQL Server version 4.2x that provides a way to manage integrated and mixed security. In SQL Server 6.0 this functionality is provided by the SQL Enterprise Manager.
SQL Service Manager
A SQL Server-supplied utility that provides a graphical way to start, pause, and stop SQL Server, SQL Monitor, and SQL Replicator. SQL Server is also integrated with the service control management of Windows NT, so you can also start, pause, and stop SQL Server, SQL Monitor, and SQL Replicator from the Services application in the Control Panel or from the Server Manager application.
SQL Transfer Manager
SQL Server-supplied utility that provides an easy, graphical way to transfer objects and data from one SQL Server to another. You can transfer from a Microsoft-based SQL Server or other SQL Server to a Windows NT-based Microsoft SQL Server. (For example, you can transfer data from a Microsoft SQL Server running on an Intel-based SQL Server to a different processor architecture.)
standalone installation
An installation of SQL Server on a computer that is not connected to a network. A standalone installation may be used to install SQL Server on a computer that will soon be but is not yet connected to a network (for example, it does not yet have a network adapter card installed.) Or, a standalone installation might be performed on a computer that is intended as a development system that will have no need for network connections.
standard security
Security mode that uses SQL Server's own login validation process for all connections. To log in to a SQL Server, each user must provide a valid login ID and password.
statement permissions
Authorization that provides the privilege to issue certain Transact-SQL statements. Statement permissions are not object-specific. They can be granted only by the system administrator or the database owner. Statement permissions are also called command permissions.
statistics refresh
The interval, in minutes and seconds, for refreshing SQL server statistics information. The default is 30 seconds.
stored procedure
A precompiled collection of Transact-SQL statements and optional control-of-flow statements stored under a name and processed as a unit. Stored procedures are stored within database, can be executed with one call from an application, and allow user-declared variables, conditional execution and other powerful programming features. SQL Server-supplied stored procedures are called system stored procedures.
string functions
Functions that perform operations on binary data, character strings, or expressions. Built-in string functions return values commonly needed for operations on character data. String function names are not keywords.
structured query language (SQL)
A database query and programming language originally developed by IBM® for mainframe computers. It is widely used for accessing data in, querying, updating, and managing relational database systems. There is now an ANSI-standard SQL definition for all computer systems.
subquery
A SELECT statement that is nested inside another SELECT, INSERT, UPDATE, or DELETE statement, or inside another subquery.
subscribe
In replication, agreeing to receive a publication or an article. A destination database on a subscription server subscribes to replicated data from a publication database on a publication server.
subscriber
See subscription server.
subscription database
See destination database.
subscription server
In replication, a subscription server maintains destination databases, which receive and maintain copies of published data. Also referred to as a subscriber.
symmetric multiprocessor
A computer with more than one processor, where each processor can access memory, handle interrupts, and access I/O just like every other processor in the computer.
synchronization
In replication, the process that before a subscription server can receive replicated transactions from an article or a publication, the publication and destination tables must contain the same schema and data.
synchronization process
Process that creates synchronization files containing data from published tables and applies these files, along with table schema files, to destination database tables. The synchronization process is a subsystem of the scheduling engine in SQL Executive.
system administrator (SA)
A person responsible for the administrative (SA) and operational functions that are independent of any particular application. The system administrator is likely to be a person with a comprehensive overview of SQL Server and all its applications. The SA advises application designers about the data that already exists on SQL Server, makes recommendations about standardizing data definitions across applications, and so on.

The SA operates outside the protection system, (SQL Server does no permission checking for the system administrator). The SA is also treated as the owner of whatever database he or she is using. Anyone who knows the SA's password can log in and act in the role of SA.

system catalog
Collection of system tables found only in the master database.
system databases
Three databases provided on a newly installed SQL Server:
  • The master database, which controls user databases and the operation of SQL Server;
  • the tempdb database, which is used for temporary tables; and
  • the model database, which is used as a template when creating new user databases.

    In addition, you can also install the sample database, pubs, which is provided as a learning tool and is the basis for most of the examples in the Microsoft SQL Server documentation. If pubs was not installed with SQL Server, you can install it using the INSTPUBS.SQL script.

system functions
Functions that return special information from the database. System Functions allow access to database or server information from within an expression such as a WHERE clause or the SELECT statement.
system stored procedures
A SQL Server-supplied, precompiled collection of Transact-SQL statements. System stored procedures are provided as shortcuts for retrieving information from the system tables or mechanisms for accomplishing database administration and other tasks that involve updating system tables. The names of all system stored procedures begin with sp_. System stored procedures are located in the master database and are owned by the system administrator, but many of them can be run from any database. If a system stored procedure is executed in a database other than master, it operates on the system tables in the database from which it is executed.

You can also write your own precompiled collection of Transact-SQL statements, called user-defined stored procedures, that can be executed from any database.

In addition to system procedures, extended stored procedures are installed with SQL Server. Extended stored procedures provide additional functionality for SQL Server.

system tables
The data dictionary tables. System tables keep track of information about SQL Server as a whole and about each user database. All of the SQL Server-supplied tables in the master database (the controlling database) are considered system tables. In addition, each user database is created with a subset of these system tables. The master database contains some system tables that are not found in user databases.

The master database and its tables are created when you install SQL Server. The system tables in a user database are automatically created when a database is created. The names of all system tables begin with sys.

Permissions for using the system tables are controlled by the database owner, just like permissions on any other tables. The SQL Server installation program sets up permissions so that all users can read the system tables, except for a few fields (such as syslogins.password). The system tables can be queried just like any other tables. In addition, many SQL Server system procedures provide shortcuts for querying the system tables.

table
A collection of rows (or records) that have associated columns (or fields). It is the logical equivalent of a database file.
table creation script
See table schema script.
table data file
In replication, a file containing a snapshot of the data of a published table and used during synchronization as the source of data inserted into the destination table. The data snapshot is written to a file ending in the .TMP filename extension. See also table schema script.
table lock
A lock on a table, allocated as a single unit.
table schema script
A script containing the schema of a published table and used during synchronization to create the destination table. The schema script is written to a file ending in the .SCH filename extension. See also table data file.
table-level constraint
Constraints that allow various forms of data integrity to be defined on an individual column (column-level constraint) or on a combination of columns (table-level constraints) when the table is defined or altered. Constraints support domain integrity, entity integrity, and referential integrity, as well as user-defined integrity.
tabular data stream (TDS)
The SQL Server internal client-server data transfer protocol. TDS allows client and server products to communicate regardless of operating system platform, server release, or network transport.
tape dump
Dumping a database to any tape device supported by Windows NT. If you are creating a tape dump device, you must first install the tape device using Windows NT. The tape device must be physically attached to the SQL Server you are backing up.
TDS
See tabular data stream.
tempdb database
Database that provides a storage area for temporary tables and other temporary working storage needs. No special permissions are required to use tempdb (that is, to create temporary tables or to execute commands that might require storage space in the tempdb database). All temporary tables are stored in tempdb, no matter what database the user who creates them is using.
temporary table
A table that is placed in the temporary database, tempdb, and is destroyed at the end of the session.

A temporary table is created by prefacing the table name (in the CREATE statement) with a pound sign. For example, create table #authors (au_id char (11)).

The first 13 characters of a temporary table name (excluding the pound sign) must be unique in tempdb. Because all temporary objects belong to the tempdb database, you can create a temporary table with the same name as a table already in another database.

text datatype
A SQL Server system datatype specifying variable-length columns that can hold up to 231 - (2,147,483,647) characters. The text datatype cannot be used for variables or parameters in stored procedures.
theta join
Joins based on a comparison of scalar values (=, > , >= , < , <= , < >, !<, !>) are called theta joins.
thread
A mechanism that allows one or more paths of execution through the same instance of an application. Each device requires one thread and each remote site requires two threads. SQL Server takes advantage of the native thread services of Windows NT.

There are separate threads for each network, a separate thread for database checkpoints, and a pool of threads for all users.

tight consistency
A replication model that guarantees all copies will be identical to the original. It is usually implemented using two-phase commit, and it requires a high-speed LAN. It also reduces database availability and is less scalable in its implementation as compared to loose consistency.
timestamp datatype
A SQL Server system datatype, the timestamp datatype has no relation to the system time¾it is simply a monotomically increasing counter whose values will always be unique within a database.
tinyint datatype
A SQL Server system datatype, it is a tiny integer column that holds whole numbers between 0 and 255, inclusive. Storage size is 1 byte.
total errors
The number of errors that SQL Server detected while reading and writing.
total read
The number of disk reads by SQL Server.
total write
The number of disk writes by SQL Server.
Transact-SQL (T-SQL)
The standard language for communicating between applications and SQL Server. The Transact-SQL language is an enhancement to Structured Query Language (SQL), the ANSI-standard relational database language, and it provides a comprehensive language for defining tables, for inserting, updating, or deleting information stored in tables, and for controlling access to data in those tables. Transact-SQL includes statements, commands, control-of-flow language, stored procedures, triggers, rules, and defaults. Extensions such as stored procedures make Transact-SQL a full programming language.
transaction
A group of database operations combined together into a logical unit of work that is either completely executed or completely terminated.
transaction log
A reserved area of the database in which all changes to the database are recorded. It is stored in the syslogs system table and is used by SQL Server during automatic recovery.
transaction processing
A processing method in which transactions are executed immediately after they are received by the system.
transaction rollback
Rollback of a user-specified transaction to the last savepoint inside a transaction or to the beginning of a transaction.
trigger
A special form of stored procedure that goes into effect when data in a specified table is modified. Triggers are often created to enforce referential integrity or consistency among logically related data in different tables.
trusted connection
Authenticated connections between clients and servers. These are referred to as trusted connections. The multiprotocol and named pipe protocols provide trusted connections. Integrated security requires network protocols that support trusted connections.
T-SQL
See Transact-SQL.
two-phase commit
Process that ensures that transactions that apply to more than one server are completed on all servers or on none.
type conversion function
Function that transforms expressions from one datatype into another.
unattended installation
Process that allows you to install SQL Server 6.0 without having to respond to prompts for information from the setup program. Instead, you create an initialization file, save the initialization file on a storage device accessible to the computer that will be set up, and start setup using some required options. During setup the configuration parameters are read from the initialization file.
UNC
See universal naming convention.
underlying object
An object (a table or another view) from which a view is derived. A view can have one or more underlying objects.
underlying table
A table from which a view is derived. A view can have one or more underlying tables. (A view can have underlying views.) Also called base table.
Unhandled Event Forwarding Server
See forwarding server.
UNIQUE constraints
Constraints that enforce entity integrity on a non-primary key. Ensure that no duplicate values are entered, Null values are not allowed, and that an index is created to enhance performance.
unique index
An index in which no two rows are permitted to have the same index value, thus prohibiting duplicate index or key values. The system checks for duplicate key values when the index is created and checks each time data is added with an INSERT or UPDATE statement.
universal naming convention (UNC)
Naming convention that consists of the following format:

\\servername\sharename\path\filename

unrestricted publication
In replication, a security status. A publication marked Unrestricted (the default) is displayed to and can be subscribed to by any registered subscription server. See also restricted publication.
update
An addition, deletion, or change to data.
update statistics
Statistics that update information about the distribution of key values in specified indexes. If there was no data in the table when the index on the table was created, update the index statistics after data is added.
user databases
All of the SQL Server - supplied tables in the master database. In addition, each user database is created with a subset of those system tables. The master database and its tables are created when SQL Server is installed. The system tables in a user database are automatically created when a database is created.
username
A name known to a database and assigned to a login ID for the purpose of allowing a user to have access to that database. The abilities a user has within a database depend on the permissions granted to the username, and the permissions granted to any groups the username is a member of. A username can have as many as 30 characters and must be unique within the database. The characters can be alphanumeric, but the first character must be a letter or the symbols # or _ (for example, CHRIS or USER8).
user-defined datatype
A definition of the type of data a column can contain. It is created by the user and defined in terms of existing system datatypes. Rules and defaults can be bound to user-defined datatypes (but not to system datatypes).
varbinary datatype
A SQL Server system datatype, varbinary(n) is a variable-length binary column that holds up to 255 bytes of variable-length binary data. The binary datatypes are not for hexadecimal data, but rather for bit patterns. They are used for storing programming code or pictures. A varbinary column can contain 0 bytes, but n must be between 1 and 255, inclusive. Storage size is the actual size of the data values entered, not n. Conversions and calculations of hexadecimal numbers stored as binary can be unreliable. Because of the way it uses space, choose varbinary when you expect variation in the size of the data. Data of type varbinary consist of the characters 0 to 9 and A to F (or a to f), and the first varbinary string must be preceded with 0x when it is input. A length of 10 for a varbinary column means 20 characters. If you enter strings that are too long for the specified length, varbinary entries are truncated.
varchar datatype
A SQL Server system datatype, varchar(n) is a column of variable-length characters that holds any combination of up to 255 letters, symbols, and numbers. Specify the maximum size of the column with n. A char column can contain 0 characters, but n must be between 1 and 255, inclusive. Storage size is the actual size of the data values entered, not n. Because of the way it uses space, varchar is best suited for data-like names, where the length of each entry can vary considerably. But varchar imposes more overhead than char, so if the length is fairly consistent, use char instead. Data of type varchar must be enclosed in single quotation marks when it is input. To have a truly empty sting, insert the keyword NULL rather than an empty string, such as ' '. You can use the LIKE keyword and wildcard characters with varchar. If you enter strings that are too long for the specified length, varchar entries are truncated.
variables
Defined entities that are assigned values. A local variable is defined with a DECLARE statement and assigned an initial value within the statement batch where it is declared with a SELECT statement. Global variables are predefined and maintained by the system.
vector aggregate
Functions that are applied to all rows that have the same value in a specified column or expression with the GROUP BY clause and, optionally, the HAVING clause (producing a value for each group per function).
vertical filtering
See vertical partitioning.
vertical partitioning
In replication, creating an article that replicates only selected columns from the base table. Subscription servers receive only that vertically partitioned subset of data. Note that the replicated columns must include the primary key column(s).
view
An alternative way of looking at data from one or more tables in the database, a view is a "virtual table." A view is usually created as a subset of columns from one or more tables. The tables from which views are derived are called base tables. A view can also be derived from another view. The definition of a view (the base tables from which it is derived) is stored in the database. The data that you view is stored in only one place, the base tables. No separate copies of data are associated with this stored definition. A view looks almost exactly like any other database table. You can display it and operate on it almost as you can on any other table.
wildcard characters
Special characters, the underscore (_), the percent sign (%), and brackets ([ ]), used with the LIKE keyword to stand for particular matching patterns in search conditions.
Windows NT Event Viewer
Windows NT application that allows you to view events, filter certain events, and to retain event logs.
Windows NT Performance Monitor
Windows NT utility that provides system administrators a way to monitor the performance of SQL Server. SQL Server statistics include statistics on locks, current size of transaction logs, user connections, and server performance. You can even set alerts to take any action you specify if a specified threshold is reached.
worm drive
A drive that has a write once, read many times functionality.
write-ahead log
A transaction logging method in which the log is always written prior to the data.


Topic Not Found

No matching topic was found. Some possible reasons and remedies are as follows:

  • The file (.chm) that contains the destination topic is not in the expected location.

Remedy: Rerun the MSDN Library Setup.

  • The file (.chm) that contains the current topic or destination topic is out-of-date and the link is no longer valid.

Remedy: Install the latest version of the MSDN Library.

  • The MSDN Library CD is not in the CD-ROM drive.

Remedy: Insert the MSDN Library CD into the CD-ROM drive.


Language Object Methods

Language Methods

Language Object Properties Methods Collections

Day

Month

Remove

ShortMonth


SQLServer Object Properties

SQLServer Object Properties Methods Lists Collections

Property | Description

Application Application Write: No | The Application object.
ApplicationName String Write: Before Connect | The name of the application. Supplied by the application. This property can be changed after a DisConnect and before a ReConnect.
AutoReConnect Type: Boolean Write: Yes | Determines if SQL-DMO will automatically reestablish broken connections. If True, a connection broken before an operation will be reconnected automatically. If False, broken connections are not reconnected automatically.
CommandTerminator String Write: Yes | The Transact-SQL command terminator. The default is "go".
Configuration Configuration Write: No | The Configuration object for this SQLServer.
ConnectionID Long Write: No | The SQL-DMO connection ID unique for this SQL-DMO instance.
DistributionDatabase String Write: No | The replication distribution database.
DistributionServer String Write: No | The replication distribution server.
DistributionWorkingDirectory String Write: Yes | The replication distribution working directory.
Executive Executive Write: No | The Executive object for this SQL Server.
HostName String Write: Before Connect | The name of the client computer. Supplied by the application. This property can be changed after calling DisConnect and before calling ReConnect.
IntegratedSecurity IntegratedSecurity Write: No | The IntegratedSecurity object.
Language String Write: Yes | The Language used by the SQL Server.
Login Identifier Write: Before Connect | The login ID used to connect to SQL Server. Supplied by the application.
LoginSecure Boolean Write: Before Connect | Determines if a secure connection is requested when the Connect method is called. If True, a secure connection is requested. If False, a normal connection is requested.
LoginTimeout Long Write: Before Connect | The number of seconds to wait for a connection attempt to succeed. The default is -1 which means 60 seconds. A value of 0 means no timeout.
MaxNumericPrecision Long Write: No | The maximum precision available for exact numeric datatypes, including decimal and numeric.
Name String Write: Before Connect | The name of the SQL Server. Supplied by the application.
NetPacketSize Long Write: Before Connect | The network packet size in bytes. The default is 0 which means 4096 bytes.
NextDeviceNumber Long Write: No | The next available device number. The maximum device number is 256.
Parent Application Write: No | The Application object.
Password Identifier Write: Before Connect | The password used to connect to SQL Server. Supplied by the application.
ProcessID Long Write: No | The SQL Server process ID of the connection used by the SQLServer object.
QueryTimeout Long Write: Yes | The number of seconds to wait for a query execution attempt to begin returning results. The default is -1 which means no timeout. A value of 0 also means no timeout.
Registry Registry Write: No | The Registry object for this SQL Server.
SaLogin Boolean Write: No | Indicates if the login used for the connection has system administrator (SA) privilege.
Status SQLOLE_SVCSTATUS_TYPE Write: No | The service status of the SQL Server.
TrueLogin Identifier Write: No | The real login used of the connection to SQL Server. This may be different than Login for a secure connection.
TrueName Identifier Write: No | The name of the SQL Server stored in @@servername.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.
UserProfile SQLOLE_SRVUSERPROFILE_TYPE Write: No | The SQL Server profile information for the currently connected user.
VersionMajor Long Write: No | The SQL Server version number to the left of the decimal point.
VersionMinor Long Write: No | The SQL Server version number to the right of the decimal point.
VersionString String Write: No | The version of the SQL Server stored in @@version.


Login Object Methods

Login Methods

Login Object Properties Methods Lists Collections

AliasName

Remove

Script

SetPassword

UserName


StoredProcedure Object Methods

StoredProcedure Methods

StoredProcedure Object Properties Method Lists Collections

Grant

Remove

Revoke

Script


Default Object Methods

Default Methods

Default Object Properties Methods Lists Collections

BindToColumn

BindToDatatype

Remove

Script

UnbindFromColumn

UnbindFromDatatype


SystemDatatype Object Properties

SystemDatatype Properties

SystemDatatype Object Properties Collections

Property | Description

AllowIdentity Boolean Write: No | Indicates if the system datatype can be used as an identity column. If True, a column of this datatype can have the identity property. If False, a column of this datatype cannot have the identity property.
AllowNulls Boolean Write: No | Indicates if the system datatype can be specified to allow NULL values. If True, NULL values can be allowed. If False, NULL values cannot be allowed.
Application Application Write: No | The Application object.
IsNumeric Boolean Write: No | Indicates if the system datatype is an exact numeric datatype with a precision and scale, like the decimal and numeric datatypes. If True, it is an exact numeric datatype. If False, it is not an exact numeric datatype.
MaximumLength Long Write: No | The maximum number of bytes used to store a value of this datatype.
Name Identifier Write: No | The name of the system datatype.
Parent Database Write: No | The Database object.
TypeOf SQLOLE_OBJECT_TYPE Write: No | The type of object.
UserData Long Write: Yes | Temporary storage space contained in this object for private use by the application. SQL-DMO does not use this property.


UserDefinedDatatype Methods

UserDefinedDatatype Object Properties Methods Lists Collections

Remove

Script


Rule Object Methods

Rule Methods

Rule Object Properties Methods Lists Collections

BindToColumn

BindToDatatype

Remove

Script

UnbindFromColumn

UnbindFromDatatype


Remove Method

SQLServer.Executive.Task Object

Description

Drops the SQL Server task and removes the Task object.

Visual Basic

Task.Remove

C++

HRESULT pTask->Remove ( );

Reference

sp_droptask


Application Collections

Application Object Properties Methods Collections

Collection | Description

Properties Properties Write: No | The collection of Property objects.
SQLServers SQLServers Write: No | The collection of SQLServer objects.