Alternative to Cursor - sql-server-2008

I am looking for an alternative way to using a cursor for a stored procedure. Instead of selecting each Database (LAL, SINC, SMSS) like I do below, I would like to select a list of strings from a separate table and insert them into the #rates table, joined with there corresponding db/table. Is there a way to do this with a join, or will I need to write this with Dynamic SQL/Cursor?
I'm looking for possible solutions and appreciate all advice. Thanks.
DECLARE #rates TABLE
(
DB CHAR(5),
FUTASUTA CHAR(3),
DSCRIPTN CHAR(31),
FUSUTXRT DECIMAL(18,4)
)
-- LAL Rates
INSERT INTO #rates
SELECT 'LAL', FUTASUTA, DSCRIPTN, (CONVERT(DECIMAL(18,4),FUSUTXRT))/10000000 as FUSUTXRT
FROM [LAL].[dbo].[UPR40100]
-- SINC Rates
INSERT INTO #rates
SELECT 'SINC', FUTASUTA, DSCRIPTN, (CONVERT(DECIMAL(18,4),FUSUTXRT))/10000000 as FUSUTXRT
FROM [SINC].[dbo].[UPR40100]
-- SMSS Rates
INSERT INTO #rates
SELECT 'SMSS', FUTASUTA, DSCRIPTN, (CONVERT(DECIMAL(18,4),FUSUTXRT))/10000000 as FUSUTXRT
FROM [SMSS].[dbo].[UPR40100]
....etc
The table with Distinct databases is a simple table with names/id's
id | Name
1 | LAL
2 | SINC
3 | SMSS
etc...

