<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Microsoft Access Team Blog : SQL Server</title><link>http://blogs.msdn.com/access/archive/tags/SQL+Server/default.aspx</link><description>Tags: SQL Server</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Handling the SQL Server bigint data type in Access 2007 using ADO</title><link>http://blogs.msdn.com/access/archive/2009/06/10/handling-the-sql-server-bigint-data-type-in-access-2007-using-ado.aspx</link><pubDate>Thu, 11 Jun 2009 01:31:28 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9725173</guid><dc:creator>Mike Stowe</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/access/comments/9725173.aspx</comments><wfw:commentRss>http://blogs.msdn.com/access/commentrss.aspx?PostID=9725173</wfw:commentRss><description>&lt;p&gt;&lt;strong&gt;Today’s guest blogger is Vinny Malanga. Vinny is the CTO of &lt;a href="http://www.imisoftwareinc.com/"&gt;IMI Software, Inc.&lt;/a&gt;, which specializes in software development for the property management industry.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I recently received a call from a client asking for help on how to use the SQL Server &lt;strong&gt;bigint&lt;/strong&gt; data type in a disconnected Access .accdb file. Here’s the scenario:&lt;/p&gt;  &lt;p&gt;There’s a SQL Server table that is using the &lt;strong&gt;bigint&lt;/strong&gt; data type as an identity column. In this scenario, the Access database is completely disconnected from the SQL Server 2008 database. There is no use of ODBC or linked tables. All data access is handled using ADO.&lt;/p&gt;  &lt;p&gt;As explained in &lt;a href="http://msdn.microsoft.com/en-us/sqlserver/cc514207.aspx"&gt;SQL Server 2008 Books Online&lt;/a&gt; the range of the &lt;strong&gt;bigint&lt;/strong&gt; data type is -2^63 (-9,223,372,036,854,775,808) to 2^63-1 (9,223,372,036,854,775,807). The problem is that there is no equivalent Access data type to the SQL Server &lt;strong&gt;bigint&lt;/strong&gt; data type. But, you are not out of luck. There are a couple of ways that you can handle this. Both options are explained below.&lt;/p&gt;  &lt;p&gt;The first option is to have all stored procedures or views which return the &lt;strong&gt;bigint&lt;/strong&gt; value to Access explicitly cast the &lt;strong&gt;bigint&lt;/strong&gt; value to a &lt;strong&gt;varchar&lt;/strong&gt;. Access can then utilize the data as a string value. When sending the value back to SQL Server (such as when updating or deleting a record), the stored procedure simply casts the string back to a &lt;strong&gt;bigint&lt;/strong&gt; so it can be used appropriately in SQL Server.&lt;/p&gt;  &lt;p&gt;The second option is to utilize the &lt;strong&gt;Variant&lt;/strong&gt; data type in Access. I know what you may be thinking at this point. At first glance, many of you may not like the sound of this, and as a general rule, I tend to agree, but it is worth exploring this option. By taking this approach, there is no casting in SQL Server necessary. The &lt;strong&gt;Variant&lt;/strong&gt; data type can hold the &lt;strong&gt;bigint&lt;/strong&gt; value that SQL Server sends to Access because the &lt;strong&gt;Decimal&lt;/strong&gt; data type is a subtype of the &lt;strong&gt;Variant&lt;/strong&gt; data type. You can’t explicitly declare a &lt;strong&gt;Decimal&lt;/strong&gt; data type in Access but the &lt;strong&gt;Variant&lt;/strong&gt; data type does store the value as a decimal. You can see this by running the &lt;strong&gt;VarType(&lt;i&gt;VarName&lt;/i&gt;)&lt;/strong&gt; function. The result is 14 which is the VB constant for &lt;strong&gt;vbDecimal&lt;/strong&gt;. You could also run the &lt;strong&gt;TypeName(&lt;i&gt;VarName&lt;/i&gt;)&lt;/strong&gt; function which returns &lt;strong&gt;Decimal&lt;/strong&gt;. I’ve included these methods in the sample access database in the &lt;i&gt;cmdGetName_Click()&lt;/i&gt; event. Just uncomment them and the result will print in the debug window. &lt;/p&gt;  &lt;p&gt;Another small caveat to using a variant is if you are going to display the value in a textbox. The large &lt;strong&gt;bigint&lt;/strong&gt; values will display in scientific notation. For example, if you are displaying the &lt;strong&gt;bigint&lt;/strong&gt; value 9223372036854775807, an Access textbox will display this as 9.22337203685478E+18. However, the actual value is stored appropriately so this isn’t an issue if the field is hidden. For display purposes though, you could cast the value to a string using &lt;strong&gt;CStr(&lt;i&gt;Expression&lt;/i&gt;)&lt;/strong&gt; when binding to the textbox (&lt;i&gt;again, a little more overhead&lt;/i&gt;), or simply display the value in a label control.&lt;/p&gt;  &lt;p&gt;As a general rule, using variants can degrade performance. Since the data type isn’t explicitly declared, VBA has the additional overhead of maintaining which data type it is actually storing. Also, variants are large, 16 bytes so they have a higher memory footprint. However, variants are there for a reason and sometimes they do have their purpose. This could be one of them. I’m not totally opposed to this method, but personally I try to avoid using the &lt;strong&gt;Variant&lt;/strong&gt; data type when another option is available. So, personally, I tend to gravitate toward the first option. &lt;/p&gt;  &lt;p&gt;I’ve supplied some SQL scripts and a &lt;a href="http://cid-f83d4d33f0a1a23a.skydrive.live.com/self.aspx/Sample%20Databases/BigIntAccessDemo.accdb"&gt;sample Access database&lt;/a&gt; applying both methods There are also some examples in the sample database on the use of classes, disconnected ADO Recordsets, and general object oriented programming principles. &lt;/p&gt;  &lt;p&gt;Here are the scripts to create the objects in a SQL Server database.&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;-- 1 Create a table:&lt;/span&gt;
&lt;span class="rem"&gt;-- I have set the identity to begin at the largest bigint value&lt;/span&gt;
&lt;span class="rem"&gt;-- for demonstration purposes.&lt;/span&gt;
&lt;span class="kwrd"&gt;CREATE&lt;/span&gt; &lt;span class="kwrd"&gt;TABLE&lt;/span&gt; [dbo].[tblName](
    [RecordID] [bigint] &lt;span class="kwrd"&gt;IDENTITY&lt;/span&gt;(9223372036854775807,-1) &lt;span class="kwrd"&gt;NOT&lt;/span&gt; &lt;span class="kwrd"&gt;NULL&lt;/span&gt;,
    [Name] [&lt;span class="kwrd"&gt;varchar&lt;/span&gt;](50) &lt;span class="kwrd"&gt;NULL&lt;/span&gt;,
 &lt;span class="kwrd"&gt;CONSTRAINT&lt;/span&gt; [PK_tblName] &lt;span class="kwrd"&gt;PRIMARY&lt;/span&gt; &lt;span class="kwrd"&gt;KEY&lt;/span&gt; &lt;span class="kwrd"&gt;CLUSTERED&lt;/span&gt; 
(
    [RecordID] &lt;span class="kwrd"&gt;ASC&lt;/span&gt;
)
&lt;span class="kwrd"&gt;WITH&lt;/span&gt; (PAD_INDEX = &lt;span class="kwrd"&gt;OFF&lt;/span&gt;, STATISTICS_NORECOMPUTE = &lt;span class="kwrd"&gt;OFF&lt;/span&gt;, IGNORE_DUP_KEY = &lt;span class="kwrd"&gt;OFF&lt;/span&gt;, 
       ALLOW_ROW_LOCKS = &lt;span class="kwrd"&gt;ON&lt;/span&gt;, ALLOW_PAGE_LOCKS = &lt;span class="kwrd"&gt;ON&lt;/span&gt;) &lt;span class="kwrd"&gt;ON&lt;/span&gt; [&lt;span class="kwrd"&gt;PRIMARY&lt;/span&gt;]
) &lt;span class="kwrd"&gt;ON&lt;/span&gt; [&lt;span class="kwrd"&gt;PRIMARY&lt;/span&gt;]
&lt;span class="kwrd"&gt;GO&lt;/span&gt;

