Sie sind auf Seite 1von 53

SQL Server FAQ - Introduction, Purpose, Disclaimers

What's this FAQ?


FAQ stands for Frequently Asked Questions. A FAQ is intended as a starting point
and reference, and should reduce the number of times a single question has to be
answered. This FAQ is associated with the newsgroups comp.databases.ms-
sqlserver , the MS SQL Server mailing list sponsored by SWYNK.COM, and the
following Microsoft-hosted news groups:
• microsoft.public.sqlserver.connect
• microsoft.public.sqlserver.misc
• microsoft.public.sqlserver.odbc
• microsoft.public.sqlserver.programming
• microsoft.public.sqlserver.replication
• microsoft.public.sqlserver.server
This FAQ is intended to provide help on the most commonly encountered questions
from these groups and will also include questions and suggestions submitted or
suggested by users of this FAQ.
Additional SQL Server FAQ information can be found on the Sybase site,
http://reality.sgi.com/pablo/Sybase_FAQ, or the Microsoft site, at
http://www.microsoft.com/sqlsupport/content/faq.
Who's responsible?
This FAQ is maintained by Stephen Wynkoop and Michael Hotek. Most of the
information in the FAQ is taken from articles posted on the Microsoft SQL Server
mailing list, client questions, and USENET comp.databases.ms-sqlserver . If you
recognize your question or answer here and want us to remove it, we will if yours
was the sole source of the question/answer. We make some effort to verify the
answers but I DO NOT guarantee that they are correct.
If you wish to contribute to or comment on this FAQ, send e-mail to
swynk@swynk.com or mhotek@swynk.com.
If you write and ask us questions, and we have some spare time, we may be able
to answer them. The amount of e-mail coming in prevents us from answering most
questions, but we'll certainly look to add your question to the FAQ if needed and
will try to help out wherever we can. Please don't be offended if we are unable to
assist. Please don't ask questions before checking in this FAQ.

SQL Server FAQ - Development


How many bytes can I fit on a row/page in SQL Server and why? Are there
any workarounds?

Rows can never cross page boundaries - page size in 6.5 and earlier is 2K, in SQL
7.0 it is 8K.

For 6.5 and earlier :-

Each 2048 byte page has a 32 byte header leaving 2016 bytes for data. You can
have 2 rows of 1008 bytes or 10 rows of 201 bytes. The row size also includes a
few bytes of overhead in addition to the data itself; there is more overhead if there
are variable length columns.

One row cannot be 2016 bytes - this is because when you insert/update/delete a
row, the entire row must be written to the transaction log in a log record. Log
pages also have 2016 available bytes per page, and need 50 bytes for transaction
log specific information, so this gives a maximum size for a single row of 1962
bytes.

You CAN define a table with a rowsize greater than this as long as it contains
variable/NULL columns. However, if you try at any point to insert/update a row that
has data that actually exceeds this limit then the operation will fail.

There are no workarounds for this. You will have to split the table into multiple
tables if you need more data than a row can take.
How can I output records/messages to a flat file from inside a SQL Server
TSQL script/stored-procedure/trigger?
SQL Server doesn't have a handy SPOOL command like Oracle does, but there are a
number of ways of doing what you want.

1. Use xp_cmdshell and the ECHO command. Use the > or >> redirection symbols
to either create or append to a file.
xp_cmdshell "@ECHO test message >> C:\file.fil"

2. Put the information you want into a table (note this can't be an ordinary
temporary table, but it can be a global temporary table) and then bcp it out to a file
via xp_cmdshell.
xp_cmdshell "bcp <dbname>..<tablename> out c:\file.fil -Usa -P<password> -c"

3. Write your own extended stored procedure. As this is a C program it can use
standard file access commands to achieve whatever you want.

4. Run the select through ISQL via xp_cmdshell and use the -o parameter to output
the results to a file. This example uses the -E parameter to avoild hard-coding a
userid.

declare @str varchar(255)


select @str = 'isql -Q"select * from <tablename>" -E -oc:\file.fil'
exec master..xp_cmdshell @str
How can I add/amend/delete columns in SQL Server? E.g. Int to Char,
char(5) to char(15), change NULL to NOT NULL etc.
Under SQL 7.0 all the above are easily done with the GUI or supplied stored-
procedures.

With SQL 6.5 and below it is only possible to ADD a nullable column. For any other
change a new table must be created, the data copied across, and the tables
renamed around.

Certain 3rd party tools provide a GUI interface to do this, that makes it look
transparent, however they are really doing all the work described above, so if you
make the change to a large table it will take a long time to do the work.

Examples of tools are Microsoft's Visual Database Tools (part of Visual Interdev),
Sylvain Faust's SQL-Programmer, and Embarcadero's DBArtisan.

Note that there have been reports of MS VDT losing data if you amend columns on
a table and SQL does not have enough free-space to complete the task.
Where are the cascade update/delete functions in SQL Server?
There aren't any I'm afraid. These were initially thought to be going into SQL 7 but
won't be there now. They will be in a "future" SQL release.

You need to implement your own cascade functionality with triggers. See Q142480
in the MS Kb for more information on this and the ways to work with foreign keys
which cause problems due to the way that triggers work/fire.
How do I encrypt fields in SQL Server?
There is no supported, documented way of doing this, and because you can't write
user-defined functions yet then your choices are :-

1. Write your own extended-stored-procedure (XP) to do it. However this can't be


applied as a function, so it is messy - you need to call the XP per column and then
issue an update with the value it returns.

2. Do it in the application, back at the VB, C etc. level. This is what most people do
and is the recommended method.

3. ** This option only here for completeness **


There are undocumented pwdencrypt() and pwdcompare() functions - they are for
MS internal use and their function is likely to change/break in future - people who
ignored advice and used them in 6.x applications have reported problems using
them in SQL 7.0 Beta's.
As many people now know about these functions they are mentioned here for
completeness, but if you use these functions you will not receive support from
Microsoft and will be completely on your own when you got problems with a new
SP/version.

4. Wait and see if SQL 7.1/8.0/whatever implements UDF's.

5. Use a DBMS that does support UDF's like DB/2, Oracle....


What tools are available to produce entity relationship diagrams for SQL
Server?
There are several on the market, including (in no particular order)
ER/Studio
Case Wise
Erwin
PowerDesigner
InfoModeler
Visio Professional
Also there are some tools built-in to MS products. Note that these just do diagrams,
whereas the 3rd party tools above have a wide-range of project lifecycle, reverse
engineering etc. abilities.

Visual Database Tools does ER-diagrams


SQL 7.0 has built-in ER diagrams
MS-Access (you'll have to connect all the SQL tables first)
How can I issue a SQL command that uses a variable for the tablename,
columns etc.?
Look up the EXEC command.
A short example that selects a column from a table :-
USE pubs
go
DECLARE @str varchar(255)
DECLARE @columnname varchar(30)
SELECT @columnname='au_lname'
SELECT @str = 'SELECT ' + @columnname + ' FROM authors'
EXEC (@str)
-------------------------------
Another example from the books-online
This example shows how EXECUTE handles dynamically built strings with variables.
This example creates a cursor (tables_cursor) to hold a list of all user-defined
tables (type = 'U').
DECLARE tables_cursor CURSOR
FOR
SELECT name FROM sysobjects WHERE type = 'U'
OPEN tables_cursor
DECLARE @tablename varchar(30)
FETCH NEXT FROM tables_cursor INTO @tablename
WHILE (@@fetch_status <> -1)
BEGIN
/*
A @@fetch_status of -2 means that the row has been deleted.
No need to test for this as the result of this loop is to
drop all user-defined tables.
*/
EXEC ("DROP TABLE " @tablename)
FETCH NEXT FROM tables_cursor INTO @tablename
END
PRINT "All user-defined tables have been dropped from the database."
DEALLOCATE tables_cursor
How do I do row-level locking on SQL Server?
Only SQL 7.0 has full built-in row-level locking.

SQL 6.5 has limited row-level locking that only occurs for inserts to the end of the
last page of a table, if "sp_tableoption 'table_name', 'Insert row lock', true" is set.
See the books-online for 6.5 for more information.
SQL 6.0 and previous have no row-level locking capabilities.

You can however effectively do row level locking with version 6.5 and earlier as
long as each row takes up a whole page - thus locking 1 page is the same as 1 row.
You can do this by padding a row with CHAR NOT NULL fields until the row length is
forced to be greater than 1024 bytes. (Rows cannot span pages so this forces one
row per page).

However, you should note that although the rows on this last data page are being
row-level locked, any non-clustered index pages involved are not. These can be a
source of contention and even deadlock - when two logically distinct transactions
need to lock one or more index pages, and pessimistically in different orders.
How can I change the owner of an object?
With SQL 7.0 there is a stored-procedure to do this, however under SQL 6.5 and
earlier there is no supported method to do this.

It can be achieved by directly addressing and updating the system table concerned
though.

1. Configure your server to allow updates to system tables


2. Begin a transaction
3. Update the sysobjects table, changing the uid column value of the objects
concerned to the uid you want.
4. Check that the right number of rows have been affected.
5. Commit or rollback the transaction, depending on the result
6. Configure your server to NOT allow updates to system tables
7. Stop and start your SQL Server

(The last step is necessary as portions of system tables are kept in memory by SQL
Server, and the only way to force these to update is to recycle SQL Server)
What is the limit on the number of tables in a query in SQL Server?
With SQL 6.5 and earlier the limit is 16 - regardless of which "version" of SQL you
are running - e.g. EE. With SQL 7.0 the limit is 256. These figures are hard-coded
into the SQL kernel and are arbitrarily chosen by the MS developers - but with good
reason. The more tables there are, the longer it takes to optimise a query properly.
There has to be a trade-off between the speed of running a query and the speed of
optimising it.

It *is* possible to up the limit of 16 in SQL 6.5 by setting traceflag -T105. This is
an undocumented and unsupported trace flag, so MS may not support you with any
problems on a system that is running this. However, it was allegedly put into the
product to allow some of the more complex Peoplesoft queries to run, and so it
must have had some testing/QA done on it.

Normally, if a query needs more than 16 tables then you have a very bad query
and/or database design. The best practice would be to break the query down into
smaller parts and use temporary tables to hold interim resultsets. This will also
make the query more understandable and may even speed it up as the optimiser
has more of a chance to choose correct access plans and indices.
How can I speed up SQL Server applications running over slow links?
First we need to define what a "slow" link is. Typically this is anything from
64Kbit/sec and down. On links of this speed the size of a resultset and the number
of network packets that are exchanged can make a significant difference to overall
response times.

First, either do a network trace, or use SQL Trace to see what exactly is being
transferred during a typical client session. Then try the following :-

1. If large intermediate resultsets are being returned, then see if you can write the
logic into a stored-procedure so that only the end results are returned. Try and
reduce the number of sent/received pieces of SQL by using stored-procedures as
much as possible.

2. If the connection uses ODBC and the overhead it creates running sp_serverinfo,
sp_cursor, temporary stored-procedures etc. is causing the problem then use
passthrough queries if possible and turn off the temporary stored-proc creation in
the ODBC dsn properties.

3. Configure the db-lib/ODBC connection to use the tcp-ip sockets net-lib. This
performs best over slow network connections and can make a significant difference.

4. Is the application using client-side cursors? Try v3 or above of ODBC which


should give you transparent server-side cursors.

5. Don't return 1000 rows to the client if all they need to see on the screen is the
first 20.

6. If there are large amounts of static data that need to be retrieved then consider
replication to a client copy of Access, SQL 6.5 Workstation or with SQL 7.0 a local
copy of SQL Server. Over slow links this should only really be used for mainly static
data.

7. Don't send any SQL across the link at all. Use Citrix or NT Terminal Edition to run
the application centrally and install ICA/RDP clients on the remote machines. The
applications then all run locally on a server next to the SQL Server (the same box
isn't recommended). The only thing that goes across the slow-link are screen-
updates, which are optimised and compressed and so will often work satisfactorily
on a 14.4Kbit/sec modem link. This also has the advantage that there is no longer
any client code to maintain at the remote sites either. There are whitepapers on
Citrix, MS and Compaq's sites about sizing the server(s) you will need to run in this
mode.
How do I store/retrieve text and image data in SQL Server?
To store/retrieve this sort of data within TSQL scripts you have to use the
WRITETEXT and READTEXT commands rather than standard INSERT/SELECT
statements. These are documented, with examples, in the books-online but are
basically a real pain to use. There are more manageable commands available from
within the relevant programming languages - e.g. RDO and ADO from VB/C can use
GetChunk and AppendChunk commands - but you still have to manage the
image/text chunks/blocks of data at a time. About the only upside of storing this
sort of data within SQL Server is that it can be kept transactionally consistent with
the other data.

If you just want to insert/retrieve an entire image/text then look at the TEXTCOPY
program (textcopy /? for parameters) in the <sql>\BINN directory. It is a
command-line program along the lines of BCP.

If transactional consistency doesn't matter, or can be achieved programmatically,


then it is easier to store the data outside the database as an ordinary file. Within
the database just hold a UNC pointer to where the file is held. This usually makes it
much easier to display/edit the data as the name can simply be passed to whatever
tool is doing the manipulation.
How can I access data across two separate databases in SQL Server?
With SQL 6.5 and below this is easy as long as the databases are on the same
server. Then just use the fully qualified names of the tables concerned :-

select * from <dbname>.<ownername>.<tablename>


select * from db1..tab1, db2..tab1 where ...........................

If the databases are on separate servers then 6.5 and below offer remote stored
procedures (look them up in the docs) but that is your only server-side choice,
there is no way to directly access the tables involved. If you need direct access
then you will need to make two separate client connections to each server and
process the data at the client end. Something like the JET engine can be used to
make this easier and make the two servers look like one.

With SQL 7.0 you can access tables across servers with a single client connection
because the fully qualified object name now allows the servername to be passed, so
you can do

select * from server1.db1..tab1, server2.db1..tab1 where ...........................


Creating a table by using SELECT
Oracle has a syntax like the following that will easily make a clone copy of a table
with all of its data. This makes testing and comparisons exceedingly easy.
CREATE TABLE tab_dup AS SELECT * FROM tab_orig
How do you accomplish this with SQL Server?
You can use the following syntax to use SELECT to create a table based on the
results from the SELECT statement:
SELECT INTO FROM
The "select into/bcp" database option must be set for this to work. Also, if you're
creating a stored procedure, if you create a table with a pound sign as the first
character in the name of the table, the table is created as a temporary table. This
means two things. First, it's created in TEMPDB (check the size you have allocated
if you run into problems with running out of space), and second, the table will be
automatically removed when the stored procedure has completed. Also, if you want
to simply create a second table that has the same structure as the first, you can do
this by using a where statement that will never be true. For example:
select * into NewTable from ExistingTable where 1 = 2
How can I drop a column from an existing table?
You'll have to drop and re-create it (back it up first, of course). You can use SQL
Enterprise manager to automatically create the script for the existing table, modify
the columns to be created, then use the modified script to create a new table. You
can then copy the existing table into the new table, calling out the specific columns
to include in your SELECT statement.
How do I get the definition for a table?
What is the format of the SQL query to display the definition for a table? For
example, if I have a table called CUSTOMERS which is defined like the following:
CREATE TABLE CUSTOMERS ( CUSTID varchar(20), NAME varcar(50) )
How would I use SQL to actually show me the above information?
There are a couple of approaches, but the simplest is to use:
sphelp CUSTOMERS
There are also products out there, one of which is SQL-Programmer, available at
http://www.sfi-software.com that may solve the problem. Documentation on this
specific product is located at http://www.sfi-software.com/products.htm.
Why doesn't my delete trigger work with DRI?
If I have a table "A" with a primary key "A.pk", and two other tables "B" & "C" with
foreign keys "B.fk" & "C.fk" and I have set up the following delete trigger on "A" --

=========================
delete B
from deleted, B
where deleted.pk = B.fk

delete C
from deleted, C
where deleted.pk = C.fk

=========================

The trigger is designed to delete the record in the main table and delete the related
records in the other tables. But I get the following error --

[Microsoft][ODBC_SQL Server Driver][SQL Server] DELETE Statement conflicted


with COLUMN REFERENCE constraint 'B.fk'. The conflict
occured in database '...', table 'B', column '...' (#547)

[Microsoft][ODBC SQL Server Driver] Command has been aborted (#3621)


The problem is that triggers are always executed *after* the SQL statement that
fires them. In this case, you need one that runs *before*, a capability which does
not exist. The error you get is the result of the DELETE, not the trigger, because
you are trying to delete a row in A whose PK is referenced by the FK in B. That is
exactly what DRI is intended to *prevent*, hence the error.
You have two choices:
1) Drop the DRI constraints in B and C. Your trigger will then do what you want.
(This is what triggers were meant to do; they preceded DRI.) You should also put
INSERT triggers on B and C to ensure that there is a matching PK in A.
2) Use a stored procedure for the deletion instead of a trigger. You can then do the
DELETES in the correct sequence to satisfy the DRI constraints. DELETE from B and
C first, then from A. You should also drop the DELETE trigger in A, since it is now
redundant. This is the DRI-compatible method.
When you use DRI, the main utility of DELETE triggers is for backup of deleted
rows, copying them to another "archive" table. While "cascading deletes" seem
intuitively right, they just do not work. This question comes up fairly often, and
should be added to the FAQ.
As another side point, any "cascading" effect with triggers will work only if the
nesting is less than 16 deep, and if nesting has not been turned off (using
sp_configure). Also triggers will not call themselves recursively; if a trigger affects
any other rows in the *same* table, the same trigger is *not* called again for the
subsequent rows. In contrast, stored procedures do not suffer from these
limitations.
Extended Stored Procedures
Extended Stored Procedures are DLLs that can be called from within SQL code using
the same conventions as Stored Procedues. As DLLs they have access to the
operating system, other DLLs, OS files, etc. They are executed in the
process/address space of SQL Server and thus have the potential to crash SQL
Server.

Where's the documentation of XPs (Extended Stored Procedures)?


The majority of references, and all the information about programming them, are to
be found in the 'Programming Open Data Services' book. ODS is a companion API
to DB-Lib and these two are what you write your XP's in (using MS Visual C under
NT).

