I have a stored procedure as below
AS
BEGIN
IF(#statement = 1)
BEGIN
INSERT INTO [employee].[dbo].[emp_detail] ([fname], [lname], [age],[gender],
[department], [salary])
VALUES (#fname, #lname, #age, #gender,
#department, #salary)
END
IF(#statement = 2)
BEGIN
SELECT *
FROM emp_detail
END
I want to select data from the table by using this stored procedure.
My code is as below :
List<Nullable<int>> tbl = context.USP_MVC(2,fname, lname,Convert.ToInt32(age), gender, department, salary).ToList();
It is showing an error
int does not contain definition of to list
Create a complex type of stored procedure using .edmx file, and change the your like this:
List<StoredProcedureName_Result> tbl = context.USP_MVC(2, fname, lname, Convert.ToInt32(age), gender, department, salary).ToList();
Related
I'm trying to insert values to both tables at the same time. I'm using a form in my application where I use the inserted values from the form to inert them into the db. But now I'm inserting values to one table (Users).
public function registerUser($formdata){
helper('global');// a heper for randomString().
//Asign value to columns
$db_data['Emailaddress'] = $formdata['emailaddress'];
$db_data['Password'] = password_hash($formdata['password'], PASSWORD_DEFAULT);
$db_data['Status'] = 'Free';
$db_data['Token'] = randomString(32);
$db_data['FirstLogin'] = 0;
$db_data['Users.UsersKey'] = $db_data['UsersSettings.UsersKey'];
//insert to db
$this->db->table('Users', 'UsersSettings')->join('UsersSettings','Users.UsersKey = UsersSettings.UsersKey', 'inner')->insert($db_data);
}
public function updateUserSetting_proccess(){
$formdata = $this->request->getPostGet();
return $this->SettingsModel->update_user_settings($formdata);
}
The content of the Users table is:
SELECT TOP (1000) [UsersKey]
,[UniqueID]
,[Token]
,[ResetToken]
,[Emailaddress]
,[Password]
,[Status]
,[DateTimeAdded]
,[DateTimeLastUpdated]
,[FirstLogin]
FROM [dbo].[Users]
The UsersKey is inserted automaticly because of the auto increment.
The second table I want to use is UsersSettings with content:
SELECT TOP (1000) [UsersSettingsKey]
,[UsersKey]
,[FirstName]
,[LastName]
,[Logo]
,[Organization]
,[Address]
,[Number]
,[Addition]
,[Postcode]
,[City]
,[Country]
,[Language]
,[Theme]
,[CalcPercentage]
,[CalcAdminFee]
,[ColorPrimary]
,[ColorSecondary]
,[DateTimeLastUpdated]
FROM [dbo].[UsersSettings]
I want the UsersKey from UsersSettings have the same value in Users UsersKey.
I tried this:
join('UsersSettings','Users.UsersKey = UsersSettings.UsersKey', 'inner')
but it didn't help. Can someong give me some suggestions?
You'll need to perform the insert into table Users first in order to get the generated UsersKey.
Explanation of why inserting into table Users first is required, may be shown with the SQL equivalent:
declare #lv_UsersKey int
-- insert into table Users (only essential parts shown)
insert into Users(....) values (...)
-- capture UsersKey for inserted record
select #lv_UsersKey = cast(SCOPE_IDENTITY() as int)
-- then insert into UsersSettings (only essential parts shown)
insert into UsersSettings (UsersKey, ....) values (#lv_UsersKey, ...)
Transferring the above SQL to codeigniter will look like this:
$this->db->table('Users')->insert($db_data);
$inserted_users_key = $this->db->insert_id();
$db_data2['UsersKey'] = $inserted_users_key;
// some more init of $db_data2 here
$this->db->table('UsersSettings')->insert($db_data2);
Let's say I have the following monthly tables with table names formatted such that the number after the underscore refers to the month. What I want to do is to combine these 12 tables into one without having to write 10-30 insert/union all statements
table_1
table_2
table_3
table_4
table_5
table_6
table_7
table_8
table_9
table_10
table_11
table_12 -- (only 12 in this instance but could be as many as 36)
My current approach is to first create the master table with data from table_1.
create temporary table master_table_1_12 as
select * -- * to keep it simple for this example
from table_1;
Then use variables such that I can simply keep hitting the run button until it errors out with "table_13 does not exist"
set month_id=(select max(month_id) from master_table_1_12) + 1;
set table_name=concat('table_',$month_id);
insert into master_table_1_12
select *
from identifier($table_name);
Note: All monthly tables have a month_id column
Sure it saves some space on the console(compared to multiple inserts), but I still have to run it 12 times. Are Snowflake Tasks something I could use for this? I couldn't find a fitting example from their documentation to code that up but, if anyone had success with that or with a Javascript based SP for a problem like this, please enlighten.
Here's a stored procedure that will insert into master_table_1_12 from selects on table_1 through table_12. Modify as required:
create or replace procedure FILL_MASTER_TABLE()
returns string
language javascript
as
$$
var rows = 0;
for (var i=1; i<=12; i++) {
rows += insertRows(i);
}
return rows + " rows inserted into master_table_1_12.";
// End of main function
function insertRows(i) {
sql =
`insert into master_table_1_12
select *
from table_${i};`;
return doInsert(sql);
}
function doInsert(queryString) {
var out;
cmd1 = {sqlText: queryString};
stmt = snowflake.createStatement(cmd1);
var rs = stmt.execute();;
rs.next();
return rs.getColumnValue(1);
}
$$;
call fill_master_table();
By the way, if you don't have any processing to do and just need to consolidate the tables, you can do something like this:
insert into master_table_1_12
select * from table_1
union all
select * from table_2
union all
select * from table_3
union all
select * from table_4
union all
select * from table_5
union all
select * from table_6
union all
select * from table_7
union all
select * from table_8
union all
select * from table_9
union all
select * from table_10
union all
select * from table_11
union all
select * from table_12
;
Can you not create a view on top of these 12 tables. The view will be an union of all these tables.
Based on the comments below, I further elaborated my answer. please try this approach. It will provide better performance when your table is large. Partitioning it will improve performance. This is based on real experience.
CREATE TABLE SALES_2000 (REGION VARCHAR, UNITS_SOLD NUMBER);
CREATE TABLE SALES_2001 (REGION VARCHAR, UNITS_SOLD NUMBER);
CREATE TABLE SALES_2002 (REGION VARCHAR, UNITS_SOLD NUMBER);
CREATE TABLE SALES_2003 (REGION VARCHAR, UNITS_SOLD NUMBER);
INSERT INTO SALES_2000 VALUES('ASIA', 25);
INSERT INTO SALES_2001 VALUES('ASIA', 50);
INSERT INTO SALES_2002 VALUES('ASIA', 55);
INSERT INTO SALES_2003 VALUES('ASIA', 65);
CREATE VIEW ALL_SALES AS
SELECT * FROM SALES_2000
UNION
SELECT * FROM SALES_2001
UNION
SELECT * FROM SALES_2002
UNION
SELECT * FROM SALES_2003;
SELECT * FROM ALL_SALES WHERE UNITS_SOLD = 25;
I ended up creating a UDF that spits out a create view statement and a stored procedure that executes it to create a temporary view. I work with tables following specific naming convention, so you might have to tweak this solution a little for your use case. The separation of UDF and stored proc actually helps with that as you'd mostly need to tweak the SQL UDF. I am sharing a simplified version of what I actually have in the interest of keeping it representative of the tables I listed in my question.
SQL UDF FOR GENERATING A CREATE VIEW STATETEMENT
create or replace function sandbox.public.define_view(table_pattern varchar, start_month varchar, end_month varchar)
returns table ("" varchar) as
$$
with cte1(month_id) as
(select start_month::int + row_number() over (order by 1) - 1
from table(generator(rowcount=> end_month::int - start_month::int + 1)))
,cte2(month_id,statement) as
(select 0,
concat('create or replace temporary view master_',
split_part(table_pattern,'.',-1),
start_month,
'_',
end_month,
' as ')
union all
select month_id,
concat('select * from ',
table_pattern,
month_id,
case when month_id=end_month::int then ';' else ' union all ' end)
from cte1)
select listagg(statement, '\n') within group (order by month_id) as create_view_statement
from cte2
$$;
PROCEDURE FOR EXECUTING THE OUTPUT OF THE UDF ABOVE
create or replace procedure sandbox.public.create_view(TABLE_PATTERN varchar, START_MONTH varchar,END_MONTH varchar)
returns varchar not null
language Javascript
execute as caller
as
$$
sql_command = 'select * from table(sandbox.public.define_view(:1, :2, :3))';
var stmt = snowflake.createStatement({sqlText: sql_command ,binds: [TABLE_PATTERN, START_MONTH, END_MONTH]}).execute();
stmt.next();
var ddl = stmt.getColumnValue(1);
var run=snowflake.createStatement({sqlText: ddl}).execute();
run.next();
var message=run.getColumnValue(1);
return "Temporary " + message;
$$;
USAGE DEMO
set table_pattern ='sandbox.public.table_';
set start_month ='1';
set end_month = '12';
set master_view='master_'||split_part($table_pattern,'.',-1)||$start_month||'_'||$end_month;
call create_view($table_pattern, $start_month, $end_month);
select top 100 *
from identifier($master_view);
I'm creating a stored procedure that populates two tables tblAirport and tblCountry. tblCountry gets its country names from tblAirport but I only want one instance of the country name to show up in `tblCountry. So far for my stored procedure I have this
DECLARE #PK INT = (SELECT PK FROM tblAirport WHERE strName = #strName)
IF #PK IS NULL
INSERT INTO tblAirport (ICAOCode,IATACode,strName,strCity,strCountry,degLat,minLat,secLat,Equator,degLong,minLong,secLong,Meridian,strElevation)
VALUES (#ICAOCode,#IATACode,#strName,#strCity,#strCountry,#degLat,#minLat,#secLat,#Equator,#degLong,#minLong,#secLong,#Meridian,#strElevation)
SET #PK = (SELECT PK FROM tblAirport WHERE strName = #strName);
IF EXISTS (SELECT * FROM tblCountry WHERE strCountry = #strCountry)
SET #strCountry = #strCountry + 'x'
INSERT INTO tblCountry (strCountry)
VALUES (#strCountry)
I tried using IF EXISTS (SELECT * FROM tblCountry WHERE strCountry = #strCountry)
SET #strCountry = #strCountry + 'x' just to show any duplicate countries but I don't know how to eliminate the duplicates from my table. I'm new to SQL and I've only learned the IF EXISTS function. Any suggestions would be great. Thank you!
This is how to handle a multiline IF ELSE (https://technet.microsoft.com/en-us/library/ms182717(v=sql.110).aspx)
IF NOT EXISTS (SELECT * FROM tblCountry WHERE strCountry = #strCountry)
BEGIN
INSERT INTO tblCountry (strCountry) VALUES (#strCountry)
END;
In general though, I'd be concerned about a procedure that uses the data to drive the possible values in a lookup list, especially something like countries that should probably be pre-defined up front. You'd hate for them to enter free-form duplicates that are really the same country with a slightly different spelling.
I am creating a web app in which I am executing a select command on my stored procedure, but I want to insert the same fetched data into another table.
So I tried to do something like the following
CREATE PROCEDURE profinalinstexpensesonid
(#from varchar(5000),
#to varchar(5000),
#trainer varchar(5000),
#sonvinid varchar(5000)
)
AS
BEGIN
INSERT INTO invoice(sonvinid, tid, date, brandname, zone, location, area, venuename, venue, instructore, amount)
SELECT
instructoreexpense.sonvinid,
sonvininsert.trainer,
CONVERT(VARCHAR, sonvininsert.date, 105) AS date,
sonvininsert.brandname,
SUBSTRING(sonvininsert.zone, 1, 1) AS zone,
sonvininsert.location,
sonvininsert.area,
companysonvinunitvenue.venuename,
sonvininsert.venue,
sonvininsert.instructore,
instructoreexpense.amount
FROM
instructoreexpense
LEFT OUTER JOIN
sonvininsert ON sonvininsert.sonvinid = instructoreexpense.sonvinid
AND sonvininsert.status = '0'
LEFT OUTER JOIN
finalinstructoreexpense ON finalinstructoreexpense.sonvinid = instructoreexpense.sonvinid
LEFT OUTER JOIN
companysonvinunitvenue ON companysonvinunitvenue.id = sonvininsert.comsonvinid
WHERE
sonvininsert.date BETWEEN CONVERT(DATETIME, #from, 105)
AND CONVERT(DATETIME, #to, 105)
AND sonvininsert.trainer = (SELECT empname
FROM trainerdetails
WHERE trid = #trainer)
AND instructoreexpense.sonvinid NOT IN (SELECT CAST(Item AS INTEGER)
FROM SplitString(#sonvinid, ','))
ORDER BY
instructoreexpense.sonvinid
END
and when I execute the stored procedure like
exec profinalinstexpensesonid '01-01-2013','01-01-2017','andrews'
I am getting the following error
Msg 8152, Level 16, State 13, Procedure profinalinstexpensesonid, Line 10
String or binary data would be truncated.
On my line 10 I have the following code
insert into invoice(sonvinid, tid, date, brandname, zone, location, area, venuename, venue, instructore, amount)
I don't know what is wrong here?
The error message states the size of a column in invoice table is less compared to the size of the data being inserted into it.
For example if column brandname has data type varchar(50) and you are trying to insert more than 50 characters then it will cause error.
To resolve this compare the size of columns in invoice with the size of the columns being inserted.
You need to check column size of invoice table as well as columns in select list from which you are populating data.
Let's say you are inserting column "B" having data type as varchar(70) from table2 in column "A" having data type varchar(50) in table1; this won't work as you are trying to insert 70 characters in 50 varchar sized column.
Check source & destination column data type & it's length; and change it and try again.
I have three sql tables called financetrail , fooperson and idDog .All of them have the column idFoo :
I have created the following stored procedure
CREATE PROCEDURE [dbo].[getCustomerFinance] #idFinanceType INT
AS
BEGIN
SELECT idCustomer
FROM financetrail
where idFinanceType = #idFinanceType ;
END
GO
so i can dynamically choose customers of a certain finance type.
The above procedure generates a table along these lines:
I also have this query
SELECT firstName , lastName
FROM IdDog RIGHT JOIN fooPerson
ON IdDog.idFoo = fooPerson.idFoo WHERE IdDog.idIdDog IS NULL;
The result gives me all customers who don't have a dog in the dog table.
What i want to do ?
I want to create a stored procedure that would give me all the customers who don't have a valid idCard(query above) and are of a certain riskType defined from the stored procedure above .
What i have tried ?
I have tried doing the following :
ALTER PROCEDURE [dbo].[getMissingDogs]
AS
BEGIN
DECLARE #financeFilterTable table ( idCustomer INT)
INSERT INTO #financeFilterTable
EXEC getCustomerRisk 3
SELECT * FROM #financeFilterTable
SELECT firstName , lastName
FROM IdCard RIGHT JOIN FooPerson
ON IdCard.idCustomer = FooPerson.idFoo WHERE IdDog.idIdDog IS NULL;
END
and i get the following results :
In the current result set i have two tables . One table giving Customer ids for customers of a certain risk type and the second table giving the customers who don't have an idCard .
I want to find all customers who fulfill both criteria (have a certain risk type and not have an idCard ) in one table
Is that possible ?
I am not sure if I fully understand your requirement. Would it be possible please to post some sample data and expected query results?
Maybe the stored procecure below works for you?
ALTER PROCEDURE [dbo].[getMissingDogs]
#idFinanceType INT
AS
BEGIN
DECLARE #financeFilterTable table ( idCustomer INT)
INSERT INTO #financeFilterTable
EXEC getCustomerRisk #idFinanceType
SELECT firstName , lastName
FROM IdCard RIGHT JOIN FooPerson ON IdCard.idCustomer = FooPerson.idFoo
INNER JOIN #financeFilterTable AS RiskType ON RiskType.idCustomer = IdCard.idCustomer
WHERE IdDog.idIdDog IS NULL;
END