Friday, July 3, 2009

Creating SQL Job using T-SQL Statements

The following shows how to create and add scheduled SQL jobs in MS SQL Server.

EXECUTE msdb.dbo.sp_add_job
@job_name = 'Database Backup',
@enabled = 1,
@owner_login_name = 'sa'

EXECUTE msdb.dbo.sp_add_schedule
@schedule_name = 'Daily database backup',
@enabled = 1,
@freq_type = 4, -- daily
@freq_interval = 1, -- daily
@active_start_time = '180000'

EXECUTE msdb.dbo.sp_attach_schedule
@job_name = 'Database Backup',
@schedule_name = 'Daily database backup'

EXECUTE msdb.dbo.sp_add_jobserver
@job_name = 'Database Backup',
@server_name = 'ServerName'

EXECUTE msdb.dbo.sp_add_jobstep
@job_name = 'Database Backup',
@step_name = 'Backup database on daily basis',
@subsystem = 'TSQL',
@command = 'BACKUP DATABASE TestDatabase TO DISK = ''C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\BACKUP\TestDatabase.bak''

Thursday, July 2, 2009

Retrieving Client Browser's Culture in ASP.NET

I fall in a couple of situations where I needed to get the client’s culture from the server side in an ASP.NET application. I googled this and found only client side solutions, but I knew there was some way to get this information because the ASP.NET framework supports client based culture (through the UI Culture = "Auto" in the page attributes and the globalization section in the web.config). The only way I thought of getting the client culture was from the Request object.

After examining the HTTP Headers collection I found the Accept-Language header. It contains information about the user's preferred languages.

This is a sample Accept-Language header:

Accept-Language
bg-BG,en-US;q=0.7,ar-BH;q=0.3

The languages are explicitly defined in the browser and their order is determined. You are probably wondering what this q-thing means. According to the RFC 3282 (Content Language Headers) it specifies the language quality or in other words the language priority set in the client's browser. In the example above bg-BG (Bulgarian (Bulgaria) has highest priority then en-US (English (United States)) and the last preferred language is ar-BH (Arabic (Bahrain)).

The Accept-Language header lists all languages set in the browser in a comma separated list which makes it easy to extract each language.

From ASP.NET you can access this header using the Headers collection in the Request object - Request.Headers["Accept-Language"]. Then you can process it the way you like.

Also instead of using Request.Headers["Accept-Language"] you can simply use the HttpRequest.UserLanguages to get a sorted string array of client language preferences.

Wednesday, July 1, 2009

Unveiling System.MDW

Let me explain an (unintuitive) Access/JET security feature: the workgroup file. The workgroup information file, or WIF, stores your user and group information. It stores the usernames and passwords. Each workgroup information file, or .MDW file, contains a unique set of IDs that Access uses for its security encryption. In fact each user has a 'PID' which, combined with their username and the workgroup PIDs, generates an unique code that Access uses to determine your permissions. So where am I going with this?

Every Access install, for every version of Access, uses a default workgroup file that has the same workgroup PIDs, the same username ("Admin") and the same PID for that user. So if you are trying to secure a database by modifying the default workgroup file, you're already out of luck! Anyone using another computer already has the appropriate set of PIDs, by default, to walk right through your security. So this is a big gotcha.

Access has a default workgroup file named 'System.MDW'. Depending on your version of Access and your OS version, this file can be stored in a multitude of places. For me (Access 97/Win2K) it is stored in C:\WINNT\SYSTEM32\System.MDW . Older versions of Access use one MDW file for an entire computer; newer versions are more multi-user savvy and will install a separate System.MDW file for each user in the system. New NT-based operating systems use the C:\WINDOWS folder by default. Older OS's (Win2K/NT4) use the C:\WINNT folder by default. In all cases (Access 97 and newer), you can find the file by searching for "System.MDW".

Obviously then, it is not intended that you use the provided-by-default workgroup file. What then shall you do? Create a new, custom MDW file with PIDs you specify. To create a new workgroup file, you can (again, depending on Access version) find and run WRKGADM.EXE or go to Tools->Security->Workgroup Administrator. For me, the file is located at: C:\WINNT\SYSTEM32\WRKGADM.EXE

I'm not going to run through securing your new workgroup file; the Access security FAQ does an excellent job already.

Now that you have a custom workgroup file for use, how do you go about getting Access to use it?

Shortcuts (.LNK files) - The proper way to open a database using Access/JET security - Use the command-line /wrkgrp parameter to specify the workgroup you will use for your secured database. This will always involve the creation of a custom shortcut. An example of the shortcut's 'Target' line is:

"C:\Program Files\Microsoft Office\Office\MSACCESS.EXE" "C:\atemp\dev\rq_fe.mdb" /wrkgrp "C:\atemp\dev\icg.mdw"

This would open the 'rq_fe.MDB' file using my custom 'icg.mdw' workgroup file.