SQL Server FAQ - Enterprise Manager


When I look at the size of my database, the data/log size does not display
properly, reports a size larger than I have defined, reports negative space.
How can I fix this?
Basically, you can't. This is similar to the question posted below on the log being
full. Enterprise Manager has a very well documented bug that does not report
database size correctly. To get the proper size of your database/log, use the
sp_spaceused stored procedure.
Why does my SQL Server log show that it's still full? - I have truncated it.
The reason for this is that all the tools that interrogate log space - e.g. dbcc sqlperf,
sp_spaceused and SQL EM all just look at the system catalog information in
sysindexes - the dpages column. In SQL 6.5 and earlier this information is NOT
kept up to date, so it is constantly wrong. The reason it is not kept updated is that
it would cause a performance bottleneck.

The easiest way to correct the information is :-

dbcc checktable(syslogs)
go
checkpoint
go

The information will then be correct until the next update/delete/insert transaction
is issued.

If your log REALLY is full - i.e. you're getting a 1105 error on syslogs, then try a
"dump transaction <dbname> with no_log". If this still doesn't fix it, then one of
the following is occurring.

1. You may have an open transaction. Check that with the following command.

use <databasename>
go
dbcc opentran(<databasename>)

2. You may have un-replicated transactions. See Q184499 for info on this and how
to clear it up.

See Q110139 and Q184499 for more information on syslogs filling up and how to
resolve them.
Why do my device sizes appear as negative values in SQL EM? It won't let
me make any changes because of this.
This is caused by a known bug in Enterprise Manager when there is greater than
2Gb of free space on a disk. It was fixed in 6.5 SP3 and above. If you are running
SQL EM from a client then you will need to apply SP3 to that as well.
Are there any "easter eggs" in SQL Server?
The only one I'm aware of is in SQL Enterprise Manager under 6.5. (It may be there
in 6.0 but I've never tried it).

Using the Enterprise Manager create a "New Server Group" called starfighter.

Register a Server called IS COOL (note there is a space there) under this new
server group. Click 'register anyway' as it won't connect.
Highlight "IS COOL" and click the "About Box " to see the development team.
Why can't I connect Enterprise Manager to my local copy of SQL Server? It
connects ok to other machines.
This is down to the way that SQL interfaces with the NT networking code. The
easiest way around this is to register the local server with a name of "." or "(local)"
- ignore the double quotes in either case. Both of these names should force SQL to
use a local-named pipe to connect which should work no matter what the default
SQL connection parameters are set to.
I'm doing a transfer using the SQL EM transfer tool, and not only is it not
transferring the objects, it is dropping them from the source. What is going
on?
This is a known bug that is caused when the server you are connecting to has a
period in the name. Typically this is because you are referring to it by tcp-ip
address.

What happens is that SQL sees the period and does a local named-pipe connect -
which it should do if the name consists of just a period, but not when it contains a
period - this means that SQL connects to the local machine as the target. As most
people have checked the "drop objects first" box it then proceeds to drop all the
objects concerned from what it thinks is the target machine - which is unfortunately
the local (source) machine.

To prevent this problem do not refer to your SQL Server's by IP address. Either :-
1. Put an entry for the name/address in your NT HOSTS file -
<NT>\SYSTEM32\DRIVERS\ETC\HOSTS.
or
2. Use SQL Client Config Manager to define a named connection for the Server in
question. In the advanced properties put the server's IP address as well as the net-
lib dll needed to connect.

Then just use the server 'name' instead of the IP address in the transfer to/from
fields.
I'm not seeing anything in the current activity screen in SQL EM. What's
gone wrong?
This is usually caused by the "select into/bulkcopy" database attribute for tempdb
being unchecked.

Set the option on again using SQL EM or sp_dboption and that should fix it.
SQL Server FAQ Backup and Restore
My SQL Server database is showing as "recovering". Why and what can I
do?

Every time SQL Server starts up it recovers all databases so that all transactions
are either committed or rolled-back. This recovery process normally only takes a
few seconds/minutes, but it the server was terminated in the middle of a long
running update, then the recovery can take at least as long as the update had
taken so far - sometimes longer due to contention on the log device.

Give it plenty of time to recover, but at the same time check the current and
previous errorlog files, and NT errorlogs, for any indications of what has happened.
If you've hit a hardware problem or SQL bug, then there WILL be errors there to
give an indication on what happened.

Check the physical disk activity lights on the server, and also check the
sysprocesses activity to see if the recovery task is using cpu and/or disk i/o. Only
on very rare occasions will SQL Server not recover the database correctly.

Additonally to check on recovery progress you could set trace flag 3412 which
writes an entry to the errorlog when each transaction is rolled forward or back.

If a database will not recover and you do NOT have a backup then you can use the
following trace flags to bypass recovery. If you use these then the database/data
may not be in a consistent state, but if you have no other choice then use them and
then immediately transfer out (using bcp or transfer tools) all the objects you
require.

3607 Skips automatic recovery for all databases.


3608 Skips automatic recovery for all databases except the master database.

If the database is still unavailable - marked as suspect - then issue the following
command to put the database into emergency mode (you'll need to allow updates
first). You can then go into the database (no need to restart SQL) and extract out
the data.

UPDATE master..sysdatabases SET status=-32768 WHERE name='<dbname>'

If all else fails, or you are unsure what to do, then don't hesitate to place a call with
Microsoft Product Support Services (PSS). They are there 24x7x365 to deal with
problems like this and the charge is nominal compared to the loss of your data!
Why can't I backup/restore my SQL Server database to the network?
The reason is that the MSSQLSERVER service is running under a separate set of NT
credentials. It doesn't matter who YOU are logged on as (after all SQL runs quite
happily when no-one is logged on to the console doesn't it). Therefore your logon
account and any mapped drives are irrelevant. It is SQL Server doing the backup,
not you.
The default set of NT credentials used by MSSQLSERVER is the Localsystem
account. You can check what userid that MSSQLSERVER is running under by looking
at control panel/services highlighting MSSQLSERVER and choosing the start-up
option.

The Localsystem account has no access to shares on the network as it isn't an


authenticated network account.

So, if you want to backup to a network share you have two choices :-

1. Change the account the MSSQLSERVER service runs under to a user account with
the relevant network rights.

or

2. Amend the following registry value on the TARGET server and add the
sharename you want to dump to - the share does not then authenticate who is
coming in and so a Localsystem account will work. The server service on the target
server must be re-started before the change takes effect. Note that this effectively
removes security on that share, so you need to be careful about what is in the
share.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Param
eters\NullSessionShares

Whichever method you use, you MUST also use a UNC name to reference the file
required and not a drive letter.

e.g. DUMP DATABASE pubs to DISK='\\server01\share\backupdir\backup.dmp'


Can I do a SQL backup to a tape drive on another server?
No, not with built-in SQL tools. SQL will only dump to local tape devices. If you
could find an NT driver that would make a remote tape drive look local then this
would work as SQL just uses standard i/o calls. I don't know of such a driver at the
moment.

You can always dump the SQL database to disk locally (or across the network with
some provisos) and then back that up to tape.

