How to select rows inside a CLR stored procedure in MS SQL Server 2008? - sql

Following along with an example I found on the internet, I wrote the following C# code that implements a CLR stored procedure in MS SQL Server 2008:
public class Class1
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void CountStringLength(string inputString)
{
SqlContext.Pipe.Send(inputString.Length.ToString());
}
}
This procedure takes a string as a parameter and outputs the number of characters in the string.
I have been working on some code that retrieves data from SQL; there's nothing special about the way the data is retrieved: it makes a connection to the SQL server, selects the data, and then closes the connection. I want to make this code run inside a stored procedure or trigger on my SQL server.
I suppose that I could make the code run exactly the same as the existing SQL code: make a connection to the SQL server, select the data, and then close the connection. However, this doesn't make sense once the code is running on the SQL server itself! Why would I want code that runs on the SQL server make the server connect to itself?!?!
Is there a best practice for what I'm trying to do? Can I select rows in my code using the same connection that is used to execute the stored procedure?

I found the answer explained here: http://technet.microsoft.com/en-us/library/ms131053.aspx
The connection that the CLR procedure runs from is called the "Context Connection" and it is used like this:
using(SqlConnection connection = new SqlConnection("context connection=true"))
{
connection.Open();
// Use the connection
}
I wonder why you have to "open" the connection? I would think that the connection is already open since it is executing the procedure that is running.
Also closely related: http://msdn.microsoft.com/en-us/library/938d9dz2(v=vs.90).aspx

Related

SSIS Oracle connection string as project parameter is not being replaced at runtime

We move data from Oracle 11 to SQL 2014 using SSIS project deployment model. We use Attunity 3.0 connector.
Connection string to oracle data source is a project parameter and is also stored in a table in SQL.
We use custom stored procedure that
Gets this connection string stored in the sql table
sets project parameters (via [SSISDB].[catalog].[set_execution_parameter_value] )
executes packages (via [SSISDB].[catalog].[start_execution] )
We use [SSISDB].[internal].[execution_parameter_values] to check that parameter values are being replaced during run time with the connection string we stored in the backend.
What's interesting is that, even though Oracle connection string is being replaced during runtime, the package still tries to use the connection string it has been complied with(Project Params). We do not have the same issue when connecting to a SQL Source in a similar fashion.
Do you have any suggestions? Is it a known issue?
Found the solution. Turns out that the oracle connection string that we stored in the table did not prefix the server name with "SERVER = ". The connection string would straight away start with For Eg - 'x1abc01.something.com:1234/x1abc01;ORACLEHOME=;ORACLEHOME64=;WINAUTH=0;'. Changed the connection string to 'SERVER = x1abc01.something.com:1234/x1abc01;ORACLEHOME=;ORACLEHOME64=;WINAUTH=0;' and it started working now. We tested it by deploying the ssis solution with one connection string and changing it with a different connection string from the database and the overwritten value persists.
However, its still bizarre where the disconnect happens when the run time connection string has an invalid value and its not reported out as an error and ssis quietly switches to design time value in Project Param.

Use of database name in connection string

What is the use of mentioning the database name in connection string while opening a connection from dot net application to SQL server? Because even though we mention a database name in connection string we have to explicitly write the fully qualified name (DBName.schemaName.ProcName) while calling a stored procedure if the default DB is different for that particular user.
Connecting to database from a .NET application is different from accessing a table of different database.
use of mentioning the database name in connection string
so for instance you can use connection string below to connect to myDB at MyServer
Data Source=MyServer;Initial Catalog=myDB;Integrated Security=True
if you will not specify at least these information how your .NET application can connect to a stored procedure (MyProcInMyDB) located in myDB.
Now for part you asked
though we mention a database name while calling a stored procedure if
the default DB is different for that particular user
this is not a normal case to access stored procedure of another database using same connection string if it is a very special case (not likely) then you will do it for calling one or two stored procedures. But if it is required quite often within your application then you should create a separate connection string. Using same connection string and calling like
command.CommandText = "myDB2.dbo.getList"
can result is difficult maintenance and flexibility

For a Front end access user interface connected to a backend SQL server, do I create new queries for tables in the SQL server or Access frontend?

