Using the OPENROWSET FunctionThe OPENROWSET function can be used to access data from data sources external to SQL Server.. The OPENROWSET function can also be used as yet another way to
Trang 1Using the OPENROWSET Function
The OPENROWSET function can be used to access data from data sources external to SQL Server This can be a great way to interact with data in external sources without requiring administrators to first configure a linked server The OPENROWSET function can also be used as yet another way to bulk load data into SQL Server
OPENROWSET is a table-valued function That means that the result of the call to the function is actually a table The implication is that you use the
OPENROWSET( ) function call in place of a table reference in statements that work with tables (like SELECT, INSERT, UPDATE, and DELETE)
Start by seeing how to use SQL Server to access external data
1 Determine if ad hoc queries have already been enabled on your server Run the following statements in a query window in SSMS
A zero in the run_value column in the result set means ad hoc queries are disabled, and a one means they are enabled.
EXEC sp_configure 'show advanced',1;
RECONFIGURE;
EXEC sp_configure 'Ad Hoc Distributed Queries';
2 Ensure that ad hoc distributed queries are enabled Run the following statements:
EXEC sp_configure 'show advanced',1;
RECONFIGURE;
EXEC sp_configure 'Ad Hoc Distributed Queries', 1;
RECONFIGURE;
3 By default the various OLE DB providers on the server allow
ad hoc access View the list of the providers on your server by connecting to your SQL Server instance in the SSMS Object
Explorer Then expand Server Objects | Linked Servers | Providers Right click on a provider and choose Properties to view its
properties Is it set to disallow ad hoc access? What about the other providers?
Trang 2The basic syntax of the OPENROWSET Function looks like this:
OPENROWSET
(
'provider_name',
{ 'datasource'; 'user_id'; 'password' | 'provider_string' },
{ [ catalog ] [ schema ] object | 'query'
)
The “provider_name” is the name of the OLE DB provider you wish to use
when connecting to the external database For SQL Server, you can use SQLNCLI
You can find out what the names of your other available providers are by looking
at the documentation for the providers, looking in the registry (HKLM\SOFTWARE\ Microsoft\Microsoft SQL Server\MSSQL10.MSSQLSERVER\Providers), and,
of course, searching the Internet for resources
The provider will need to know where and as whom to connect There are two
ways to do this You can use a canonical format of ‘datasource’; ‘user_id’; ‘password’”
or we can specify a “provider_string.”
The “‘datasource’; ‘user_id’; ‘password’” is a single parameter that has semi-colon
delimited elements This method of providing connection details is the easiest to
use, but requires that you use SQL Authentication (assuming the target is another
SQL instance) This means the credentials are entered as clear text in the syntax
That’s alarming
The “provider_string” method is a little harder to get right, but makes it possible
to use a trusted connection (Windows Authentication) to the external data source
This can be tricky to get right, but once you get it configured, it is a much more
secure way to connect You can also use additional information in your connection
strings to further control the behavior of the connection
Once you have specified how to connect, you finally need to specify what data
to retrieve You again have a choice You can either state a database.schema.object
qualified object identifier, or you can write a query to be executed by the external
data source
If you use the database.schema.object identifier to name an object to return data from, the referenced object needs to be a valid table or view, and the identity the
connection is made with must have permissions to the object In the documentation
of the statement you see the word “catalog” used instead of “database.” Again,
catalog is just what the ANSI specification calls a database
Trang 3Querying Data with OPENROWSET
Let’s see how to use the OPENROWSET function to query some data from a remote instance of SQL Server Assume there is another instance of SQL Server named
WebSQL You want to query (SELECT) data from the WebSQL.AdventureWorks2008 Sales.SalesOrderHeader table The following statements show a number of variations, all of which would work Pay attention to how the OPENROWSET() function call is placed where you would normally find a table name in a SELECT statement:
Using the 'datasource';'loginname';'password' format
and referencing an object
SELECT * FROM OPENROWSET(
'SQLNCLI',
'WEBSQL';'sa';'P@ssw0rd',
AdventureWorks2008.Sales.SalesOrderHeader);
Using the 'datasource';'loginname';'password' format
and supplying a query
SELECT * FROM OPENROWSET(
'SQLNCLI',
'WEBSQL';'sa';'P@ssw0rd',
'SELECT * FROM AdventureWorks2008.Sales.SalesOrderHeader');
Using the 'provider string' format
and passing a query
SELECT * FROM OPENROWSET(
'SQLNCLI',
'Server=WEBSQL;Trusted_Connection=Yes;Database=AdventureWorks;',
'SELECT * FROM AdventureWorks2008.Sales.SalesOrderHeader');
In the examples where the canonical format is used you see that you can read the credentials used to connect in clear text That is a major security issue
Of course, in the samples above the “sa” account is being used to connect as well, and that is another big no-no It is shown that way in this example to highlight
Exam Warning
Remember that ad hoc queries are disabled by default The administrator has to have enabled them using sp_configure.
Trang 4how much of a security risk these types of queries can be if they are not written
and reviewed carefully
The “provider_string” version of the preceding query was able to use a “Trusted Connection,” but that string can be difficult to configure It requires that the servers
interact properly with Active Directory and takes some configuration by the
Windows administrator to make it work However, once it is properly configured it
is a much more secure and controllable way to connect
EXERCISE 8.4
Using oPENROWSET
In this exercise, you will create a text file with some sample data in it
You will then use the OPENROWSET() function to query data from the
text file from within SQL Server This exercise assumes that you have
administrative privileges on the SQL Server instance you are working
with, that you have the AdventureWorks2008 sample database installed
on your SQL Server instance, and that you are running the wizard from
the same computer where the SQL Server instance is installed You must
have completed Exercise 8.3 to enable ad hoc distributed queries as well.
1 Create a directory off the root of the C: Drive named C:\BCP (if it
doesn’t already exist from before).
2 Using Notepad create a new text file named C:\BCP\Presidents.csv
Enter the following text into the file and save it:
PresidentID,FirstName,LastName
1,George,Washington
2,John,Adams
3,Thomas,Jefferson
3 In a query window in SSMS enter the following query to select
the data from the text file:
SELECT * FROM OPENROWSET (
'MSDASQL',
'Driver={Microsoft Text Driver ( *.txt; *.csv)};
DBQ=c:\bcp;', 'SELECT * from presidents.csv');
4 Try creating some different text files to query from How about
a tab-delimited file?
Trang 5Modifying Data with OPENROWSET
OPENROWSET can be used with INSERT, UPDATE, and DELETE statements
as well Just as you could query data in a remote data source using a SELECT
statement with OPENROWSET, you can also change data in a remote data store
The trick is to place the OPENROWSET(…) function call where the table reference would normally exist
Here is an example of change data in the WebSQL.AdventureWorks.Person Person table:
UPDATE OPENROWSET(
'SQLNCLI',
'Server=WEBSQL;Trusted_Connection=Yes;Database=AdventureWorks;',
AdventureWorks2008.Person.Person)
SET FirstName = 'Ken'
WHERE BusinessEntityID = 1;
We will talk a little more about this in a later section
Copying Data with OPENROWSET
Another powerful thing to do with that is to store the data you query from the external data source as data in your own SQL server instance You can do this with the SELECT…INTO or INSERT…SELECT statements
The following example shows both methods to copy data from the WebSQL AdventureWorks2008.Sales.SalesOrderHeader table to a local table called
AdventureWorks2008.Sales.SalesOrderHeaderCopy:
Create a local table as a result of the copy
SELECT * INTO AdventureWorks2008.Sales.SalesOrderHeaderCopy
FROM OPENROWSET(
'SQLNCLI',
'Server=WebSQL;Trusted_Connection=Yes;Database=AdventureWorks;',
AdventureWorks2008.Sales.SalesOrderHeader);
Insert the selected data into an existing table
INSERT INTO Sales.SalesOrderHeaderCopy
SELECT *
FROM OPENROWSET(
'SQLNCLI',
'Server=WebSQL;Trusted_Connection=Yes;Database=AdventureWorks;',
AdventureWorks2008.Sales.SalesOrderHeader);