SqlBulkCopy to temporary table in SqlServer 2008 - c#

i need to move a large amount of data to a sql server 2008 database. I get data from a source server and write using SqlBulkCopy to destination server. this data have to be parsed from a stored procedure and then deleted. I'd like to create a temporary data but, if i create the temp data on the client using SqlCommand the SqlBulkCopy can access the table and works fine, if i execute the same script on the server with a Stored Procedure the SqlBulkCopy.WriteToServer returns the InvalidOperationException "Cannot access destination table '#Tax'"
this is the code perfectly working:
SqlDataReader oSqlDataReader -> read form server source
SqlConnection oSqlConnection = new SqlConnection(_ConnectionTarget)
SqlCommand oSqlCommand = new SqlCommand("Create Table #Tax (Id int)", oSqlConnection);
oSqlCommand.CommandType = CommandType.Text;
oSqlCommand.CommandTimeout = 0;
oSqlCommand.ExecuteNonQuery();
SqlBulkCopy oSqlBulkCopy = new SqlBulkCopy(oSqlConnection)
oSqlBulkCopy.DestinationTableName = "#Tax";
oSqlBulkCopy.WriteToServer(oSqlDataReader);
this is the code throwing the InvalidOperationException exception:
SqlDataReader oSqlDataReader -> read form server a
SqlConnection oSqlConnection = new SqlConnection(_ConnectionTarget)
SqlCommand oSqlCommand = new SqlCommand("SP_CreateTax", oSqlConnection);
oSqlCommand.CommandType = CommandType.StoredProcedure;
oSqlCommand.CommandTimeout = 0;
oSqlCommand.ExecuteNonQuery();
SqlBulkCopy oSqlBulkCopy = new SqlBulkCopy(oSqlConnection)
oSqlBulkCopy.DestinationTableName = "#Tax";
oSqlBulkCopy.WriteToServer(oSqlDataReader);
SP_CreateTax:
Create Procedure SP_CreateTax
AS
Begin
Create Table #Tax (Id int)
End

The problem is that the temp table created in your stored procedure is only valid within the scope of that stored proc. Once it's done, the temp table is dropped.
Create the temp table the way you have (the way it works) via the inline sql and move on.

It seems that your stored procedure isn't executed and then your temporary table isn't created.
The reason is this:
SqlCommand oSqlCommand = new SqlCommand("SP_CreateTax", oSqlConnection);
Your stored procedure isn't executed, because to execute a procedure, you have to invoke: EXEC SP_CreateTax.
Note: It's not suggested to create stored procedures named with SP, because the names of reserved system stored procedures of SQL Server start with SP. For this reason, the names of custom stored procedures must be distinguished from the system ones, naming them, for example, as uSP_CreateTax.

Related

Timeout error in running a multi-server SQL Server query