&lt;span class="rem"&gt;-- Create four Stored Procedures.&lt;/span&gt;
&lt;span class="kwrd"&gt;CREATE&lt;/span&gt; &lt;span class="kwrd"&gt;PROCEDURE&lt;/span&gt; [dbo].[procGetNameUsingString] 
&lt;span class="kwrd"&gt;AS&lt;/span&gt;
&lt;span class="kwrd"&gt;BEGIN&lt;/span&gt;
    &lt;span class="kwrd"&gt;SET&lt;/span&gt; NOCOUNT &lt;span class="kwrd"&gt;ON&lt;/span&gt;;
    &lt;span class="rem"&gt;-- bigint range is -9223372036854775808 to 9223372036854775807&lt;/span&gt;

    &lt;span class="rem"&gt;-- Cast RecordID to varchar(19) when sending to Access&lt;/span&gt;
    &lt;span class="rem"&gt;-- 19 is the number of characters needed to hold the largest&lt;/span&gt;
    &lt;span class="rem"&gt;-- length bigint value. Use 20 if you're going to use negative&lt;/span&gt;
    &lt;span class="rem"&gt;-- numbers to account for the negative sign.&lt;/span&gt;
    &lt;span class="kwrd"&gt;SELECT&lt;/span&gt; &lt;span class="kwrd"&gt;CAST&lt;/span&gt;(RecordID &lt;span class="kwrd"&gt;AS&lt;/span&gt; &lt;span class="kwrd"&gt;varchar&lt;/span&gt;(19)) &lt;span class="kwrd"&gt;AS&lt;/span&gt; RecordID, Name &lt;span class="kwrd"&gt;FROM&lt;/span&gt; tblName
&lt;span class="kwrd"&gt;END&lt;/span&gt;
&lt;span class="kwrd"&gt;GO&lt;/span&gt;

