- Introduction
- Table of Contents
- Microsoft SQL Server Defined
- Microsoft SQL Server Features
- Microsoft SQL Server Administration
- Microsoft SQL Server Programming
- Performance Tuning
- Practical Applications
- Choosing the Back End
- The DBA's Toolbox, Part 1
- The DBA's Toolbox, Part 2
- Scripting Solutions for SQL Server
- Building a SQL Server Lab
- Using Graphics Files with SQL Server
- Enterprise Resource Planning
- Customer Relationship Management (CRM)
- Building a Reporting Data Server
- Building a Database Documenter, Part 1
- Building a Database Documenter, Part 2
- Data Management Objects
- Data Management Objects: The Server Object
- Data Management Objects: Server Object Methods
- Data Management Objects: Collections and the Database Object
- Data Management Objects: Database Information
- Data Management Objects: Database Control
- Data Management Objects: Database Maintenance
- Data Management Objects: Logging the Process
- Data Management Objects: Running SQL Statements
- Data Management Objects: Multiple Row Returns
- Data Management Objects: Other Database Objects
- Data Management Objects: Security
- Data Management Objects: Scripting
- Powershell and SQL Server - Overview
- PowerShell and SQL Server - Objects and Providers
- Powershell and SQL Server - A Script Framework
- Powershell and SQL Server - Logging the Process
- Powershell and SQL Server - Reading a Control File
- Powershell and SQL Server - SQL Server Access
- Powershell and SQL Server - Web Pages from a SQL Query
- Powershell and SQL Server - Scrubbing the Event Logs
- SQL Server 2008 PowerShell Provider
- SQL Server I/O: Importing and Exporting Data
- SQL Server I/O: XML in Database Terms
- SQL Server I/O: Creating XML Output
- SQL Server I/O: Reading XML Documents
- SQL Server I/O: Using XML Control Mechanisms
- SQL Server I/O: Creating Hierarchies
- SQL Server I/O: Using HTTP with SQL Server XML
- SQL Server I/O: Using HTTP with SQL Server XML Templates
- SQL Server I/O: Remote Queries
- SQL Server I/O: Working with Text Files
- Using Microsoft SQL Server on Handheld Devices
- Front-Ends 101: Microsoft Access
- Comparing Two SQL Server Databases
- English Query - Part 1
- English Query - Part 2
- English Query - Part 3
- English Query - Part 4
- English Query - Part 5
- RSS Feeds from SQL Server
- Using SQL Server Agent to Monitor Backups
- Reporting Services - Creating a Maintenance Report
- SQL Server Chargeback Strategies, Part 1
- SQL Server Chargeback Strategies, Part 2
- SQL Server Replication Example
- Creating a Master Agent and Alert Server
- The SQL Server Central Management System: Definition
- The SQL Server Central Management System: Base Tables
- The SQL Server Central Management System: Execution of Server Information (Part 1)
- The SQL Server Central Management System: Execution of Server Information (Part 2)
- The SQL Server Central Management System: Collecting Performance Metrics
- The SQL Server Central Management System: Centralizing Agent Jobs, Events and Scripts
- The SQL Server Central Management System: Reporting the Data and Project Summary
- Time Tracking for SQL Server Operations
- Migrating Departmental Data Stores to SQL Server
- Migrating Departmental Data Stores to SQL Server: Model the System
- Migrating Departmental Data Stores to SQL Server: Model the System, Continued
- Migrating Departmental Data Stores to SQL Server: Decide on the Destination
- Migrating Departmental Data Stores to SQL Server: Design the ETL
- Migrating Departmental Data Stores to SQL Server: Design the ETL, Continued
- Migrating Departmental Data Stores to SQL Server: Attach the Front End, Test, and Monitor
- Tracking SQL Server Timed Events, Part 1
- Tracking SQL Server Timed Events, Part 2
- Patterns and Practices for the Data Professional
- Managing Vendor Databases
- Consolidation Options
- Connecting to a SQL Azure Database from Microsoft Access
- SharePoint 2007 and SQL Server, Part One
- SharePoint 2007 and SQL Server, Part Two
- SharePoint 2007 and SQL Server, Part Three
- Querying Multiple Data Sources from a Single Location (Distributed Queries)
- Importing and Exporting Data for SQL Azure
- Working on Distributed Teams
- Professional Development
- Application Architecture Assessments
- Business Intelligence
- Tips and Troubleshooting
- Additional Resources
Data Management Objects: Multiple Row Returns
Last updated Feb 18, 2005.
In the Data Management Objects coding that I've shown you in the last few articles, I originally focused on running commands that didn't need permanent output. These commands include maintenance and information regarding the server, in which showing the information on-screen was the only requirement.
Along the way, I showed you how to output that information to a text file, which allows a historical reference. In the last article, I also showed you how to retrieve a single row and column of data from a T-SQL query.
In this article, I'll put it all together and show you how to make a truly extendable piece of code. When complete, this code allows you to have a "driver" file with any T-SQL statements you wish, which outputs the results of that T-SQL both to the screen and to a results file.
As always, the place to begin coding is with the requirements. I'll then create my comments and then code the comments.
The requirements for this code in bullet form are:
- The code should accept input from a text file.
- It should allow any valid T-SQL statements.
- It should connect to a particular server and database.
- It should return the results of the query to the screen.
- It should return the results to a file.
These are simple requirements, and as such, you might be tempted to leave out this step. Don't do it! It's always best practice to do a requirements layout, even one as simple as this.
Next, I create my comments. I do this by laying the process out in blocks, such as "create variables" and "Input and output files." Once I begin coding, I might rename these sections or move them around to fit the code.
With that process in mind, I'll show you the complete code here, and then describe the newer sections below:
' dmoQuery.vbs
' Created: 02/18/05 - Buck Woody
' Change Log:
' Variables
Dim strMsgBoxText ' Text Holder
Dim objServer ' SQL Server name
Dim objDatabase ' Database name
Dim strSQLStatement ' SQL query to run
Dim strQueryResults ' Results of the query
Dim objFileSystem ' File System object
Dim objInputFile ' Input File
Dim objOutputFile ' OutputFile
Dim strMessage ' Logging Message
Dim intRowNumber ' Current row number placeholder
Dim intColumnNumber ' Current column number placeholder
' Input File
Set objFileSystem = CreateObject("Scripting.FileSystemObject")
Set objInputFile = objFileSystem.OpenTextFile("c:\temp\SQLInput.txt", 1)
' Fill the SQL Statement to run
strSQLStatement = objInputFile.ReadAll
' Output File
Set objFileSystem = CreateObject("Scripting.FileSystemObject")
Set objOutputFile = objFileSystem.OpenTextFile("c:\temp\SQLOutput.txt", 8, True)
' Create the server object using SQL-DMO
Set objServer = CreateObject("SQLDMO.SQLServer2")
' Login with current Windows account
objServer.LoginSecure = True
objServer.Connect "(local)"
' Connect to the database
Set objDatabase = objServer.Databases("pubs")
Set strQueryResults = objDatabase.ExecuteWithResults(strSQLStatement)
' Do the work
For intRowNumber = 1 to strQueryResults.Rows
For intColumnNumber = 1 to strQueryResults.Columns
strMsgBoxText = strMsgBoxText & VBTAB & strQueryResults.GetColumnString(intRowNumber, intColumnNumber)
Next
strMsgBoxText = strMsgBoxText & VBCRLF
Next
' Show the message box
MsgBox strMsgBoxText
' Output to Results file
objOutputFile.WriteLine(strMsgBoxText)
' Clean up
Set objDatabase = Nothing
Set objServer = Nothing
For the most part, the code follows along with what I've shown you before. Looking at the outer "skeleton," I set up the variables, connected to a server and database, left some space in the middle to work, and then closed the database and server objects.
The "work" section contains the new parts. Let's begin with the Input File part:
' Input File
Set objFileSystem = CreateObject("Scripting.FileSystemObject")
Set objInputFile = objFileSystem.OpenTextFile("c:\temp\SQLInput.txt", 1)
' Fill the SQL Statement to run
strSQLStatement = objInputFile.ReadAll
A few articles back, I showed you how to work with files. At that time, we were mostly interested in writing files, and we've duplicated that same kind of code in the Output File section which follows. In this section, however, we're more interested in reading a file. As with the output file, I create a FileSystem object and open a text file. Notice that the mode option changes to 1 – which is all that's needed to read a file.
The other difference is that, instead of writing to the file with the WriteLine method, I use the ReadAll method on the file object there in the 5th line of the code snippet shown above. I assigned the output of that method to a string of text, called strSQLStatement, so I can use it later. This satisfies the first requirement. Whatever is in the file c:\temp\SQLInput.txt will load into this string.
The work section has the engine of the program. Let's take a look:
' Do the work
For intRowNumber = 1 to strQueryResults.Rows
For intColumnNumber = 1 to strQueryResults.Columns
strMsgBoxText = strMsgBoxText & VBTAB & strQueryResults.GetColumnString(intRowNumber, intColumnNumber)
Next
strMsgBoxText = strMsgBoxText & VBCRLF
Next
The first thing I do is set up a loop – that's the outer For..Next part – that contains the rows I will work with. This causes the program to iterate through all of the rows of the query. It does that by using a property of the strQueryResults object called Rows, which contains the total number of rows in the query.
Right away I set up another loop. This is because within each row of data, there are multiple (as yet unknown) columns of data. I use the same process to iterate through all the columns as I did for the rows. Pretty neat!
The point of all this iteration is to stuff the results into a string, which is what the 4th line in the code snippet does. The 6th line adds a final carriage-return to the row of data, so it is placed before the Next that handles the rows.
The rest you've seen before, such as the message box output to the screen and the file write.
You can use this same process to iterate through any row and column based set, and to create a file based on the results.
The input file I used looks like this:
SELECT * FROM authors GO
You can use multi-line inputs if you wish, but include a GO between block statements.
One final word about this code: if you're returning a lot of data, remove the lines that read:
' Show the message box MsgBox strMsgBoxText
Message boxes don't have scrollbars, and just aren't suited for large sets of data. Instead, send the output to a file or use another text object to handle the results.
Online Resources
The full documentation for the SQL Server Object Library can be found here.