I am a new database intern working with a access front end and SQL server backend database. The database was custom made for the company. One of my assignments is to take scripts and apply them to make four new tables. I am aware that I need to make a new query for each new table but I don't know if I should make the query in SQL server management studio or the frontend access program. I have tried copying and pasting the given scripts into a new query in access but I get an error message "invalid SQL statement expected 'DELETE', 'INSERT'...". I decided to try to break done the program a little bit and tested the first line
IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id =OBJECT_ID(N'[dbo] .[FK_tblInstrumentInterfaceLog_tlkpInstrument]') AND parent_object_id = OBJECT_ID(N'[dbo].[tblInstrumentInterfaceLog]'))
but the same error message keeps popping up. I even tried just SELECT * FROM sys.foreign_keys, and I got the error message "could not find file...". I am very much a beginner and any guidance would be appreciated.Basically am I supposed to be applying these scripts the server SQL database or on the front end access program?
Are you using a pass-through query? i.e. not just a select query. Access needs to know where to send the query and since you are using TSQL not Access SQL this needs to be executed on the server.
Normally when you query a linked table the information of how to get the data (the connection string) is tied to the table. But for this kind of query you'll probably need to tell Access explicitly. Unless you are using an ADP/ADE, then the connection info travels with the program not the table.
As a general rule, you use SQL management studio (SSMS) to create and run those scripts. So the general accepted approach here is such scripts will not be placed in the front end. As noted such scripts if for some reason must be placed in the front end, then you have to create them as pass-though, but EVEN in this case you want to use the SSMS to create such quires.
So the answer here is you create the new scripts and make table queries in the back end, or in this case using the SQL server management studio.
The syntax checking, query editor etc. in recent versions of SSMS now has auto-complete etc. and you can test/write/update those scripts in SQL server. Once you have such a query or even several of them, then the resulting “several” statements can be pasted into a front end query that been created as pass-though. If you do not use a pass-though query, then you are creating and using and assuming client side SQL (JET (now called ACE)).
The client side has it own version of SQL syntax, and it is NOT 100% compatible with the SERVER SIDE. If you writing SQL in the client that is NOT pass though, then you using a linked table to SQL server. These linked tables thus will use local (JET/ACE) based SQL queries. The ODBC driver thus translates this SQL into server side compatible syntax. However the JET/ACE sql syntax is very limited when compared to SQL server and no server side commands exist in this SQL syntax for the client data engine (JET/ACE)
So for many quires, you will and can simply build such queries using the Access query builder.
However for SQL that needs to run 100% server side then such quires has to be setup as pass-though and are in most cased built + tested using SSMS.

SQL server - execute scalar function without specifing db name

I have a user defined SQL function that I am able to call from management studio using syntax dbo.Function(arg)
Now, when I have to call this function from C# if I don't specify **dbname**.dbo.Function(arg) I get an error that SQL server does not find this user defined function. How can I solve this without specifing dbname ? I already connect to the server using a connection string that specifies the "initial catalog = dbname"
It seems that I cannot reproduce mentioned behavior at this point :-) (either using SQL server 2005 or 2008) I have to put this question on hold
Your connection string needs to specify the database to use initially. It might look something like this:
var cn = new SqlConnection(
"SERVER=SomeServer;DATABASE=SomeDb;Integrated Security=SSPI;"
);
Without that, you're probably being dumped into the master database, which is why you need to fully qualify the function name.

Call a Sproc on another SQL Server without being linked via TSQL

I want to call a sproc on server B from server A in TSQL without linking the servers. Is it possible to use something like a connection string to execute this sproc? The return will be a single nvarchar value.
Regards.
To avoid "linked servers", you'd normally use OPENDATASOURCE
After comment:
EXEC OPENDATASOURCE('SQLNCLI', 'Data Source=London\Payroll;Integrated Security=SSPI').remoteDB.remoteSchema.remoteProc #param1, #param2,...
Simple 4 part naming convention. The whole OPENDATASOURCE simply replaces the linked server name...
Note: you may have issues with "adhoc access"
i know of no way of doing it without ...
creating an extended stored proc to do it for you
perhaps using xp_cmdshell to use isql to execute your stored proc .. however, getting the result might be tricky (perhaps write the result to a table on your current server in the same sql file that isql is reading)
-don