&lt;span class="kwrd"&gt;CREATE&lt;/span&gt; &lt;span class="kwrd"&gt;PROCEDURE&lt;/span&gt; [dbo].[procGetNameUsingVariant] 
&lt;span class="kwrd"&gt;AS&lt;/span&gt;
&lt;span class="kwrd"&gt;BEGIN&lt;/span&gt;
    &lt;span class="kwrd"&gt;SET&lt;/span&gt; NOCOUNT &lt;span class="kwrd"&gt;ON&lt;/span&gt;;
    &lt;span class="kwrd"&gt;SELECT&lt;/span&gt;  RecordID, Name &lt;span class="kwrd"&gt;FROM&lt;/span&gt; tblName
&lt;span class="kwrd"&gt;END&lt;/span&gt;
&lt;span class="kwrd"&gt;GO&lt;/span&gt;

&lt;span class="kwrd"&gt;CREATE&lt;/span&gt; &lt;span class="kwrd"&gt;PROCEDURE&lt;/span&gt; [dbo].[procUpdateNameUsingString]
    (
        @RecordID        &lt;span class="kwrd"&gt;varchar&lt;/span&gt;(19),
        @Name            &lt;span class="kwrd"&gt;varchar&lt;/span&gt;(50),
        @ReturnValue    &lt;span class="kwrd"&gt;bit&lt;/span&gt; &lt;span class="kwrd"&gt;OUTPUT&lt;/span&gt;
    )
&lt;span class="kwrd"&gt;AS&lt;/span&gt;
&lt;span class="kwrd"&gt;BEGIN&lt;/span&gt;
    &lt;span class="kwrd"&gt;SET&lt;/span&gt; NOCOUNT &lt;span class="kwrd"&gt;ON&lt;/span&gt;;
    &lt;span class="rem"&gt;-- Declare a variable to hold the bigint value&lt;/span&gt;
    &lt;span class="rem"&gt;-- and assign it the result of casting the incoming&lt;/span&gt;
    &lt;span class="rem"&gt;-- string representation of RecordID back to a bigint value.&lt;/span&gt;
    &lt;span class="kwrd"&gt;DECLARE&lt;/span&gt; @RecordIDBigInt bigint
    &lt;span class="kwrd"&gt;SET&lt;/span&gt; @RecordIDBigInt = &lt;span class="kwrd"&gt;CAST&lt;/span&gt;(@RecordID &lt;span class="kwrd"&gt;AS&lt;/span&gt; bigint)
    &lt;span class="rem"&gt;-- Update the record using the bigint value.&lt;/span&gt;
    &lt;span class="kwrd"&gt;UPDATE&lt;/span&gt; tblName
    &lt;span class="kwrd"&gt;SET&lt;/span&gt; Name = @Name
    &lt;span class="kwrd"&gt;WHERE&lt;/span&gt; RecordID = @RecordIDBigInt
    
    &lt;span class="kwrd"&gt;SET&lt;/span&gt; @ReturnValue = &lt;span class="preproc"&gt;@@ROWCOUNT&lt;/span&gt;
&lt;span class="kwrd"&gt;END&lt;/span&gt;
&lt;span class="kwrd"&gt;GO&lt;/span&gt;

&lt;span class="kwrd"&gt;CREATE&lt;/span&gt; &lt;span class="kwrd"&gt;PROCEDURE&lt;/span&gt; [dbo].[procUpdateNameUsingVariant]
    (
        @RecordID        bigint,
        @Name            &lt;span class="kwrd"&gt;varchar&lt;/span&gt;(50),
        @ReturnValue    &lt;span class="kwrd"&gt;bit&lt;/span&gt; &lt;span class="kwrd"&gt;OUTPUT&lt;/span&gt;
    )
&lt;span class="kwrd"&gt;AS&lt;/span&gt;
&lt;span class="kwrd"&gt;BEGIN&lt;/span&gt;
    &lt;span class="kwrd"&gt;SET&lt;/span&gt; NOCOUNT &lt;span class="kwrd"&gt;ON&lt;/span&gt;;

    &lt;span class="kwrd"&gt;UPDATE&lt;/span&gt; tblName
    &lt;span class="kwrd"&gt;SET&lt;/span&gt; Name = @Name
    &lt;span class="kwrd"&gt;WHERE&lt;/span&gt; RecordID = @RecordID
    
    &lt;span class="kwrd"&gt;SET&lt;/span&gt; @ReturnValue = &lt;span class="preproc"&gt;@@ROWCOUNT&lt;/span&gt;
&lt;span class="kwrd"&gt;END&lt;/span&gt;
&lt;span class="kwrd"&gt;GO&lt;/span&gt;

&lt;span class="rem"&gt;-- Create a view (example if using views&lt;/span&gt;
&lt;span class="rem"&gt;-- rather than stored procedures).&lt;/span&gt;
&lt;span class="kwrd"&gt;CREATE&lt;/span&gt; &lt;span class="kwrd"&gt;VIEW&lt;/span&gt; [dbo].[vwGetNameUsingString]
&lt;span class="kwrd"&gt;AS&lt;/span&gt;
&lt;span class="kwrd"&gt;SELECT&lt;/span&gt;     RecordID, &lt;span class="kwrd"&gt;CAST&lt;/span&gt;(Name &lt;span class="kwrd"&gt;AS&lt;/span&gt; &lt;span class="kwrd"&gt;varchar&lt;/span&gt;(19)) &lt;span class="kwrd"&gt;AS&lt;/span&gt; Expr1
&lt;span class="kwrd"&gt;FROM&lt;/span&gt;         dbo.tblName
GO&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	margin: 0em
}
.csharpcode .rem {
	color: #008000
}
.csharpcode .kwrd {
	color: #0000ff
}
.csharpcode .str {
	color: #006080
}
.csharpcode .op {
	color: #0000c0
}
.csharpcode .preproc {
	color: #cc6633
}
.csharpcode .asp {
	background-color: #ffff00
}
.csharpcode .html {
	color: #800000
}
.csharpcode .attr {
	color: #ff0000
}
.csharpcode .alt {
	background-color: #f4f4f4; margin: 0em; width: 100%
}
.csharpcode .lnum {
	color: #606060
}&lt;/style&gt;