Finally, you CAN do what you want with a 3rd party backup tool that has a SQL
agent. Examples are BEI Ultrabac, Cheyenne Arcserve, Seagate BackupExec,
Legato Networker and IBM ADSM - I'm sure there are others.
These put SQL dumps (via a standard named-pipe interface) onto a standard dump
tape, potentially as part of a complete server backup and not just SQL. Obviously if
the named-pipe connection is made across the network then the dump will usually
be a lot slower than doing it locally.
Why is a SQL Server restore (LOAD DATABASE) so much slower than a
dump database?
The answer to this is that SQL initialises all pages during a load. So if you have
50Mb of data in a 5Gb database, the dump only processes the used 50Mb. But
when the load occurs it loads the 50Mb of data - which takes roughly the same time
as the dump - and then initialises the rest of the 4.95Gb of free space. This
initialisation is done page by page and goes as fast as the disk subsystem will
allow.
How can I recover a SQL Server database when all I have left is the .DAT
device?
For SQL 6.5 and below use the DISK REINIT and REFIT commands. These are
documented in the Books-Online.
Alternatively, you can download a commercial data recovery product called
MSSQLRecovery, which supports SQL Server 6.5 and 7.0 and is available at
http://www.officerecovery.com/mssql/.
How do I disable tape compression during my SQL Server backup?
Trace flag 3205 will disable tape drive compression.

SQL Server FAQ - Client Programming


How do I run a SQL Server stored procedure from MS Access?
Create a pass-through query in the Access Query designer. Put in the name of the
stored procedure as the text of the query. If desired, edit the Connection property
of the Query to contain the Data Source, etc required by the query (there is a
Builder than can help). When you run the query, any result set (rows and columns)
returned by the stored procedure will appear as the query's result set.
What about passing parameters to the stored procedure?
This is a little more complicated and requires using Access Basic. In general, you
create or edit a query (using CreateQueryDef or OpenQueryDef) and assign a SQL
statement to the query's SQL property. You can look up CreateQueryDef etc in
Access Help. Note that the SQL statement you create must have all the delimiters
that SQL Server expects. Example: my stored procedure sp_mine takes a
parameter of type char(10) and another of type int. A valid string could be:
sp_mine 'martin', 5

To create this string, I can do:

mySQL = "sp_mine 'martin', 5"

IF "martin" and "5" are already in variables, I can write:

mySQL = "sp_mine '" & sName & "', " & string(iNumber)

Note: The single quotes are important!


