Transfer data from one SQL Server table to another - sql-server

For example I have one SQL Server database that contains a table
Id Address
1 England,London,someaddress
2 Germany,Berlin,someaddress2
And I have another SQL Server database that contains following table with scheme
Id Country City Address
I need transfer data from first database to second. Like this.
id Country City Address
1 England London someaddress
2 Germany Berlin someaddress2
How can I do that?

You can do that by creating a User Define Function that detect Country , City, Address by Splitting and than insert into second table.
Split Function :
CREATE FUNCTION [dbo].[Split](#String varchar(8000), #Delimiter char(1))
returns #temptable TABLE (id int , items varchar(8000))
as
begin
declare #idx int
declare #id int
declare #slice varchar(8000)
set #id = 1
select #idx = 1
if len(#String)<1 or #String is null return
while #idx!= 0
begin
set #idx = charindex(#Delimiter,#String)
if #idx!=0
set #slice = left(#String,#idx - 1)
else
set #slice = #String
if(len(#slice)>0)
begin
insert into #temptable(id, Items) values( #id , #slice)
set #id = #id + 1
end
set #String = right(#String,len(#String) - #idx)
if len(#String) = 0 break
end
return
end
then use in Insert Query like this :
INSERT INTO NewTbl
SELECT .... ,
(SELECT ITEMS FROM dbo.Split(Address) where id = 1) as Country,
(SELECT ITEMS FROM dbo.Split(Address) where id = 2) as City,
(SELECT ITEMS FROM dbo.Split(Address) where id = 3) as Address,
...

There are a few ways to actually move the data.
1.) Linked Server http://msdn.microsoft.com/en-us/library/ms188279.aspx
2.) OpenRowSet http://msdn.microsoft.com/en-us/library/ms190312.aspx
3.) Replication http://msdn.microsoft.com/en-us/library/ms151198.aspx
Depending on your needs you need to choose the best one for you.
If you want the data from your second database to be accessable in your original databse, in the same way as it's own data, for queries, stored procedures...etc have a look at Linked Servers.
If you want a one off access to data have a look at OpenRowSet.
If you have the same table on both databases and want to keep that data in sync automatically I would look at Replication. You can set up your own replication stored procedures that can perform custom logic, like the split.
You then can impliment the split as noted in the other answer to split your data.

If you want to copy data from one server to another database server .then you must make linked server between them.
and execute like following query.
insert into [127.234.11.50].[cgwssitws].dbo.tbl_ws_hotelier(paramid,hotelid,paramname,paramvalue)
select paramid,hotelid,paramname,paramvalue from [126.32.22.30].[CGWS_Hotel].dbo.tbl_param where hotelid='22'

Related

I am searching for a loop query over multiple databases and insert result into existing table in one database to collect al data

I am searching for a loop query over multiple databases and insert result into existing table in one database to collect al data.
There are 28 existing databases at the moment but when i start the query below it says table already exists at the second database.
when this works i want to loop a much larger query then this.
I also tried executing and union all but if a new database is added it must be collected autmatically.
See example i've tried below:
--drop table if exists [hulptabellen].dbo.HIdatabases
declare #dbList table (dbName varchar(128), indx int)
insert into #dbList
select dbName = dbname, row_number() over (order by dbname)
from [hulptabellen].dbo.HIdatabases
--declare variables for use in the while loop
declare #index int = 1
declare #totalDBs int = (select count(*) from #dbList)
declare #currentDB varchar(128)
declare #cmd varchar(300)
--define the command which will be used on each database.
declare #cmdTemplate varchar(300) =
'
use {dbName};
select * insert into [hulptabellen].dbo.cladrloc from {dbname}.dbo.cladrloc
'
--loop through each database and execute the command
while #index <= #totalDBs
begin
set #currentDB = (select dbName from #dbList where indx = #index)
set #cmd = replace(#cmdTemplate, '{dbName}', #currentDB)
execute(#cmd)
set #index += 1
end
Create the table outside your loop and insert into the table this way:
INSERT INTO [hulptabellen].dbo.cladrloc (col1,col2)
SELECT col1,col2
FROM {dbname}.dbo.cladrloc
FYI: When you use the following syntax, a new table is created, so it can be executed only once.
SELECT *
INTO [hulptabellen].dbo.cladrloc
FROM {dbname}.dbo.cladrloc

How to get and use the value returned by a stored procedure to a INSERT INTO... SELECT... statement

I am just new in SQL language and still studying it. I'm having hard time looking for answer on how can I use the stored procedure and insert value into a table.
I have this stored procedure:
CREATE PROCEDURE TestID
AS
SET NOCOUNT ON;
BEGIN
DECLARE #NewID VARCHAR(30),
#GenID INT,
#BrgyCode VARCHAR(5) = '23548'
SET #GenID = (SELECT TOP (1) NextID
FROM dbo.RandomIDs
WHERE IsUsed = 0
ORDER BY RowNumber)
SET #NewID = #BrgyCode + '-' + CAST(#GenID AS VARCHAR (30))
UPDATE dbo.RandomIDs
SET dbo.RandomIDs.IsUsed = 1
WHERE dbo.RandomIDs.NextID = #GenID
SELECT #NewID
END;
and what I'm trying to do is this:
INSERT INTO dbo.Residents([ResidentID], NewResidentID, [ResLogdate],
...
SELECT
[ResidentID],
EXEC TestID ,
[ResLogdate],
....
FROM
source.dbo.Resident;
There is a table dbo.RandomIDs containing random 6 digit non repeating numbers where I'm pulling out the value via the stored procedure and updating the IsUsed column of the table to 1. I'm transferring data from one database to another database and doing some processing on the data while transferring. Part of the processing is generating a new ID with the required format.
But I can't get it to work Sad I've been searching the net for hours now but I'm not getting the information that I need and that the reason for my writing. I hope someone could help me with this.
Thanks,
Darren
your question is little bit confusing, because you have not explained what you want to do. As i got your question, you want to fetch random id from randomids table and after performed some processing on nextid you want to insert it into resident table [newresidentid] and end of the procedure you fetch data from resident table. if i get anything wrong feel free to ask me.
your procedure solution is following.
CREATE PROCEDURE [TestId]
AS
SET NOCOUNT ON;
BEGIN
DECLARE #NEWID NVARCHAR(30)
DECLARE #GENID BIGINT
DECLARE #BRGYCODE VARCHAR(5) = '23548'
DECLARE #COUNT INTEGER
DECLARE #ERR NVARCHAR(20) = 'NO IDS IN RANDOM ID'
SET #COUNT = (SELECT COUNT(NEXTID) FROM RandomIds WHERE [IsUsed] = 0)
SET #GENID = (SELECT TOP(1) [NEXTID] FROM RandomIds WHERE [IsUsed] = 0 ORDER BY [ID] ASC)
--SELECT #GENID AS ID
IF #COUNT = 0
BEGIN
SELECT #ERR AS ERROR
END
ELSE
BEGIN
SET #NEWID = #BRGYCODE + '-' + CAST(#GENID AS varchar(30))
UPDATE RandomIds SET [IsUsed] = 1 WHERE [NextId] = #GENID
INSERT INTO Residents ([NewResidentId] , [ResLogDate] ) VALUES (#NEWID , GETDATE())
SELECT * FROM Residents
END
END
this procedure will fetch data from your randomids table and perform some processing on nextid than after it directs insert it into resident table and if you want to insert some data through user you can use parameter after declaring procedure name
E.G
CREATE PROCEDURE [TESTID]
#PARAM1 DATATYPE,
#PARAM2 DATATYPE
AS
BEGIN
END
I'm not convinced that your requirement is a good one but here is a way to do it.
Bear in mind that concurrent sessions will not be able to read your update until it is committed so you have to kind of "lock" the update so you will get a block until you're going to commit or rollback. This is rubbish for concurrency, but that's a side effect of this requirement.
declare #cap table ( capturedValue int);
declare #GENID int;
update top (1) RandomIds set IsUsed=1
output inserted.NextID into #cap
where IsUsed=0;
set #GENID =(select max( capturedValue) from #cap )
A better way would be to use an IDENTITY or SEQUENCE to solve your problem. This would leave gaps but help concurrency.

Passing SSRS Dataset Parameters on the fly

I have a SSRS 2008 tabular report with a drill down group by. The group by is the AssignedAnalystId. In the Database and server only the AssignedAnalystId is available. I have another database on another server that has the table with the mapping between the AssignedAnalystId and there actual name (Full User Name).
What I want to do is to be able to pass in the AssignedAnalystId on the fly to the other dataset as if it were a scalar function and get the full username to show in the group instead of the AssignedAnalystId. Is there a way to do this?
Ideally, you would want to join the tables in your initial query, but you can have two separate datasets in your report and use the Lookup function to do what you need. The Lookup function takes 4 parameters; in your case you would fill in: ID field from the 1st dataset, ID field from the second dataset, username field from the second dataset, the name of the dataset. See the MSDN article for more info: http://msdn.microsoft.com/en-us/library/ee210531.aspx
A good way to filter your data is to use a Split function. Set your SSRS parameter to be comma separated values or even multi-valued and then you can use the table-valued function below to turn it into a temp table for use in your query:
CREATE FUNCTION Split (#origString varchar(max))
returns #temptable TABLE (items varchar(max))
as
begin
declare #idx int
declare #split varchar(max)
set #idx = 1
if datalength(#origString )<1 or #origString is null
return
while #idx <> 0
begin
set #idx = charindex(',', #origString)
if #idx <> 0
set #split = left(#origString, #idx - 1)
else
set #split = #origString
if(datalength(#split) > 0)
insert into #temptable(Items) values(ltrim(rtrim(#split)))
set #origString = right(#origString, datalength(#origString) - #idx)
if datalength(#origString) = 0
break
end
return
end
Then your query could would include something like this to act as a filter:
SELECT *
FROM Table1 as T1
INNER JOIN Split(#SSRScsvParameter) as T2 on T1.ID = T2.ID

Can I send array of parameter to store procedure?

I have User table, it has UserId uniqueidentifier, Name varchar and IsActive bit.
I want to create store procedure to set IsActive to false for many user, for example, if I want to deactive 2 users, I want to send Guid of those users to store procedure (prefer as array). I want to know how can I do it?
P.S. I'm working on Microsoft SQL Azure
Along the same lines than Elian, take a look at XML parameters. Generally speaking you should have a cleaner/safer implementation using xml than parsing a list of strings. Click here for a code example
Here is a solution I used a while ago and that was working fine.
Send the list of guid you want to deactive merged into a comma separated string to the sp.
Then in the sp, you first convert this string into a table thanks to a table-valued function.
Here is a sample with bigint, but you can easily modify it so that it works with guid
Step 1 : the table-valued function
CREATE FUNCTION [dbo].[BigIntListToTable] (
#list VARCHAR(max)
)
RETURNS
#tbl TABLE
(
nval BIGINT NOT NULL
) AS
BEGIN
DECLARE #nPos INT
DECLARE #nNextPos INT
DECLARE #nLen INT
SELECT #nPos = 0, #nNextPos = 1
WHILE #nNextPos > 0
BEGIN
SELECT #nNextPos = CHARINDEX(',', #list, #nPos + 1)
SELECT #nLen = CASE WHEN #nNextPos > 0
THEN #nNextPos
ELSE LEN(#list) + 1
END - #nPos - 1
INSERT #tbl (nval)
VALUES (CONVERT(BIGINT, SUBSTRING(#list, #nPos + 1, #nLen)))
SELECT #nPos = #nNextPos
END
RETURN
END
Step 2 : the stored proc
CREATE PROCEDURE [dbo].[spMySP]
#IdList VARCHAR(max)
AS
BEGIN
SET NOCOUNT ON;
SET ROWCOUNT 0
UPDATE dbo.YourTable
SET isActive = 0
FROM dbo.YourTable
INNER JOIN dbo.BigIntListToTable(#IdList) l
ON dbo.YourTable.id = l.nval
END

Splitting A String into Multiple Values in SQL Server 2000

I'm asking the question on behalf of someone that works for my client that asked me this. I'm actually more familiar with mySQL than SQL Server, but unfortunately, SQL Server is what the client has used for years.
The question basically this: Is there a way in SQL Server to split a string into multiple values (e.g. array?) that can be used in a WHERE statement.
Here's a PHP example of what I'm talking about.
<?php
$string = "10,11,12,13";
$explode = explode(",", $string);
?>
$explode would be equal to array(10,11,12,13). What I need to do is something like this:
SELECT {long field list] FROM {tables} WHERE hour IN SPLIT(",", "10,11,12,13")
With SPLIT being my pseudo-code function that performs the splitting
The reason why I'm not doing this in, let's say, PHP, is because the query is being constructed by reporting software where we can't perform logic (such as my PHP code) before sending it to the database, and the multiple values are being returned by the software as a single string separated by pipes (|).
Unfortunately I do not have access to the reporting software (I think he said it was called Logi or LogiReports or something) or the query my associate was drafting up, but all that is really important for this question is the WHERE clause.
Any ideas?
Dynamic SQL can be used:
declare #in varchar(10)
set #in = '10,11,12,13'
exec ('SELECT {long field list] FROM {tables} WHERE hour IN (' + #in + ')')
Several methods here: Arrays and list in SQL Server
For short strings, I prefer a numbers table
I could copy/paste from here but it really is worth reading
You could use a Function which receives a string containing the "id's" separated by pipes, and return it as a table, which you can query and use in a subquery maybe, like this:
SELECT {long field list] FROM {tables} WHERE hour IN
(SELECT OrderID from dbo.SplitOrderIDs('2001,2002'))
ALTER FUNCTION [dbo].[SplitOrderIDs]
(
#OrderList varchar(500)
)
RETURNS
#ParsedList table
(
OrderID int
)
AS
BEGIN
DECLARE #OrderID varchar(10), #Pos int
SET #OrderList = LTRIM(RTRIM(#OrderList))+ ','
SET #Pos = CHARINDEX(',', #OrderList, 1)
IF REPLACE(#OrderList, ',', '') <> ''
BEGIN
WHILE #Pos > 0
BEGIN
SET #OrderID = LTRIM(RTRIM(LEFT(#OrderList, #Pos - 1)))
IF #OrderID <> ''
BEGIN
INSERT INTO #ParsedList (OrderID)
VALUES (CAST(#OrderID AS int)) --Use Appropriate conversion
END
SET #OrderList = RIGHT(#OrderList, LEN(#OrderList) - #Pos)
SET #Pos = CHARINDEX(',', #OrderList, 1)
END
END
RETURN
END
you can use this stored procedure.
I hope that be useful for you.
CREATE PROCEDURE SP_STRING_SPLIT (#String varchar(8000),#Separator Char(10),#pos_select int=0)
AS
BEGIN
SET NOCOUNT ON
DECLARE #Caracter varchar(8000)
DECLARE #Pos int
Set #Pos=1
Set #Caracter=''
CREATE TABLE #ARRAY
( String varchar(8000) NOT NULL,
Pos int NOT NULL IDENTITY (1, 1)
)
While (#Pos<=len(#String))
Begin
If substring(#String,#Pos,1)=Ltrim(Rtrim(#Separator))
Begin
INSERT INTO #ARRAY SELECT #Caracter
SET #Caracter=''
End
Else
Begin
--forma la palabra}
Set #Caracter=#Caracter+substring(#String,#Pos,1)
End
If #Pos=len(#String)
Begin
INSERT INTO #ARRAY SELECT #Caracter
End
SET #Pos=#Pos+1
End
SELECT Pos,String FROM #ARRAY where (Pos=#pos_select Or #pos_select=0)
END
GO
exec SP_STRING_SPLIT 'HELLO, HOW ARE YOU?',',',0

Resources