Welcome to MSDN Blogs Sign in | Join | Help

Jeff Papiez - SQL Server Test Developer

My random thoughts, ideas, comments, and brain dumping ground.
Windows Home Server Announced

Yesterday at the CES, we announced the future availability of Windows Home Server, a new server designed to be the central digital nervous system for the home. I've been running Windows Home Server at home for about 3 months now and I tell you it's just about what I was looking for: centralized storage of music, photos, videos, software, computer backups. My hats off to the Windows Home Server team for bringing together some nifty techology to market.

Windows Home Server is super simple to operate. It's all setup to keep itself up to date with all the latest Windows security updates, so there's nothing to manage for the home owner. Turn it on, connect it to your network, and forget about it.

Adding storage to Windows Home Server couldn't be any more simple. Using either internal or external drives, simply attach the drive then use the Windows Home Server client to make the new drive available to the storage system. There's no RAID configuration to step through because Windows Home Server has its replication technology baked in. This technology enables the user to replace existing drives with larger ones as they become available. What's more is you can use any size drive when adding to your server.

At some point I'd love to see Windows Home Server become a centralized Media Center Server where I could outfit one (or more) servers with ample storage and TV tuners to record all our favorite shows and make them available throughout the house via Media Center Extenders (XBOX 360). As it stands now I can use Windows Media Connect to expose Music, Photos, and Videos to extender devices but no such luck for MCE recorded TV... though I suppose I could do this in a round about sort of way by converting the TV shows to MPEG but then I lose some of the rich meta-data and navigation options allowed for TV that is not available for Videos.

All in all though, I look forward to the final release Windows Home Server. It's been long in the making and definately something my household will benefit from!

Adding n tuners in MCE

http://blogs.msdn.com/peterrosser/archive/2006/04/03/MCE_TechTalk_1.aspx

Windows Live Messenger Released
Windows Live Messenger is released! Pick it up here: http://get.live.com/messenger/overview
Using P/Invoke to Call Unmanaged APIs from Your Managed Classes

I came across this article on MSDN this morning about using P/Invoke in managed code. Had I came across this article a few weeks back it likely would have saved me some time!

http://msdn.microsoft.com/netframework/default.aspx?pull=/library/en-us/dv_vstechart/html/pinvoke.asp

Using WatchedFolders on Media Center 2005

I don't know how many times I've had to search for this on TheGreenButton, so I thought I'd post the info here so I always know where to find it. The problem is this: I have 2 Media Center 2005 machines and one file server. Recorded TV that I want to keep around I copy to the file server and I want both my MCE machines to be able to display it in Recorded TV. I also want to be able to view recorded TV from any MCE machine, regardless of where it lives. So, here's how to configure your MCE machines and file server to play well in this scenario, aggregated from this post on TheGreenButton.com.

You probably should not do this unless you're behind a hardware firewall or NAT (like a cable/DSL router).

So here goes:

  1. Have both machines on the same network.  If the machines can't ping each other by name, this will not work.
  2. Share your recorded TV folder on each machine.  Give "Everyone" full control on the share and on the folder itself.  You can name the share the default, "Recorded TV" if you want, that's what I do.
  3. Open RegEdit, and go to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Media Center\Service\Recording.  Find the entry "WatchedFolders" and open it up.
  4. On each machine, add a new line to this entry at the bottom, pointing to the other machine's Recorded TV share.  For example, see below the steps.  You have to do this on all machines.
  5. With RegEdit still open, go to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lanmanserver\parameters
  6. Find the NullSessionShares entery and add the name of your share local share (e.g. "Recorded TV" without the quotes). 
  7. Close RegEdit.
  8. Click start, run, and open gpedit.msc.  Navigate under Computer Configuration\Windows Settings\Security Settings\Local Policies\Security Options, and find "Network access:  Let Everyone permissions apply to anonymous users".  Open that up, and change the setting to enabled.  Do this on all machines.
  9. Reboot, and check your recorded TV.  Shows from both MCE's should show up on both MCE's!

