How to retrieve a database on the other servers - c#

I want to retrieve a table on a SQL Server database that is located on another server
and I want to store the data retrieved into my own SQL Server database.
How do I can do that?
Thanks so much

one of the easiest and best method i found in this article this might be resolve your issue easily
SQL SERVER – 2008 – Copy Database With Data – Generate T-SQL For Inserting Data From One Table to Another Table

One of the fastest method if you have a lot of data is a tool called bcp.
It allows you to export and import data to a file. So you can export from the source database and then import to the target. It is very fast.

If your destination is a SQL 2008 database and you're set on using C# to connect to the source and get the data you could use a Table parameter. A DataTable in .NET is directly mappable to a User Defined Table type in SQL Server.
Here is a SO thread about it:
How to pass User Defined Table Type as Stored Procedured parameter in C#
Define your custom table type in your destination database
create type MyCustomTable as Table
(
Field1 int,
Field2 varchar(50),
Field3 decimal(18,0)
)
The concept would be to read all of the data from the source in to a data table. Then you would use a SqlParameter to execute a stored procedure or possibly text query on your destination server. By using a stored procedure that accepts a table parameter you could do the following:
CREATE PROCEDURE dbo.BulkCopyData
(
#SourceData MyCustomTable readonly --readonly has to be there, Table params have to be readonly as parameters
) AS
BEGIN
INSERT INTO dbo.DestinationTable
(
Field1,
Field2,
Field3
--more fields
)
SELECT Field1,Field2,Field3 FROM #SourceData
END
And in C# when you go to execute the command:
DataTable dt = new DataTable(); //Go get the data from your source here
SqlConnection conn = new SqlConnection("....");
conn.Open();
SqlCommand cmd = new SqlCommand("dbo.BulkCopyData",conn)
cmd.Parameters.Add( new SqlParameter("SourceData", SqlDbType.Structured){ TypeName = "dbo.MyCustomTable ", Value = dt});
cmd.Parameters[0].
cmd.ExecuteNonQuery();

You can use also openrowset function on SQL and call/query the remote server using your SQL code. This feature is not enabled by defauld (you must use the SP_CONFIGURE stored procedure and enable the remote queries to use this functionality). Here is a link with some examples.
http://msdn.microsoft.com/en-us/library/ms190312.aspx
When you need to know how to set up the configuration just let me know ;)

Connect to your DB using SQL Server management Studio
Go to Server Objects ->Add a new Linked Server
then you can use the other table as select * from LinkedServerName.DBName.dbo.TableName

Related

How to create a stored procedure with dynamically created IN set

