SQL Blog of Zach Stagers

www.scratchbox.co.uk

MCITP: Database Developer 2008

1 Comment »

Following on from my previous post, I took the next exam (70-451) in the Database Development 2008 MCITP series on the 2nd of August and passed with 93.5%!

 

Zach Stagers - MCITP Database Development 2008

 

This means that I am now a “Technology Specialist in SQL Server Developement (2008)” and a “Microsoft Certified IT Professional in Database Development (2008)”.

The 70-451 exam was pretty different to the 70-433. The questions were more focused on database design and data access, rather than remembering syntax.

The exam is also a little trickier to study for, as there aren’t any Microsoft Publications based around it. I would recommend getting hold of some practice test (I used Transcenders), studying them hard, and googling any terms you haven’t come across before or don’t feel you know well enough.

Next I plan on taking a break from certifications, and broadening my horizons by learning some C#! Wish me luck…

TS: Microsoft SQL Server 2008, Database Development (70-433)

4 Comments »

Yesterday, I took the 70-433 Microsoft exam, and I’m pleased to announce that I passed with 92% on my first attempt! This gives me the certification of Microsoft Certified Technology Specialist in SQL Server 2008 Database Development.

MCTS - Database Developer 2008

I’ve been meaning to take one of these exams for a long time now, and I’ve finally managed to do it. I spent a lot of time reading and practicing, and I’m glad that it’s all payed off!

A big thank you to a man named Niall Merrigan, as achieving this without his blog and 70-433 study guide would have been a lot more difficult! I recomend you check his site out if you’re going to take this exam.

Another resources I used was the MCTS Self-Paced Training Kit (Exam 70-433): Microsoft SQL Server 2008 – Database Development Book/DVD Package:

The informartion in this book was good, and gave a very good understanding of most things covered in the exam. I found the practice tests to be fairly similar to the real deal, and gave decent examples and links to other resources (such as MSDN and Microsoft TechNet) when reviewing the answers. Overall – I would recommend using this book whilst studying for your 70-433 exam, but you will need to top your knowledge up with the links given in the answer reviews – and maybe a few visits to Niall’s blog mentioned above.

Many of my own blog posts are also focused on the topics covered in this exam, so be sure to check back here if you need a little help.

The next exam I’ll be tackling is the 70-451, this is the next exam in the series to achieve the certification of MCITP: Database Developer 2008. I’m sure that this will require much more reading. I’ll be sure to post back with more tips once I’ve finished this one too!

Moving Database Objects between Schemas the quick way

No Comments »

I’ve been doing a bit database re-structuring lately, and I came across a nice and quick way to move database objects between schemas. Instead of dropping and recreating the object in the schema you require it to be in – simply execute the below:

ALTER SCHEMA MySchema TRANSFER dbo.Sproc;

The above example will move the object “dbo.Sproc” into the “MySchema” schema.

Short and sweet.

Returning Tabular Data as XML with FOR XML PATH and Nested XML Queries

No Comments »

FOR XML PATH is the favorite amongst most Database Developers due to its ease of use, and the fact that you can build almost any XML structure with it.

I’ll also be discusing nested XML Queries in this post, which kind of goes hand in hand with FOR XML PATH. More on this later.

I’ll start off with an example, then explain what’s going on afterwards:

SELECT P.Name AS "@Name",
       P.Age AS "@Age",
       'PersonId = ' + CAST(P.PersonId AS VARCHAR(5)) AS "comment()",
       (
        SELECT O.OrderId AS "@OrderId",
               O.Item AS "@Item"
	FROM Orders O
	WHERE O.PersonId = P.PersonId
	FOR XML PATH('Order'), TYPE
       ) 

FROM Person P

WHERE P.PersonId IN (1, 2)

FOR XML PATH('Person'), ROOT('People'), ELEMENTS XSINIL

As with each of the other XML Modes (Raw, Auto, and Explicit), you’re able to change the name of your elements from the default. To achieve this use FOR XML PATH('Person'), this will give your rows the name “Person”.

ROOT('People') specifies the root element to be wrapped around you’re XML. The keyword ELEMENTS in this instance doesn’t do a whole lot as the structure is placed into elements and attributes depending on the names given to the columns, but XSINIL cannot be specified without it. XSINIL is used to give you’re XML a namespace, as well as to handle NULL values.

The actual output of the query used aboved is as below:

<People xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Person Name="Zach Stagers" Age="22">
    <!--PersonId = 1-->
    <Order OrderId="1" Item="Bike" />
    <Order OrderId="2" Item="Laptop" />
    <Order OrderId="3" Item="Phone" />
    <Order OrderId="4" Item="Keyboard" />
    <Order OrderId="5" Item="Mouse" />
    <Order OrderId="10" Item="Pizza" />
  </Person>
  <Person Name="Libbie Coulson" Age="24">
    <!--PersonId = 2-->
  </Person>
</People>

The first two columns in the select are specified as “@Name” and “@Age”, this assigns them as attributes to the Person Element.

Specifying the column names as “comment()” makes the value a comment within the XML, note that this is case sensitive – “comment()” is not the same as “Comment()”.