The sample Watched Folders:

C:\Documents and Settings\All Users\Documents\Recorded TV
E:\Recorded TV
\\machine1\Recorded TV
\\machine1\Recorded TV

Unable to Install SQL 2005 Management Tools with Visual Studio 2005 installed.

SQL Server Express Edition 2005 (Express) installs a set of command line tools that it calls Workstation Components, which happens to collide with the Management Tools for the other SQL Server 2005 editions. This presents a problem if you first install Visual Studio 2005 and SQL Server Express 2005 before installing SQL Server 2005 on the same machine. The Workstation Components shipped with Express consist of command line tools only, no SQL Management Studio.

If you already have Express installed and you want to install the full set of Workstation Components from a different edition, such as Developer, you'll first need to remove the Workstation Components from the Control Panel. Once that's done you can install the Workstation Components that include SQL Management Studio.

j.

Watch the PDC05 Sessions

Missed the PDC like I did? Well here's your chance to catch up. You can view all the sessions from here:

http://microsoft.sitestream.com/PDC05/

My favorite so far: TLNL09: Tips & Tricks: Productivity Tips for the Visual C# 2005 IDE

SQL Server 2005 Upgrade Advisor and SQL Clusters

If you've thought about using SQL Server 2005 Upgrade Advisor to determine the upgradability of your SQL Server 2000 cluster, be aware of the following issue. When you launch the Upgrade Advisor Analysis Wizard, you're prompted for the Server Name, which defaults to that of the local machine where the wizard is running. When scanning a cluster you need to enter the name of the Virtual SQL Server Instance. After checking the SQL Server component and clicking the next button, you'll be given a list of instances to scan.

The list of instances will include all SQL Server instances, whether they are local to the active node, or if they belong to other virtual SQL Server instances that run on the cluster. Selecting an instance other than the instance owned by the Virtual SQL Server cluster will ultimately raise an error when the wizard attempts to connect to the server and enumerate the list of available databases. To avoid this error, be sure to select the appropriate instance for the "server" you're connected to.

J.

Passing a DataSet to a SQLCLR Stored Procedure
Is it possible to pass a DataSet to SQL and process the data in a SQLCLR stored procedure? This is the question I set out to answer.
 
The .NET Framework 2.0 adds some features to the DataSet that make this scenario possible (WriteXml, ReadXml). I created a sample that proves this concept.
 
First we need the CLR stored proc to handle the passed in dataset. Start by creating a new "SQL Server Project" in Visual Studio 2005. This example uses the Northwind database installed with SQLExpress.
 
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.IO;
using System.Xml.Serialization;
using System.Text;
 