How do I access SQL Server from C/C++?
There are two ways to work with it from C++: ODBC, and DB-Library.
DB-Lib is the older, more "native" route; it works *only* with SQL Server. ODBC is
MS's interoperable database standard, and works with any MS database (and lots of
others); it recently became an ISO standard. MS furnishes an ODBC driver for SQL
Server that is a native implementation (not just another layer over DB-Lib), and
that is fast enough that they use it to run TPC-C benchmarks for SQL Server.
The MFC database classes are based on ODBC, and you can freely use ODBC calls
in your derived database and recordset classes. This makes ODBC the natural
choice for an MFC application.
Are there any good books on the subject?
While it's *possible* to use only the MFC access methods, it's better to at least
understand the ODBC calls happening beneath your feet. Recommended texts
include:
• ODBC 2.0 Programmer's Reference and SDK Guide, Microsoft Press, ISBN 1-
55615-658-8, $24.95US.
• Inside ODBC, Kyle Geiger, ISBN 1-55615-815-7, $39.95US (Note: Kyle is the
ODBC architect)
• Database Developer's Companion, included as part of the SQL Server
documentation
• SQL Server Books Online
• Inside Visual C++, Kruglinski, ISBN 1-55615-891-2, $45.00US
• Win32 Programming Using VC++, Blaszczak
How do I move a database from Access to SQL Server?
See knowledge base article Q152032 for additional information.
Moving to SQL Server will depend a bit on what version of Access you're using. With
Access 95, download the upsizing wizard from the Access portion of the Microsoft
site ( http://www.microsoft.com/access, or directly here) and use it to do the work
for you. This is also true when using Access 2.0, you should use the Upsizing
Wizard available for that environment.
Experience from one poster:
Performance will be slower than rewriting the application in VB or using stored
procedures (actually, it may even be slower than straight Access and file server!) It
may, however, let you support more users and achieve greater data integrity and
simpler administration.
For a new SQL programmer, it is best to move one step at a time. Once the
backend database is running smoothly, you can redo the front end to either use
more passthrough TSQL statements or rewrite it in VB.
The real performance payoff of using SQL server comes only when transactional
queries are moved into the server as stored procedures.
Some more caveats on the backend:
• Access cascade relationships are not mapped to SQL server, so deleting a
master record in SQL does not delete the corresponding detail records.
• Use ODBC SQL driver 2.50 and not 2.65, or you will have difficulty deleting
null records.
• Access dates and SQL dates have different origins. If you use date field for
storing time, be prepared for some surprises when you transfer the data.
• SQL tables must have a unique index to be updatable. If your access tables
are not strict relational, they cannot be upsized to SQL server.
• You may need to prevent user from searching on unindexed fields because
that is extremely slow.
• Obviously Access naming that may include spaces are not allowed on SQL
tables.
In general, an access application that was not designed with sql server in mind is
much harder or impossible to upsize without rewriting it.
We did an upsizing project recently and that took three months, even though we
know exactly what we were doing.
Additional Information:
Using Access 97, there is, as of this writing, no upsizing wizard available, though
one is in the works according to Microsoft. No ETA on availability as of yet
(1/26/97). Books on the subject include:
• The Revolutionary Guide to Microsoft Access, and
• Special Edition Using SQL Server 6.5, Second Edit ion (make sure you get the
second edition)
Note: to be fair, I (Steve Wynkoop) wrote these, there may be others. I do know
the coverage is in these books. If you are interested in more info on these, they're
located, along with more detailed information, on this site,
http://www.pobox.com/~swynk.
The alternative to either doing it manually from Access 97 or waiting for the wizard
is to convert your tables to Access 95 format and use that environment, and its
associated upsizing tools, for the effort. Not elegant, but certainly an option.
There are some folks making tools out there, You should be sure to visit their web
sites to check out their wares if this is something you'll be doing on any medium-to-
large scale:
• Weir Performance Technologies produces upsizing tools and Access optimizer
tools. More information on their web site. They also have some interesting
conversion tools when moving between platforms. The tools know the
differences between function syntax's across the platforms you're converting
between.
• Aditi Technologies produces upsizing tools that will help you move your
databases from Access to SQL Server. Visit their site for more information.
Working with Stored Procedures with ODBC
Using a cursor fetch statement inside a SP causes results to be returned to the
ODBC client prematurely. How can I prevent this behavior?
In SQL Server, SET NOCOUNT ON eliminates the sending of DONE_IN_PROC
messages to the client for each statement in a stored procedure. The global
variable @@ROWCOUNT is updated even when NOCOUNT is turned ON.
Equality check for NULL is different via ODBC vs ISQL
Why would the equality check for NULL give different results through ODBC than
ISQL?
The global variable ANSI_NULLS 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. ODBC turns
this behavior on by default and you should globally change this behavior by using
the syntax "SET ANSI_NULLS OFF".
How do I create an auto-increment field?
How do i create a auto-increment field in MS-SQL server 6.5?
You'll need to use the the IDENTITY datatype. You can optionally give it a seed and
increment. It's also a good column as (and probably most frequently used as) a
unique key on the database. You indicate the range of values for the identity by
choosing the column size (int, smallint, etc.) of the field when you create the
column.

SQL Server FAQ - General


Is MS SQL Server Y2K compliant?
That depends on what you mean by "compliant". If you mean the base SQL
functionality works as you would expect then yes, as long as you are using "proper"
datetime formats then all versions of SQL Server perform correctly - if you are
holding dates in char/numeric format, then it totally depends on how you are
processing them, it is not an MS SQL Server issue.

SQL Server does date-windowing for two digit dates. 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.
However, if you mean the whole of the MS SQL Server product set including all the
gui tools, then there are a few non-showstopper problems that have been found.
These are all documented at www.microsoft.com/y2k along with MS's stance and
technical info on Y2K issues for all their products. The SQL 6.5 Y2K fix titles are also
copied at the bottom of this note.

These problems have been found, fixed and tested in SQL 6.5 and will be in Service
Pack 5 when it is released. Before that a Y2K fix (build 339) can be obtained from
MS PSS - however I would recommend waiting for SP5.

SQL 7.0 will be Y2K compliant at release.

SQL 1.x, 4.x and 6.0 are NOT being tested or certified by MS. They are unlikely to
have any other problems than those found in the 6.5 product though, so if you can
live with those (and most people can), then they should be ok.

Vendor's certification should only be one part of Y2K testing anyway - the most
important part is that YOU test your clients, servers, apps, databases, networks
etc. in your production environment.

------------------
SQL 6.5 Y2K bug numbers and titles
1745
Year 2000 Problem with Expiredate
8
1793 Y2000, ExpireDate is not set correctly when year of 2000 used in DUMP
7 DATABASE
1794 RETAINDAYS: expired dump media can not be overwritten if current year is
7 >= 2000
1794
Dump db with RETAINDAYS during Y2000-9, EXPIREDATE will be set to NULL
8
1799 Y2000: dump device dumped with expiredate set to >=2000 can be override
7 with init
1766 Task Manager UI: one time task date\time spin box doesn't pick up
1 2/29/2000
1815
Web Assistant: Cannot use Year as 00 on Scheduling
3
1817
Invalid Y2K dates are accepted with no error by sp_addtask
0
1818 Invalid Y2K dates are accepted with no error by sp_purgehistory and sp_
0 updatealert
Where is the SQL Server FAQ? Or other useful SQL information.
SQL Books Online is a good source, as is Technet with 100's of techie
articles/whitepapers on SQL as well as the Knowledgebase.

SQL Server Mailing List at www.swynk.com


SQL Server newsgroups : microsoft.public.sqlserver.* and
comp.dcom.databases.ms-sqlserver

GO MSSQL on Compuserve for SQL forums

Books (a few good ones, but this doesn't mean anything not listed isn't good! Many
of these go through various revisions, so check you're getting the latest and
greatest version) :-

Microsoft SQL Server 6.5 Programming Unleashed : Sams/various : Good for


programming/TSQL

Microsoft SQL Server 6.5 Unleashed : Sams/various : Good for


DBA's/admin/performance/general

Inside Microsoft SQL Server 6.5 : MSPress/Ron Soukup : SQL Server Internals, how
it works, why the history. Plenty of good undocumented stuff.

Microsoft SQL Server 6.5 DBA Survival Guide : SAMS/Spenik and Sledge: Short and
to the point on common DBA tasks

SQL Server 6.5 Secrets: IDG/Rensin and Fedorchek : Tons of very good scripts

Special Edition Using Microsoft SQL Server 6.5 : Que/Stephen Wynkoop : Excellent
starter book and reference work for step by step examples of performaing many
tasks.

SQL for Smarties : Morgan-K/Joe Celko : Advanced SQL programming techniques,


tricks and tips. Not SQL Server specific but highly recommended.

Hitchhikers Guide to VB and SQL Server : MSPress/Bill Vaughn : If you're coding VB


to access SQL and you're not sure whether to use db-lib, odbc, ado, rdo, ole-db,
rds, rdo, dmo (I think that's all of them) then this is the bible.

BackOffice Resource Kit Part II : MSPress : Good stuff on SQL connectivity and
some internals, plus some nice utilities and whitepapers.
SQL Puzzles and Ansers : Morgan-K/Joe Celko : Advanced SQL programming
techniques, tricks and tips. Not SQL Server specific but highly recommended.

SQL Server System Administration : New Riders/Baird, Miller, Hotek, et al : SQL


Server 7.0 for the experienced admin. Covers intermediate and advanced topics as
well as how to squeeze additional capabilities and performance out of your server.

Significant effort and work has been put into this FAQ by Neil Pike. You can also
find some of his work on the NTFAQ
Can I compress a SQL Server .DAT device/file? Will it cause any problems?
Yes you can as long as you stop SQL first - NT needs exclusive access to a file in
order to compress it. In theory everything should be fine as SQL isn't interested in
what is happening down at the filesystem level.

In practice, this is not recommended due to the performance problems it can cause,
especially if you compress an empty database/device and then start filling it up -
there is then a lot of overhead in NTFS expanding the file as previously it had
compressed very well due to the large number of binary zeroes used to pad empty
pages.
Why does the SQL Server Database Maintenance Wizard warn about using
it on databases greater than 400MB in size?
The DMW sets up an "aggressive" set of dbcc and other healthchecks. On "large"
databases this sort of housekeeping can take a long time, so you might not want to
do everything every night. In this situation you might want to set up your own
maintenance tasks, perhaps only running checkdb once per week, and newalloc
every night, with index rebuilds once a month or so.

MS's choice of "large" is 400Mb - probably a bit low given the speed of current
cpu's/disks etc. The answer is, if you're happy with the time it takes to run the
DMW generated tasks, then stick with it, regardless of your database size.
Can I do an NT defrag on a SQL Server .DAT device/file? Will it cause any
problems or do any good?
Yes you can as long as you stop SQL first - NT needs exclusive access to a file in
order to defragment it. As long as there are no bugs in the defrag program and the
system doesn't crash in the middle of a defrag then there shouldn't be any
problems.

Will it help? Usually not much as SQL devices don't tend to change in size once they
are created, so unless a disk was badly fragmented when the device was created so
that NT could not allocate contiguous space for it all then it won't be fragmented.

If you create your SQL devices on a freshly formatted drive then you won't get any
fragmentation.
What does dbcc traceon(208) mean in SQL Server? I see it in SQL's
errorlogs, but I'm not issuing it.
This traceflag is set by some applications as they rely on SQL 6.0's quoted identifier
behaviour for object names. For differences introduced with 6.5 to this behaviour
look at the "What's New" section in the 6.5 books-online.
Where can I get the ANSI92 SQL information from?
This is information is only available from ANSI themselves and as far as I know is
only available on paper (to discourage piracy). They charge for the information -
they have to have some form of income stream after all.

More information can be had from their web-site www.ansi.org


What packages are available to do source control on SQL Server SP's, DDL
etc.?
Microsoft has integrated their Repository into SQL 7 so there will probably be some
functions there with new versions of Visual SourceSafe, but assuming VSS doesn't
meet your needs, then 3rd party DBMS tools do offer these features :-
Cast Workbench - www.castsoftware.com
SQL Programmer - www.sfi-software.com See a Review
RapidSQL - www.embarcadero.com See a Review
DBArtisan - www.embarcadero.com See a Review

SQL Server FAQ - Internet Development


How can I return the row count from an IDC query?
I´m using IDC to query an SQLServer database, I´ve tried to make a 'select
count..' query but I can´t display anything in the .htx file.
SELECT 'count'=COUNT(*) FROM Mydatabase.dbo.Mytable
WHERE value like '%something%'
You need to give a header name to your column.
How do I publish SQL Server information on my web server?
If you're using Microsoft's IIS as your server, you can use the Internet Database
Connector. The IDC works with a set of files, your form, the IDC file and an HTX file
to produce output based on your database. The IDC file itself contains the query
that is used against the server. The HTX is the results set formatting file, and of
course your form file is responsible for gathering parameters from the user.
Specific information is availble at http://www.pobox.com/~swynk -- select the link
that goes to the article in MCP Magazine that details IDCs.
Also, be sure to check out the ISAPI IDC and ODBC FAQ, located at
http://rampages.onramp.net/~steveg/iis4.html.
I can't pass parameters to a stored procedure from an IDC
For my electronic guest book application I've defined a little sql server database. In
order to access the stored information, using a html form, I've written a HTML
extension file and an IDC file. The IDC file includes the following query:
SELECT * FROM users +WHERE firstname like '%FirstName%' + and lastname like
'%LastName%' + and nick like '%Nick%' + and age like %Age% + and
male_female = %Sex% + and ownpres_text like '%ownpres%' + and email like
'%EMail%' + and school like '%School%' + and area_city like '%City_area%' + and
state like '%State%' + and country like '%Country%'
In all of the above, the corresponding SQL 6.5 definition is "CHAR" except for the
Age, Sex and OwnPres columns. These are smallint, bin and text respectively.
It isn't possible to access the information stored in the database. Instead, there's
this message:
Error Performing Query [State=22005][Error=257][Microsoft][ODBC SQL Server
Driver] [SQL Server]Implicit conversion from datatype 'int' to 'varchar' is not
allowed. Use the CONVERT function to run this query.
The error occurs in the IDC file. form variables passed into the sql queries are
character string, so error occurs in the comparison for age and sex. Try these:
select * from users WHERE firstname like '%FirstName%' and lastname like
'%LastName%' and nick like '%Nick%' and convert(varchar,age) like '%Age%' and
convert(varchar,male_female) = '%Sex%' and ownpres_text like '%ownpres%' and
email like '%EMail%' and school like '%School%' and area_city like '%City_area%'
and state like '%State%' and country like '%Country%'
You have to remember to specify to the user to enter 1 and 0 for the Sex field.
How do I create an anonymous user for access to SQL Server from IIS?
I get the error below when trying to insert a record into a SQL Server database
table from an IIS hosted web form.
"Microsoft OLE DB Provider for ODBC Drivers error '80004005'
[Microsoft][ODBC SQL Server Driver][SQL Server] Login failed"
I am a newbie at this, and though I have no problem manipulating an Access
database from the web, I can't seem to get SQL Server to let me in, even while
logged into my computer as the administrator. I have tried allowing guest access
into the server but no dice. Do I send the generic user ID and password as a string
to the server when I make the connection from the web server? I can't find the
syntax examples if that's the way to do it. Any ideas???? Any help greatly
appreciated.
Typically, you need to ceate a DSN using the 32 bit ODBC manager in Control panel
for the database under consideration. Then you would use this DSN (system or
user, depending on the connectivity software) and supply a username password so
that the SQL server allows access.
You have another option: change the security mode of your sql server to implement
integrated security. This allows any user who is authenticated by the NT domain to
access the SQL server. You can further restrict access for different users in the NT
domain by using grant/revoke inside SQL server.

SQL Server FAQ - Logs


Why does my transaction-log fill up when I use fast-bcp or select into?. I
thought this didn't log anything.
Fast BCP and select into do not log record updates. However they DO log extent
allocations. They need to do this so that if the process is terminated unexpectedly
(maybe the power goes out), SQL can recover the space.

Therefore with large bcp's/select into's - when a lot of extents need allocating - the
log can still fill. In which case it needs to be made larger.
How can I view the SQL Server log?
Most of the information in the SQL log (syslogs) is not accessible via standard SQL
commands. The ways of accessing this information are :-
1. You can get transaction id and operation type only (no data) through a select *
from syslogs. Or use the following code (courtesy of Tibor Karaszi) to make it a bit
more readable.
SELECT
xactid AS TRAN_ID,
CASE op
WHEN 0 THEN 'BEGINXACT Start Transaction'
WHEN 1 THEN 'Not Used'
WHEN 2 THEN 'Not Used'
WHEN 3 THEN 'Not Used'
WHEN 4 THEN 'INSERT Insert Row'
WHEN 5 THEN 'DELETE Delete Row'
WHEN 6 THEN 'INSIND Deferred Update step 2 insert record'
WHEN 7 THEN 'IINSERT NC Index Insert'
WHEN 8 THEN 'IDELETE NC Index Delete'
WHEN 9 THEN 'MODIFY Modify Row'
WHEN 10 THEN 'NOOP'
WHEN 11 THEN 'INOOP Deferred Update step 1 insert record'
WHEN 12 THEN 'DNOOP Deferred Update step 1 delete record'
WHEN 13 THEN 'ALLOC Allocation'
WHEN 14 THEN 'DBNEXTID Extent allocation'
WHEN 15 THEN 'EXTENT Extent allocation'
WHEN 16 THEN 'SPLIT Page split'
WHEN 17 THEN 'CHECKPOINT'
WHEN 18 THEN 'SAVEXACT Savepoint'
WHEN 19 THEN 'CMD'
WHEN 20 THEN 'DEXTENT Deallocate extent'
WHEN 21 THEN 'DEALLOC Deallocate page'
WHEN 22 THEN 'DROPEXTS Delete all extents on alloc pg'
WHEN 23 THEN 'AEXTENT Alloc extent - mark all pgs used'
WHEN 24 THEN 'SALLOC Alloc new page for split'
WHEN 25 THEN 'Not Used'
WHEN 26 THEN 'Not Used'
WHEN 27 THEN 'SORT Sort allocations'
WHEN 28 THEN 'SODEALLOC Related to sort allocations'
WHEN 29 THEN 'ALTDB Alter database record'
WHEN 30 THEN 'ENDXACT End Transaction'
WHEN 31 THEN 'SORTTS Related to sort allocations'
WHEN 32 THEN 'TEXT Log record of direct TEXT insert'
WHEN 33 THEN 'INOOPTEXT Log record for deferred TEXT insert'
WHEN 34 THEN 'DNOOPTEXT Log record for deferred TEXT delete'
WHEN 35 THEN 'INSINDTEXT Indirrect insert log record'
WHEN 36 THEN 'TEXTDELETE Delete text log record'
WHEN 37 THEN 'SORTEDSPLIT Used for sorted splits'
WHEN 38 THEN 'CHGINDSTAT Incremental sysindexes stat changes'
WHEN 39 THEN 'CHGINDPG Direct change to sysindexes'
WHEN 40 THEN 'TXTPTR Info log row WHEN retrieving TEXTPTR'
WHEN 41 THEN 'TEXTINFO Info log for WRITETEXT/UPDATETEXT'
WHEN 42 THEN 'RESETIDENT Used WHEN a truncate table resets an identity value'
WHEN 43 THEN 'UNDO Compensating log record for Insert Only Row Locking
(IORL)'
WHEN 44 THEN 'INSERT_IORL Insert with Row Locking record'
WHEN 45 THEN 'INSIND_IORL INSIND with IORL'
WHEN 46 THEN 'IINSERT_IORL IINDEX with IORL'
WHEN 47 THEN 'SPLIT_IORL Page split with IORL'
WHEN 48 THEN 'SALLOC_IORL Alloc new page for split with IORL'
WHEN 49 THEN 'ALLOC_IORL Allocation with IORL'
WHEN 50 THEN 'PREALLOCLOG Pre-allocate log space for CLRs'
ELSE 'Unknown Type' END AS LOG_RECORD
FROM syslogs

2. dbcc log command. Not well documented, but some details below. Note that as
with most undocumented dbcc commands you need to do a dbcc traceon(3604)
first to see the output.
3. Logview from www.dbsg.com.
4. Log Analyzer from www.platinum.com
(All these are currently for 6.5 or earlier)
---------------------------------------
dbcc log [ (@dbid, @objid, @pagenum, @rownum, @records, @type [, @printopt])
]
dbcc log (5, 0, 0, 0, -1, 0, 1) // Show the last begin transaction record in the log
Parameters:
@dbid Database ID
@objid Object ID
A negative value indicates that @pagenum & @rownum represent a row in the log
to use as a starting point in the scan of the log.
A value of zero indicates that log records for changes to @pagenum will be included
in the commands output.
A positive value followed by a non-zero value for @pagenum indicates that
@pagenum and @rownum represent a transaction ID. Log records for that
transaction will be included in the output.
A positive value followed by zero values for @pagenum and @rownum indicates an
object ID. Log records for changes to that object will be included in the output.
@pagenum page number
@rownum row number in the log
Together with @pagenum, this is either a starting point in a scan of the log or a
transaction id.
@records number of records to examine. If positive, the first
@type
@printopt

SQL Server FAQ - Replication


Replication failing over trusted connection
Am attempting to set up replication and the replication is failing with the following
message:
37000[Microsoft][ODBC SQL Server Driver] [SQL Server]Login failed-User; Reason:
Not associated with a trusted SQL Server connection.
Remember there are two different ways to login to SQL Server. One is "standard"
security, with a SQL Server login name and password. The other is via a trusted
connection (sounds like you may have a problem there). Perhaps check your
domain servers -- if you're in a different domain -- and set up a trust relationship
between the two domains, if possible. Or change the SQL Server security model to
"mixed" (Windows NT and SQL Server). If you've set up a login somewhere as
"trusted" but the publication server is not trusted by the subscribing server, you've
got a problem right there.
If your servers are in the same domain, get the account of SQL Executive service
running on the distribution server ( or publisher, if you have not separate
distributor). For replication purposes this account has to be domain-wide. Then on
subscription server check:
• If this account is in Administrators group.
• If not, check with SQL Security Manager if this account is mapped to
repl_publisher SQL Server account.
If both checks fail, you can try to use xp_grantlogin, for example:
xp_grantlogin , 'repl'
Check the documentation - Transaction SQL Reference, extended stored
procedures, xp_grantlogin.
An other option I've never used is to specify userid and password to distribuition
task. Check the article Replication Tasks Scheduling.
No tables showing up for replication
I have a problem with replication. I have two data devices test & dialogue. The
database sherman shows up in both but in dialogue it is empty, no tables.
I want the database in dialogue & that to be the master. I have struggled, and I
can not achieve it. I finally think publish/subscribe may be the way.
So I tried that but each time I get the error:
Installation of SQL server replication system resquires the SQL
executive to be run under a windows NT
user account other than local system.

I have tried Admin, and admin user (tony) SQL login as sa. I am stumped, I would
like to know how to subscribe/publish, but I urgently need my original problem
solved.
To solve this problem, follow these steps:
1) Open "Services" -window from Control Panel.
2) Find the "SQLExecutive" service from the list and select it.
3) Push the "Startup" -button and check the "Log On As" selection. Value "This
Account:" (and account name) should be selected.
#2: No tables showing up for replication
One other area to consider if you're having troubles with replication is that of
unique keys on the tables you're attempting to publish. If you don't have unique
keys defined, the table will not be listed as available for publishing. You *must*
have a key defined for all tables you plan to publish.

SQL Server FAQ - SQL Mail


How can I set-up SQL Mail on SQL Server without using an MS-Mail or
Exchange server? I'd like to use my standard SMTP/POP3 services.
Try the following instructions (note these aren't written by the author, and haven't
been tested either, but they do, allegedly, work)

