SQL Server Stored Procedure insert query with given parameters - sql-server

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

Save dynamic result from stored procedure into a dynamic table

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.

TSQLT Database Unit test

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.

Reading specific value with Openrowset in SQL Server 2016

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 way to toggle user defined column name or default column name in stored procedure

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.

Setting a variable to a certain value or default to all values in a column

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

Resources