I defined a linked server to a remote server in my local SQL Server.
I run a query in join of local and remote servers as below:
SELECT *
FROM [RemteServer].[RemoteDB].[dbo].[Links]
WHERE Id NOT IN
(
SELECT ExternalId
FROM [dbo].[Links]
)
When I run this query on SQL Server Management Studio, It executes during 2 minutes, but when I run it on a C# program on my local machine connected to local SQL Server it produces timeout error.
I set connect timeout on C# connection string to 600. also I set Connection timeout and Query timeout on Linked Server properties to 600.
How can I prevent timeout error?
P.S: SQL server version is 2008. I use Visual Studio 2015 and use ADO connection on VS.
My recommendation would be to migrate the bulk of this query onto the SQL Server, and use a stored procedure to do the work.
SQL Server
CREATE PROCEDURE dbo.lsp_GetRemoteLinks
AS
BEGIN
IF OBJECT_ID('tempdb..#RemoteLinks') IS NOT NULL DROP TABLE #RemoteLinks
SELECT *
INTO #RemoteLinks
FROM [RemteServer].[RemoteDB].[dbo].[Links]
SELECT *
FROM #RemoteLinks
WHERE (Id NOT IN (SELECT ExternalId FROM [dbo].[Links] ))
DROP TABLE #RemoteLinks
END
GO
C#
DataTable RemoteLinks = new DataTable();
using (SqlConnection conn = new SqlConnection(strConn)) {
conn.Open();
using (SqlCommand cmd = new SqlCommand("lsp_GetRemoteLinks", conn)) {
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = 120;
RemoteLinks.Load(cmd.ExecuteReader());
}
conn.Close();
}
This should cut your times down, but I did put increase the CommandTimeout value.
If this data did not need to be "live" with it's freshness I would consider making a permanent local table and use SQL Agent to re-populate it at regular intervals, and then you would be able to use Indexes on the table to improve efficiency further.
Your performance on this query is not ideal because you are essentially trying to read every record from the Linked server onto your Local server where the query is being executed. If you can filter the results by adding a WHERE clause that will be executed on the remote server, your performance will significantly improve.
DECLARE #ExtLinks TABLE (Id INT)
INSERT INTO #ExtLinks (Id)
SELECT ID
FROM [RemteServer].[RemoteDB].[dbo].[Links]
--WHERE Princess = 'Zelda'
SELECT * FROM #ExtLinks
WHERE Id NOT IN
(
SELECT ExternalId
FROM [dbo].[Links]
)

Select record from multiple database

I'm using Microsoft SQL Server 2008 R2 and asp.net for C#.
Currently I'm doing an intranet. It consists of many modules inside intranet. Each module uses its own database. Normally I will using connection string for calling to the database.
I plan to do a main page to manage all pending tasks inside each module. Means on the main page, I will show all the pending tasks of all modules. Since they are all using different connection strings, what approaches can be used to achieve this?
The example below show how I access database through single connection string:
string connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
string strsql = " select * from User ";
SqlConnection con = new SqlConnection(connectionString);
SqlDataAdapter da = new SqlDataAdapter(strsql, connectionString);
con.Open();
DataSet ds = new DataSet();
da.Fill(ds);
con.Close();
con.Dispose();
Create a proc where you can call table of different database with respective Db names.
create proc proc_name
as begin
select * from [DB_name1].dbo.tablename
union all
select * from [DB_name2].dbo.tablename
end
now call the proc from your code behind.
No matter what ever db name in your connection string,still you can access
Note: check your DB has rights to access other DB.

invalid object name sql exception for table name in c#

