Wednesday, October 29, 2008

Fix user mapping after restoring database to another server instance

Often when you restore a backup from SQL server you run into funky
problems with users. Suppose you have login calvin and you restore a
database from another server that already has user called calvin. When
you try to map the server calvin to the database calvin, you might
get the error:

Error 15023: User or role 'calvin' already exists in the current database.

To fix this:

sp_change_users_login 'update_one', 'calvin', 'calvin', 'password'
-- this command will link the server user to the database level user.

Thursday, October 23, 2008

xcopy

echo ---------------- >> c:\backup_log.log
echo \calvin\*.* >> c:\backup_log.log
xcopy d:\calvin\*.* "\\192.168.1.99\F$\calvin-backup\calvin\*.*" /H /D
/E /C /R /Y>> c:\backup_log.log
time /t >> "c:\backup_log.log"

Friday, September 26, 2008

truncate SQL 2005 Log file

Unlike SQL 2000, you can't conveniently just truncate the transaction
log. But you can do this:

1. Highlight the database-> Tasks->Detach..-> Click OK
2. Go to log file folder -> rename the xxx_log.ldf to something else
3. Highlight Databases->Attach…-> Click Add -> add the database MDF
file, highlight the log file in the lower part of the window and click
the 'Remove' button.
4. After this is done, you can verify the contents of the attached
database and then delete the log file.

Monday, August 18, 2008

AJAX Calendar Extender only shows partial weekdays

The Calendar extender in my page only shows 5 days in a week, instead
of a full 7 days. There is no parameters controlling this behavior.
After some investigation I found that's because I have defined padding
in my stylesheet for TD:

TD {padding-left:5px;padding-right:5px;}

Generally it's not a good idea to change the general TD style,
especially third-party control will be used. I put the padding in my
own table class then problem solved!

Wednesday, August 6, 2008

Call server postback from ModalPopup extender

The Atlas AJAX Toolkit has a very convenient ModalPopup extender. However by default it doesn't do post back on button clicks, even the event is wired with the button:
< runat="server" id="btnAddExistingPart" text="Add" cssclass="SplashButton" onclick="btnAddExistingPart_Click">
Upon click it only dismiss the modal popup.

You have to explicitly call the post back client method to initiate the post back:
protected void Page_Load(object sender, EventArgs e)
{
...
btnAddExistingPart.OnClientClick = "__doPostBack('" + btnAddExistingPart.UniqueID + "','')";
...
}

Monday, August 4, 2008

System admin script

To lock the workstation (tested on Win2K/XP): rundll32 user32.dll,LockWorkStation

Thursday, July 17, 2008

OleDbCommand doesn't support named parameters

When calling a parameterized stored procedure, if you pass parameters to a SqlCommand object

(i.e.
cmd.Parameters.AddWithValue("@productID", strProductID);
cmd.Parameters.AddWithValue("@productName", strName);
...
)

SqlCommand will correctly map the value with the parameter regardless of the order these AddWithValue methods are called. However, OleDbCommand doesn't support named parameters (MS confirmed it: http://support.microsoft.com/kb/316744). You have to make sure the order you call the AddWithValue method matches the order of your SP parameters. Obviously the SqlCommand is much more convinient because you can simply skip some parameters that have default values defined in SP. In my database utility class for SqlClient, I can pack the parameters in a HashTable and pass them in:

public DataSet ExecuteSPQuery(string spName, Hashtable param)
{
SqlConnection myConnection = null;
DataSet dataSet = new DataSet();
try
{
myConnection = ConnectToDB();
SqlCommand cmd = new SqlCommand();
cmd.Connection = myConnection;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = spName;

// a different way of looping a hashtable
if (param != null)
{
foreach (DictionaryEntry de in param)
{
cmd.Parameters.AddWithValue("@" + de.Key.ToString(), de.Value.ToString());
}
}

SqlDataAdapter myAdapter = new SqlDataAdapter();
myAdapter.SelectCommand = cmd;
myAdapter.Fill(dataSet);

}
finally
{
if (myConnection != null)
myConnection.Close();
}

if (dataSet != null && dataSet.Tables.Count == 0)
return null;
else
return dataSet;
}

However for OldDb client, I have to use a queue to do that, and anytime there is a change to the SP, I have to change everywhere that queue is populated, or to define a method for each SP I call. How nice...