SSIS passing a variable to execute sql task (create table parameter) - sql

I have a package that contains two execute sql tasks followed by numerous DFTs. The first has the statement:
select CAST(floor(rand()*1000)+1 AS INT) AS SeqVar
And has the ResultSet Single row - this works perfect. It gives me a random number between 1 and 1000 and passes that value on to a variable I have called SeqVar. (I have also verified that this works)
The problem I am having is in my second execute SQL task where I try and use the SeqVar variable outputted from the first Execute SQL teask as a parameter in the following statement:
IF OBJECT_ID('tempdb.dbo.[##temp1]') IS NOT NULL
DROP TABLE [##temp1]
CREATE TABLE [##temp1] (
[RecID] int IDENTITY(?,1),
[Name] VARCHAR(30),
[ABA] VARCHAR(10),
[Account] VARCHAR(20),
[Type] VARCHAR(1),
[Date] date,
[Amount] money
);
Under parameter mapping I have the SeqVar variable name, Direction is Input, Data Type numeric, Parameter name is 0, and Parameter size is 1000.
The value I get has to go where I have the "?" in the create tempdb statement. I am trying to have my code start at a random number and increment by 1.
I know this would probably be easier with a Script task but that tool is broken on my maching (weird dts pipeline errors). Thanks in advance and this is all in SSIS 2008.

Using identity in this way seems like a strange solution just to start a sequence at some random value. Parameters formatted as ? definitely don't work in that context in SQL.
However, another way to manage this, if the method is a given, is to set the entire code of your SQL task using an expression where you sub in the value as a simple string concatenation and then run the resulting string.

Better do create table as like below then use RESEED property to set it to your Random Variable Value'
IF OBJECT_ID('tempdb.dbo.[##temp1]') IS NOT NULL
DROP TABLE [##temp1]
CREATE TABLE [##temp1] (
[RecID] int IDENTITY(1,1),
[Name] VARCHAR(30),
[ABA] VARCHAR(10),
[Account] VARCHAR(20),
[Type] VARCHAR(1),
[Date] date,
[Amount] money
);
DECLARE #RANDOM_VALUE INT = 50
DBCC CHECKIDENT('##TEMP1',RESEED,#RANDOM_VALUE)

Related

How to DECLARE TYPE myType AS TABLE?

I am trying to use table-valued parameter to pass a column to "IN" clause in SQL Server. To do so I need to declare a type of table.
The SQL expression:
DECLARE TYPE myType AS TABLE( myid varchar(50) NULL);
is giving the error:
'myType' is not a recognized CURSOR option.
Replacing DECLARE to CREATE is working good.
Using "CREATE" is requiring to drop this type in any next SQL calls like:
IF TYPE_ID('myType') IS NOT NULL DROP TYPE myType;
But I would like to use the type "myType" just within this SQL expression only.
How to declare a type as table without creating it permanently and without deleting it in all requests?
DECLARE requires the following sinthax:
DECLARE #LastName NVARCHAR(30), #FirstName NVARCHAR(20), #Country NCHAR(2);
With DECLARE, you can:
To assign a variable name(using #).
To assign a Variable Type
To assign a NULL default Variable value
So "DECLARE TYPE" is not a valid statement.
Have a look to temporary tables in sql.
You can create a temporary table in sql with the following code:
CREATE TABLE #TempTable
(
name VARCHAR(50),
age int,
gender VARCHAR (50)
)
INSERT INTO #TempTable
SELECT name, age, gender
FROM student
WHERE gender = 'Male'
With a temporary table, you can store a subset of data from a standard table for a certain period of time.
Temporary tables are stored inside “tempdb” which is a system database.

HSQLDB Stored Procedure Error: attempt to assign to non-updatable column

I am using HSQLDB 2.3.2 and am getting a bizarre error when trying to create a stored procedure.
My addresses table:
CREATE TABLE IF NOT EXISTS addresses (
address_id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) NOT NULL PRIMARY KEY,
address_line_1 NVARCHAR(500) NOT NULL,
address_line_2 NVARCHAR(500),
address_city NVARCHAR(100) NOT NULL,
address_postal_code NVARCHAR(25) NOT NULL,
CONSTRAINT uc_addresses UNIQUE (address_line_1, address_city)
)
An insert to populate it:
INSERT INTO addresses (
address_line_1,
address_city,
address_postal_code
) VALUES (
'123 Test Blvd.', 'Testville', '11111'
)
And my proc:
CREATE PROCEDURE sp_get_address_by_id(
IN address_id INTEGER,
OUT address_id INTEGER,
OUT address_line_1 NVARCHAR(500),
OUT address_line_2 NVARCHAR(500),
OUT address_city NVARCHAR(100),
OUT address_postal_code NVARCHAR(25))
READS SQL DATA
BEGIN ATOMIC
SELECT
a.address_id,
a.address_line_1,
a.address_line_2,
a.address_city,
a.address_postal_code
INTO
address_id,
address_line_1,
address_line_2,
address_city,
address_postal_code
FROM
addresses a
WHERE
a.address_id = address_id;
END
When I run this I get:
Error: attempt to assign to non-updatable column
SQLState: 0U000
ErrorCode: -2500
Questions:
What is wrong with my proc (what is producing this error)?
I'm actually looking for a CREATE IF NOT EXISTS-type declaration, so I can run this script over and over again and the procedure will only get created one time if it doesn't already exist. Will this happen or do I need to change the syntax to accomplish IF NOT EXISTS?
Try the syntax below, according to the hsqldb documentation
http://hsqldb.org/doc/2.0/guide/sqlroutines-chapt.html#src_psm_assignment
The SET statement is used for assignment. It can be used flexibly with
rows or single values.
Also change the address_id parameter to type INOUT and remove the duplicate address_id parameter lines.
CREATE PROCEDURE sp_get_address_by_id(
INOUT address_id INTEGER,
OUT address_line_1 NVARCHAR(500),
OUT address_line_2 NVARCHAR(500),
OUT address_city NVARCHAR(100),
OUT address_postal_code NVARCHAR(25))
READS SQL DATA
BEGIN ATOMIC
SET (address_id,
address_line_1,
address_line_2,
address_city,
address_postal_code)
=
(
SELECT
a.address_id,
a.address_line_1,
a.address_line_2,
a.address_city,
a.address_postal_code
FROM
addresses a
WHERE
a.address_id = address_id
);
END
You can try adding this as the first statement in your script if you want to drop the procedure if it already exists, so that you can re-run the script many times. You can search the documentation for <specific routine designator> for more info.
DROP SPECIFIC PROCEDURE sp_get_address_by_id IF EXISTS;
In your procedure you have two parameters with the same name:
IN address_id INTEGER,
OUT address_id INTEGER,
It may cause a problem when you refer to address_id in the body of procedure.
You should rather use:
INOUT address_id INTEGER,
instead of these two lines.
Answering your second question:
Why do you want to run this script over and over again without rebuilding the procedure? Running this script again has sense when something has changed in it.
If you don't plan to change this procedure but you want to change other things in your script then maybe you should simply move this procedure to other script and run it only once
If you plan to change the body of procedure then it should be rebuilded every time. So you should use CREATE OR REPLACE PROCEDURE
For followers, the same error message is thrown if you do this:
PreparedStatement selectStmt = conn.prepareStatement(query);
ResultSet rs = selectStmt.executeQuery()) {
rs.next();
rs.updateLong("column", value); // boom
one fix is to use this style:
PreparedStatement selectStmt =
conn.prepareStatement(query, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);

Array as input variable in Stored Procedure [duplicate]

I have a list ClaimData in C# and it has three items Date, Type and Description
There can be multiple rows in this as below,
ClaimData
Date Type Description
01/02/2012 "Medical" "Its a medical"
05/02/2013 "Theft" "Its a Theft"
01/02/2014 "Test" "Its a Test"
I want to pass this whole data to a stored procedure in one go to the sql server, so that I can reduce the database hits. I have written stored procedure which can iterate through this list and insert them in a table.
How to achieve by manipulating the list object could be passed to the stored procedure as a parameter?
You will need to do a couple of things to get this going, since your parameter is getting multiple values you need to create a Table Type and make your store procedure accept a parameter of that type.
Since you are passing a TABLE as a parameter you will need to create a TABLE TYPE something as follows
TABLE TYPE
CREATE TYPE dbo.ClaimData AS TABLE
(
[Date] DATE
[Type] VARCHAR(50)
[Description] VARCHAR(100)
)
GO
Stored Procedure to Accept That Type Param
CREATE PROCEDURE mainValues
#TableParam ClaimData READONLY --<-- Accepts a parameter of that type
AS -- Note it is ReadOnly
BEGIN
SET NOCOUNT ON;
--Temp table to store the passed values
-- since the passed parameter is only Read only and you
-- cannot make any changes to the parameter so if you need to
-- manipulate the data inside parameter you will need to get it
-- into a Table vaiable.
-- Declare a Table variable
DECLARE #tmp_values table(
[Date] DATE
[Type] VARCHAR(50)
[Description] VARCHAR(100)
);
--Get values into that Table variable
INSERT INTO #tmp_values ([Date],[Type],[Description])
SELECT [Date],[Type],[Description] FROM #TableParam
-- Do other cool stuff with your passed data
SELECT * FROM #tmp_values --<-- For testing purpose
END
EXECUTE PROC
Declare a variable of that type and populate it with your values.
DECLARE #Table ClaimData( --<-- Declare a variable of your type
[Date] DATE
[Type] VARCHAR(50)
[Description] VARCHAR(100)
);
-- Populate the variable
INSERT INTO #Table ([Date],[Type],[Description])
SELECT [Date],[Type],[Description] FROM Source_Table
EXECUTE mainValues #Table --<-- Stored Procedure Executed
I sent all three column as a string using string builder and delimeter '|'
DateString = '01/02/2012|05/02/2013|01/02/2014'
TypeString = 'Medical|Theft|Test'
DescString = "Its a medical|..."
On database side I used a function to delimit these strings and inserted all these values in a temp table. This solved my problem.

How to pass multiple values to single parameter in stored procedure

I'm using SSRS for reporting and executing a stored procedure to generate the data for my reports
DECLARE #return_value int
EXEC #return_value = [dbo].[MYREPORT]
#ComparePeriod = 'Daily',
#OverrideCompareDate = NULL,
#PortfolioId = '5,6',
#OverrideStartDate = NULL,
#NewPositionsOnly = NULL,
#SourceID = 13
SELECT 'Return Value' = #return_value
GO
In the above when I passed #PortfolioId = '5,6' it is giving me wrong inputs
I need all records for portfolio id 5 and 6 also is this correct way to send the multiple values ?
When I execute my reports only giving #PortfolioId = '5' it is giving me 120 records
and when I execute it by giving #PortfolioId = '6' it is giving me 70 records
So when I will give #PortfolioId = '5,6' it should have to give me only 190 records altogether, but it is giving me more no of records I don't understand where I exactly go wrong .
Could anyone help me?
thanks
all code is too huge to paste , i'm pasting relevant code please suggest clue.
CREATE PROCEDURE [dbo].[GENERATE_REPORT]
(
#ComparePeriod VARCHAR(10),
#OverrideCompareDate DATETIME,
#PortfolioId VARCHAR(50) = '2', --this must be multiple
#OverrideStartDate DATETIME = NULL,
#NewPositionsOnly BIT = 0,
#SourceID INT = NULL
) AS
BEGIN
SELECT
Position.Date,
Position.SecurityId,
Position.Level1Industry,
Position.MoodyFacilityRating,
Position.SPFacilityRating,
Position.CompositeFacilityRating,
Position.SecurityType,
Position.FacilityType,
Position.Position
FROM
Fireball_Reporting.dbo.Reporting_DailyNAV_Pricing POSITION WITH (NOLOCK, READUNCOMMITTED)
LEFT JOIN Fireball.dbo.AdditionalSecurityPrice ClosingPrice WITH (NOLOCK, READUNCOMMITTED) ON
ClosingPrice.SecurityID = Position.PricingSecurityID AND
ClosingPrice.Date = Position.Date AND
ClosingPrice.SecurityPriceSourceID = #SourceID AND
ClosingPrice.PortfolioID IN (
SELECT
PARAM
FROM
Fireball_Reporting.dbo.ParseMultiValuedParameter(#PortfolioId, ',') )
This can not be done easily. There's no way to make an NVARCHAR parameter take "more than one value". What I've done before is - as you do already - make the parameter value like a list with comma-separated values. Then, split this string up into its parts in the stored procedure.
Splitting up can be done using string functions. Add every part to a temporary table. Pseudo-code for this could be:
CREATE TABLE #TempTable (ID INT)
WHILE LEN(#PortfolioID) > 0
BEGIN
IF NOT <#PortfolioID contains Comma>
BEGIN
INSERT INTO #TempTable VALUES CAST(#PortfolioID as INT)
SET #PortfolioID = ''
END ELSE
BEGIN
INSERT INTO #Temptable VALUES CAST(<Part until next comma> AS INT)
SET #PortfolioID = <Everything after the next comma>
END
END
Then, change your condition to
WHERE PortfolioId IN (SELECT ID FROM #TempTable)
EDIT
You may be interested in the documentation for multi value parameters in SSRS, which states:
You can define a multivalue parameter for any report parameter that
you create. However, if you want to pass multiple parameter values
back to a data source by using the query, the following requirements
must be satisfied:
The data source must be SQL Server, Oracle, Analysis Services, SAP BI
NetWeaver, or Hyperion Essbase.
The data source cannot be a stored procedure. Reporting Services does
not support passing a multivalue parameter array to a stored
procedure.
The query must use an IN clause to specify the parameter.
This I found here.
I spent time finding a proper way. This may be useful for others.
Create a UDF and refer in the query -
http://www.geekzilla.co.uk/view5C09B52C-4600-4B66-9DD7-DCE840D64CBD.htm
USE THIS
I have had this exact issue for almost 2 weeks, extremely frustrating but I FINALLY found this site and it was a clear walk-through of what to do.
http://blog.summitcloud.com/2010/01/multivalue-parameters-with-stored-procedures-in-ssrs-sql/
I hope this helps people because it was exactly what I was looking for
Either use a User Defined Table
Or you can use CSV by defining your own CSV function as per This Post.
I'd probably recommend the second method, as your stored proc is already written in the correct format and you'll find it handy later on if you need to do this down the road.
Cheers!
I think, below procedure help you to what you are looking for.
CREATE PROCEDURE [dbo].[FindEmployeeRecord]
#EmployeeID nvarchar(Max)
AS
BEGIN
DECLARE #sqLQuery VARCHAR(MAX)
Declare #AnswersTempTable Table
(
EmpId int,
EmployeeName nvarchar (250),
EmployeeAddress nvarchar (250),
PostalCode nvarchar (50),
TelephoneNo nvarchar (50),
Email nvarchar (250),
status nvarchar (50),
Sex nvarchar (50)
)
Set #sqlQuery =
'select e.EmpId,e.EmployeeName,e.Email,e.Sex,ed.EmployeeAddress,ed.PostalCode,ed.TelephoneNo,ed.status
from Employee e
join EmployeeDetail ed on e.Empid = ed.iEmpID
where Convert(nvarchar(Max),e.EmpId) in ('+#EmployeeId+')
order by EmpId'
Insert into #AnswersTempTable
exec (#sqlQuery)
select * from #AnswersTempTable
END

Activity displayed as one character only

Good Morning
I created a little procedure where I add activities to a database table.
This is the code I used.
USE dbActivities
GO
CREATE PROCEDURE addActivity
#ActivityDate VARCHAR,
#description VARCHAR,
#maxPeople INT,
#Cost MONEY
AS
BEGIN
INSERT INTO Activity(ActivityDate,Description, MaxPeople, Cost)
VALUES(#ActivityDate, #description, #maxPeople, #Cost)
END
GO
I then select the table to view it.
USE dbActivities
GO
CREATE PROCEDURE viewActivities
AS
SELECT * FROM Activity
GO
The strange thing however is that the Description is displayed as only one character in the datatable. So, if I added the description...say "Swimming", when I view the table it is only displayed with one character 'S'.
Why is that?
regards
Arian
The VARCHAR equals to VARCHAR(1). Use e.g. VARCHAR(60) instead.