&lt;p&gt;Once you’ve run the scripts, your SQL database will contain one new table, four new stored procedures, and one new view. You’ll want to add a record to the newly-created table to make use of the form in the sample Access database.&lt;/p&gt;

&lt;p&gt;You can download the sample Access database from &lt;a href="http://cid-f83d4d33f0a1a23a.skydrive.live.com/self.aspx/Sample%20Databases/BigIntAccessDemo.accdb"&gt;here&lt;/a&gt;. You should change the connection string in the Connect subroutine of the clsDataAccess module to suit your environment. Note that the code requires a reference to the Microsoft ActiveX Data Objects 6.0 Library. The sample database already contains the reference; this is something to keep in mind if you implement the class in your database.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
&lt;style type="text/css"&gt;
.csharpcode {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	margin: 0em
}
.csharpcode .rem {
	color: #008000
}
.csharpcode .kwrd {
	color: #0000ff
}
.csharpcode .str {
	color: #006080
}
.csharpcode .op {
	color: #0000c0
}
.csharpcode .preproc {
	color: #cc6633
}
.csharpcode .asp {
	background-color: #ffff00
}
.csharpcode .html {
	color: #800000
}
.csharpcode .attr {
	color: #ff0000
}
.csharpcode .alt {
	background-color: #f4f4f4; margin: 0em; width: 100%
}
.csharpcode .lnum {
	color: #606060
}&lt;/style&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9725173" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/access/archive/tags/Access+2007/default.aspx">Access 2007</category><category domain="http://blogs.msdn.com/access/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://blogs.msdn.com/access/archive/tags/Power+Tips/default.aspx">Power Tips</category></item><item><title>Channel 9 video about Access and SQL Server Migration</title><link>http://blogs.msdn.com/access/archive/2009/03/17/channel-9-video-about-access-and-sql-server-migration.aspx</link><pubDate>Wed, 18 Mar 2009 09:00:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9485999</guid><dc:creator>Clint Covington</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/access/comments/9485999.aspx</comments><wfw:commentRss>http://blogs.msdn.com/access/commentrss.aspx?PostID=9485999</wfw:commentRss><description>&lt;p&gt;&lt;a href="http://channel9.msdn.com/shows/ARCast.TV/ARCastTV-Luke-Chung-on-Access-Db-and-Migration-Challenges/"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="image" border="0" alt="image" align="right" src="http://blogs.msdn.com/blogfiles/access/WindowsLiveWriter/Channel9videoaboutAccessandSQLServerMigr_1437F/image_5.png" width="240" height="180" /&gt;&lt;/a&gt; Luke Chung from FMS recently talked on Channel 9 about &lt;a href="http://channel9.msdn.com/shows/ARCast.TV/ARCastTV-Luke-Chung-on-Access-Db-and-Migration-Challenges/"&gt;his view of Access solutions&lt;/a&gt; -- where they fit well, what challenges users and developers often face in creating and maintaining them, and how they have evolved from standalone desktop solutions to having the capability to be integrated with web-based and SharePoint centric solutions. He further explains primary reasons why some Access database solutions are migrated to SQL Server database based solutions, what different approaches are used to carry out migrations, and how to get started with the migration process when a large number of Access databases are involved. &lt;/p&gt;  &lt;p&gt;You can get more info from FMS about upsizing &lt;a href="http://www.fmsinc.com/MicrosoftAccess/SQLServerUpsizing/index.html"&gt;here&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;Luke has also recently written about &lt;a href="http://www.fmsinc.com/MicrosoftAccess/2007/Top-Features.html"&gt;Top Features of Microsoft Access 2007 that Aren’t Available in Prior Versions&lt;/a&gt;. Many of you might find it interesting.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9485999" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/access/archive/tags/SQL+Server/default.aspx">SQL Server</category></item><item><title>Using SQL Server 2008 Table-Valued Parameters (TVPs) from Access</title><link>http://blogs.msdn.com/access/archive/2009/01/28/using-sql-server-2008-table-valued-parameters-tvps-from-access.aspx</link><pubDate>Wed, 28 Jan 2009 20:13:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9381368</guid><dc:creator>Clint Covington</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/access/comments/9381368.aspx</comments><wfw:commentRss>http://blogs.msdn.com/access/commentrss.aspx?PostID=9381368</wfw:commentRss><description>&lt;P&gt;&lt;EM&gt;Today’s guest writer is&amp;nbsp;Mary Chipman. Mary is a programmer-writer for the Data Programmability team at Microsoft and co-author of the classic &lt;/EM&gt;&lt;A href="http://www.amazon.com/Microsoft-Access-Developers-Guide-Server/dp/0672319446/" mce_href="http://www.amazon.com/Microsoft-Access-Developers-Guide-Server/dp/0672319446/"&gt;&lt;EM&gt;Microsoft Access Developer's Guide to SQL Server&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt;. &lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;Table-valued parameters (TVPs) in SQL Server 2008 provide an easy way to marshal multiple rows of data from a client application to SQL Server without requiring multiple round trips or special server-side logic for processing the data. TVPs come in handy when you want to code explicit transactions inside of stored procedures, performing multiple data operations as a single unit of work. You can encapsulate multiple rows of data in a single parameterized command. The incoming data rows are stored in a table variable that can then be operated on by using Transact-SQL.&lt;/P&gt;
&lt;P&gt;In versions of SQL Server prior to SQL Server 2008 you had to jump through a lot of hoops to pass in and process multiple rows of data. Stored procedure input parameters did not accept arrays or structured data, so developers used such techniques as bundling multiple data values into delimited strings or XML documents. Those text values then needed to be processed, which required that you validate the data structures and unbundle the values. With TVPs, you simply pass in the rows of data to be operated on. This not only frees server resources to focus on set-based operations, making your transactions more scalable and efficient, but it also simplifies your server-side Transact-SQL code.&lt;/P&gt;
&lt;P&gt;Using TVPs from Access makes sense only for a limited set of scenarios, such as a store-and-forward application that operates on data locally in Access and then posts changes to SQL Server, "unbound" applications that interoperate with stored procedures, and transactional applications such as orders-line items in which all rows need to be either committed or rolled back to guarantee data consistency. The default way of updating server-side data—one row at a time—is adequate in most data access scenarios. This article discusses how you can use TVPs as an alternative, as well as the drawbacks of using this technique in Access.&lt;/P&gt;
&lt;H3&gt;How TVPs Work&lt;/H3&gt;
&lt;P&gt;Table-valued parameters are based on strongly-typed table structures that are defined by using the Transact-SQL &lt;B&gt;CREATE TYPE&lt;/B&gt; statement. In order to use a TVP, you must first create a table type and define its structure in the database. The table type functions as a container for the structured data rows that you pass to the server, so it mirrors the data structure of the underlying data you want to use it with. Once you've defined the table type, you can then use it to define an input parameter for a stored procedure or Transact-SQL statement.&lt;/P&gt;
&lt;P&gt;You can work with TVPs directly in Transact-SQL code, or by using either ADO.NET or SQL Server Native Client objects. In ADO.NET, the &lt;B&gt;SqlParameter&lt;/B&gt; class has been extended to take a &lt;B&gt;DataTable&lt;/B&gt; as a value. The SQL Server Native Client OLE DB API accomplishes the same thing by leveraging the COM &lt;B&gt;IRowset&lt;/B&gt; interface along with a new implementation that allows buffering.&lt;/P&gt;
&lt;P&gt;The downside for Access developers is that the ADO API has not been updated to support TVPs directly through ADO Parameter objects. Unless you want to program directly against the SQL Server Native Client API by declaring and calling API functions, that leaves you with a single option: pass-through queries running Transact-SQL, which you can modify programmatically using a DAO &lt;B&gt;QueryDef&lt;/B&gt; object.&lt;/P&gt;
&lt;H3&gt;TVPs and Access Pass-Through Queries&lt;/H3&gt;
&lt;P&gt;Access pass-through queries, as the name implies, allow you to bypass the Jet database engine and to send Transact-SQL code directly to SQL Server for execution. Although pass-through queries can be used to return records, this feature is not available if you want to use table-valued parameters. To use TVPs, you must set the query's &lt;B&gt;Returns Records&lt;/B&gt; property to &lt;B&gt;No&lt;/B&gt; or Access will raise an error. Unfortunately, this means that you will be unable to return any information whatsoever through the pass-through query mechanism. If you need to get information back from the server, such as new identity values, you will need to execute a separate query to accomplish that.&lt;/P&gt;
&lt;P&gt;Pass-through queries are most easily manipulated programmatically using the DAO &lt;B&gt;QueryDef&lt;/B&gt; object. In addition to setting &lt;B&gt;Returns Records&lt;/B&gt; to &lt;B&gt;No&lt;/B&gt;, you will need to set the &lt;B&gt;Connect&lt;/B&gt; property to a valid ODBC connection string and the &lt;B&gt;SQL&lt;/B&gt; property to a string value that contains the Transact-SQL statements you are passing to the server for processing. &lt;/P&gt;
&lt;P&gt;TVPs can be especially useful if you are working with an "unbound" application that relies on code execution and stored procedures rather than using bound controls to manipulate data. The tradeoff is that your client code in Access needs to be more complex, as it must parse row data into properly delimited Transact-SQL statements. The benefits include a simpler server-side programming model with more maintainable stored procedure code, faster performance from set-based operations, and better scalability for larger data volumes. Another consideration is that TVPs are server-side objects, therefore they can be used from multiple client applications, not just Access.&lt;/P&gt;
&lt;H3&gt;TVP Walkthrough&lt;/H3&gt;
&lt;P&gt;Here are the steps for creating a simple proof-of-concept example using the Northwind database in SQL Server 2008. &lt;/P&gt;
&lt;P&gt;The example creates a table structure that is saved in the database and used to insert multiple new rows into the Categories table. Note that the Categories base table contains an identity column. It also does not have a unique index defined on CategoryName, which would allow duplicate categories to be inserted. These are both potential problems that you'll need to anticipate and work around in a real-world situation. Execute the following Transact-SQL statements in SQL Server Management Studio to create the CategoryTableType. &lt;/P&gt;
&lt;P&gt;&lt;FONT size=2 face="Courier New"&gt;Use Northwind &lt;BR&gt;GO &lt;BR&gt;CREATE TYPE dbo.CategoryTableType AS TABLE &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ( CategoryName nvarchar(15), CategoryDescription ntext ) &lt;BR&gt;GO&lt;/FONT&gt; &lt;/P&gt;
&lt;P&gt;Once the CategoryTableType is created, you can use it to define a stored procedure input parameter. The following usp_InsertCategory stored procedure takes the CategoryTableType as an input parameter, which is defined using the &lt;B&gt;READONLY&lt;/B&gt; keyword. Other features of the stored procedure include:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;An output parameter returns information to the caller. Even though you can't obtain it from the pass-through query, it's possible that you might also want to call the stored procedure from a .NET application, where the output parameter value would be available. &lt;/LI&gt;
&lt;LI&gt;Try/Catch error handling, which was introduced in SQL Server 2005. Again, you can't use this feature from a pass-through query, but you could conceivably call the stored procedure from another client. &lt;/LI&gt;
&lt;LI&gt;An explicit transaction using &lt;B&gt;BEGIN TRAN&lt;/B&gt;, &lt;B&gt;COMMIT&lt;/B&gt;, and &lt;B&gt;ROLLBACK&lt;/B&gt; statements. This ensures that all rows inserted into the Categories table will commit in a single transaction, or all will be rolled back. For example, if you have 10 rows, and there is an error with only 1 of them, then none of the rows will be inserted. If you do not have an explicit transaction, 9 out the 10 rows will be committed, but you will have no way of knowing which one was the problem row that didn't make it. &lt;/LI&gt;
&lt;LI&gt;In the Catch block, the code calls the &lt;B&gt;@@TRANCOUNT&lt;/B&gt; function to see if a transaction is active. This allows you to avoid triggering another error if you attempt a rollback without an active transaction. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Execute the following Transact-SQL statements in the SQL Server Management Studio window to create the usp_InsertCategory stored procedure.&lt;/P&gt;&lt;PRE&gt;CREATE PROCEDURE dbo.usp_InsertCategory 
	(@tvpNewCategories dbo.CategoryTableType READONLY,
	@ReturnMessage nvarchar(255) = NULL OUTPUT)