Set up Microsoft SQL Server service. · Note: Microsoft SQL Server must start up
using a user account that has been given administrator privileges. The account
must also allow the user to logon as a service. This allows Microsoft SQL Server to
interact with email. · Note: By default, SQL Server 6.5 creates an account named
" SQLExecutiveCmdExec". Verify that this account exists and is set up properly:

1. Click on the "Start" button


2. Programs
3. Administrative Tools ( Common )
4. User Manager for Domains, if the option is "User Manager" go to step 9.
5. When the User Manager program loads, select "Users" from the menu.
6. Choose the menu option "Select Domain"
7. Type in the name of the machine, e.g. "DBASQLTEST"
8. Click the OK button.
9. You should now have a list of users on the machine.
10. If the account "SQLExecutiveCmdExec" exists: double-click the user, a dialog
box will appear. Skip to step 18.
11. Select "Users" from the menu.
12. Choose the menu option "New User".
13. A dialog box will appear.
14. In the User Name field, type "SQLExecutiveCmdExec"
15. In the Full Name field, type "SQLExecutiveCmdExec"
16. In the password field type a unique password (record you password in a safe
place, you will need it later in this setup )
17. In the Confirm Password field retype the password you just entered.
18. Uncheck the box next to "User Must change Password at Next Logon".
19. Check the box next to "User Cannot Change Password".
20. Check the box next to "Password Never Expires".
21. Click on the "Groups" button.
22. The Group Membership dialog box will appear.
23. Add the group "Administrators" 24. Click the "OK" button to close the Group
Membership dialog.
25. Click the "OK" button to close the User Properties dialog.
26. Select "Policies" from the menu.
27. Choose the menu option "User Rights".
28. The User Rights Policy dialog box will appear.
29. Check the box next to "Show Advanced User Rights"
30. On the drop down select list, choose the option "Log on as a Service".
31. Click on the "Add" button. 32. The "Add Users and Groups" dialog box will
appear.
33. On the drop down select list, choose the current computer name, e.g.
"\\SERVERNAME*".
34. Click the "Show Users" button.
35. Scroll down the list of users and select "SQLExecutiveCmdExec".
36. Click on the "Add" button.
37. The user "SQLExecutiveCmdExec" should now be in the "Add Names:" list.
38. Click on the "OK" button to close the "Add Users and Groups" dialog.
39. Click on the "OK" button to close the "User Rights Policy" dialog.

Install Windows NT Messaging.