public partialclassStoredProcedures
{
  [Microsoft.SqlServer.Server.SqlProcedure]
  publicstaticvoid uspProcessCustomers(string customerData)
  {
    // Need to convert the inbound string to a byte array
    UTF8Encoding encoding = newUTF8Encoding();
    DataSet ds = newDataSet();
 
    // Convert the string to a byte array, then load into a MemoryStream
    using (MemoryStream ms = newMemoryStream(encoding.GetBytes(customerData)))
    {
      // Populate the DataSet from the MemoryStream
      ds.ReadXml(ms);
    }
 
    // Iterate through the dataset and process each record.
    foreach (DataRow dr in ds.Tables["customers"].Rows)
    {
      if (dr.RowState != DataRowState.Unchanged &&
          dr.RowState != DataRowState.Detached)
      {
        string procName = string.Empty;
        // Instantiate a SqlCommand object to perform the
        // required DB operation
        using (SqlCommand cmd = newSqlCommand())
        {
          cmd.CommandType = CommandType.StoredProcedure;
          // determine which procedure to execute
          // based on the state of the row
          switch (dr.RowState)
          {
            caseDataRowState.Added:
            caseDataRowState.Modified:
              if (dr.RowState == DataRowState.Added)
              {
                procName = "uspInsCustomer";
              }
              else
              {
                procName = "uspUpdCustomer";
              }
 
              // Populate the Parameters collection
              cmd.Parameters.Add(
                  newSqlParameter("@customerID", dr["CustomerID"].ToString()));
              cmd.Parameters.Add(
                  newSqlParameter("@companyName", dr["CompanyName"].ToString()));
              cmd.Parameters.Add(
                  newSqlParameter("@contactName", dr["ContactName"].ToString()));
              cmd.Parameters.Add(
                  newSqlParameter("@contactTitle", dr["ContactTitle"].ToString()));
              cmd.Parameters.Add(
                  newSqlParameter("@address", dr["Address"].ToString()));
              cmd.Parameters.Add(
                  newSqlParameter("@city", dr["City"].ToString()));
              cmd.Parameters.Add(
                  newSqlParameter("@region", dr["Region"].ToString()));
              cmd.Parameters.Add(
                  newSqlParameter("@postalCode", dr["PostalCode"].ToString()));
              cmd.Parameters.Add(
                  newSqlParameter("@country", dr["Country"].ToString()));
              cmd.Parameters.Add(
                  newSqlParameter("@phone", dr["Phone"].ToString()));
              cmd.Parameters.Add(
                  newSqlParameter("@fax", dr["Fax"].ToString()));
              break;
            caseDataRowState.Deleted:
              procName = "uspDelCustomer";
 
              // Populate the Parameters collection
              cmd.Parameters.Add(
                  newSqlParameter("@customerID", dr["CustomerID"].ToString()));
              break;
          }
 
          using (SqlConnection cxn = newSqlConnection("context connection=true"))
          {
            cmd.Connection = cxn;
            cmd.CommandText = procName;
            cmd.Connection.Open();
            cmd.ExecuteNonQuery();
            cmd.Connection.Close();
          }
        }
      }
    }
  }
}
 
If you use Visual Studio to deploy the stored procedure to the database you'll need to drop and recreate the procedure. This is because the procedure gets created with the customerData parameter as NVarChar(4000). In order to accept even a minimal DataSet (in my test I populated the DS with 10 records), 4000 chars isn't going to be large enough. To get around this you can use the new variable text types in SQL Server 2005, in this case NVarChar(max):
 
CREATE PROCEDURE uspProcessCustomers
@CustomerData AS NVarChar(max)
AS
EXTERNAL NAME SQLData.StoredProcedures.uspProcessCustomers
 
The procedures for inserting/updating/deleting aren't that interesting, so I'll leave those to your imagination. Now we need a client app that consumes this stored procedure. Start by creating a new Windows Forms client. Add to the client a button, then add the following to the button click event handler:
 