AS
SET NOCOUNT ON
BEGIN TRY
	BEGIN TRAN
		INSERT INTO dbo.Categories (CategoryName, Description)
		SELECT CategoryName, CategoryDescription FROM @tvpNewCategories 
		IF @@ROWCOUNT = 0
			RAISERROR ('No Categories inserted.', 16, 1)
	COMMIT
	SELECT @ReturnMessage='Categories inserted.';
END TRY

BEGIN CATCH
	IF @@TRANCOUNT &amp;gt; 0
		ROLLBACK
		SELECT @ReturnMessage = ERROR_MESSAGE() +
			' Severity=' + CAST(ERROR_SEVERITY() AS nvarchar(2))
END CATCH
GO&lt;/PRE&gt;
&lt;P&gt;In Access, create a pass-through query and set the &lt;B&gt;Returns Records&lt;/B&gt; property to &lt;B&gt;No&lt;/B&gt;. Set the &lt;B&gt;ODBC Connect Str&lt;/B&gt; property to a DSN or valid ODBC connection string.&lt;/P&gt;
&lt;P&gt;Paste the following Transact-SQL statements into the SQL pane of your pass-through query. You can also test these statements from SQL Server Management Studio query window—the result will be the same. The only difference is that in Management Studio you will be able to see the return message.&lt;/P&gt;&lt;PRE&gt;DECLARE @ReturnMessage nvarchar(255)
DECLARE @catType CategoryTableType
INSERT INTO @catType
EXEC ('
SELECT ''Organic'', ''Organically grown produce and grains''
SELECT ''Conventional'', ''Non-organically grown produce and grains''
SELECT ''Irish'', ''Mrs. O''''Leary''''s creamery products''
')
EXEC dbo.usp_InsertCategory @catType, @ReturnMessage OUTPUT;
SELECT @ReturnMessage as ReturnMessage&lt;/PRE&gt;
&lt;P&gt;What these Transact-SQL statements are doing is packaging up the values you want to pass to the usp_InsertCategory stored procedure, and inserting the proper escape characters so that it can be processed without triggering a syntax error. When you execute the pass-through query, these statements will be passed directly to SQL Server to be parsed and executed. None of the statements will be processed by Jet or ODBC. Note that I've added an "Irish" category to demonstrate the correct syntax for passing apostrophes (single quotes). This is the sort of string processing you'll need to handle in your VBA code as you concatenate row values with Transact-SQL statement syntax. For example, you could use the VBA Replace function to find and double up any apostrophes.&lt;/P&gt;
&lt;P&gt;Before you execute the query, open a SQL Server Profiler trace. Execute the query, and you will see that the statements are indeed passed through directly to SQL Server.&lt;/P&gt;
&lt;P&gt;Enter the following statements into the SQL Server Management Studio window:&lt;/P&gt;&lt;PRE&gt;SELECT CategoryID, CategoryName, Description from dbo.Categories&lt;/PRE&gt;
&lt;P&gt;You will see that the new rows have been inserted. If you define a unique index on the CategoryName column and then attempt to execute the InsertCategory stored procedure again, you will see the error message only if you execute the statements from SQL Server Management Studio, but nothing if you execute the Access pass-through query. You can examine the Profiler trace to verify that the statements have in fact been sent from Access.&lt;/P&gt;
&lt;H3&gt;Summary&lt;/H3&gt;
&lt;P&gt;You'll probably only be interested in calling TVPs from Access pass-through queries for a limited number of scenarios that need to pass multiple rows of structured data to SQL Server to be processed on the server. There are several drawbacks to this technique: you won't get any design-time syntax checking, and run time error handling will be limited. In addition, you won't be able to retrieve new identity column values from within the pass-through query, because it can't return any data. You can work around these limitations, but it will require making specific design decisions as well as coding workarounds. The main benefit is that you are making your database transactions more scalable and efficient by performing iterative string processing in your client code, freeing up server resources to focus on set-based operations.&lt;/P&gt;
&lt;H3&gt;See Also&lt;/H3&gt;
&lt;P&gt;The documentation for table-valued parameters can be found in SQL Server Books Online at &lt;A href="http://msdn.microsoft.com/en-us/library/bb510489.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb510489.aspx"&gt;http://msdn.microsoft.com/en-us/library/bb510489.aspx&lt;/A&gt;. &lt;/P&gt;
&lt;H3&gt;Bio&lt;/H3&gt;
&lt;P&gt;Mary Chipman is a programmer-writer for the Data Programmability team at Microsoft. She was recently profiled in Women in Technology for TechEd Online at &lt;A href="http://msdn.microsoft.com/en-us/events/teched/cc510243.aspx" mce_href="http://msdn.microsoft.com/en-us/events/teched/cc510243.aspx"&gt;http://msdn.microsoft.com/en-us/events/teched/cc510243.aspx&lt;/A&gt;. You can find the online panel she hosted at TechEd 2008 by going to &lt;A href="http://msdn.microsoft.com/en-us/events/teched/cc676818.aspx" mce_href="http://msdn.microsoft.com/en-us/events/teched/cc676818.aspx"&gt;http://msdn.microsoft.com/en-us/events/teched/cc676818.aspx&lt;/A&gt; and searching for: "Are we there yet? Successfully navigating the bumpy road from Access to SQL Server". Mary will also be presenting at TechEd 2009 (&lt;A href="http://www.msteched.com/" mce_href="http://www.msteched.com/"&gt;http://www.msteched.com&lt;/A&gt;) on the topic of working with SQL Server from Access. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9381368" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/access/archive/tags/SQL+Server/default.aspx">SQL Server</category></item><item><title>Announcement: Storing Access apps and data in the cloud</title><link>http://blogs.msdn.com/access/archive/2008/10/28/storing-access-apps-and-data-in-the-cloud.aspx</link><pubDate>Tue, 28 Oct 2008 19:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9019673</guid><dc:creator>Clint Covington</dc:creator><slash:comments>22</slash:comments><comments>http://blogs.msdn.com/access/comments/9019673.aspx</comments><wfw:commentRss>http://blogs.msdn.com/access/commentrss.aspx?PostID=9019673</wfw:commentRss><description>&lt;p&gt;&lt;i&gt;Today&amp;#8217;s guest writer is Liam Cavanagh from the Sync Framework and SQL Services team. They are doing some cool stuff that allows Access developers to store their app and data in the cloud using SQL Server Data Services. Liam is looking for people that want to beta test an upcoming release early next year. --Clint&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;Today at PDC we are announcing Codename &amp;#8220;Huron&amp;#8221;, a set of synchronization experiences built on top of the sync functionality in &lt;a href="http://www.microsoft.com/sql/dataservices/default.mspx" mce_href="http://www.microsoft.com/sql/dataservices/default.mspx"&gt;SQL Data Services&amp;#8217;&lt;/a&gt; cloud database and the &lt;a href="http://msdn.microsoft.com/sync" mce_href="http://msdn.microsoft.com/sync"&gt;Microsoft Sync Framework&lt;/a&gt; to provide business database sharing. Business database sharing offers a simple way to scale data to large numbers of users while not parting from the investment made in current technologies. It also enables users to subscribe and then edit the data locally in the format of their choice whether that is Office Access, SQL Server Express or SQL Server Compact and then push changes into SQL Data Services. The first end-to-end experience we will provide is for Office Access and will allow users to:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Publish databases to the cloud along with reports, forms and objects &lt;/li&gt;    &lt;li&gt;Subscribe to published data and automatically configure the local database for sync &lt;/li&gt;    &lt;li&gt;Make online changes through SQL Data Services and propagate those changes to subscribed users once they connect &lt;/li&gt;    &lt;li&gt;Enable scheduled and background synchronization of data changes through SQL Data Services and then on to other subscribed users &lt;/li&gt;    &lt;li&gt;Backup and restore of database applications to the cloud &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If you are interested in joining our early beta, please email &lt;a href="mailto:DataLabs@Microsoft.com" mce_href="mailto:DataLabs@Microsoft.com"&gt;DataLabs@Microsoft.com&lt;/a&gt; with &amp;#8220;Huron beta&amp;#8221; in the subject. For more information on Codename &amp;#8220;Huron&amp;#8221;, please visit &lt;a href="http://www.sqlserviceslabs.com"&gt;http://www.sqlserviceslabs.com&lt;/a&gt; and click on &lt;a href="http://sqlserviceslabs.net/huron.html" target="_blank"&gt;Project Huron&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;u&gt;Screen Shots&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/access/WindowsLiveWriter/StoringAccessappsanddatainthecloud_1129B/image_2.png" mce_href="http://blogs.msdn.com/blogfiles/access/WindowsLiveWriter/StoringAccessappsanddatainthecloud_1129B/image_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="188" alt="image" src="http://blogs.msdn.com/blogfiles/access/WindowsLiveWriter/StoringAccessappsanddatainthecloud_1129B/image_thumb.png" width="244" border="0" mce_src="http://blogs.msdn.com/blogfiles/access/WindowsLiveWriter/StoringAccessappsanddatainthecloud_1129B/image_thumb.png" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/access/WindowsLiveWriter/StoringAccessappsanddatainthecloud_1129B/clip_image002_2.jpg" mce_href="http://blogs.msdn.com/blogfiles/access/WindowsLiveWriter/StoringAccessappsanddatainthecloud_1129B/clip_image002_2.jpg"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="177" alt="clip_image002" src="http://blogs.msdn.com/blogfiles/access/WindowsLiveWriter/StoringAccessappsanddatainthecloud_1129B/clip_image002_thumb.jpg" width="244" border="0" mce_src="http://blogs.msdn.com/blogfiles/access/WindowsLiveWriter/StoringAccessappsanddatainthecloud_1129B/clip_image002_thumb.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/access/WindowsLiveWriter/StoringAccessappsanddatainthecloud_1129B/clip_image004_2.jpg" mce_href="http://blogs.msdn.com/blogfiles/access/WindowsLiveWriter/StoringAccessappsanddatainthecloud_1129B/clip_image004_2.jpg"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="178" alt="clip_image004" src="http://blogs.msdn.com/blogfiles/access/WindowsLiveWriter/StoringAccessappsanddatainthecloud_1129B/clip_image004_thumb.jpg" width="244" border="0" mce_src="http://blogs.msdn.com/blogfiles/access/WindowsLiveWriter/StoringAccessappsanddatainthecloud_1129B/clip_image004_thumb.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Updated link and post title: 10/29/2008.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9019673" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/access/archive/tags/SQL+Server/default.aspx">SQL Server</category></item><item><title>Tech Talk: Using Access with SQL Server Panel Discussion from TechEd 2008</title><link>http://blogs.msdn.com/access/archive/2008/06/19/tech-talk-using-access-with-sql-server-panel-discussion-from-tech-ed-2008.aspx</link><pubDate>Fri, 20 Jun 2008 00:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8623181</guid><dc:creator>Clint Covington</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.msdn.com/access/comments/8623181.aspx</comments><wfw:commentRss>http://blogs.msdn.com/access/commentrss.aspx?PostID=8623181</wfw:commentRss><description>&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;There is a good talk available called &lt;A href="http://mfile.akamai.com/14853/wmv/microsofttec.download.akamai.com/14853/TechEdOnline/Videos/08_NA_dev_TEOPanel_05_low.asx" mce_href="http://mfile.akamai.com/14853/wmv/microsofttec.download.akamai.com/14853/TechEdOnline/Videos/08_NA_dev_TEOPanel_05_low.asx"&gt;Are we there yet? Successfully navigating the bumpy road from Access to SQL Server&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Here is the description:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;“Use SQL Server, not Access”, is advice commonly handed out when the Jet database engine outgrows its usefulness. However, that’s often easier said than done. Each database application is unique; some may have salvageable components, whereas others may need to be redesigned and rebuilt from scratch. In addition, there are substantial differences between the Jet and SQL Server database engines that can make a straight port unworkable in many situations. This panel discusses criteria for deciding whether to migrate data from Access to SQL Server, and for determining the optimal migration path once the decision is made. The panelists will share their real-world expertise to help you determine a successful strategy that best suits your business needs. With Mary Chipman, Armen Stein, Luke Chung, Paul Sheriff, and Stephen Forte.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;There are other good talks available &lt;A href="http://msdn.microsoft.com/en-us/events/teched/cc676818.aspx" mce_href="http://msdn.microsoft.com/en-us/events/teched/cc676818.aspx"&gt;here&lt;/A&gt;…&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8623181" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/access/archive/tags/SQL+Server/default.aspx">SQL Server</category></item></channel></rss>