Following method will work for you :
DECLARE #TABLE TABLE(DBNAME VARCHAR(50))
DECLARE #DYNAMICQUERY VARCHAR(MAX)
INSERT INTO #TABLE VALUES('LAL')
INSERT INTO #TABLE VALUES('SINC')
INSERT INTO #TABLE VALUES('SMSS')
SET #DYNAMICQUERY =
(
SELECT 'INSERT INTO #rates SELECT '''+ DBNAME +''', FUTASUTA,DSCRIPTN, (CONVERT(DECIMAL(18,4),FUSUTXRT))/10000000 as FUSUTXRT FROM ['+ DBNAME + '].[dbo].[UPR40100];'
FROM #TABLE
FOR XML PATH('')
)
EXEC(#DYNAMICQUERY)

Related

How to SELECT multiple values in MYSQL trigger?

how can I SELECT multiple values INTO variables in MYSQL trigger?
I have tried SELECT values into variables in this way but it didn't work. I was inspired by this thread how to use trigger to set value based on query result.
When I examined value in variables, it is NULL. When I put this SELECT into mysql workbench it will select right values. I check column types and they are same type as variables in trigger.
With debug I discovered that there is problem with SELECTing values.
Thank you in advance.
Here is my trigger:
CREATE TRIGGER fin_den_zam_insert
AFTER INSERT
ON table1 FOR EACH ROW
BEGIN
DECLARE koef1 DECIMAL(6,3);
DECLARE koef2 DECIMAL(6,3);
DECLARE koef3 DECIMAL(6,3);
DECLARE sum DECIMAL(6,3);
SELECT DISTINCT
koef_salary, koef_sunday, koef_holiday
INTO
koef1 , koef2, koef3
FROM
employee E
WHERE
E.personal_number = NEW.personal_number_id;
SET sum := NEW.salary * (koef1 + koef2 + koef3);
INSERT INTO export_table
(
id_export,
personal_number,
final_sum
)
VALUES
(
NULL,
NEW.personal_number_id,
sum
);
END;
//
DELIMITER ;
You must be careful with reserved words like sum, that can cause very much trouble-
most people write before every own variable _ like _sum, so that also a stranger can identofy such variables.
That is as you can see not absoltely necessary, but helps also when you tale a look in 5 years
create table employee
(personal_number int,koef_salary DECIMAL(6,3), koef_sunday DECIMAL(6,3), koef_holiday DECIMAL(6,3));
create table export_table(
id_export int auto_increment primary key,
personal_number int,
final_sum DECIMAL(6,3)
);
CREATE table table1
(id_export int auto_increment primary key
, personal_number_id int
, salary DECIMAL(6,3));
insert into employee values(1,1.1,1.3,1.4);
CREATE TRIGGER fin_den_zam_insert
AFTER INSERT
ON table1 FOR EACH ROW
BEGIN
DECLARE koef1 DECIMAL(6,3);
DECLARE koef2 DECIMAL(6,3);
DECLARE koef3 DECIMAL(6,3);
DECLARE final_sum DECIMAL(6,3);
SELECT DISTINCT
koef_salary, koef_sunday, koef_holiday
INTO
koef1 , koef2, koef3
FROM
employee E
WHERE
E.personal_number = NEW.personal_number_id;
SET final_sum := NEW.salary * (koef1 + koef2 + koef3);
INSERT INTO export_table
(
id_export,
personal_number,
final_sum
)
VALUES
(
NULL,
NEW.personal_number_id,
final_sum
);
END
INSERT INTO table1 VALUES (NULL,1,100)
SELECT * FROM export_table
id_export | personal_number | final_sum
--------: | --------------: | --------:
1 | 1 | 380.000
db<>fiddle here

SELECTing the column names for another SELECT - possible?

I have a table t1 with a 'foo' column, and records containing 'bar' and 'baz' in column 'foo'. I also have a table t2 with columns 'bar', 'baz' and 'quux'. I want to do something like the following:
SELECT (SELECT foo from t1) FROM t2;
that is, get the two column names from t1 and query those columns of t2. If I try to do this with MonetDB, I get an error message:
cardinality violation (2>1)
so,
is there some other way to do this with MonetDB?
is this possible in MySQL? other DBMSes?
Example queries (or non-query directives followed by a query) are welcome.
first you need to select the columns into a variable and then use that variable to get tables
something like the following (it is not the actual implementation)
declare #colname varchar(250)
select #colname=foo from t1
select #colname from t2
this may be help.
This is how you can accomplish it in SQL Server
-- Create #T1 which contains names of columns and #T2 which contains the actual columns
CREATE TABLE #T1(colname nvarchar(max))
INSERT INTO #T1 (colname) VALUES ('b')
INSERT INTO #T1 (colname) VALUES ('c')
CREATE TABLE #T2(a int IDENTITY(1,1), b DATETIME DEFAULT GETDATE(), c NVARCHAR(max) DEFAULT 'blah')
INSERT INTO #T2 DEFAULT VALUES
INSERT INTO #T2 DEFAULT VALUES
INSERT INTO #T2 DEFAULT VALUES
--#dSQL will contain the actual SQL string to be executed
DECLARE #dSQL nvarchar(max) = ' '
SELECT #dsql = CONCAT(#dsql,'[',colname,'],') FROM #T1
SELECT #dsql = CONCAT('SELECT',LEFT(#dsql,LEN(#dsql)-1),' FROM #T2')
--You can see the SQL query being executed
PRINT #dsql
--Actually execute it
exec sp_executesql #dsql
MS Sql dynamic sql example.
create table t1(foo varchar(100))
insert t1(foo)
values('bar,baz');
create table t2(bar int, baz int)
insert t2 (bar, baz)
values
(1,100),
(3,300);
declare #cmd varchar(max);
select #cmd= 'select '+ (select top(1) foo from t1) + ' from t2';
EXEC (#cmd);
Result
bar baz
1 1 100
2 3 300
Or may be foo contains column names in different rows, not exactly clear from your question.
create table t1(foo varchar(100))
insert t1(foo)
values('bar'),('baz');
create table t2(bar int, baz int)
insert t2 (bar, baz)
values
(1,100),
(3,300);
declare #cmd varchar(max);
select #cmd= 'select '+ stuff((select ','+ foo from t1 for xml path('')),1,1,'') + ' from t2';
EXEC (#cmd);

How to copy data from one table to another "EXCEPT" one field

How to INSERT into another table except specific field
e.g
TABLE A
ID(auto_inc) CODE NAME
1 001 TEST1
2 002 TEST2
I want to insert CODE and NAME to another table, in this case TABLE B but except ID because it is auto increment
Note: I don't want to use "INSERT INTO TABLE B SELECT CODE, NAME FROM TABLE A", because I have an existing table with around 50 fields and I don't want to write it one by one
Thanks for any suggests and replies
This can't be done without specifying the columns (excludes the primary key).
This question might help you. Copy data into another table
You can get all the columns using information_schema.columns:
select group_concat(column_name separator ', ')
from information_schema.columns c
where table_name = 'tableA' and
column_name <> 'id';
This gives you the list. Then past the list into your code. You can also use a prepared statement for this, but a prepared statement might be overkill.
If this is a one time thing?
If yes, do the insert into tableA (select * from table B)
then Alter the table to drop the column that your dont need.
I tried to copy from a table to another one with one extra field.
source table is TERRITORY_t
* the principle is to create a temp table identical to the source table, adjust column fields of the temp table and copy the content of the temp table to the destination table.
This is what I did:
create a temp table called TERRITORY_temp
generate SQL by running export
CREATE TABLE IF NOT EXISTS TERRITORY_temp (
Territory_Id int(11) NOT NULL,
Territory_Name varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (Territory_Id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
copy over with
INSERT INTO TERRITORY_temp (Territory_Id, Territory_Name) VALUES
(1, 'SouthEast'),
(2, 'SouthWest'),
(3, 'NorthEast'),
(4, 'NorthWest'),
(5, 'Central');
or
INSERT INTO TERRITORY_temp
SELECT * from TERRITORY_t
add the extra field(s) to match with the new table
copy from the temp table to the destination table
INSERT INTO TERRITORY_new
SELECT * from TERRITORY_temp
Please provide feedback.
Step 1. Create stored procedure
CREATE PROCEDURE CopyDataTable
#SourceTable varchar(255),
#TargetTable varchar(255),
#SourceFilter nvarchar(max) = ''
AS
BEGIN
SET NOCOUNT ON;
DECLARE #SourceColumns VARCHAR(MAX)=''
DECLARE #TargetColumns VARCHAR(MAX)=''
DECLARE #Query VARCHAR(MAX)=''
SELECT
#SourceColumns = ISNULL(#SourceColumns +',', '') + T.COLUMN_NAME
FROM
(
select name as COLUMN_NAME from sys.all_columns
where object_id = (select object_id from sys.tables where name = #SourceTable)
and is_identity = 0
)T
SELECT
#TargetColumns = ISNULL(#TargetColumns +',', '') + T.COLUMN_NAME
FROM
(
select name as COLUMN_NAME from sys.all_columns
where object_id = (select object_id from sys.tables where name = #TargetTable)
and is_identity = 0
)T
set #Query = 'INSERT INTO ' + #TargetTable + ' (' + SUBSTRING(#TargetColumns,2 , 9999) + ') SELECT ' + SUBSTRING(#SourceColumns,2 , 9999) + ' FROM ' + #SourceTable + ' ' + #SourceFilter;
PRINT #Query
--EXEC(#Query)
END
GO
Step 2. Run stored procedure
use YourDatabaseName
exec dbo.CopyDataTable 'SourceTable','TargetTable'
Explanations
a) dbo.CopyDataTable will transfer all data from SourceTable to TargetTable, except field with Identity
b) You can apply filter when call stored procedure, in order to transfer only row based on criteria
exec dbo.CopyDataTable 'SourceTable','TargetTable', 'WHERE FieldName=3'
exec dbo.CopyDataTable 'SourceTable','TargetTable', 'WHERE FieldName=''TextValue'''
c) Remove -- from --EXEC(#Query) WHEN finish

How to dynamically write the query in SQL Server 2008?

How to write the dynamically the below query?
Table
empid designation interestes
1 developer,tester cricket,chess
1 developer chess
1 techlead cricket
Condition:
IF empid = 1
AND (designation LIKE '%developer%' OR designationLIKE '%techlead%')
OR (interests LIKE '%cricket%').
How to write the above query dynamically if designations need to send more than 2,and also same on interstes .
please tell me ...
EDIT stored procedure code:
ALTER PROCEDURE [dbo].[usp_GetDevices]
#id INT,
#designation NVARCHAR (MAX)
AS
BEGIN
declare #idsplat varchar(MAX)
set #idsplat = #UserIds
create table #u1 (id1 varchar(MAX))
set #idsplat = 'insert #u1 select ' + replace(#idsplat, ',', ' union select ')
exec(#idsplat)
Select
id FROM dbo.DevicesList WHERE id=#id AND designation IN (select id1 from #u1)
END
Then when your form is submitted, create a string of designations (should really be a list of foreign keys if you have a 1 to many relationship) and pass that to the SQL. Then parse it into a table using one of many open-source SQL user functions:
-- #designations = 'developer,tester,techlead'
select text_val
from dbo.fn_ParseText2Table(#designations,',')
/* results:
text_val
--------
developer
tester
techlead
*/
Once you have the values in a table you can do any standard join or query operations.

Dynamic insert into variable table statement SQL Server

I have a variable table:
DECLARE #A_Table TABLE(ID INT, att1 VARCHAR(100), att2 nvarchar(200))
I want to make dynamic sql, so I insert into this table some data (all inside a loop):
WHILE (#i <= 100) BEGIN
SELECT #other_att = NAME FROM #other_Table where ID = #i;
SET #sql = 'INSERT ' + #A_Table+ '(ID,att1,att2) SELECT '+CAST(#i AS VARCHAR)+' , '''+ #other_att+''', SUM('+ #other_att') FROM '+ #EVEN_OTHER_Table;
EXEC (#sql);
END
sql every time would look like:
INSERT INTO #A_Table SELECT 1 , 'subject', SUM(subject)
INSERT INTO #A_Table SELECT 2 , 'age', SUM(age)
INSERT INTO #A_Table SELECT 3 , 'sex', SUM(sex)....
AND after executing this :
SO I will get:
#A_Table:
id att1 att2
1 subject 4.3
2 age 4.5
3 sex 4.1
but I get an error:
Msg 137, Level 16, State 1, Line 48
Must declare the scalar variable "#A_Table".
SO what is it the syntax to insert dynamically into a variable table?
Ok I have understood it.
You could use the INSERT ... EXEC syntax to insert the data returned by the dynamic SELECT. Of course, you would then need to remove the INSERT part from the dynamic statement.
WHILE (#i <= 100) BEGIN
SELECT #other_att = NAME FROM #other_Table where ID = #i;
SET #sql = 'SELECT '+CAST(#i AS VARCHAR)+' , ''' + #other_att+''', SUM('+ #other_att + ') FROM '+ #EVEN_OTHER_Table;
INSERT INTO #A_Table (ID,att1,att2)
EXEC (#sql);
END
You have a table variable, not a variable that contains the table name.
So you would need the following.
WHILE (#i <= 100) BEGIN
SELECT #other_att = NAME FROM #other_Table where ID = #i;
SET #sql = 'INSERT INTO #A_Table (ID,att1,att2) SELECT '+CAST(#i AS VARCHAR)+' , '''+ #other_att+''', SUM('+ #other_att') FROM #EVEN_OTHER_Table';
EXEC (#sql);
END
You would also need to declare the table variable as a statement inside the #sql variable, and execute your declare table and inserts together, or use a local/global temporary table.
With a local temporary table (stored in the tempdb) you could do something like this.
CREATE TABLE #testtbl (ID INT);
EXEC ('INSERT INTO #testtbl VALUES (1)');
SELECT * FROM #testtbl
DROP TABLE #testtbl
Some good info about temporary tables in BOL
http://msdn.microsoft.com/en-us/library/ms174979.aspx - quite far down the page
And the table type.
http://msdn.microsoft.com/en-us/library/ms175010.aspx
Your EXEC statement occurs in a different context and is therefore unaware of any variables created in your original context.
To create dynamic insert query it is really a task, I also struggle to find it ,finally I have tried in the following way and it's successfully working. Please find the code below.
CREATE PROCEDURE [dbo].[InsertTodaysData] (#tbl varchar(50),#Days int,
#MDate varchar(50), #EValue varchar(50), #Speed varchar(50),
#Totalreturn varchar(50),#Closingv varchar(50), #TotalReturnV varchar(50))
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #SQLQuery varchar(2000)
-- Insert statements for procedure here
set #SQLQuery = 'INSERT INTO '+#tbl+' (ID,MDate,EValue,Speed,TotalReturnRatio,ClosingValue,
TotalReturnValue) VALUES ('+#Days+','''+#MDate+''', '+#EValue+', '+#Speed+',
'+#Totalreturn+', '+#Closingv+', '+#TotalReturnV+')'
EXECUTE(#SQLQuery)
END
Hope this will help you..