We are purchasing some software at work that uses SQL Server 2000 as a back end. I’ve been bringing those systems up and relearning SQL Server since I haven’t look at it in more than five years. We’ll be importing some existing data for this software so I’ve started writing up a few scripts. I’m using PHP with ADOdb for database access. For the most part things have gone well, with some small expections/gotchas. Fortunately none of the problems I noticed were hard to fix, but they did seem a little odd sometimes. Here are some notes on my experiences with this process thus far:
-
FreeTDS – Build
In order to get PHP talk to SQL Server 2000 I’m using FreeTDS on a FreeBSD system. The first thing to note is that SQL Server 2000 uses 8.0 TDS. When building from FreeTDS from the ports collection be sure to override the default, which is 5.0. You’ll also need to enable msdblib in FreeTDS, so make sure that WITH_MSDBLIB is enabled during the build also. Then all that is needed for PHP4 to speak to SQL Server is the php4-mssql port.
-
FreeTDS – Config
In recent versions of FreeTDS they’ve started using a freetds.conf file to configure connections. There is an example in there for connecting to SQL Server 2000, here is what I ended up using:
[SQL2K]
host = xxx.xxx.xxx.xx
port = 1433
tds version = 8.0
; dump file = /var/log/freetds.log
; dump file append = yes
; debug level = 99
I had a few problems connecting initially, so it was helpful to run with debug on until I got things straightened out. In PHP you’d use SQL2K to connect instead of the host name or IP address.
-
FreeTDS – Domain Logins
Our user accounts are all managed by Active Directory, besides the default accounts in SQL Server 2000 all of the permissions are handled via Windows domain accounts. This means that all of your usernames have to be prefixed with the Windows domain. Something like
EXAMPLEusername
. If you run into problems check out the FreeTDS documentation about domain logins. -
SQL Server 2000 – Quoting
Note that quotes are escaped with quotes, not back slashes. I personally don’t care for this method, but it seems to be the only one that SQL Server 2000 supports. If you are going to use CSV to import data you need to pay attention to this. Although CSV is supported I ended up going to tab delimited instead. This is the default that SQL server expects and it made some of the quoting issues easier.
-
ADOdb – rs2tabout()
For the sake of consistency I’m using ADOdb to deal with database access in PHP. One neat feature I found was the ability to easily export a result set to CSV or tab delimited formats. This was exactly what I needed to do, so this seemed like a great solution. Unfortunately rs2tabout() tries to escape quotes, which SQL Server choked on. The quotes didn’t need to be escaped since tabs were being used as delimiters, so I poked at the code to see what was happening. All of the export functions derive from a base function with several options, so I was able to call that function directly and override the defaults. If you want data tab delimited with quote escaping turned off you can do that with:
print(_adodb_export($rs, "t", " ", true, false, false));
or
$line = _adodb_export($rs, "t", " ", false, false, false);
-
bcp
Importing lots of data with bcp is much easier than clicking through the import/export wizard. To make life easier you’ll need a format file for the table that your are importing data into. The easiest way I’ve found to generate the format file is to let bcp do it for you:
bcp testdb.dbo.tablename format tablename.dat -U username -P password -f tablename.fmt -c
Then importing is done like this:
bcp testdb.dbo.tablename in tablename.tsv -U username -P password -f tablename.fmt -e tablename.err
If bcp has any problems importing data will be logged in thetablename.err
file. If it runs into enough errors the import will terminate, the default is ten. In the test table that I’ve been using has 98,000+ records in it. The process of retrieving the data and formating into tab separated values (tsv) takes about 110 seconds. The import with bcp takes less than 5 seconds. I like it when things go fast 🙂
That pretty much covers it for now.
6 replies on “SQL Server 2000 Notes”
[…] >Quote Changes In PostgreSQL Saturday 18 June 2005 @ 11:31am After complaining about SQL Server 2000 not using the back slash to escape quotes it looks li […]
[…] I’ve been reasonably happy with SQL Server 2000, especially after I got it working with PHP from FreeBSD. Today though, I ran into something that I was surprised to see in SQL Server, there is a maximum row size of 8060 bytes. I was disappointed that Microsoft’s current production database system would still have this kind of limitation. […]
Dude, your blog comes to the rescue once again (I hope)! I’m having trouble with PHP on Neptune not wanting to talk to the database. I totally missed the FreeTDS settings, among other things you mentioned here. I should probably start documenting things this way myself.
@Jim –
That’s one of the reasons I started a blog in the first place, secondary memory for my brain 🙂
joseph i am not able to insert the value in the table please help me code is as follow:
CREATE PROC EMPDTL_INPU
( @EMP_INS VARCHAR(12), @EMP_ID INT, @FNAME VARCHAR(20), @LNAME VARCHAR(20), @SEX CHAR(1), @C_NUMBER VARCHAR(20), @EMAIL_ID VARCHAR(20), @ADDRESS VARCHAR(20), @ZIP VARCHAR(20) )
AS
@EMP_INS = (select @EMP_ID = EMP_ID from EMP_DTL where EMP_ID =’@EMP_ID’)
CHECK = @EMP_INS
IF @EMP_INS = IS NULL
THEN
BEGIN
Insert into EMP_DTL(EMP_ID, FNAME, LNAME, SEX, C_NUMBER, EMAIL_ID, ADDRESS, ZIP)
VALUES(@EMP_ID, @FNAME, @LNAME, @SEX, @C_NUMBER, @EMAIL_ID, @ADDRESS, @ZIP)
END IF
update EMP_DTL
set
EMP_ID = @EMP_ID, FNAME = @FNAME, LNAME = @LNAME, SEX = @SEX, C_NUMBER = @C_NUMBER, EMAIL_ID= @ EMAIL_ID, ADDRESS = @ADDRESS, ZIP = @ZIP
where EMP_ID = @EMP_ID
END
hey it should be either IF @EMP_INS = ‘NULL’ or simply IF @EMP_INS IS NULL, but how can you use assignment operator as well as is keyword?
all d best
himansu
09853436485