I wrote this code, but it doesn't work. Gives Invalid object name 'Inventory'`. Any Suggestion?
using (SqlConnection cn = new SqlConnection())
{
cn.ConnectionString =
#"Data Source=(local);Integrated Security=SSPI;" +
"Initial Catalog=AutoLot";
cn.Open();
string strSQL = "Select * From Inventory";
SqlCommand myCommand = new SqlCommand(strSQL, cn);
// Obtain a data reader a la ExecuteReader().
using (SqlDataReader mydatareader = mycommand.ExecuteReader())
{}
Check in Database Inventory table is present or not and if Present then both name should be same
If you've checked all your database settings, access rights and table definitions and still cannot get rid of that error?
It's because ASP.net cannot understand your SQL query - as shocking as that may sound.
I had the same problem, with UPDATE statements wanting to use aliases and not the usually expected dbo.myTable name definitions.
The simplest way to avoid this situation, where asp.net just doesn't parse SQL like SQL Server would (!!), is to place the code into a Stored Procedure.
This was my SQL directly from SQL Server 2005 and it worked perfectly as is...
UPDATE tsa
SET tsa.ActionComplete = #ActionComplete,
tsa.CompleteDate = GETDATE(),
tsa.Notes = #ActionNotes
FROM blahblah
WHERE blahblah
But for what ever reason, the ASP.net parser inside the SqlDataSource control could not make sense of it (even though it ran perfectly inside the GUI's Test Query feature!).
I was getting
invalid object name in 'tsa'
So I placed the lot inside a Stored Procedure...
USE [mydatabase];
GO
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
ALTER PROCEDURE [dbo].[spTETupdateActions]
#StudentID VARCHAR(10),
#ActionComplete INT = 0,
#ActionNotes VARCHAR(MAX),
#TETmeetingID INT,
#WeekNo INT,
#TETID INT,
#TETdate DATETIME,
#ActionItem VARCHAR(MAX)
WITH
EXEC AS CALLER AS
UPDATE tsa
SET tsa.ActionComplete = #ActionComplete,
tsa.CompleteDate = GETDATE(),
tsa.Notes = #ActionNotes
FROM blahblah
WHERE blahblah
GO
And voila! No more errors! Why? Because the parsing of the SQL is done inside SQL Server not ASP.net!

Copy a whole table from a SQL Server CE database to another

I'm developing a C# application and I want to copy a whole table from a SQL Server CE database to another programmatically. I know I can use this command in SQL Server, but I'm not sure how to use two database connections in one query in C#.
Select * into DestinationDB.dbo.tableName from SourceDB.dbo.SourceTable
Thanks in advance.
You wouldn't do it the same way as in SQL Server because there's no single server that manages both databases. Your app is the only thing that links the two databases so the the data has to go through your app. You're trying to do it the wrong way and that's why you can't find a solution: you're looking for the wrong thing.
There are examples of this out there. I know, because I've written more than one myself. You simply need to use a data adapter to populate a DataTable from the first database and then a data adapter to save the contents of that DataTable to the second database. If the data sources are the same type then you can even use just one data adapter because the SelectCommand and InsertCommand can have different connections.
using (var adapter = new SqlDataAdapter("SELECT statement here", "source connection string here"))
using (var destinationConnection = new SqlConnection("destination connection string here"))
using (var insertCommand = new SqlCommand("INSERT statement here", destinationConnection))
{
// Add parameters to insertCommand here.
adapter.InsertCommand = insertCommand;
// Leave the RowState of all DataRows as Added so they are ready to be inserted.
adapter.AcceptChangesDuringFill = false;
var table = new DataTable();
// Retrieve data from source and save to destination.
adapter.Fill(table);
adapter.Update(table);
}
That example uses SqlClient but it works the same for any provider, including SqlServerCe.

executing Oracle stored procedures using ADO (c#)

Im trying to call a Oracle stored proc from a C# application using the following code
Connection conn = new Connection();
Recordset rs = new Recordset();
conn.Open("Provider=MSDAORA;User Id=username;Password=password;Data Source=DB;", null, null, 0); ;
rs.Open("sproc 'abc', 'xyz'", conn, ADODB.CursorTypeEnum.adOpenStatic, ADODB.LockTypeEnum.adLockReadOnly, -1);
where abc and xyz are input parameters..
However, I get "invalid SQL statement exception" when I try to run it..
Is there any other way to execute a oracle stored proc. I can execute MSSQL stored procs or normal Oracle queries in the same way described above..
I even tried using createparameter, but that didn't help either
Thanks,
Sam
Grab the Oracle ODP.NET tools: http://www.oracle.com/technology/software/tech/windows/odpnet/index.html
They are what I use to interact with our Oracle database from my ASP.NET application
Check here for an example of calling an Oracle stored procedure in C#.
Basically, with the package:
// Create oracle command object for the stored procedure
OracleCommand cmd = new OracleCommand("HR_DATA.GETCURSORS", conn);
cmd.CommandType = CommandType.StoredProcedure;
// Enter a parameter for the procedure
OracleParameter dep_id = new OracleParameter();
dep_id.OracleDbType = OracleDbType.Decimal;
dep_id.Direction = ParameterDirection.Input;
dep_id.Value = 60;
cmd.Parameters.Add(dep_id);
// Add more parameters ...
// Execute the stored procedure
Here's a link to the API documentation
Nevermind.. Apparently I was missing brackets around input parameters...
Thanks,
Sam

Categories