privatevoid button1_Click(object sender, EventArgs e)
{
   this.Cursor = Cursors.WaitCursor;
   this.button1.Enabled = false;
  
   // Create the dataset
   
DataSet
ds = newDataSet();
 
 
   // Create the data table
   
DataTable
dt = newDataTable("Customers");
   ds.Tables.Add(dt);
 
   // Create the table schema
   
DataColumn
dc = dt.Columns.Add("CustomerID", typeof(string));
 
   // the first column is the primary key
   
dc.AllowDBNull = false;
   dc.Unique = true;
   dt.Columns.Add("CompanyName", typeof(string));
   dt.Columns.Add("ContactName", typeof(string));
   dt.Columns.Add("ContactTitle", typeof(string));
   dt.Columns.Add("Address", typeof(string));
   dt.Columns.Add("City", typeof(string));
   dt.Columns.Add("Region", typeof(string));
   dt.Columns.Add("PostalCode", typeof(string));
   dt.Columns.Add("Country", typeof(string));
   dt.Columns.Add("Phone", typeof(string));
   dt.Columns.Add("Fax", typeof(string));
 
   // Add a few records to the data table.
   
for
(int i = 1; i <= 10; i++)
   {
      // create a new row
      
DataRow
dr = dt.NewRow();
 
      // populate the fields
      
dr[0] = "C" + i.ToString();
      dr[1] = "Company Name " + i.ToString();      
      dr[2] = "Contact Name " + i.ToString();      
      dr[3] = "Contact Title " + i.ToString();
      dr[4] = "Address " + i.ToString();
      dr[5] = "City " + i.ToString();
      dr[6] = "Region " + i.ToString();
      dr[7] = "POSTL " + i.ToString();
      dr[8] = "Country " + i.ToString();
      dr[9] = "Phone " + i.ToString();
      dr[10] = "FAX " + i.ToString();
 
      // add the row to the table
      
dt.Rows.Add(dr);
   }
 
   string strConnection = "Data Source=.\\sqlexpress;" +
      "Initial Catalog=Northwind;Integrated Security=True";
 
   // Now, connect to the database and pass the dataset
   using (SqlConnection cxn = newSqlConnection(strConnection))
   {
      SqlCommand cmd = newSqlCommand("uspProcessCustomers", cxn);
      cmd.CommandTimeout = 1800;
      cmd.CommandType = CommandType.StoredProcedure;
 
      // SqlParameter to hold the dataset
       SqlParameter param1 = newSqlParameter("@customerData", SqlDbType.NVarChar);
 
      // Create a temporary MemoryStream to hold the output
      // of the WriteXml method of the DataSet
      using (MemoryStream memoryStream = newMemoryStream())
      {
         ds.WriteXml(memoryStream);
         UTF8Encoding encoding = newUTF8Encoding();
         param1.Value = encoding.GetString(memoryStream.ToArray());
      }
 
      // Add the SqlParameter to the Parameters collection
      cmd.Parameters.Add(param1);
 
      // Open the connection to the database
      cmd.Connection.Open();
 
      // Execute the query
      cmd.ExecuteNonQuery();
 
      // Finally, close the connection
      cmd.Connection.Close();
   }
 
   this.button1.Enabled = true;
   this.Cursor = Cursors.Arrow;
}
 
That's all it takes. I welcome your comments and suggestions on this post.
 
J. 
SQL Server 2005 and SQL Server Express 2005 on The Same Machine
Installing both SQL Server 2005 (SQL) and SQL Server Express 2005 (Express) on the same machine can present a problem that might not be easily identifiable.

You can install both of these products on the same machine, though you must take care when choosing which options get installed. If you install the Management Tools for Express you will be unable to install the Management Tool for SQL.

So, if you have Express installed then want to install SQL, make sure you do not have Management Tools for Express already installed, otherwise none of the tools will be installed for SQL, and you'll be left with the likes of sqlcmd.exe for managing SQL untill the Express tools are uninstalled.

j.

What am I doing now?

A few things have changed since I blogged last. I've changed managers (though on the same team), and I'm working with a new product, SQL Server 2005 Upgrade Advisor. I own testing for the Upgrade Advisor engine and Report Viewer UI. I'll also own the UI testing for the Upgrade Advisor Wizard too.

In case you haven't heard of SQL Server 2005 Upgrade Advisor, let me tell you a little bit about it. It will be a tool that will ship in the box with SQL Server 2005, as well as made available through web download. It's a tool that will help identify upgrade blockers and potential pitfalls with your installation of SQL Server 2000. In addition to the core of SQL Server 2000, we will also analyze Analysis Services, Reporting Services, and Notifiction Services and DTS packages. If you've used Upgrade Advisor already, or have any questions or comments, send 'em my way!

j.

Re-installing WMI

For those folks out there using Windows Server 2003 SP1 Build 1277 along with the SQL Server 2005 December CTP, you may be unable to install SQL Server 2005 with the following error:

Microsoft SQL Server 2005 Beta 3 Setup

The SQL Server System Configuration Checker cannot be executed due to WMI configuration on the machine SI4P64LF3-05 Error:2147749907 (0x80041013).

