sql server linked oracle how to execute query with dataset - sql-server

In sql server I have a table with id. I pass id through openquery in a loop.
while #coun < 1000
begin
select #id=id from #temp where num = #coun
#sql = 'select * from tableoracle where id=' + #id
execute('insert into #temp2 select * from openquery(ORAC, ' + #sql+')')
set #coun = #coun + 1
End
Can I send the id immediately as a set and not one by one?
if you access the entire table at once in oracle without id, the request hangs,
a lot of data

found the solution
declare #a varchar(max) = (select '(' + stuff (
(SELECT ',''' +id + ''''
FROM #temp
for xml path('')),
1, 1, '') + ')')
#sql = 'select * from tableoracle where id in ' + #a
execute('insert into #temp2 select * from openquery(ORAC, ' + #sql+')')

Related

How to Pass Tablename, Fieldnames, Values as perameters in Stored Procedure using CI?

I am developing a custom application using CodeIgniter and MSSQL Server. Here i am using stored procedures.
Now i am wondering to implement codeigniter query type functionality where i can create a universal stored procedure in SQL Server and at the time of using i can pass tablename, array of fields and values.
It can work for both insert and update.
Something like we do in CodeIgniter to execute the query,
$data = array('fieldname1' => 'value1',
'fieldname2' => 'value2');
$this->db->insert($tablename,$data);
Just like this if we can pass the table name and array of the data to stored procedure and stored procedure automatically execute it.
If this can be done, it can save lots n lots of man hours. If anyone have already done i will be very much happy to see the solution.
You need to make string very specific in this case.
Figure out your table name, Column name, Column values for insert. For update 2 more parameters are required Id column name and its value.
GO
---- exec InsertUpdate 'tablename', 'col1, col2, col3', 'val1, val2, val3', 'idcol', 'idval'
GO
Create proc InsertUpdate
( #TableName nvarchar(500),
#ColName nvarchar(max),
#ColValues nvarchar(max),
#IDColName nvarchar(100) = '', --- for update only otherwise null
#IdColValue nvarchar(Max) = '' --- for update only otherwise null
)
As
Begin
declare #Query nvarchar(max)
if (#IdColValue = '')
Begin
set #Query = ' Insert into ' + #TableName + ' (' + #ColName + ') values (' + #ColValues + ')'
End
Else
Begin
;with CtColumn as (
select ROW_NUMBER() over (order by (select 1000)) as Slno, * from Split(#ColName,',') )
, CtValue as (
select ROW_NUMBER() over (order by (select 1000)) as Slno, * from Split(#ColValues, ','))
, CTFinal as (
select CCOl.Slno, CCOl.Items as ColName, CVal.Items as ColValue from CtColumn as CCOl inner join CtValue as CVal on CCOl.Slno=CVal.Slno )
select #Query = 'update ' + #TableName + ' set ' +
stuff ( (select ',' + ColName + '=' + ColValue from CTFinal for xml path ('')) ,1,1,'') +
' where ' + #IDColName + '=' + #IdColValue
End
exec sp_executesql #Query
End
Go

how to generate insert data script from #temp tables?

In DB I have #temp tables with data and I need to generate insert Scripts (for all data).
How it can be done ? I right clicked on tempDB and selected > Tasks > Generate Scripts but I can't select #temp tables to generate script (they are not avaialble to select).
how I can geneate Insert script from #temp tables I m using SQL Server 2008 R2.
You can insert your query results into sql table (temporary table , it will be created automatically ):
SELECT * INTO myTempTable FROM (query results)
e.g : SELECT * INTO myTempTable FROM user where condition
A table named myTempTable will be created inside schema dbo
Then click on database click :
Tasks > Generate Scripts
and you choose the table myTempTable
Another best way to do it just bit faster but longer.
Use SqlPubWiz
Just go:
C:\Program Files (x86)\Microsoft SQL Server\90\Tools\Publishing\1.4
and run and fill required information regarding log in into database and choose your database and get your whole database script and find the table's insert script that you wanted in your saved script file.
You can use the following query batch for generating scripts for temp tables and you can select the rows based on the conditions. I have got this from here. In the original source, the Author created Stored Procedure for generating scripts. I have formatted and modified for declaring TableName with Condition. You need to run this query batch in tempdb with your #temp table name. Thanks to Neeraj Prasad Sharma.
DECLARE #QUERY VARCHAR(MAX) = 'Dbo.#Temp where 1 = 1'
SET NOCOUNT ON
DECLARE #WithStrINdex AS INT
DECLARE #WhereStrINdex AS INT
DECLARE #INDExtouse AS INT
DECLARE #SchemaAndTAble VARCHAR(270)
DECLARE #Schema_name VARCHAR(30)
DECLARE #Table_name VARCHAR(240)
DECLARE #Condition VARCHAR(MAX)
SELECT #WithStrINdex = 0
SELECT #WithStrINdex = CHARINDEX('WITH', #Query), #WhereStrINdex = CHARINDEX('WHERE', #Query)
IF(#WithStrINdex != 0)
SELECT #INDExtouse = #WithStrINdex
ELSE
SELECT #INDExtouse = #WhereStrINdex
SELECT #SchemaAndTAble = LEFT(#Query, #INDExtouse - 1)
SELECT #SchemaAndTAble = LTRIM(RTRIM(#SchemaAndTAble))
SELECT #Schema_name = LEFT(#SchemaAndTAble, CHARINDEX('.', #SchemaAndTAble ) - 1)
,#Table_name = SUBSTRING(#SchemaAndTAble, CHARINDEX('.', #SchemaAndTAble ) + 1, LEN(#SchemaAndTAble))
,#CONDITION = SUBSTRING(#Query, #WhereStrINdex + 6, LEN(#Query))--27+6
DECLARE #COLUMNS TABLE([Row_number] SMALLINT, Column_Name VARCHAR(MAX))
DECLARE #CONDITIONS AS VARCHAR(MAX)
DECLARE #Total_Rows AS SMALLINT
DECLARE #Counter AS SMALLINT
DECLARE #ComaCol AS VARCHAR(MAX)
SELECT #ComaCol = '', #Counter = 1, #CONDITIONS = ''
print #Schema_name
print #Table_name
INSERT INTO #COLUMNS
SELECT ROW_NUMBER() OVER(ORDER BY ORDINAL_POSITION) [Count] ,COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = #Schema_name
AND TABLE_NAME = #Table_name
AND COLUMN_NAME NOT IN ('SYNCDESTINATION','PENDINGSYNCDESTINATION' ,'SKUID','SALECREDITEDTO')
SELECT #Total_Rows = COUNT(*) FROM #COLUMNS
SELECT #Table_name = '['+#Table_name+']'
SELECT #Schema_name = '['+#Schema_name+']'
WHILE (#Counter< = #Total_Rows )
BEGIN
SELECT #ComaCol = #ComaCol + ' ['+Column_Name+'],' FROM #COLUMNS
Where [Row_number] = #Counter
SELECT #CONDITIONS = #CONDITIONS+ ' + CASE WHEN ['+Column_Name+'] IS NULL THEN ''NULL'' ELSE '''''''' +
REPLACE( CONVERT(VARCHAR(MAX),['+Column_Name+']) ,'''''''','''')
+'''''''' END +'+''','''
FROM #COLUMNS WHERE [Row_number] = #Counter
SET #Counter = #Counter + 1
END
SELECT #CONDITIONS = RIGHT(#CONDITIONS, LEN(#CONDITIONS) -2)
SELECT #CONDITIONS = LEFT(#CONDITIONS, LEN(#CONDITIONS) -4)
SELECT #ComaCol = SUBSTRING (#ComaCol, 0, LEN(#ComaCol))
SELECT #CONDITIONS = '''INSERT INTO ' + #Schema_name + '.' + #Table_name + '(' + #ComaCol + ')' +' VALUES( '+'''' + '+' + #CONDITIONS
SELECT #CONDITIONS = #CONDITIONS + '+' + ''')'''
SELECT #CONDITIONS = 'SELECT' + #CONDITIONS + 'FROM' + #Schema_name + '.' + #Table_name + ' WITH(NOLOCK) ' + ' WHERE ' + #Condition
PRINT(#CONDITIONS)
EXEC(#CONDITIONS)
You have to right click on database and click on
Tasks -> Generate Scripts
now you are having a popup screen go to next click
Select specific database objects
now select your table from Tables option and click next now you have Advanced button there click on it.
You will have another small popup screen available choose
Types of data to script and select
Data only
click OK and don't forget to see the path as file name where your script save carefully.
Now click Next and again Next your script is ready with the data.

CTE having dynamic variable

I have these 2 example of CTE statement, one is hardcoded and the other is dynamic. The hardcoded works but not the dynamic. Can you check what's wrong with my dynamic statement? Thanks
-- THIS WORKS
WITH CTE AS
(
SELECT TOP 1 *
FROM Citi_v823_21Nov2013.dbo.GroupRelation_Audit
WHERE Citi_v823_21Nov2013.dbo.GroupRelation_Audit.ParentEntityIDCounter = #ParentEntityIDCounter
AND Citi_v823_21Nov2013.dbo.GroupRelation_Audit.ChildEntityIDCounter = #ChildEntityIDCounter
AND IsNull(Citi_v823_21Nov2013.dbo.GroupRelation_Audit.AuditDateModified, '1900-01-01') < GETDATE()
ORDER BY GroupRelationCounter DESC
)
UPDATE CTE SET DateEffectiveTo = #DateEffectiveFrom_GroupRelation
--THIS DOESN'T WORK
DECLARE #TargetDB NVARCHAR(Max)
DECLARE #SourceDB NVARCHAR(Max)
DECLARE #DateEffectiveFrom_GroupRelation DATETIME
DECLARE #UpdateRecords_GroupRelation NVARCHAR(Max)
SET #TargetDB = 'Citi_v823_21Nov2013'
SET #SourceDB = 'UATCitiv82320131018'
SET #DateEffectiveFrom_GroupRelation = '2013-09-29'
SET #UpdateRecords_GroupRelation = '
;WITH CTE AS
(
SELECT TOP 1 *
FROM ' + #TargetDB + '.dbo.GroupRelation_Audit
WHERE ' + #TargetDB + '.dbo.GroupRelation_Audit.ParentEntityIDCounter = ' + CONVERT(NVARCHAR(Max), #ParentEntityIDCounter) +'
AND ' + #TargetDB + '.dbo.GroupRelation_Audit.ChildEntityIDCounter = ' + CONVERT(NVARCHAR(Max), #ChildEntityIDCounter) +'
AND IsNull(' + #TargetDB + '.dbo.GroupRelation_Audit.AuditDateModified, ''1900-01-01'') < GETDATE() ''
ORDER BY ' + #TargetDB + '.dbo.GroupRelation_Audit.GroupRelationCounter DESC
)'
UPDATE CTE SET DateEffectiveTo = #DateEffectiveFrom_GroupRelation
EXEC sp_executesql #UpdateRecords_GroupRelation
Move your UPDATE statement inside the SQL statement.
The CTE is locally-scoped, so that statement won't known what CTE is and will simply throw an invalid object error.
Sample code:
declare #sql nvarchar(max)
select *
into ##t
from
(select 3 as b) tmp
select * from ##t;
set #sql = ';WITH a as (select 1 as b) update ##t set b = (select top 1 * from a) '
EXEC sp_executesql #sql
select * from ##t
drop table ##t

Not able to run a statement because of issue with the sql syntax

This solution is for an unbounded Gridview paging and having problem with the syntax of this query:
> #currTable varchar(20),
#startRowIndex int,
#maximumRows int,
#totalRows int OUTPUT
AS
DECLARE #first_id int, #startRow int
IF #startRowIndex = 1
SET #startRowIndex = 1
ELSE
SET #startRowIndex = ((#startRowIndex - 1) * #maximumRows)+1
SET ROWCOUNT #startRowIndex
DECLARE #sql varchar(250);
SET #sql = 'SELECT ID, StringID_from_Master, GUID, short_Text, lang_String, date_Changed, prev_LangString, needsTranslation, displayRecord, brief_Descrip FROM ' + #currTable + ' ';
EXECUTE(#sql);
PRINT #first_id
SET ROWCOUNT #maximumRows
SELECT #sql = 'SELECT ' + CAST(#first_id as varchar(20)) + ' = ID FROM ' + QUOTENAME(#currTable) + ' ORDER BY ID ' ;
EXEC (#sql);
SET ROWCOUNT 0
-- Get the total rows
SET #sql = 'SELECT ' + + CAST(#totalRowsas varchar(20)) + ' = COUNT(ID) FROM ' + #currTable + ' ';
EXECUTE(#sql);
RETURN
<
The errors is:
Conversion failed when converting the varchar value ''SELECT ' to data type int.
Tried also
nvarchar and varchar. = + CAST(#first_id as varchar(10)) +
If you're trying to implement paging, this is wrong in so many ways. First, you're using SET ROWCOUNT to limit to #startRowIndex, but then you're selecting ALL n rows (with no ORDER BY), then getting the first ID, then counting the total rows by selecting from the table? Might I suggest a better approach?
CREATE PROCEDURE dbo.PageSmarter
#Table NVARCHAR(128), -- table names should not be varchar(20)
#FirstRow INT,
#PageSize INT,
#TotalRows INT OUTPUT
AS
BEGIN
SET NOCOUNT ON; -- always, in every stored procedure
DECLARE
#first_id INT,
#startRow INT,
#sql NVARCHAR(MAX);
SET #sql = N'WITH x AS
(
SELECT
ID,
rn = ROW_NUMBER() OVER (ORDER BY ID)
FROM
' + #Table + '
)
SELECT rn, ID
INTO #x FROM x
WHERE rn BETWEEN ' + CONVERT(VARCHAR(12), #FirstRow)
+ 'AND (' + CONVERT(VARCHAR(12), #FirstRow)
+ ' + ' + CONVERT(VARCHAR(12), #PageSize) + ' - 1);
SELECT first_id = MIN(ID) FROM #x;
SELECT
ID, StringID_from_Master, GUID, short_Text, lang_String, date_Changed,
prev_LangString, needsTranslation, displayRecord, brief_Descrip
FROM ' + #Table + ' AS src
WHERE EXISTS
(
SELECT 1 FROM #x
WHERE ID = src.ID
);';
EXEC sp_executeSQL #sql;
SELECT #totalRows = SUM(row_count)
FROM sys.dm_db_partition_stats
WHERE [object_id] = OBJECT_ID(#Table);
END
GO
DECLARE #tr INT;
EXEC dbo.PageSmarter 'dbo.tablename', 10, 2, #tr OUTPUT;
SELECT #tr;
I haven't tested all edge cases with this specific implementation. I will confess, there are much better ways to do this, but they usually aren't complicated with the additional requirement of dynamic table names. This suggests that there is something inherently wrong with your design if you can run the exact same queries against any number of tables and get similar results.
In any case, you can review some of the (quite lengthy) discussion about various approaches to paging over at SQL Server Central:
http://www.sqlservercentral.com/articles/T-SQL/66030/
There are 62 comments following up on the article:
http://www.sqlservercentral.com/Forums/Topic672980-329-1.aspx
I am guessing your #first_id field is an int. If so, then you need to CAST/Convert your #first_id value to a string/varchar.
CAST(#first_id as varchar(10))
or
Convert(varchar(10), #first_id)
MSDN documentation on CAST/Convert for SQL server
EDIT: After looking at your query again, I notice that you are setting your #first_id = ID, This is incorrect syntax, the correct syntax would be below.
SELECT #sql = 'SELECT ID AS ' + CAST(#first_id as varchar(10)) + ' FROM ' +
QUOTENAME(#currTable) + ' ORDER BY ID ' ;
EXEC (#sql);
It appears you're trying to create an alias for your column ID. The string you're building won't result in a valid SQL statement if it contains a number. It would come out to something like this:
SELECT 123 = ID FROM dbo.MyTable ORDER BY ID
Try this:
SELECT ID AS '123' FROM dbo.MyTable ORDER BY ID
To achieve that:
SELECT #sql = 'SELECT ID AS ''' + CAST(#first_id as varchar(10)) +
''' FROM ' + QUOTENAME(#currTable) +
' ORDER BY ID ' ;
I would do it this way
create table #e (a int)
SET #sql = 'insert #e SELECT COUNT(ID) FROM ' + #currTable + ' ';
exec(#sql)
select #totalRows = a from #e
drop table #e

Insert script for a particular set of rows in SQL

I am using SQL Server 2008. I use to take the script of my data from SQL table using Tasks --> Generate Scripts option.
Here is my problem:
Let's say I have 21,000 records in Employee table. When I take the script of this table, it takes the insert script for all 21000 records. What is the solution if I want to take only the script of 18000 records from the table?
Is there any solution using SQL query or from the tasks wizard?
Thanks in advance...
Create a new View where you select your desired rows from your Employee table e.g. SELECT TOP 21000...
Then simply script that View instead of the Table.
In case the views are not an option for you I wrote the following code based on the Aaron Bertrand's answer here that will give the insert statement for a single record in the db.
CREATE PROCEDURE dbo.GenerateSingleInsert
#table NVARCHAR(511), -- expects schema.table notation
#pk_column SYSNAME, -- column that is primary key
#pk_value NVARCHAR(10) -- change data type accordingly
AS
BEGIN
SET NOCOUNT ON;
DECLARE #cols NVARCHAR(MAX), #vals NVARCHAR(MAX),
#valOut NVARCHAR(MAX), #valSQL NVARCHAR(MAX);
SELECT #cols = N'', #vals = N'';
SELECT #cols = #cols + ',' + QUOTENAME(name),
#vals = #vals + ' + '','' + ' + 'ISNULL('+REPLICATE(CHAR(39),4)+'+RTRIM(' +
CASE WHEN system_type_id IN (40,41,42,43,58,61) -- dateteime and time stamp type
THEN
'CONVERT(CHAR(8), ' + QUOTENAME(name) + ', 112) + '' ''+ CONVERT(CHAR(14), ' + QUOTENAME(name) + ', 14)'
WHEN system_type_id IN (35) -- text type
THEN
'REPLACE(CAST(' + QUOTENAME(name) + 'as nvarchar(MAX)),'+REPLICATE(CHAR(39),4)+','+REPLICATE(CHAR(39),6)+')'
ELSE
'REPLACE(' + QUOTENAME(name) + ','+REPLICATE(CHAR(39),4)+','+REPLICATE(CHAR(39),6)+')'
END
+ ')+' + REPLICATE(CHAR(39),4) + ',''null'') + '
FROM sys.columns WHERE [object_id] = OBJECT_ID(#table)
AND system_type_id <> 189 -- can't insert rowversion
AND is_computed = 0; -- can't insert computed columns
SELECT #cols = STUFF(#cols, 1, 1, ''),
#vals = REPLICATE(CHAR(39),2) + STUFF(#vals, 1, 6, '') + REPLICATE(CHAR(39),2) ;
SELECT #valSQL = N'SELECT #valOut = ' + #vals + ' FROM ' + #table + ' WHERE '
+ QUOTENAME(#pk_column) + ' = ''' + RTRIM(#pk_value) + ''';';
EXEC sp_executesql #valSQL, N'#valOut NVARCHAR(MAX) OUTPUT', #valOut OUTPUT;
SELECT SQL = 'INSERT ' + #table + '(' + #cols + ') SELECT ' + #valOut;
END
I took the above code and wrapped it the following proc that will use the where clause you give it to select which insert statements to create
CREATE PROCEDURE dbo.GenerateInserts
#table NVARCHAR(511), -- expects schema.table notation
#pk_column SYSNAME, -- column that is primary key
#whereClause NVARCHAR(500) -- the where clause used to parse down the data
AS
BEGIN
declare #temp TABLE ( keyValue nvarchar(10), Pos int );
declare #result TABLE ( insertString nvarchar(MAX) );
declare #query NVARCHAR(MAX)
set #query =
'with qry as
(
SELECT ' + #pk_column + ' as KeyValue, ROW_NUMBER() over(ORDER BY ' + #pk_column + ') Pos
from ' + #table + '
' + #whereClause + '
)
select * from qry'
insert into #temp
exec sp_sqlexec #query
Declare #i int, #key nvarchar(10)
select #i = count(*) from #temp
WHILE #i > 0 BEGIN
select #key = KeyValue from #temp where Pos = #i
insert into #result
exec [dbo].[GenerateSingleInsert] #table, #pk_column, #key
set #i = #i - 1
END
select insertString from #result
END
Calling it could look like the following. You pass in the table name, the table primary key and the where clause and you should end up with your insert statements.
set #whereClause = 'where PrettyColorsId > 1000 and PrettyColorsID < 5000'
exec [dbo].GenerateInserts 'dbo.PrettyColors', 'PrettyColorsID', #whereClause
set #whereClause = 'where Color in (' + #SomeValues + ')'
exec [dbo].GenerateInserts 'dbo.PrettyColors', 'PrettyColorsID', #whereClause

Resources