Note: Next, make sure Windows NT Messaging is installed on the Microsoft SQL
Server machine. SQLmail uses Windows Messaging, so it needs to be configured for
proper operation. This can be verified by:
1. Open the Control Panel and double click on Add/Remove Programs.
2. Select the Windows NT Setup tab and scroll to the bottom of the list box that
appears.
3. Verify that the Windows Messaging check box is checked.
4. If it is not,check it now.
5. Click OK.
6. At this point, if you need to install Windows Messaging you will need to supply
the Windows NT CD.
Set Up Mail Services
Note: You will need two internet mail accounts before continuing.
1. You will need a POP mail account login, password and server name.
2. You will need a SMTP mail account login, password and server name.
3. Next, close all programs on the Microsoft SQL Server machine and log in as a
new user. Use the SQLExecutiveCmdExec account.
1. On the desktop, right-click the "Inbox" icon, and select Properties option. Here
you will need to add anew profile for the SQLExec user. Click on the "Add" button to
begin creating a Windows Messaging Profile:
2. Uncheck the box next to "Microsoft Mail" (Unless there is an Exchange Server
Available)
3. Ensure the box next to "Internet Mail" is checked.
4. Click on the "Next" button.
5. You will be asked for the method to connect to the mail server, check the radio
button next to "Network".
6. Click on the "Next" button.
7. You will be asked to specify the Mail server name or IP address, enter either one
here.
8. Click on the "Next" button.
9. You will be asked to choose the mode for transferring messages. Check the radio
button next to "Automatic".
10. Click on the "Next" button.
11. You will be asked for the email address, enter it in the Email Address field.
12. Enter "SQLExecutiveCmdExec" in the Full Name field.
13. Click on the "Next" button.
14. You will be asked for the mailbox name. Enter a mailbox name in the mailbox
name field, e.g. userid. (This is the mail server login name ).
15. Enter the password for the mailbox name in the password field. (This is the mail
server login name's password ).
16. Click on the "Next" button.
17. You will be asked for a location for your personal address book. Use the default.
18. Click on the "Next" button.
19. You will be asked for a location for your personal folder file. Use the default.
20. Click on the "Next" button.
21. You should receive the message that setup is "Done!"
22. Click on the "Finish" button.
23. In the profiles list box, you should now see an entry for "Windows Messaging
Settings".
24. Click on the "Copy" button.
25. You will be asked to name the new profile. Type "SQLExecutiveCmdExec".
26. Click "OK" to commit the copy.
27. In the profiles list box, you should now see an entry for
" SQLExecutiveCmdExec".
28. In the drop down select list for "When Starting Windows Messaging, use this
profile:", choose the newly created profile, "SQLExecutiveCmdExec".
29. Click on the "Close" button to complete the setup.
Configure SQL Server Service and SQLExecutive to use new mail account
You will need to stop the Microsoft SQL Server service
1. Open the Control Panel.
2. Double-click Services.
3. Scroll down until you find Microsoft SQL Server, select it, and click the stop
button.
4. The service status should change to stopped.
5. Double-click on the Microsoft SQL Server service to bring up its properties dialog
box.
6. At the bottom of the dialog is the account by which Microsoft SQL Server will use
to startup. Change this to use the SQLExecutiveCmdExec account. Be sure to enter
the password correctly here or Microsoft SQL Server will not start up.
7. Close this dialog by clicking the "OK" button.
8. Start the service by clicking the start button.
9. The service should start up successfully. If it does not start check to make sure
the password you just entered matches the one entered in the User Manager for
Domains.
10. Scroll down until you find SQLExecutive, select it, and click the stop button.
11. The service status should change to stopped.
12. Double-click on the SQLExecutive service to bring up its properties dialog box.
13. At the bottom of the dialog is the account by which Microsoft SQL Server will
use to startup. Change this to use the SQLExecutiveCmdExec account. Be sure to
enter the password correctly here or Microsoft SQL Server will not start up.
14. Close this dialog by clicking the "OK" button.
15. Start the service by clicking the start button.
16. The service should start up successfully. If it does not start check to make sure
the password you just entered matches the one entered in the User Manager for
Domains.
Configure SQL Server Setup Options
1. Click on the "Start" button
2. Programs
3. Microsoft SQL Server 6.5
4. SQL Setup
5. The "Welcome" dialog will appear. Click the "Continue" button.
6. The "SQL Server Already Installed" dialog will appear. Click the "Continue"
button.
7. Check the radio button next to "Set Server Options".
8. Click the "Continue" button.
9. Check the box next to "Autostart SQL Mail".
10. Click the "Mail Profile" button, which is the last button in the center of the
dialog box.
11. In the dialog box that appears, enter "SQLExecutiveCmdExec".
12. Click the "OK" button.
13. Click "Change Options" button.
14. The "Exchange Login Configuration" dialog box may appear again. If it does,
simply click the "Continue" button.
15. A dialog box stating that the options have been successfully set should appear.
Click the "Exit to Windows NT" button.
You will need to stop and restart SQL Server
1. Click on the "Start" button
2. Programs
3. Microsoft SQL Server 6.5
4. SQL Service Manager
5. A dialog box with a traffic light will appear.
6. Double click the Red light to stop the service. Watch the status bar at the bottom
of the dialog box for the message "The service is stopped"
7. Double click the Green light to start the service. Watch the status bar at the
bottom of the dialog box for the message "The service is running"
8. Close the dialog box.
Set up Internet Mail ( MAPI Setup )
You should have at least Internet Explorer installed on your server.
1. Double click the "Internet Explorer" icon on your desktop to start IE3.
2. Select "Go" from the menu.
3. Choose the "Read Mail" option.
4. The "Browse for Folder" dialog box will appear.
5. You may either choose a folder or use the default.
6. Click on the "OK" button.
7. A new dialog "Wizard" will appear.
8. Click on the "Next" button.
9. In the name field, enter "SQLExecutiveCmdExec".
10. In the Email Address field enter the email address, e.g. user@domain.com.
11. Click on the "Next" button.
12. In the "Incoming mail (POP3) server" field, enter the name of the POP3 server.
13. In the "Outgoing mail (SMTP) server" field, enter the name of the SMTP server.
14. Click on the "Next" button.
15. In the "Account Name" field, enter the email account name, e.g. userid
16. In the "Password" field, enter the email account name's password.
17. Click on the "Next" button.
18. You will be asked for the connection type, choose "I use a LAN connection"
19. Click on the "Next" button.
20. Click on the "Finish" button.
21. The MAPI mail client will appear. You may close the MAPI mail client
application.
Start SQL Enterprise Manager. See if SQL Mail is working by expanding your server
and seeing if the SQL Mail icon turns green. · If it turns red, something went
wrong; green means it is working properly. · It may take a little time for this icon to
turn any color, so wait for a little bit before doing anything else. · If everything
seems to be working properly, open the SQL Tool and type the following:
1. xp_sendmail 'user@domain.com',@message='This is a test message.' Where
user@domain.com is an existing internet mail address that can receive messages.
2. Execute the statement by pressing Ctrl-E or clicking the green GO button in the
Query Tool. You should receive a message in the result window stating "Mail Sent."
Hopefully the configuration process went well and Microsoft SQL Server is now
capable of processing mail. There are numerous stored procedures available to
process inbound and outbound mail. See the SQL reference manuals for more
information on these.
How do I install SQL Mail? I've got problems installing SQL Mail on SQL
Server.
First read the manual - SQL provides a very good, searchable, books-online.

After that go to www.microsoft.com/support and check out the following SQL Mail
knowledgebase articles :-

Q118501 for MS-Mail post-offices


Q153159 for Exchange post-offices

Any other problems then do a search for "SQLMAIL" and you'll find other more
specific articles.
Unable to Get Mail to Work Properly
I cannot get Sql Server 6.0 mail to start under Windows NT 4.0, I setup a valid
profile for the built in NT mail service but sql mail will never start.
One way you can enable this option is to install MS Exchange Server/Client and
create a profile (private information store, if I'm right) that would represent an
account that recieves mail from SQLServer 6.5. The SQL Mail option in SQLServer
can then be configured to point to this profile... This scenario works quite well for
me. I can have mail sent by SQLServer, directly into my Exchange/Outlook Inbox.
I'm not sure of SQLServer 6.0 version's support for this scenario. Also, I'm not sure
if a similar option exists for users of MS Mail.
Can I send mail from a stored procedure or trigger?
Use the xp_sendmail procedure.
SQLServer versions after 4.2x can be setup to start an msmail session
automatically without a user being logged in. For example, in 6.0 you setup mail
parameters in the SQLSetup program. Be sure to tell it to start the mail session
automatically. (Otherwise you manually start the mail session with the xp_startmail
procedure -- specify the user name and password as parameters to the call.)
If you are running SQLServer service under the system account, you must create a
share for your mail postoffice and the share must be marked in the registry to allow
services to access it. The registry key is
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanServer\Parame
ters\NullSession Shares...
This information is found in the Microsoft Knowledgebase, article Q118501.
This url seems to work:
http://198.105.232.6:80/KB/bussys/sql_odbc/Q118501.htm

SQL Server FAQ - System Tables


Can I trust sysdepends to track dependencies?
sysdepends only track child dependencies, not parental. In a way it does, but what
is important to understand is that it is populated based on the information available
from the object being created (a CREATE PROCEDURE) for example.
If the new stored procedure calls sp2, and sp2 exists at the time the sp_parent is
created, sysdepends will be updated. If sp2 is added later, you will end up with "no"
information in sysdepends. Basically, sysdepends is for information "as is" and don't
bet on it.
How can I amend the system tables in SQL Server? Can I put a trigger on
one?
First, it should be said that unless you are using code that MS have published then
any direct updates to the system tables are not supported - so if you're not sure
either don't do it, or take a backup first.

With the exception of "materialised" tables like syslocks and sysprocesses you can
pretty much use standard SQL commands to update the system tables.

Some system tables SQL Server updates internally via it's own api's and some it
does via standard TSQL. Any updates it does via standard TSQL would result in a
trigger firing, however there is no list of what tables this would work with, and it
certainly wouldn't be supported if you did use it.

To update system tables first you have to set the "allow updates" flag as follows :-

sp_configure 'allow updates',1


go
reconfigure with override
go

Then go can make updates - make sure you always do this within a transaction so
that if you affect more rows than you meant to then it can be rolled back.
Afterwards reset the 'allow updates' flag.

sp_configure 'allow updates',1


go
reconfigure with override
go

There are also a few occasions where MS have put in "extra" protection to stop
users mucking about. One example is sysindexes where you must specify the
name, id and indid in the where clause otherwise the update will fail.
SQL Server FAQ - Transfer/move objects/data
How do I transfer data from another DBMS/format to SQL Server? (e.g.
from FoxPro, Access, AS/400, DB/2, Oracle....)
There are a variety of methods :-
1. For MS-Access you can try the free Access upsizing wizards available from MS's
website - check out the softlib area under www.microsoft.com/support. These will
convert from versions of Access to SQL 4.x and 6.x. No conversion to 7.x is
currently available, so convert to 6.5 and then upgrade that copy of SQL Server to
7.0.
2. If you can unload the data from the foreign dbms into flat-file format - e.g. tab
separated, comma-separated, fixed-format etc. then you can use the SQL BCP.EXE
tool. This is a command-line program and is fully doc'd in the books-online. It is the
fastest way of getting data into/out of SQL Server, but it only works via flat-files.
3. If you have an ODBC driver for the other format then there are several 3rd party
tools you can use that offer transfer/migration functionality and are GUI-based, but
can also be automated and run from the command-line. These tools can be used to
copy to/from ANY ODBC data sources - they don't have to be SQL Server at one
end. Examples of these sorts of tools are :-

Data Junction
SQL Mover
InfoPump
DBArtisan

4. If you have SQL 7.0 then this comes with a tool called DTS that works in a
similar manner to the above. It works with any ODBC or OLE-DB accessible data
source. Again it doesn't have to be SQL 7.0 at one end. However if you weren't
using it to migrate to/from SQL 7.0 you would have to check whether there were
any licensing implications.
5. Specifically for the AS/400 there are a couple of tools that have been around for
some time - offering real-time replication as well as transfer.

Data Mirror
Symbiator
How do I remove the tempdb database from master?
Do the following.
1. Configure tempdb to be in RAM for 2 MB. Use SQL EM or sp_configure.
2. Execute a reconfigure with override.
3. Stop and restart SQL Server.
4. Add a new device for tempdb. Do not call it temp_db - any other name should be
ok
5. Make that new device a 'default' device; make sure no other device is marked as
default, especially master. You can check/change default status either using SQL
EM, or the sp_diskdefault stored-procedure. Both are fully described in the books-
online.
6. Configure tempdb to NOT be in RAM (set value to 0)
7. Execute a reconfigure with override.
8. Stop and restart SQL Server
9. Re-mark whichever device(s) you want to be default.
I am having problems with SQL Server running bcp from xp_cmdshell -
why does it not run or see the files I want it to?
First make sure that you have the rights to run xp_cmdshell - do an xp_cmdshell
'dir' and check you get a resultset of filenames back.

Then be aware that the MSSQLSERVER service is running under a separate set of
NT credentials. It doesn't matter who YOU are logged on as (after all SQL runs
quite happily when no-one is logged on to the console doesn't it). Therefore your
logon account and any mapped drives are irrelevant. It is SQL Server running the
bcp, not you, so as far as drive letters go it can only see the local ones - local
meaning on the server, do not be confused into thinking that if you are issuing the
query from a workstation that the query is referencing your workstation's local
drives.

The default set of NT credentials used by MSSQLSERVER is the Localsystem


account. You can check what userid that MSSQLSERVER is running under by looking
at control panel/services highlighting MSSQLSERVER and choosing the start-up
option.

The Localsystem account has no access to shares on the network as it isn't an


authenticated network account.

So, if you want bcp running under xp_cmdshell to access a network resource you
have two choices :-

1. Change the account the MSSQLSERVER service runs under to a user account with
the relevant network rights.

or

2. Amend the following registry value on the TARGET server and add the
sharename you want to access - the share does not then authenticate who is
coming in and so a Localsystem account will work. The server service on the target
server must be re-started before the change takes effect. Note that this effectively
removes security on that share, so you need to be careful about what is in the
share.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Param
eters\NullSessionShares

Whichever method you use, you MUST use a UNC name to reference the resources
required and not a drive letter.
i.e. xp_cmdshell 'bcp servername..tablename out \\server01\share\bcp.fil
.............'
How can I move a SQL Server device from one disk to another, or rename
it?
There are two ways :-

1. Use device mirroring. Mirror the device to the "new" location and then break the
mirror and delete the old device. This method does not need SQL downtime and can
be done via the gui or via TSQL.
2. Use the sp_movedevice sp that is documented in the Books-Online. After making
the change stop SQL Server, physically move the device, then restart it. Therefore
this method requires downtime, but it is faster as using OS level commands is
faster than SQL mirroring.

All that sp_movedevice does is update the phyname in the sysdevices table.

Note that the above method works for all USER databases. If you want to move
master this way, then note that the phyname parameter in sysdevices is only for
documentation - you might as well change it anyway to keep things in line. The
actual method SQL uses for locating the master device is by looking in the registry
:-

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\Paramet
ers\SQLArg0

So it is the value in this key that needs amending.


How can I transfer SQL Server data between an Intel box and an Alpha?
With 6.5 and below you cannot use the DUMP and LOAD DATABASE commands - it
does not do the necessary byte re-ordering to make this work. Therefore you must
use bcp, the transfer tools supplied in SQL EM or write your own ODBC/DMO based
applet.

With SQL 7.0 the byte re-ordering is done for you and so dumps and loads across
architectures are supported.
How do I transfer data between SQL Server databases / across servers?
1. The fastest method for whole databases is to use the DUMP DATABASE and
LOAD DATABASE commands. You need to make sure that the databases are the
same size and made up of the same segment fragments in the same order. If you
do an sp_help_revdatabase on both this will allow you to check the required DDL
for this. You can DUMP and LOAD from a local tape device and transport the tape if
you do not have a network connection.

2. If you only want tables/data you can use the SQL BCP.EXE tool. This is a
command-line program and is fully doc'd in the books-online. It works on one table
at a time and allows you to create a flat file on disk.

3. For stored-procedures/views etc. there is an old command-line based tool called


DEFNCOPY.EXE that works like BCP. It isn't used much these days unless you still
have SQL Server on OS/2 - though it still works on NT at least up until 6.5.

4. SQL Enterprise Manager comes with a built-in gui transfer function, and SQL 7
comes with a separate, equivalent tool. This allows transfer of all objects between
two databases/servers but requires a network connection between the two.

5. 3rd-party DBMS management tools:


Data Junction
SQL Mover
InfoPump
DBArtisan

SQL Server FAQ - Troubleshooting


How does SQL Server clear up orphaned connections?

It doesn't. It never terminates a connection unless it is told to by a user, a KILL


command is issued, or the operating system tells it that the network connection it is
using has been disconnected.

How long the operating system takes to kill a network connection, or whether it is
done at all, depends on the net-lib and network protocol used. For parameters on
keep-alive frames and session time-outs for the relevant network protocol the best
guide is the NT Server resource kit, which describes how NT's various networ layers
work.

Typically, named-pipe connections over netbeui will be timed out quite quickly,
followed by named-pipes over IP. If you're using tcp-ip sockets then these sessions
aren't timed-out at all by default.
How do I get the printdmp.exe program in SQL Server to work?
Basically you don't. The output it produces from AV dump files that it analyses is
still useless to anyone without the SQL Server source code. (If you have SQL
Server source code, then please send me a copy!)

If you are getting AV dumps and you're already on the latest service pack then your
only option is to make a paid support call to MS PSS for them to resolve the issue.
If they want you to run printdmp then they'll give you the info on how to run it.
However, I've never known them want anyone to do this - they usually want the
whole dump file, along with SQL errorlog(s), sp_configure output etc.
I am getting a blue screen / completely hung machine / server restart on
my SQL Server/client.
All the above can ONLY be caused by a problem with something in NT running in
Kernel Mode. e.g. bits of NT, scsi drivers, network drivers, video drivers etc.

All SQL Server code runs in user mode, just like any normal program. Therefore it
is no more capable of causing a blue-screen than Word is. It can only "cause" the
problem in as much as it might hit the disk subsystem hard and expose a bug in a
scsi driver.

If you are getting one of these problems then it needs to be investigated like any
other NT blue-screen problem. i.e. check the driver/program in control at the time,
use dumpexam, apply a newer servicepack, contact MS.
I have a query that seems to lock other users out of the system. Especially
with tempdb. What is going on?
In situations like this the usual problem is with locks. Check with sp_lock or
sp_lock2 what the offending query is doing.

One common occurrence that people fell foul of was introduced in SQL 6.5 when MS
decided to let table creation be allowed in transactions by making it an ATOMIC
transaction. A by product of this is that when a SELECT INTO is done it locks out
system tables in the database concerned and prevents other users from accessing
them. With a long-running select into this can cause real problems.

MS recognised this and as long as you have service pack 1 applied you can set
traceflag -T5302 to remove this behaviour. Check out Q153441 for more info.
My SQL Server database has been marked "suspect" - what can I do?
In addition to these ideas, also check out www.microsoft.com/support for the MS
Knowledgebase. Specifically Q165918.

Firstly look in <sql>\LOG and look at all recent errorlog(s). There WILL be an
indication here as to why the database has been marked suspect. You need to fix
whatever the problem is first (i.e. missing file, permissions problem, hardware error
etc.)

Then, when the problem has been fixed and you're either sure that the data is
going to be ok, or you have no backup anyway, so you've nothing to lose, then
change the database status to normal and restart SQL Server. To change the
database status, and to get more information on recovery, look up the
sp_resetstatus sp in the Books Online.

If you don't have access to sp_resetstatus information, then the short version of
this is :-

UPDATE master..sysdatabases SET status = status ^ 256 WHERE name =


< dbname>

If the database still goes back into suspect mode, and you can't fix the original
problem, and you have no recent backup, then you can get information out of the
database by putting it into emergency mode. If you do this, extract the
data/objects out with bcp/transfer manager and then rebuild the database. Note
that the data may be corrupt or transactionally inconsistent.

Issue the following command to put the database into emergency mode (you'll
need to allow updates first)
UPDATE master..sysdatabases SET status=-32768 WHERE name='<dbname>'
Why can't I get at a network file when I run a program with xp_cmdshell
from SQL Server?
The reason is that the MSSQLSERVER service is running under a separate set of NT
credentials. It doesn't matter who YOU are logged on as (after all SQL runs quite
happily when no-one is logged on to the console doesn't it). Therefore your logon
account and any mapped drives are irrelevant. It is SQL Server running the
program (e.g. bcp) not you.

The default set of NT credentials used by MSSQLSERVER is the Localsystem


account. You can check what userid that MSSQLSERVER is running under by looking
at control panel/services highlighting MSSQLSERVER and choosing the start-up
option.

The Localsystem account has no access to shares on the network as it isn't an


authenticated network account.

So, if you want a program running under xp_cmdshell to access a network resource
you have two choices :-

1. Change the account the MSSQLSERVER service runs under to a user account with
the relevant network rights.

or

2. Amend the following registry value on the TARGET server and add the
sharename you want to access - the share does not then authenticate who is
coming in and so a Localsystem account will work. The server service on the target
server must be re-started before the change takes effect. Note that this effectively
removes security on that share, so you need to be careful about what is in the
share.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Param
eters\NullSessionShares

Whichever method you use, you MUST use a UNC name to reference the resources
required and not a drive letter.

e.g. xp_cmdshell 'dir \\server01\share'

I am getting a message 'dbprocess dead or not enabled' from SQL Server. I


am seeing an 'Exception Access Violation' message in the SQL errorlog. I
am getting *.DMP files in the <sql>\log directory. What is going on?
Basically SQL is probably internally gpf'ing/AV'ing (same thing) - you should see
messages to this effect in the SQL errorlog. There are only three reasons for this :-
1. A database corruption - you can check for this with the dbcc checkdb, newalloc
and checkcatalog commands.
2. A hardware problem - usually duff memory.
3. A bug in the SQL Server code (this is the most likely cause - database
corruptions rarely cause gpf's, and hardware errors normally show up in other
ways). This is the Microsoft C code that makes up SQLSERVR.EXE and dll's, NOT
your TSQL code. If you have SQL code that causes an AV it is Microsoft's bug, not
yours.

Assuming it's not a database corruption, then follow the following diagnostic
process :-

1. Check the Microsoft Kb on Technet (if you don't have Technet then order it
now!). Also check the on-line website at www.microsoft.com/support which is more
up to date than Technet. Search on kbbug AND AV AND SQL to find all documented
AV bugs. Many contain workarounds.
2. Are you on the latest version of SQL Server and the latest service pack? MS fix a
lot of AV errors in every service pack, so it is definitely worth getting current. If
you're not on the latest service pack then that is the first thing MS are going to ask
you to do if you contact them anyway.
3. Check the SQL errorlog and save away all the messages - especially anything
telling you what SQL was being executed at the time.
4. Check the \<sql>\LOG directory for SQLxxxx.DMP files that may have been
created. These contain information on what SQL Server was doing at the time,
module stack traces etc. Save these away for MS support as necessary. (Though
there is a PRINTDMP.EXE utility supplied the output of this is still of no use to
anyone unless they have the SQLServer C source code)
5. Can you re-create the problem at will? If the SQL being run is not shown in the
errorlog, then find out what the user/developer was doing at the time. Use SQL
Trace to capture the actual SQL code being run if you can. If you can't recreate it,
it's still worth reporting as long as you have the errorlog(s) and dump file(s).
6. If you can re-create the problem, then see if you can create a reproduction script
to show the problem. This needs to be capable of running on a brand-new install of
SQL Server on a new database. Therefore it needs to contain all tables, user
defined data types, triggers, views etc. needed to show the problem. If it needs
data then try and keep this to a minimum. (If the script/data is reasonably short
then post to one of the
newsgroups and one of MVP's can report it to MS for you).
7. Can you work around the problem by re-writing the SQL? Even with a
reproduction script MS are unlikely to turn a fix around quickly - unless you are a
multi-million dollar customer. And even then you wouldn't just be applying one
small fix, it would be a latest build with lots of other fixes too - it won't have been
regression tested, so it could cause more damage than it fixed anyway.
8. Report the problem to MS PSS. PLEASE do this even if you can workaround it.
Unless MS get these bug reports then they can't fix them. (With a repro script an
MVP will do it for you). Your call fee WILL be re-imbursed as all calls about bugs are
free. (However, on the "normal" support-line the person answering the phone can't
know it's a bug, so they'll need your credit card details anyway).

MS will need you to supply :-


SQL Errorlog(s)
NT event log(s) - if any NT errors were occuring at the time
TSQL code running at the time
Details of hardware, version of NT, servicepacks etc. WINMSDP output is good for
this.

With SQL 7 there is a new utility that will garner most of this information for you
automatically. It is called sqldiag -
sqldiag -U<login> -P<password> -O<output filename>
I am missing the whole of MSDB, or just some tables - how do I create
them?
In the <sql>\INSTALL directory are the scripts that SQL runs itself to create the
MSDB database and it's tables. If you need to re-create it, then make sure the
devices are already there and then run :-
instmsdb.sql
servrmsgs.sql
web.sql
via ISQL/W or ISQL.
How can I fix a corruption in a system table?
If the problem can be fixed with an index re-create, then there is a system stored-
procedure to do this.

sp_fixindex <db_name>,<system_table_name>,<index-id>
e.g. sp_fixindex pubs,sysindexes,2

You can also issue the relevant dbcc command directly if sp_fixindex refuses to
attempt the fix - e.g. for a non-clustered index on sysobjects

DBCC DBREPAIR(dbid, REPAIRINDEX, sysobjects, 2)

It is not possible to rebuild the clustered index on sysindexes or sysobjects.

If the above do not work, then the only choice is to create a new database and then
use the transfer tools in SQL EM to copy the good data and objects across.
Why do my SQL Server identity values get out of synch causing
gaps/duplicates etc.? Is there anything I can do about it?
Why? Because of inherent problems with the way they were implemented. For
performance reasons the current identity value isn't updated and committed in the
system tables every time a row is inserted. This would lead to unacceptably bad
performance, especially with SQL 6.x's page-level locking architecture - it could
even lead to deadlocks. Therefore the value is stored in memory and only
committed to disk when a clean shutdown of SQL occurs.

So, if SQL doesn't shut down cleanly, or there is some memory problem caused by
an exception violation then the value will not be correct next time SQL starts. There
are also some other bugs that would cause the value not to be updated, but MS
fixed most of these with 6.5 SP3.
The only thing you can do about it is to put dbcc checkident(<tablename>)
statements in a startup stored-procedure (details of this in the BOL) so that the
values get fixed every time SQL starts - obviously for very large tables this may
take a few minutes.

MS's own code/stored-procedures are not immune to this. One very common case
is where you get duplicate key messages on sysbackuphistory (in MSDB) when you
do a database dump. This is because the table uses an identity column.

(MS promise this situation will not occur with SQL 7.x as they have re-worked how
the identity columns function internally)
What are the *.DMP files that appear in the SQL Server log directory. I've
tried printing them with PRINTDMP.EXE but it doesn't work.
These are a sign that SQL Server has had a "handled access violation" - a gpf.

The dump files contain information on what SQL Server was doing at the time,
module stack traces etc. Though there is a PRINTDMP.EXE utility supplied the
output of this is still of no use to anyone unless they have the SQLServer C source
code.

Save the dumps away, together with errorlog info, what SQL was running at the
time etc. and contact MS PSS for support in resolving the problem. (Assuming
you've already applied the latest service pack and dbcc'd your databases to make
sure there are no problems there)
I'm getting an error 1117 in SQL Server. Can I rebuild the extents
somehow?
It is recommended that you select/bcp out all the relevant data and then recreate
the objects concerned. However, if you want to attempt a rebuild of the extents
then make a backup first, and then try the following after putting the database into
single-user mode first :-

dbcc rebuildextents (@db_id, @object_id, @index_id)

Parameters:
@db_id Id of the database
@object_id Id of the object to be rebuild
@index_id Id of the index to be rebuild
Why do I have problems revoking permissions on some tables with SQL
Server? The command works ok, but the users still have permissions (as
shown by sp_helprotect)
This is a known bug in SQL Server with tables that have 8n-1 columns. I.e. 7, 15,
22 etc.

To workaround it remove all entries from sysprotects and then re-grant permissions
as necessary.
use <dbname>
go
exec sp_configure 'allow updates',1
go
reconfigure with override
go
delete sysprotects where id = object_id('<tblname>')
go
exec sp_configure 'allow updates',0
go
reconfigure with override
go
Why do I get the message "WARNING: Process being freed while holding
Dataserver semaphore" in SQL Server.
This is a fairly common error.

1. Check for previous errors - this is often not the actual error that occurred but is a
symptom of a previous error that has caused SQL Server to get confused. It then
ends up trying to exit a routine without having cleared up all the resources that it
owns. It is the previous error that you should look up in Technet/MS
Knowledgebase.

2. It can be a symptom of not having enough resources. Up the number of open


objects, locks and open databases. This may help.

3. Apply the latest servicepack - this or the underlying error may well have been
fixed already.

4. If none of the above apply, and your problem does not match any known,
documented issue then you will have to call MS PSS and open a paid fault call. If
you can reproduce the problem with a script run against a new, clean database
then it should be fairly easy for a fix to be written.
I'm getting a 1112 error on SQL Server - what's going on?
This message will only occur with SQL 4.x and is fixed in all subsequent versions.
The ONLY permanent fix is to upgrade to SQL 6.0 or above.

The error occurs if SQL has crashed during the allocation of an extent - this
sometimes leaves a "being allocated" bit set in the extent. When SQL comes to
need that extent to expand a table then you get the error because SQL thinks the
bit should never me set and some form of corruption has occurred.

Because SQL always allocates extents in the same order, once you get the error
you will carry on getting it unless you drop some objects and free up extents nearer
the start of the database that it can allocate ok. This only puts off the time till the
next 1112.

To "fix" the error you can get and run a file called 1112.EXE from MS PSS or
ftp.microsoft.com/bussys/sql/transfer. This contains details of what to do to run it -
note the database needs to be in single-user mode at the time. All it does is whiz
through the extent map and reset any bits that show as "being allocated".
Note this "fix" only fixes that particular occurence of the problem. The problem will
come back, so move to a supported version of SQL that has a permanent fix for this
problem.
I'm getting a "sort failed 1501" message on SQL Server - what's going on?
This is usually caused by a time-out when creating an index - if you see "state 12"
after the 1501 then it definitely is. This hard-coded timeout was upped with SQL
6.5 SP3 and is rarely seen now (though it does still sometimes occur). It is normally
caused by a slow or congested disk subsystem - either get some faster
disks/controllers or make sure that no other processes are contending on the same
disks at the time of the query that causes the error.

If the above doesn't fit, then you can try upping the "sort pages" parameter in
sp_configure. This may keep more of the sort in memory and reduce the iterations
it goes through and thus prevent the error.

Other than that all you can do is contact MS PSS with the error message, including
state number, and let them delve through the code to see what piece of code the
state message you're getting is in. (The state codes are unique)
I've just changed NT domain for my SQL Server/clients - why can't I
connect to the server any more?
This isn't a SQL issue, it's an NT one. If you are using a net-lib that requires NT
authentication - e.g. named-pipes or multiprotocol - then you MUST be able to
authenticate to the copy of NT running SQL Server.

You can test whether you can do this by doing a "NET VIEW \\servername" from a
command prompt on the client. If you get an access denied message, or get
prompted for a password, then you aren't being authenticated.

If this happens then you need to setup a trust between the domains. Or, you could
use a net-lib that does not need authentication - e.g. tcp-ip sockets.

If you can't have a trust (and really this IS the best method) then you can override
the NT details by doing a "net use \\<server>\ipc$
/user:<serverdomain>\<userid> <password>" with an account that is in the
domain. But this is a manual process and prone to fail when the password changes.
I've put tempdb in ram and now I can't restart my SQL Server.
This is because the memory allocated by SQL Server does NOT include tempdb in
ram. There must be enough memory for SQL, tempdb AND NT otherwise SQL will
fail to start. To recover from this.

1. Stop SQL Server and SQL Executive. Also make sure that SQL Enterprise
Manager isn't running.
2. Go to the <sql>\binn directory and type "sqlservr -c -f" - this will start SQL in
single-user mode with a minimum config.
3. Ignore the text messages in this window - but wait for them to finish appearing
(shouldn't take more than 10-20 seconds)
4. SQL Server is now started.
5. Go to another window and start ISQL/W and connect locally with the sa userid.
6. In ISQL/W issue the following commands :-

sp_configure tempdb, 0
go
reconfigure
go

7. Now go back to the window SQL is running in and type "shutdown" and enter
8. SQL Server should shut down. If it doesn't then hit <ctrl-c> to shut it down.
9. Now you should be able to start SQL normally and connect. You will need to re-
size tempdb as it will have gone back to the original 2Mb in master.
I can't run SQL Server Enterprise Manager. I'm getting an error SQLOLE
OLE object could not be registered. Class not registered (80040154).
This is a problem with the class not being resgistered in the registry properly. Use
the regsvr32 utility to re-register it :-

regsvr32 <sql>\binn\sqlole65.dll

Replacing <sql> with the full drive/dir that SQL is installed into.
I am having problems with SQL Server running bcp from xp_cmdshell -
why does it not run or see the files I want it to?
First make sure that you have the rights to run xp_cmdshell - do an xp_cmdshell
'dir' and check you get a resultset of filenames back.

Then be aware that the MSSQLSERVER service is running under a separate set of
NT credentials. It doesn't matter who YOU are logged on as (after all SQL runs
quite happily when no-one is logged on to the console doesn't it). Therefore your
logon account and any mapped drives are irrelevant. It is SQL Server running the
bcp, not you, so as far as drive letters go it can only see the local ones - local
meaning on the server, do not be confused into thinking that if you are issuing the
query from a workstation that the query is referencing your workstation's local
drives.

The default set of NT credentials used by MSSQLSERVER is the Localsystem


account. You can check what userid that MSSQLSERVER is running under by looking
at control panel/services highlighting MSSQLSERVER and choosing the start-up
option.

The Localsystem account has no access to shares on the network as it isn't an


authenticated network account.

So, if you want bcp running under xp_cmdshell to access a network resource you
have two choices :-

1. Change the account the MSSQLSERVER service runs under to a user account with
the relevant network rights.
or

2. Amend the following registry value on the TARGET server and add the
sharename you want to access - the share does not then authenticate who is
coming in and so a Localsystem account will work. The server service on the target
server must be re-started before the change takes effect. Note that this effectively
removes security on that share, so you need to be careful about what is in the
share.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Param
eters\NullSessionShares

Whichever method you use, you MUST use a UNC name to reference the resources
required and not a drive letter.

i.e. xp_cmdshell 'bcp servername..tablename out \\server01\share\bcp.fil


.............'

SQL Server FAQ - Tuning


What is TempDB?
The 'tempdb' is used by SQL Server for temporary worktables. It is very common
for SQL statements to generate one or many worktables. It is also quite common
for stored procedures to explicitly create tempory work tables in 'tempdb'. An
'ORDER BY' clause will cause a sort operation which is done in 'tempdb'.
The amount of space needed in 'tempdb' depends on the size of your databases and
the operations that are performed on the data. It would not be unreasonable to
need a 'tempdb' that is 50% of the size of your production data or larger. Your
needs may be much smaller. (See next topic for sizing information).
The 'tempdb' is created with a default size of 2MB when SQL Server is installed.
This is almost always not enough.
How big should TEMPDB be?
Sizing tempdb has always been an art. It is used for two things: (1) the server
kernel uses it as temporary scratch space for work tables associated with some
joins or order bys, etc.; and (2) to store temporary tables (#tables) created by
users or stored procedures.
Without knowing your application, I could offer the following guidelines:
1) If your application does not create #tables then I usually recommend a size that
is some percentage of the total database size. This approach is similar to that
suggested by a previous response to your message of using the two largest tables.
I usually start with a percentage in the range of 10-25% of the total size. You
might want to set aside a disk partition big enough to take the 25%, create a
Sybase device that uses it all, and start by giving tempdb the 10% and see how
things go. If your application does create #tables then you might want to use a
combination of a general purpose percentage coupled with an estimate of the size
#tables created at any one time.
2) During load/stress testing you can look to see how much space is actually being
utilized in tempdb every so many seconds and use that data to size the production
environment.
3) Make sure you place tempdb on a separate controller/disk drive to get that IO
away from your other devices.
4) Deallocate the initial 2M of tempdb allocated to the master device as part of the
installation process so that all the IO is on the dedicated tempdb device.