The cause of this error is a corrupt install of WMI, caused by upgrading Windows Server 2003 to SP1 build 1277. To fix this issue, copy the following into notepad and save it with either a .cmd or .bat extension. Then run the script to re-install WMI:

%SYSTEMDRIVE%
CD %windir%\system32\wbem
Mofcomp.exe cimwin32.mof
Regsvr32 /s wbemupgd.dll
Regsvr32 /s wbemsvc.dll
wmiprvse /regserver

 

If that doesn't work, try the info here posted on msdn:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/reinstalling_wmi.asp

J.

Life moves pretty fast...

... and if we don't stop and smell the roses... ah who am I kidding. I'm not word sleuth. But I do know this. My wife and I had our first child, a cute little boy named Jacob, back in March. He's growing like a weed. I can hardly believe how fast they grow. Somedays I wish that he'd just grow faster so we could go do things together. Then again, I don't want to rush things. We live in a time where we expect everything to happen so quickly, often not wanting to wait for things any longer than absoletly necessary. I really hope I don't become one of those parents that expect my toddler to act as if they are all grown up and mature. Those people get under my skin. Kids need to be kids. They need to enjoy their childhood while they can, because before THEY know it they'll be old enough to where they have to attend school, go to work, and take on adult responsibilities. No sense in rushing that.

I sort of feel sorry for those children that happen to be super smart that are sent off to college when they are in their wee teen years. I didn't attend college until I was in my early twenties. Oh wait, I forgot about those 3 quarters I spent at the local Community College after High School, but those don't really count. Back to the topic at hand. Where was I? Oh yes.. smart kids and college. If Jacob (my son, from the first paragraph) were to be one of those brainiacs, would I send him to College? Um.. let me see.. NO. I would do everything I could to allow him to continue his education, but I wouldn't send him off until he was physically and emotionally ready for what a college campus had to offer.

I do look forward to seeing my son grow up and experience life. Seeing what he has been going through already has been a treat. I can only imagine what the future will hold.

HowTo: Debug a Managed Stored Procedure with Visual Studio 2005 and SQL Server 2005

In response to a newsgroup post, I wrote this quick little tutorial.

This tutorial assumes you have the AdventureWorks database installed, but any database will do.
1. Create SQL Server Project in Visual Studio
2. Add a connection to AdventureWorks database when prompted for a connection.
3. Add a new item to the project, new Stored Procedure, name: uspHellowWorld.cs
4. add the following code to uspHelloWorld():

    SqlContext.GetPipe().Send("Hello World");

5. Deploy the project (right click on the product, select Deploy)
6. In the Server Explorer window, right click on the Data Connection to the AdventureWorks database, select "Allow SQL/CLR Debugging". CLick YES to the message that says "SQL/CLR debugging will cause all managed threads on the server to be stopped. Do you want to continue?"
7. Set a break point on the code created in step 4.
8. Press F5 to start debugging. You should see that your project will get re-deployed, then vs debugging will startup and your breakpoint should be hit.
 
This is about as simple as it gets.
 
j.
Query for a list of Procs that contain a string

I was browsing the SqlServerCentral.com forums today and came across a post where a user was asking how to write a query to list all the stored procedures that contain a specific string. This might be useful, so I thought I better blog it lest I forget.

CREATE PROCEDURE uspGetProcs (@StringToMatch  AS VARCHAR(256)) AS

    SELECT routine_name
    FROM INFORMATION_SCHEMA.ROUTINES
    WHERE routine_definition 
         
LIKE '%' + @StringToMatch + '%'
    ORDER BY routine_name

The original post can be found here:

http://www.sqlservercentral.com/forums/shwmessage.aspx?messageid=127531

Note: Jon Galloway does point out a great point: Use INFORMATION_SCHEMA rather than the sys* objects as they are subject to change. I edited this post to reflect the more appropriate means of generating the same result. If you want to see the original, click on the link. :)

j.

More Posts Next page »
Page view tracker