One column name that I haven’t used in the example is “text()”, this sets the value as the text of the element, instead of an attribute.. for example, using this against P.Name turns the value into:

 <Person Age="22">Zach Stagers</Person> 

Nested XML Queries

Nested XML Queries are what gives the FOR XML PATH mode its structure. To do this, as in the example above, you would use a correlated subquery. Here, you link the subquery to the outer query on the PersonId – linking the person to their orders, and therefore listing the orders beneath the correct person.

The subqueries FOR XML statement must have TYPE specified. This translates the queries results into true XML, Microsoft did this for backwards compatibility reasons.

Returning Tabular Data as XML with FOR XML EXPLICIT

No Comments »

FOR XML EXPLICIT can be a little awkward to use to say the least, but it has it uses. The good thing about EXPLICIT, is that you can mold it into almost any structure you like.

I actually found that reviewing the results as tabular data is what really helped me understand what the FOR XML EXPLICIT query is doing.

Below is the example code that I’m using:

SELECT
	1 AS Tag,
	NULL AS Parent,
	Name AS "Person!1!Name",
	PersonId AS "Person!1!PersonId",
	NULL AS "Orders!2!Item"
FROM Person

UNION ALL

SELECT
	2 AS Tag,
	1 AS Parent,
	NULL AS "Person!1!Name",
	PersonId AS "Person!1!PersonId",
	Item AS "Orders!2!Item"

FROM Orders

ORDER BY "Person!1!PersonId"

FOR XML EXPLICIT, ROOT('People')

The first thing to note with this query, is the two columns “tag” and “parent”. You must specify these columns in order to use FOR XML EXPLICIT. These columns specify the hierarchy of your results. The first query will have a “tag” of 1, and a NULL “parent”, as it is the first object declared. Each subsequent “tag” and “parent” will then go up by increments of 1.

Another thing to note, is the column names. The value listed before the first exclamation in the column name specifies the Element Name. The value listed before the second exclamation is the “tag” that it relates to. Then the attribute name is specified. ElementName!TagNumber!AttributeName.

Lastly, it’s the ORDER BY "Person!1!PersonId" that really gives the final result its correct structure.

The XML outputted by the query specified above is as follows:

<People>
  <Person Name="Zach Stagers" PersonId="1">
    <Orders Item="Bike" />
    <Orders Item="Laptop" />
    <Orders Item="Phone" />
    <Orders Item="Keyboard" />
    <Orders Item="Mouse" />
    <Orders Item="Pizza" />
  </Person>
  <Person Name="Libbie Coulson" PersonId="2" />
</People>

As with RAW and AUTO, the ROOT() simply specifies the name of the root element. This is optional.

Without the aforementioned ORDER BY clause, all of the orders for person “Zach” would appear under “Libbie” as she is last in the list, and the UNION ALL will just tack the results from the second query to the end of the result. Ordering by the key between the two tables ensures that the orders against PersonId 1 appear under the person with PersonId 1.

As I mentioned earlier in this post, what really helped me understand what was happening with FOR XML EXPLICIT was seeing the results in there tabular format. To do this, simply remove the FOR XMLline and re-run the code. In the below tabular example, I’ve removed FOR XML EXPLICIT, ROOT('People') from the query:

FOR XML EXPLICIT - Tabular Result Example

Using BULK INSERT

No Comments »

Using BULK INSERT is a nice and efficient way to, well, do a bulk insert! It’s can be good in situations where you have many, many records to insert – to many to fit into Excel, for example.

To do a BULK INSERT, simply upload your file to the server that holds the database you’re going to be inserting into. Put the file in a relatively simple location, unless you like typing long file paths! Alternatively, you can copy and paste the file path, of course.

Below is the example file I’ll be using, along with the structure of the table…

Below is the structure of the example table I’ll be using, along with the contents of the file which will be imported.

--Table

CREATE TABLE dbo.Orders
(
OrderId INT NOT NULL,
PersonId INT NOT NULL,
Item VARCHAR(50) NOT NULL
)

--Contents of Orders.txt

4, 1, Keyboard
5, 1, Mouse

Once your file is in place, you’re ready to roll.

BULK INSERT dbo.Orders
FROM 'C:\Orders.txt'
WITH
(
FIELDTERMINATOR = ','
ROWTERMINATOR = '\n'
)

Notice the WITH statment after specifying the file location. I have only used a couple of the options available to the BULK INSERT statement. I will explain these, but a for a full list of options – see the MSDN site on BULK INSERT.

The two options I’ve used in the example are the only two that you should need to insert some relatively simple data.

FIELDTERMINATOR is used to specify the character used to split your data into the columns they belong to, you need to have the columns in the correct order in the file so that they are mapped correctly. Obviously, you need to pick a character that isn’t going to appear in any of the columns.

ROWTERMINATOR is used to specify what denotes a new row. In my example, I’ve used \n, which is equal to an enviromental newline. This tells SQL that any time there is a new line in the Orders.txt file, that this should be treated as a seperate row from the line above.