1) How to display Year as YYYY instead of YY


Enterprise Manager adopts the User's regional settings for the date format. By
default, the regional setting for the short date format is m/d/yy. To display it in
m/d/yyyy format, follow the following steps:
On the taskbar, click the Start button, point to Settings and then select Control
Panel. In the Control Panel dialog box double-click Regional Settings. In the
Regional Settings Properties dialog box, select the Date tab. Next, change the value
for the Short Date Style from M/d/yy to M/d/yyyy.
2) How to Build a Comma Delimited String from Table values
Sometimes you might want to return your records in a single comma delimited
string. For example, if you have records like :-
Mango
Banana
Peach
Grapes
Strawberry
Instead of returning it as a recordset containing these 5 records, you might want to
return them as 'Mango, Banana, Peach, Grapes, Strawberry'. Here's how you can
accomplish this.
-- Create a temporary table & insert dummy records
Create Table #Fruits (Fruit Varchar(25))
Insert #Fruits (Fruit) values('Mango')
Insert #Fruits (Fruit) values('Banana')
Insert #Fruits (Fruit) values('Peach')
Insert #Fruits (Fruit) values('Grapes')
Insert #Fruits (Fruit) values('Strawberry')
-- Build comma delimited string
Declare @Fruits Varchar(200)
Set @Fruits = ''
Update #Fruits
Set @Fruits = @Fruits + Fruit + ','
Set @Fruits = Substring(@Fruits,1,len(@Fruits)-1)
-- to remove extra comma at the end
print @Fruits
3) How to write values to a Text file
To write a result of a SELECT query in a text file :-
master..xp_cmdshell 'osql -SMyServer -Umyuser -Pmypwd
- Q"select * from products" -dNorthwind -w"1000" -oc:\MyText.txt'
To write a string (like comments, etc.) you can use this code :-
declare @cmd varchar(1000)
select @cmd = 'echo These are the Products in the
database>> "c:\MyText.txt"'
exec master..xp_cmdshell @cmd
4) How to add a User Defined Error Message
Use Master
Go