I have some SQL that I am converting to stored procedures via blind requirement/request. There is a bit of SQL in the application I'm looking at that builds the where clause with a dynamic IN (set) statement. I have searched for dynamic stored procedure but nothing close to what I'm looking for has come up for me. Here is a sample of the WHERE clause:
WHERE Var.A = #Param AND Var.Id IN
From here the SQL is built manually using a string builder and then executed. Not sure how I'd convert this into a stored procedure as I'm fairly new to them.
We are using C# and SQL Server
You could use an user-defined data type.
On the C# side it would look like this:
//Setup a DataTable with the same structure as the SQL Type
var data = new DataTable();
data.Columns.Add("value", typeof(string));
//Populate the table
data.Rows.Add("oneID");
data.Rows.Add("anotherID");
//You create your sql command
cmd.Parameters.Add("#listArgument", data);
//Command execution
On the SQL side you could have a type like this
CREATE TYPE [dbo].[NVarCharTable] AS TABLE (
[value] NVARCHAR(MAX) NOT NULL);
And then the Stored procedure:
CREATE PROCEDURE [dbo].[MyProc]
#listArgument NVarCharTable READONLY
AS
BEGIN
SELECT *
FROM FOO
WHERE Var.Id IN (Select [value] FROM #listArgument)
END
Reference: https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/sql/table-valued-parameters
If you are using SQl SERVER 2016 or above you can use the string_split function to convert the csv params into table and then use it in your IN list
e.g.
SELECT * FROM TBL WHERE Var.A = #Param AND Var.Id IN (SELECT value FROM STRING_SPLIT(#inlist, ','))
Hope this helps
To piggy back off of #lostmylogin, you can pass in a parameter delimited and use one of these SQL functions to parse it into a table:
http://sqlservercentral.com/scripts/SUBSTRING/124330
or
http://sqlservercentral.com/scripts/Miscellaneous/31913

Determine SQL Server query (stored procedure) result type

I am planning to organize my data in SQL Server as a small orm of my own, creating classes of meta data on each in my code.
For the tests I am hard-coding the objects, the next step is to generate the properties of each using SQL Server queries about those objects.
And now that I deal with the stored procedures section of my code in C#,
I was wondering how it is possible to somehow use SQL Server to query the result type of the command executed?
For example, here we know what it's doing even by reading its name ...
[dbo].[GtallDrLFilesCount]
but another could select some other type of return such as rowset string etc'
Using the above stored procedure will return an int :
if(#AllDrives=1) Begin
Select
* From [dbo].[HddFolderFiles]
End
but the next (above) selects all content rather the RowsCount
I was planning to access SQL Server and query it's objects, and as I do not plan to set return parameter (OUT), is there a more elegant way to achieve it, rather than parsing the .sql file of the stored procedure?
Like if text contains SELECT * (this is a rowset) expect it with DataTable
if text contains Select COUNT(*) (this is int) prepare int type variable.
I thought in the case I did not assign an out parameter to my stored procedures can SQL Server tell the return type somehow even though it has no out parameter to make it easy for it?
I think you would have to execute the SProc to get it's columns, but you could do it without actually returing data using set fmtonly
Even sprocs that return a single value (eg - int) return a table when you use c# ... so you just need to take a look at the reader's Columns to get the data you want.
So:
set fmtonly on
exec [dbo].[MyStoredProc] 0
set fmtonly off
Will return a recordset which you can examine in c#
var adoCon = new System.Data.SqlClient.SqlConnection(_sConnectStr);
var adoCmd = new System.Data.SqlClient.SqlCommand("your SQL (above)", adoCon);
var Rows = adoCmd.ExecuteReader();
DataTable dtSchema = Rows.GetSchemaTable();
Now - you can wander through dtSchema to get columns. It's not pure SQL, but it's a c# + SQL approach. [dbo].[GtallDrLFilesCount] will return a single column table (column of type int).
Obviously - use a SQL command (not string). The next trick is translating SQL types into native c# types (easy for some data types and tricky for others ... take a look at ADOCommand's ReturnProviderSpecificTypes option).
Hope that helps!
From SQL Server 2012+ you can use sys.dm_exec_describe_first_result_set to read metadata about resultset:
This dynamic management function takes a Transact-SQL statement as a
parameter and describes the metadata of the first result set for the
statement.
SELECT *
FROM sys.dm_exec_describe_first_result_set(
N'EXEC [dbo].[MyProcedure]', NULL, 0);
SELECT *
FROM sys.dm_exec_describe_first_result_set(
N'SELECT * FROM [dbo].[tab]', NULL, 0);
SqlFiddleDemo
This method has limitation for more info read Remarks section

populating gridview from stored procedure which inside #tempTable

I have a project with c# and Microsoft SQL Server, I want to populate my gridview with a stored procedure.
this procedure has a table declaration in it ( I need this #temptable for get some data from another database with opendatasource).
It is OK in SQL Server Management Studio but it doesn't populate my gridview(in c# project) when my procedure has a deceleration of a #tempTable (even I don't use it table).
how can I use #tempTable in procedure to use it in gridview?
p.s. I also tried #tmp, #tmp, ##tmp tables as well.
The simple answer is that unless the temporary table is created and left resident within the database, you can't connect to it as you would a normal table. #temptable is a local reference.
If you know the table definition though you could setup an appropriate data object; pass back all rows of the temporary table from the procedure; store the results in a collection of your data object and make that collection the datasource for your grid.
This would mean that you couldn'y use any drag and drop functionality from Server Explorer, but would need to code your own SQL command to retrieve that data and populate the collection.
the problem coused about type of connection. it was oledbconnetion and I changed it to sqlconnection, now I can use table variables in a stored procedure to select it in a grid

Import DataSet into SQL Server 2008 Express

I have a very large DataSet containing about 160.000 records. If I loop trough the dataset and import every record, it can take about 20 minutes before the complete dataset is imported into the SQL Server.
Isn't there a faster way for importing the dataset at once in the database?
The dataset is created from a file I process which the user provides, then I have 1 table called lets say "ImportTable" containing about 14 columns. The columns correspond with the columns in the DataSet.
I use Visual Studio 2010 professional with c#.
Thanks in advance!
You should take a close look at the SqlBulkCopy class.
It's a C# component (no external app), it takes a DataSet or DataTable as input, and copies that into SQL Server in a bulk fashion. Should be significantly faster than doing a row-by-agonizing-row (RBAR) insert operation...
Better yet: you don't even need to import your entire data set into memory - you can define a SqlDataReader on your base data, and pass that to SqlBulkCopy to read from the SqlDataReader and bulk insert into SQL Server.
You may want to take a look at the bcp command line utility. It lets you load data directly from a file into a table in the database. Depending on how the user generated file looks, you may need to re-format it, but if it has a simple delimited format you can probably use it as-is with bcp.
You can use make dataset xml using DataSet.getXml function. and pass input paremeter for SP.
for example
Create PROCEDURE dbo.MyInsertSP
(
#strXML varchar(1000)
)
AS
Begin
Insert into publishers
Select * from OpenXml(#intPointer,'/root/publisher',2)
With (pub_id char(4), pub_name varchar(40), city varchar(20),
state char(2),9) country varchar(20))
exec sp_xml_removedocument #intPointer
RETURN
End
Hope this make sense.

How to duplicate a SQL Server 2000 table programatically using .NET 2.0?

I want to backup a table saving the copy in the same database with another name. I want to do it programatically using .NET 2.0 (preferably C#). Someone can point me what should I do?
Just send this query to the server:
SELECT * INTO [BackupTable] FROM [OriginalTable]
This will create the backup table from scratch (an error will be thrown if it already exists). For large tables be prepared for it to take a while. This should mimic datatypes, collation, and NULLness (NULL or NOT NULL), but will not copy indexes, keys, or similar constraints.
If you need help sending sql queries to the database, that's a different issue.
One way to do this would be to simply execute a normal query this way using INTO in SQL:
SELECT *
INTO NewTableName
FROM ExistingTableName
This automatically creates a new table and inserts the rows of the old one.
Another way would be to use SqlBulkCopy from the System.Data.SqlClient namespace. There is a nice CodeProject article explaining how to do this:
SQL Bulk Copy with C#.Net
Programmers usually need to transfer
production data for testing or
analyzing. The simplest way to copy
lots of data from any resources to SQL
Server is BulkCopying. .NET Framework
2.0 contains a class in ADO.NET "System.Data.SqlClient" namespace:
SqlBulkCopy. The bulk copy operation
usually has two separated phases.
In the first phase you get the source
data. The source could be various data
platforms such as Access, Excel, SQL..
You must get the source data in your
code wrapping it in a DataTable, or
any DataReader class which implements
IDataReader. After that, in the second
phase, you must connect the target SQL
Database and perform the bulk copy
operation.
The bulk copy operation in .Net is a
very fast way to copy large amount of
data somewhere to SQL Server. The
reason for that is the Bulkcopy Sql
Server mechanism. Inserting all data
row by row, one after the other is a
very time and system resources
consuming. But the bulkcopy mechanism
process all data at once. So the data
inserting becomes very fast.
The code is pretty straightforward:
// Establishing connection
SqlConnectionStringBuilder cb = new SqlConnectionStringBuilder();
cb.DataSource = "SQLProduction";
cb.InitialCatalog = "Sales";
cb.IntegratedSecurity = true;
SqlConnection cnn = new SqlConnection(cb.ConnectionString);
// Getting source data
SqlCommand cmd = new SqlCommand("SELECT * FROM PendingOrders",cnn);
cnn.Open();
SqlDataReader rdr = cmd.ExecuteReader();
// Initializing an SqlBulkCopy object
SqlBulkCopy sbc = new SqlBulkCopy("server=.;database=ProductionTest;" +
"Integrated Security=SSPI");
// Copying data to destination
sbc.DestinationTableName = "Temp";
sbc.WriteToServer(rdr);
// Closing connection and the others
sbc.Close();
rdr.Close();
cnn.Close();
You could use the SQL Server Management Objects (SMO). You could make a copy of a database (data and schema). There are a lot of options you can set. The following example copies the entire database:
// Connect to the server
Server server = new Server(".");
// Get the database to copy
Database db = server.Databases["MyDatabase"];
// Set options
Transfer transfer = new Transfer(db);
transfer.CopyAllObjects = true;
transfer.DropDestinationObjectsFirst = true;
transfer.CopySchema = true;
transfer.CopyData = true;
transfer.DestinationServer = ".";
transfer.DestinationDatabase = "MyBackupDatabase";
transfer.Options.IncludeIfNotExists = true;
// Transfer Schema and Data
transfer.TransferData();
You can find the documentation of the Transfer Class on MSDN.
Depending on how many records in the table this could be a very bad idea to do from C# and the user interface.
For a small table
use the following SQL
Create table table2 (field1 int, field2 varchar(10)) --use the actual field names and datatypes of course)
insert into table2 (field1, field2)
select field1, field2 from table1
I suggest the create table to create it once and then the insert so that you can add records to the table multiple times. Select into only will work once.
At the very least, you could do "SELECT * INTO NEWTable FROM OldTable".
Do you want to create all the indexes/constraints etc?
EDIT: Adding to splattne's comments, you will have to get the handle to Table instance of the table you wish to copy. Use the Script method to get the script it will generate. Modify the script string to replace old names with new names & run it on the DB.
EDIT2: http://msdn.microsoft.com/en-us/library/microsoft.sqlserver.management.smo.table.table.aspx
http://msdn.microsoft.com/en-us/library/microsoft.sqlserver.management.smo.tableviewtabletypebase.script.aspx

Categories

Resources