could any one help me finding the Error with SP - sql-server-2008

create function Fun12(#InsCd varchar)
returns varchar(100)
as
begin
declare #ret varchar(52)
set #ret = (select [InsName] from [Assignment4].[dbo].[1466]
where rtrim(ltrim([InsCd]))= #InsCd)
return #ret
end
Executing:
declare #r varchar(50)
exec #r = dbo.Fun12 '436'
select #r
I am getting NULL value.
Could any one please help me finding the error?

You need to specify a size for your parameter #InsCd.
Some thing like this but you might want to use another value than 20 depending on the size of field InsCd.
create function Fun12(#InsCd varchar(20))

First, you should make sure that the code contained by the function actually returns something when you run it directly in SQL Server Management Studio (SSMS):
-- SQL
select InsName from [1466] where rtrim(ltrim([InsCd])) = '436';
In this case, I would use a stored procedure rather than a function. You could also use the SSMS Profiler (Tools > Profiler) to monitor the traffic to SQL Server. This way, you can actually see what gets executed, see the parameters for SPs, etc.

Related

Use Varchar variable in FROM statement

I'm wondering if there is a way, after pragmatically giving a Varchar variable a value, to use that variable in the From Statement? We have archive tables that will cycle out and back in. So, the table can go missing for several days and when they cycle back in they change the table name to end w/ the current year (Ex. 012015 when before it was 012014.) Because of this my query can throw up object errors and I'm the only guy on my team that understands the simple error and how to quickly fix the stupid thing. below is the solution I'm trying to get to work, but I keep getting the error "Must declare the table variable #Jan." I totally understand what a table variable is and how to use it and that is obviously not what I want to do here. Is there any way to use a varchar variable (or other similar variable type) in the From Statement? Code below:
Declare #Jan Varchar(40)
IF OBJECT_ID('ColTelephonyArchive.dbo.ACDSkill201401') IS NOT NULL
Begin
Set #Jan = 'ColTelephonyArchive.dbo.ACDSkill201401'
END
IF OBJECT_ID('ColTelephonyArchive.dbo.ACDSkill201501') IS NOT NULL
Begin
Set #Jan = 'ColTelephonyArchive.dbo.ACDSkill201501'
END
IF #Jan IS NULL
Begin
Set #Jan = 'Does.Not.Exist'
END
Select WorkDte, SwitchNbr, SkillNbr,StaffTimeInSec, AvailableTimeInSec, ACDCallTotCt
,AbandonCallTotCt, AbandonCall1Ct, AnswerTimeInSec, ACDTalkTimeInSec,TotAcwTimeInSec, HoldTimeInSec
FROM #Jan
If I'm getting your problem right, you need to build the dynamic query. So in your case it would be
DECLARE #qry VARCHAR(511)
SET #qry = 'Select WorkDte, SwitchNbr, SkillNbr,StaffTimeInSec, AvailableTimeInSec, ACDCallTotCt
,AbandonCallTotCt, AbandonCall1Ct, AnswerTimeInSec, ACDTalkTimeInSec,TotAcwTimeInSec, HoldTimeInSec
FROM ' + #Jan
EXEC (#qry)

Variables not recognized in an Execute SQL task

I have this sql statements running in my ssis package. I have hard coded the email address. How can i pass it as variable and externalize the variable and can pass the value from config file?
The #PackageStartTime is the system start time. I have declared that variable and set the expression in property window with #[System::StartTime] and evaluated that expression. But when i run this package and when it hits this particular task it get stuck at there saying PackageStartTime parameter is not recognized and result property is not set correctly.
Here is my code:
DECLARE #PackageStartTime Varchar(250)
SET #PackageStartTime =?
IF (SELECT COUNT(*) FROM [dbo].[Table1] WHERE RowCDate >= #PackageStartTime) > 0
BEGIN
DECLARE #SUB Varchar(250)
SET #SUB = 'File Failed' + ##SERVERNAME
DECLARE #BODY Varchar(250)
SET #BODY = 'File Failed' + ##SERVERNAME
EXEC msdb.dbo.sp_send_dbmail
#profile_name='default',
#recipients='dev#null.com',
#subject=#SUB,
#body=#BODY,
#query= 'SELECT DISTINCT FileLoadName FROM [dbo].[Table1] WHERE RowCDate >= #PackageStartTime',
#attach_query_result_as_file=1
Any idea what to solve these two things?
Thanks in advance.
Maina, I just responded to your another post on this subject. You have three posts so far that I have encountered. The questions you have asked in this one are very general in nature and the answer can be found in any good book (such as Professional Microsoft SQL Server 2008 Integration Services). You can also find complete step-by-step answer on many websites (but do not use them as a replacement of a book; otherwise chances are your knowledge of SSIS will remain patchy.
With that said, here are two links that answer your questions:
1. Passing a variable: https://www.simple-talk.com/sql/ssis/passing-variables-to-and-from-an-ssis-task/ (Actually, it appears I had sent this link to you earlier as well.)
Assigning variable values from config - http://www.bidn.com/blogs/DevinKnight/ssis/1655/passing-values-into-an-ssis-package-at-runtime-from-outside-the-package
Focus on item 1 first. After you have practiced it, create a new Execute sql task and put just his much code inside it:
DECLARE #PackageStartTime Varchar(40)=?;
SELECT COUNT(*) FROM [dbo].[Table1] WHERE RowCDate >= #PackageStartTime;
and store this row count in a package variable iCount. Returning the value is done through ResultSet property. If you are able to make this task work, you have enhanced your proficiency in Execute SQL Task.

Replacement of Context_Info SQL Azure

I am currently using the CONTEXT_INFO property of the Master database for storing the logged in username to use it later in Table Triggers for auditing.
While migrating to SQL Azure, the issue of Cross-Database connections popped and I couldn't find direct solutions to this issue.
Following are the Issue Details:
I call Stored Procedure XXX from Data Access Layer and pass the Username as Parameter
The username is used to set the CONTEXT_INFO value in XXX
The CONTEXT_INFO value is then used in Tables Insert/Update/Delete Triggers to Store Username for Application Auditing
Solutions that I found so far:
Create Table In Database to work as CONTEXT_INFO
Use 2 Connection Strings in Data Access Layer, one for Master Database (to set CONTEXT_INFO) and the other is for the application and execute the SET CONTEXT_INFO each time before opening the connection to my application
But I find both solutions risky, specially when expanding the Database over multiple SQL Azure Databases in the future.
Appreciate your support.
The approach I took is shown below. On trick was to check to see running not running on SQL Azure, then we would need to call 'SET CONTEXT_INFO ...'. This allows the same code to be execute on local SQL Server Express and Azure without changes.
Create a table to store the context info (not in master but in the same database)
CREATE TABLE [dbo].[ContextInfo] (
[ContextInfo] varbinary(128) not null,
[ApplicationUsername] nvarchar(128) not null,
[UpdatedAt] datetime NOT NULL,
CONSTRAINT [PK_UserContextInfo] PRIMARY KEY CLUSTERED ([ContextInfo] ASC)
)
Create a stored procedure to 'Set Context Info' which is called from application
CREATE PROCEDURE [dbo].[SetContextInfo]
#ApplicationUsername nvarchar(128)
AS
SET NOCOUNT ON
-- Remove all context items older than an 5 minutes ago
DELETE
FROM [dbo].[ContextInfo]
WHERE [UpdatedAt] < DATEADD(mi, -5, GETUTCDATE())
--
-- Use the MERGE command to do an update/insert
-- See: http://technet.microsoft.com/en-us/library/bb510625.aspx
--
IF SERVERPROPERTY('edition') <> 'SQL Azure'
BEGIN
DECLARE #b varbinary(128)
SET #b = CONVERT(varbinary(128),newid())
EXEC sp_executesql #statement=N'SET CONTEXT_INFO #b',#params=N'#b varbinary(128)',#b=#b
END
DECLARE #ContextInfo varbinary(128)
SELECT #ContextInfo = CONTEXT_INFO()
MERGE [dbo].[ContextInfo] AS target
USING (SELECT #ContextInfo, #ApplicationUsername) AS source ([ContextInfo], [ApplicationUsername])
ON (target.[ContextInfo] = source.[ContextInfo])
WHEN MATCHED THEN
UPDATE SET [ApplicationUsername] = source.[ApplicationUsername], [UpdatedAt] = GETUTCDATE()
WHEN NOT MATCHED THEN
INSERT ([ContextInfo], [ApplicationUsername], [UpdatedAt])
VALUES (source.[ContextInfo], source.[ApplicationUsername], GETUTCDATE());
Create a stored procedure to 'Get Context Info'
CREATE PROCEDURE [dbo].[GetContextInfo]
AS
SET NOCOUNT ON
DECLARE #ContextInfo varbinary(128)
SELECT #ContextInfo = CONTEXT_INFO()
SELECT [ApplicationUsername]
FROM [dbo].[ContextInfo]
WHERE [ContextInfo] = #ContextInfo
GO
In trigger source, use:
DECLARE #UserContext TABLE ([Username] VARCHAR(128))
INSERT INTO #UserContext (Username)
EXEC [dbo].[GetContextInfo]
Now you have the username stored in the table variable. In case changes are applied by an administrator outside of your application, you may also want to check if the username was not set and default to something like *SYSTEM_USER*.

able to select multiple dates (parameter) in ssrs

Is there a way where in I can select multiple dates and pass it as my parameters for a stored proc for a report in ssrs. selecting allow multiple values for a parameter gives a dropdown list. but can i get a calender control where I can select Multiple dates.
SQL Server Reporting Services, as of version 2008R2, does not have this functionality built in. I haven't looked at 2012, but I'd be surprised if it offered this.
(You can always build your own interface using a ReportViewer control, URL access or another access method to display reports.)
As Jamie stated, you can't really do this. The "best" work around I have come across in my experience is to pass your parameter value(s) as one text string, and use a split function to parse in your WHERE condition in the stored proc.
USE [YOUR DATABASE]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[split](
#delimited NVARCHAR(MAX),
#delimiter NVARCHAR(100)
) RETURNS #t TABLE (id INT IDENTITY(1,1), val NVARCHAR(MAX))
AS
BEGIN
DECLARE #xml XML
SET #xml = N'<t>' + REPLACE(#delimited,#delimiter,'</t><t>') + '</t>'
INSERT INTO #t(val)
SELECT r.value('.','varchar(MAX)') as item
FROM #xml.nodes('/t') as records(r)
RETURN
END
Your parameter would be something like this in your stored proc:
#Parameter VARCHAR(200)
Then your where condition in your stored proc will be something like this
where convert(varchar(10), cast([YOURDATE] as date), 101) IN (select val from dbo.split(#Paramater,','))
I hope this helps!

How do I avoid timeouts with SqlServer full text search?

We're using SqlServer 2008. In SSMS, queries on the full text catalog might take 2-5 seconds the first time, but after that, return quite quickly.
On the other hand, running a query from via Linq2Sql will timeout.
Here's what we have:
The SQL Inline Table UDF
CREATE FUNCTION dbo.SearchArchiveFTS
(
#query nvarchar(255)
)
RETURNS #ret TABLE
(
ID NVarChar(12) NOT NULL,
snapshotDate DateTime NOT NULL,
-- about 10 more
)
AS BEGIN
declare #innerQuery nvarchar(255)
set #innerQuery = #query
insert into #ret
select ID,
snapshotDate,
-- about 10 more
from dbo.Archive a
where contains(a.*, #innerQuery)
return
Query in SSMS
select * from dbo.SearchArchiveFTS('query')
//3 seconds / 3k rows
Query in Linq2Sql
db.SearchArchiveFTS("query").ToArray();
// timeout exception
Any ideas on what the problem might be?
Check that your connection is not coming in with arithabort off. In SSMS it is ON
you can easily check like this
select arithabort,*
from sys.dm_exec_sessions
where is_user_process =1
just find the SPID that is hitting the DB
You also try to see what happens when you do this in SSMS
SET ARITHABORT OFF
select * from dbo.SearchArchiveFTS('query')
Does it now take a lot longer?
It is also possible that you are getting a bad plan from LINQ
You can clean out the procedure cache and memory buffers by running the following command
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
Just be aware that it will wipe out all the plans on the server and SQL Server will have to recreate all of those and also read in all the data from disk again.......
I agree with #SQLMenace, when somehthing runs fast in SSMS but not from the application, it is usually a connection difference.
However, why use a function for something like that?
if you must use a function, why not use a table value function like this:
CREATE FUNCTION dbo.SearchArchiveFTS
(
#query nvarchar(255)
)
RETURNS TABLE
AS RETURN
(
select ID,
snapshotDate,
-- about 10 more
from dbo.Archive a
where contains(a.*, #query)
);
The issue appears to be related to a feature of SQL Server, where the FTS indices are unloaded after a period of inactivity. A background job to keep them fresh solved the problem.