EXEC sp_addmessage @msgnum = 50001, @severity = 16,


@msgtext =
N'Failed to insert Customer Transaction into %s table',
@lang =
'us_english'

Go
You can raise this message from your code like this :-
INSERT Customers (CustomerName)
VALUES ('Rick Nelson')

IF @@Error <> 0
RAISERROR
(50001,16,1, 'Customers')
5) How to get the Rowcount as well as Error at the same time
Normally when we run a Query, we check if the query was executed successfully or
not before commiting it.
DECLARE @CustomerId Int
SET @CustomerId = 1

Begin Transaction
Update Orders
Set OrderDate = GetDate()
Where CustomerId = @CustomerId

IF @@Error <> 0
Begin
Raiserror('Failed
to update Orders',16,1)
Rollback
Transaction
End

Commit Transaction
But what if you also want to get the number of records which were effected by this
query? If you do a @@Rowcount after your Error checking statement then you are
going to get 0 as the value of @@Recordcount would have been reset. And if you
place @@Recordcount before the error-checking statement then your @@Error
would get reset. So what's the solution to get both of them at the same time ? Save
both the values in a local variable and then check that local variable. Here's how it
can be done.
DECLARE @Rcount Int
DECLARE @ErrNum Int

DECLARE @CustomerId Int

SET @Rcount = 0
SET @ErrNum = 0
SET @CustomerId = 1

Begin Transaction
Update Orders
Set OrderDate = GetDate()
Where CustomerId = @CustomerId

SELECT @Rcount = @@RowCount, @ErrNum = @@Error

-- check if there was an error in Updating the records


IF @ErrNum <> 0
Begin
Raiserror('Failed
to update Orders',16,1)
Rollback
Transaction
End

-- check if some records were updated or not


IF @Rcount = 0
Begin
Raiserror('No
records for CustomerId %d',16,1, @CustomerId)
Rollback
Transaction
End

Commit Transaction

1) How to start SQLServer in Single User Mode


At times you might want to start SQL server in a single user mode to perform some
maintenance work on the server or to change server configurations or to recover a
damaged database. You can accomplish this in any of the three ways given below :-

a) From Command Prompt :-


· sqlservr -m

b) From Startup Options :-


· Go to SQL Server Properties by right-clicking on the Server name in the Enterprise
manager. · Under the 'General' tab, click on 'Startup Parameters'. · Enter a value of
-m in the Parameter.

c) From Registry :-
· Go to
HKEY_LOCAL_MACHINE\Software\Microsoft\MSSQLServer\MSSQLServer\Parameter
s. · Add new string value. · Specify the 'Name' as SQLArg( n) & 'Data' as -m. Where
n is t he argum ent num ber in t he list of argum ent s.

Caut ion: Be careful while editing the Registry. Incorrectly setting up Registry values
can cause unpredictable behavior.

2) How to start SQL Server in Minimal Configuration Mode


Sometimes a bad configuration value can prevent SQL Server from starting. Then it
won't even let you connect to SQL Server using Enterprise Manager and correct the
configuration values. The only option is to start SQL Server in a minimum
configuration mode and then correct the configuration values and restart the SQL
Server in normal mode. Here's how you can start the SQL Server in a minimal
configuration mode :-

a) From Command Prompt :-


· sqlservr -f

b) From Startup Options :-


· Go to SQL Server Properties by right-clicking on the Server name in the Enterprise
manager. · Under the 'General' tab, click on 'Startup Parameters'. · Enter a value of
-f in the Parameter.

c) From Registry :-
· Go to
HKEY_LOCAL_MACHINE\Software\Microsoft\MSSQLServer\MSSQLServer\Parameter
s. · Add new string value. · Specify the 'Name' as SQLArg( n) & 'Data' as -f. Where n
is t he argum ent num ber in t he list of argum ent s.

Caut ion: Be careful while editing the Registry. Incorrectly setting up Registry values
can cause unpredictable behavior.
3) How to get Output parameter value from Dynamic execution of a Query
Sometimes you have to execute a Query dynamically using Exec(@Sql). This
method works fine as long as you don't want any output values from the @Sql
query. But there's another method (sp_Executesql) that allows you to execute
queries dynamically as well as get their output values.

The syntax :-
EXECUTE sp_executesql
@SQLString,
@ParmDefinition,
@parm=@parmIN,
@parm1OUT=@parmRET1 OUTPUT,@parm2OUT=@parmRET2 OUTPUT
Example :-
DECLARE @IntVariable INT
DECLARE @SQLString nVARCHAR(500)
DECLARE @ParmDefinition nVARCHAR(500)
DECLARE @Lastlname nVARCHAR(30)

SET @SQLString = 'SELECT @LastlnameOUT = max(lname) FROM


pubs.dbo.employee WHERE job_lvl = @level'

SET @ParmDefinition = '@level tinyint, @LastlnameOUT


varchar(30) OUTPUT'
SET @IntVariable = 35
EXECUTE sp_executesql @SQLString, @ParmDefinition, @level
= @IntVariable, @LastlnameOUT=@Lastlname OUTPUT
SELECT @Lastlname

Note: sp_Executesql is a Extended Stored Procedure.


4) How to move Database/Transaction Log files
You can move Database & Transaction log files to a different location in 2 ways.

a) sp_detach_db & then sp_attach_db


· Make sure that no user is using the database. · Exec sp_detach_db northwind ·
Move the Data & log files to a different location · EXEC sp_attach_db 'Northwind',
'c:\mssql7\northwnd.mdf', 'c:\mssql7\northwnd.ldf'

b) BACKUP and RESTORE using WITH MOVE


· Backup :-
Backup Database Northwind To Disk = 'C:\mssql7\backup\nwind.bak'
Go
· Restore :-
USE Master
Go

RESTORE Database northwind from DISK = 'c:\mssql7\backup\nwind.bak'


WITH MOVE 'Northwind' TO 'c:\mssql7\Northwnd.mdf',
MOVE 'Northwind_log' TO 'c:\mssql7\Northwnd.ldf'
Go

c) Can be used only for moving Tempdb files.


· Use ALTER Database statement to specify a different Path for the filename.
ALTER DATABASE Tempdb MODIFY FILE (NAME = Tempdev, FILENAME =
'c:\mssql7\tempdb.mdf')

ALTER DATABASE Tempdb MODIFY FILE (NAME = Templog, FILENAME =


'c:\mssql7\templog.ldf')
· Restart SQL Server and delete the old files.
5) How to Rename a Database

a) Using sp_rename
· Make sure that no user is using the database. · Make the database in the single
user mode. You can do this by using sp_dboption.

sp_dboption 'Pubs', 'single user', true


· sp_rename Pubs, Library, Database

Note : For renaming the database, you can also use sp_renamedb.

sp_renamedb Pubs, Library


· Bring back the database in multiuser mode

sp_dboption 'Library', 'single user', false

b) Using Detach & Attach

sp_detach_db @dbname = N'Pubs'


sp_attach_db @dbname = N'Library',
@filename1 = N'd:\programfiles\MSSQL7\data\Pubs_Data.MDF',
@filename2 = N'd:\program files\MSSQL7\data\Pubs_log.ldf'

1) How to move Master Database


Moving a Master database is different from moving a User database. Last week, in
"How To’s" 2 we saw how to move User database. Now lets see how to move a
Master database.
· Right-click the SQL Server in Enterprise Manager and click Properties on the
shortcut menu.
· Click the Startup Parameters button and you see the following entries:

-dD:\MSSQL7\data\master.mdf
-eD:\MSSQL7\log\ErrorLog
-lD:\MSSQL7\data\mastlog.ldf

-d is the fully qualified path for the master database data file.
- e is the fully qualified path for the error log file.
- l is the fully qualified path for the master database log file.
· Remove these values and specify the new values. For example :

- dE:\SQLDATA\master.mdf
- lE:\SQLDATA\mastlog.ldf
Note : You can specify a new path for the error log file as well.
· Stop SQL Server. · Copy the Master.mdf and Mastlog.ldf files to the new location
(E:\Sqldata). · Restart SQL Server.
2) How to Rename a Server
· Rename the physical server. · Reboot the server. · Run the SQL Server setup
program. This will change the Registry entries. The setup will prompt you to
"Upgrade" SQL Server. Choose "yes". · Reboot the server. · Connect to the new
server name in Query analyzer. · Run this code: sp_dropserver <old server name>
· Run this code: sp_addserver <new server name>, local · Add the entry for the
new Server name in Enterprise manager and delete the entry for the Old server
name.
3) How to detect & rectify Orphaned Users in a Database
Logins are associated to users by the security identifiers (SIDs), which are stored in
the Master database. When you restore a database to a different server, the SID
may be different resulting in a mismatch between the Login-User association. These
users, without a valid login association, are called 'Orphaned Users'.

Here's how you can Detect Orphaned Users :-

Use Northwind
Go
sp_change_users_login 'Report'

To associate a Orphaned User with a Login :-


Use Northwind
Go
sp_change_users_login ‘update_one’, ‘username’, ‘loginname’

4) How to use a Stored procedure as a Derived Table


Here’s a code sample which uses the recordset returned by the execution of a
stored procedure as a derived table.

SELECT a.pub_id, b.pub_name, a.title_id, a.price, a.pubdate


FROM OPENROWSET('SQLOLEDB','servername'; 'username'; 'password',
'exec Pubs.dbo.reptq1') AS a
inner join publishers b
on a.pub_id = b.pub_id
5) How to Generate Serial Numbers in a Query

create table #Fruits


(Fruit Varchar(25))

INSERT #Fruits (Fruit)


VALUES ('Mango')
INSERT #Fruits (Fruit)
VALUES ('Apple')
INSERT #Fruits (Fruit)
VALUES ('Banana')
INSERT #Fruits (Fruit)
VALUES ('Grapes')

select Sno=count(*), a1.Fruit


from #Fruits a1 INNER JOIN #Fruits a2
ON a1.Fruit >= a2.Fruit
group by a1.Fruit
order by [Sno]

http://www.swynk.com/faq/sql/sqlfaq_general.asp
This document was created with Win2PDF available at http://www.daneprairie.com.
The unregistered version of Win2PDF is for evaluation or non-commercial use only.

Das könnte Ihnen auch gefallen