first of all, sorry for my English,
I am a newbie in stored procedure, so i'm seek for a help on it.
I have a project that need me to create a SP for a configurable table name and column name. I've manage to pass the table name and column name value from vb/vb.net and now i'm stuck on SP, below are sample of my code.
example :
frmTblname = table_a
frmClmnName = clm_A1, clm_A2, clm_A3, clm_A4, clm_A5,
toTblName = table_b,
toClmnName = clmn_b1,clmn_b2, clmn_b3, clmn_b4, clmn_b5
from vb/vb.net Rslt = ConnectionExec.RunSP(con, "sp_configurable_insert", frmTblname, frmClmnName, toTblName, toClmnName)
how to add that into SQL insert query?
Here are my SP
CREATE procedure [dbo].[sp_configurable_insert] #fromTable nvarchar(50),#fromColumn nvarchar(4000),#toTable nvarchar(50),#toColumn nvarchar(4000)
I've tried this but it seems not giving any result.
set #Query1 = 'insert into '+#toTable+'('+quotename(#toColumn)+')
select top 20 '+#fromColumn+'
from '+#fromTable+'
can anyone help me, please?
Thanks :)
Things to change:
quotename(#toColumn) will return '[clmn_b1,clmn_b2, clmn_b3, clmn_b4, clmn_b5]' which is not correct. Remove quotename() or set #toColumn = '[clmn_b1], [clmn_b2], [clmn_b3], [clmn_b4], [clmn_b5]'.
your query statement is unfinished.
Stored procedure (with correct syntax):
CREATE procedure [dbo].[sp_configurable_insert]
#fromTable nvarchar(50),
#fromColumn nvarchar(4000),
#toTable nvarchar(50),
#toColumn nvarchar(4000)
AS
BEGIN
DECLARE
#stm nvarchar(max),
#err int
SET #stm =
N'insert into '+#toTable+' ('+#toColumn+') select top 20 '+#fromColumn+' from '+#fromTable
EXEC #err = sp_executesql #stm
IF #err <> 0 BEGIN
RETURN #err
END
RETURN 0
END
you need to add EXECUTE(#Query1) to your SP and it will work
Add at the end of your query:
exec sp_executesql #Query1
So it should look like:
set #Query1 = 'insert into '+#toTable+'('+quotename(#toColumn)+')
select top 20 '+#fromColumn+'
from '+#fromTable+'
exec sp_executesql #Query1
So pay attention that #Query1 is incomplete or contains error coz quotes is unbalanced.
Related
I am facing some issues in saving the execution of stored procedure / scalar function into a table variable.
The function / stored procedure returns dynamic columns and I need to create a dynamic table to save the result of that function into it so that I can use the table.
Example: the stored procedure spGetEmployeeInfo could return employee name, employee id, etc. on such criteria they return only employee name,.
Is there a way to create a dynamic table and save the result into it after execute the stored procedure, or any suggestion.
Thanks
I don't like to get into this situation too often, but when I do, what I do is have the stored proc output into a global temp table. The name of the table is passed in as a parameter by the user. For instance:
create procedure dynamicBeCareful
#toggle bit,
#globalTempTableName varchar(50)
as
-- initializations
if left(#globalTempTableName,2) <> '##'
throw 50000, '#globalTempTableName must start with ##', 1;
declare #sql varchar(max);
-- build dynamic sql
if #toggle = 1
set #sql = 'select * into #tempTable from table1';
else
set #sql = 'select * into #tempTable from table2';
set #sql = replace(#sql, '#tempTable', #globalTempTableName);
-- terminations
exec (#sql);
declare #msg = 'Your results are in ' + #globalTempTableName;
print (#msg);
Then use it like this:
exec dynamicBeCareful 1, '##temp';
select * from ##temp;
Beyond just being dynamic in output, it also can get you out of nested insert-exec limitations.
I am trying to hands on with TSQLT unittest framework for first time and have come across a problem. I have a stored proc like this which returns some numbers
Use Mydatabase
Declare #parameter1, #parameter2,#paramter3
BEGIN
SELECT #parameter1 = dbo.[function](#paramter2,parameter3)
..
..
-- Now some Dynamic SQL joins on two tables
BEGIN
SET #SQL = 'SELECT COLUMN1, COLUMN2 FROM FROM TABLE1 INNER JOIN TABLE2 ON TABLE1.COLUMN1 =
TABLE2.COLUMN2 WHERE TABLE2.COLUMN3 = + CAST(#parameter1 as varchar(10))
EXECUTE sp_executesql #SQL, Output parameter
return
The problem is the table1 and table2 are updated daily and I can't assert to values that are changing so I came across fake tables and spy procedures,
Is there a way to utilize the spyprocedures to use the faketables rather than original tables.?
Since my actual db and Unit test db are different but with in same connection, how can I reference the actual to the test one as I am getting error as
Cannot use SpyProcedure on [WD0000\server].[database].[dbo].[usp.mystoredproc] because the procedure does not exist
TSQLT code
EXEC tSQLt.NewTestClass 'SegmentSizeTest'
GO
CREATE PROCEDURE SegmentSizeTest.[test that checks the segment size]
AS
BEGIN
DECLARE #return_value int,#TotalCount int,#OneCount int,#TwoCount int
declare #Criteria Varchar(MAX)
declare #rampUpFactor int
declare #expected int
declare #actual int
SET #Criteria = 'My Criteria'
SET #GeoflexCriteria = NULL
--#TotalCount = #TotalCount OUTPUT
--#OneCount = #OneCount OUTPUT
-- #TwoCount = #TwoCount OUTPUT
SET #rampUpFactor = 1
set #expected = 160486
------Fake Table
EXEC tSQLt.FakeTable 'UnitTest.Household';
EXEC tSQLT.FakeTable 'UnitTest.Customer';
--
..Insert to UnitTest.Household and UnitTest.Customer tables
------Execution
EXEC #return_value = [VAReportingDB].[dbo].[GetSegmentSize]
#Criteria = #Criteria,
#TotalCount = #TotalCount OUTPUT,
#OneCount = #OneCount OUTPUT,
#TwoCount = #TwoCount OUTPUT
SELECT #TotalCount as N'#TotalCount',
#OneCount as N'#OneCount',
#TwoCount as N'#TwoCount'
------Assertion
EXEC tSQLt.AssertEquals #expected, #TotalCount;
END;
GO
FakeTable replaces the original table wit a test double. Therefore any code that is written to access the original table, dynamically or otherwise, will “see” the faked table during a test.
Independently, you should pass in #parameter1 to sp_executesql instead of concatenating it into your Sql statement. At least if your original code is similar to what you posted here.
The aim here is to read a specific value from a different server and store the return value in a local parameter for use later.
Here is the error code:
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near 'Alarm'.
Here is the code I have tried:
declare #sql_string nvarchar(400);
declare #inhostnamn nvarchar(100) = 'BLUE65\SQLEXPRESS'
declare #inuser nvarchar(50) = 'dev1'
declare #password1 nvarchar(50) = 'dev1'
declare #database nvarchar(100) = 'Test_destroy'
declare #count_posts varchar(10)
declare #tabellnamn varchar(50) = 'Alarms'
declare #last_read_alarm varchar(30)
set #tabellnamn = 'Logg'
set #sql_string = N'set #last_read_alarm1 = cast(last_read as nvarchar(30)) select * from openrowset (''SQLNCLI'', ''Server='+#inhostnamn+';UID='+#inuser+';Pwd='+#password1+';Database='+#database+';Persist Security Info=True'',''select Last_ID FROM '+#database +'.dbo.Logg where Tables_sql=''Alarm'' '')';
print 'string =' + #sql_string;
exec sp_executesql #sql_string, N'#last_read_alarm1 varchar(30) OUTPUT', #last_read_alarm1=#last_read_alarm OUTPUT;
select #last_read_alarm
print #last_read_alarm;
Now I am stuck. I cannot see the error I have made, and am hoping for a couple of different eyes.
Thanks to Andrei Odegov for great assistance. It helped putting 4 ' on each side.
The correct code would be in my case now:
set #sql_string = N'select #last_read_alarm= (select * from openrowset (''SQLNCLI'', ''Server='+#inhostnamn+';UID='+#inuser+';Pwd='+#password1+';Database='+#database+';Persist Security Info=True'',''select Last_ID FROM '+#database +'.dbo.Logg where Tables_sql='''''+#tmp_str+''''' ''))';
So the answer from the query will now end up in local variable #last_read_alarm.
What is the best approach for stored procedure to toggle between user defined column names or default column name
Here is what I have done so far. This is fine for small query, is there a better way of doing this for larger query.
-- Drop stored procedure if it already exists
IF EXISTS(SELECT * FROM sys.procedures
WHERE schema_id = schema_id('dbo')
AND name = N'sp_test')
DROP PROCEDURE dbo.sp_test
GO
CREATE PROCEDURE [dbo].[sp_test]
-- /* Declare parameters */
#columnName BIT =0
AS
BEGIN
-- SELECT statement to fetch record
IF(#columnName =1)
(
SELECT
TOP 100
IM.INC_REF,
IM.ID
FROM
dbo.TEST AS IM
)
ELSE
(
SELECT
TOP 100
IM.INC_REF AS REF,
IM.ID AS ID
FROM
dbo.TEST AS IM
)
END
GO
-- ============================================
-- Execute stored procedure
-- ============================================
DECLARE #columnName AS BIT
SET #columnName =0
EXEC [dbo].[sp_test] #columnName
Thanks in advance
When we need different results from a stored procedure based on a parameter, we'll call one of two "sub" stored procedures. In your case, that would be:
CREATE PROCEDURE [dbo].[sp_test]
-- /* Declare parameters */
#columnName BIT = 0
AS
BEGIN
IF ( #columnName = 1 )
EXEC dbo.[sp_test1]
ELSE
EXEC dbo.[sp_test2]
END
GO
CREATE PROCEDURE dbo.[sp_test1]
AS
BEGIN
SELECT TOP 100
IM.INC_REF ,
IM.ID
FROM dbo.TEST AS IM
END
GO
CREATE PROCEDURE dbo.[sp_test2]
AS
BEGIN
SELECT TOP 100
IM.INC_REF AS REF ,
IM.ID AS ID
FROM dbo.TEST AS IM
END
GO
I've found this gets around the issue of badly cached plans.
Sorry if my heading is very clear. I am trying to create a stored procedure :
Create Procedure Pro1 #a nvarchar = null, #b nvarchar =null
as
Select * from table1
where Parameter1 = '1'
and Parameter2 = #a
go
Above is not the actual code but i hope it explains what i am trying to achieve. I am selecting on two parameters. 'Parameter2' depends on the variable #a. The challenge i have is that if #a remains null at execution; i want the select statement to search on all values of Parmeter2 as if the 'and' statement was not there. I could write a if else statement to execute different selects but i was hoping i could simply set #a to some sort
of wildcard value that would simply do this? Maybe something : 'like []'?
CREATE PROCEDURE dbo.Pro1 -- use schema prefix when creating objects!
#a NVARCHAR(32) = NULL -- 32 should match data type of Parameter2 column
AS
BEGIN -- wrap your body and indent for readability
SET NOCOUNT ON; -- should always turn off DONE_IN_PROC messages
SELECT columns -- please name your columns instead of SELECT *
FROM dbo.table1 -- use schema prefix when referencing objects
WHERE (Parameter2 = #a OR #a IS NULL); -- semi-colons please!
END
GO
In some cases you may find that if you have a lot of these optional parameters, SQL Server will compile a plan for one set of parameters and that plan will not be very beneficial for different parameters. So you may want something like this:
CREATE PROCEDURE dbo.Pro1
#a NVARCHAR(32) = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'SELECT columns FROM dbo.table1 WHERE 1=1';
IF #a IS NOT NULL
SET #sql += ' AND Parameter2 = #a';
EXEC sp_executesql #sql,
N'#a NVARCHAR(32)',
#a;
END
GO