I have made functions and views in SQL server. I excuted them and they are successfuly stored.
Now what should I write to use these views or functions in another query?!
I have tried
select something
from FunctionName;
but system doesn't recongnize the function.
the function is:
create function TableOfDecades ()
returns #functiontable table
(
decadeBegin int,
decadeEnd int,
NumOfMovies int
)
as
begin
declare #movie1 int;
declare #movie2 int;
declare #movie3 int;
declare #movie4 int;
declare #movie5 int;
declare #year1 int;
declare #year2 int;
select #movie1 = count(id)
from MOVIE
where year >=1350 and year <1360;
select #movie2 = count(id)
from MOVIE
where year >=1360 and year <1370;
select #movie3 = count(id)
from MOVIE
where year >=1370 and year <1380;
select #movie4 = count(id)
from MOVIE
where year >=1380 and year <1390;
select #movie5 = count(id)
from MOVIE
where year >=1390 and year <1400;
declare #maxOfMovies int;
set #maxOfMovies = -1;
if( #movie1 > #maxOfMovies )
begin
set #maxOfMovies = #movie1;
set #year1 = 1350;
set #year2 = 1360;
end
if( #movie2 > #maxOfMovies )
begin
set #maxOfMovies = #movie2;
set #year1 = 1360;
set #year2 = 1370;
end
if( #movie3 > #maxOfMovies )
begin
set #maxOfMovies = #movie3;
set #year1 = 1370;
set #year2 = 1380;
end
if( #movie4 > #maxOfMovies )
begin
set #maxOfMovies = #movie4;
set #year1 = 1380;
set #year2 = 1390;
end
if( #movie5 > #maxOfMovies )
begin
set #maxOfMovies = #movie5;
set #year1 = 1390;
set #year2 = 1400;
end
insert into #functiontable
select #maxOfMovies, #year1, #year2;
RETURN;
end
that I excuted it and it saved in folder programmability->functions->table-valued functions
Following should work ..
SELECT decadeBegin, decadeEnd, NumOfMovies
FROM dbo.TableOfDecades();
Your function needs to specifically return a Table type before it can be used by another sql call.
see http://technet.microsoft.com/en-us/library/ms191165%28v=sql.105%29.aspx
different implementations of SQL have different formats for referring to the Table-Valued Functions..
Related
I need to optimize the Procedure below. Syntax should be in Informix.
Here a table update is required with sequential update. It seems to be very large.Can it be optimized.
CREATE OR REPLACE PROCEDURE ENTRY() LANGUAGE SQL
BEGIN ATOMIC
DECLARE record integer;
DECLARE txaa_id bigint;
DECLARE id bigint;
DECLARE createDatetimed timestamp;
DECLARE idPlus bigint;
set record = 0;--
set txaa_id = 0;--
set id = 0;--
set idPlus = 0;--
set createDatetimed = null;--
FOR v_row1 as select distinct txaa_id from finalBaseData
DO
FOR v_row2 as select txsa_id , finalBaseData.txaa_id , finalBaseData.createdatetime from tx_status_audit,finalBaseData where tx_status_audit.txaa_id = v_row1.txaa_id and tx_status_audit.txaa_id = finalBaseData.txaa_id and tx_status_audit.cdts = 'OUT' order by tx_status_audit.create_datetime desc fetch first 1 rows only
DO
set record = record + 1;
IF ( record = 1)
THEN
set id = v_row2.txsa_id;
set idPlus = id + 1;
set txaa_id = v_row2.txaa_id;
set createDatetimed = v_row2.createdatetime;
END IF;
END FOR;
insert into tx_status_audit values (idPlus,'CMPT',txaa_id,'HWNG',createDatetimed);
set record = 0;
set idPlus = 0;
set txaa_id = 0;
set createDatetimed = null;
END FOR;
END;
Below is the code snippet in which MIN function using. When execute below code it is giving an error.
CREATE FUNCTION [dbo].[FN_TempCalcTransportExemp]
(
#EmployeeID varchar(20),
#PayElement varchar(20),
#Month varchar(10),
#FinYear varchar(10)
)
RETURNS decimal
AS
BEGIN
DECLARE #TarnsportExemption decimal(18,2) = 0
DECLARE #TDSIsFullExemption bit
DECLARE #PermanentPhysicalDisability decimal(18,2) = 0
DECLARE #UsingComapnyCar bit
DECLARE #Conveyance decimal(18,2) = 0
DECLARE #TransYes decimal(18,2) = 0
DECLARE #TransNo decimal(18,2) = 0
DECLARE #MinConveyance decimal(18,2) = 0
DECLARE #MinTransport decimal(18,2) = 0
SELECT
#TDSIsFullExemption = TDSDetailsFullExemption,
#TransYes = TDSDetailsYes,
#TransNo = TDSDetailsNo
FROM
tbl_TDSSettingDetails
WHERE
TDSSettingsDetailID = 2
SELECT
#Conveyance = #Month
FROM
tbl_Income
WHERE
EmployeeID = #EmployeeID
AND Element = #PayElement
AND FinancialYear = #FinYear
SELECT
#UsingComapnyCar = UsingCompanyCar,
#PermanentPhysicalDisability = PermanentPhysicalDisability
FROM
tbl_Employee_TDS
WHERE
EmployeeID = #EmployeeID
AND TDSFinancialYear = #FinYear
IF (#TDSIsFullExemption = 1)
BEGIN
SET #TarnsportExemption = #Conveyance
END
ELSE
BEGIN
IF (#UsingComapnyCar = 1)
BEGIN
IF (#Conveyance = 0)
BEGIN
SET #MinConveyance = 0
END
ELSE
BEGIN
SET #MinConveyance = #Conveyance
END
IF (#PermanentPhysicalDisability = 1)
BEGIN
SET #MinTransport = #TransYes
END
ELSE
BEGIN
SET #MinTransport = #TransNo
END
SET #TarnsportExemption = MIN(#MinConveyance, #MinTransport)
END
ELSE
BEGIN
SET #TarnsportExemption = 0
END
END
RETURN #TarnsportExemption
END
Error Message:
Msg 174, Level 15, State 1, Procedure FN_TempCalcTransportExemp, Line
66
The MIN function requires 1 argument(s).
set #TarnsportExemption = MIN(#MinConveyance,#MinTransport) - The MIN function is not what you think it is.
You probably want to do something like this:
set #TarnsportExemption = CASE WHEN #MinConveyance < #MinTransport THEN
#MinConveyance
ELSE
#MinTransport
END
Another option is this:
SELECT #TarnsportExemption = MIN(val)
FROM
(
SELECT #MinConveyance as val
UNION ALL
SELECT #MinTransport as val
)
And one more option is to use the values clause:
SELECT #TarnsportExemption = MIN(val)
FROM (VALUES ( #MinConveyance), (#MinTransport)) AS value(val)
Change your min statement like below MIN. Please refer MIN (Transact-SQL)
--fROM
set #TarnsportExemption = MIN(#MinConveyance,#MinTransport)
--To
SELECT #TarnsportExemption = MIN(A) FROM (
SELECT #MinConveyance A
UNION ALL
SELECT #MinTransport
)AS AA
In SQL, MIN function will return you minimum value of a column from selected list; so you can use MIN only in inline queries.
e.g. Select min(Salary) from Tbl_Employee
So, in your case either you can use case when then or union all to get minimum value from two variables as:-
SET #TarnsportExemption = CASE WHEN #MinConveyance < #MinTransport THEN #MinConveyance ELSE #MinTransport END
OR
SELECT #TarnsportExemption = MIN(TEMPS.[VALUE])
FROM (
SELECT #MinConveyance AS VALUE
UNION ALL
SELECT #MinTransport AS VALUE
) AS TEMPS
I'm trying to create a procedure to verify annual dates. The date is stored one time in the BD, but in the calendar on my winform it shows annually(I use annually bolded dates in C#). So what I want to do with the query, is to check is the month and the day are like the date stored in the table, but does not work. This is my query:
SELECT IdCalendar,
Description,
DateCalendar,
Annualy
FROM Calendar
WHERE
(DATEPART(MONTH,DateCalendar) like DATEPART(MONTH,#DateCalendar)) AND
(DATEPART(DAY,DateCalendar) like DATEPART(DAY,#DateCalendar))
And for example, my stored DateCalendar is '2015-12-04', and I my paramenter #DateCalendar is '2016-12-04'. Any idea about how to do a better query?
EDIT
The query does not have any error or warning. Just returns 0 rows. And my DateCalendar is stored as DateTime.
The SP:
CREATE PROC [dbo].[usp_app_Calendar_Search]
#DateCalendar DATETIME,
#Result SMALLINT OUTPUT,
#Message VARCHAR(1000) OUTPUT
AS
BEGIN
DECLARE #vResult SMALLINT, #vMessage VARCHAR(1000)
SELECT #vResult = 0, #vMessage = ''
BEGIN TRY
IF EXISTS (SELECT * FROM Calendar WHERE DateCalendar = #DateCalendar)
BEGIN
IF(#DateCalendar = 0) SET #DateCalendar = NULL
SELECT IdCalendar,
Description,
DateCalendar,
Annualy
FROM Calendar
WHERE
(DATEPART(MONTH,DateCalendar) like DATEPART(MONTH,#DateCalendar)) AND
(DATEPART(DAY,DateCalendar) like DATEPART(DAY,#DateCalendar))
SET #vResult = 1
SET #vMessage = 'Done'
END
ELSE BEGIN
SET #vResult = 0
SET #vMessage = 'Error.'
END
END TRY
BEGIN CATCH
SET #vResult = -1
SET #vMessage = 'Error: ' + ERROR_MESSAGE() + ' Line: ' + CAST(ERROR_LINE() AS VARCHAR)
END CATCH
SELECT #Result = #vResult, #Message = #vMessage
END
Thanks in advance.
The problem is with IF EXISTS (SELECT * FROM Calendar WHERE DateCalendar = #DateCalendar). I rewrite your SP:
CREATE PROC [dbo].[usp_app_Calendar_Search]
#DateCalendar DATETIME,
#Result SMALLINT OUTPUT,
#Message VARCHAR(1000) OUTPUT
AS
BEGIN
DECLARE #vResult SMALLINT = 0
,#vMessage VARCHAR(1000) = '';
IF(#DateCalendar = 0) SET #DateCalendar = NULL;
BEGIN TRY
SELECT IdCalendar,
Description,
DateCalendar,
Annualy
FROM Calendar
WHERE DATEPART(MONTH,DateCalendar) = DATEPART(MONTH,#DateCalendar)
AND DATEPART(DAY,DateCalendar) = DATEPART(DAY,#DateCalendar);
IF ##ROWCOUNT > 0
SELECT #vResult = 1, #vMessage = 'Done'
ELSE
SELECT #vResult = 0, #vMessage = 'Error.';
END TRY
BEGIN CATCH
SET #vResult = -1
SET #vMessage = 'Error: ' + ERROR_MESSAGE() + ' Line: '
+ CAST(ERROR_LINE() AS VARCHAR)
END CATCH
SELECT #Result = #vResult, #Message = #vMessage;
END
EDIT:
Now the WHERE condition is not-SARGable so it means that query optimizer will skip index on DateCalendar column (if exists any).
You can use computed columns like #Tom Page suggested in comment:
ALTER TABLE Calendar ADD MonthCalendar AS DATEPART(MONTH,DateCalendar);
ALTER TABLE Calendar ADD DayCalendar AS DATEPART(day,DateCalendar);
/*Create Index on Calculated Columns for Month and day*/
CREATE INDEX IX_Calendar_Month_Day ON Calendar(MonthCalendar , DayCalendar);
/*Use Computed Column Index in W*/
DECLARE #DateCalendar datetime = '2015-12-25';
SELECT IdCalendar, Description, DateCalendar, Annualy
FROM Calendar
WHERE MonthCalendar = DATEPART(MONTH,#DateCalendar)
AND DayCalendar = DATEPART(DAY,#DateCalenda);
I am getting the following error
An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Add a name or single space as the alias name.
for the query show below:
CREATE PROC [dbo].[Sp_Table1] #ctlg_ipt_event_id int
AS
SET NOCOUNT ON
DECLARE #current_status NCHAR(1), #ready_status_code NCHAR(1)
DECLARE #current_action NCHAR(1), #ready_action_code NCHAR(1), #done_action_code NCHAR(1)
DECLARE #pst_user_id int
SELECT #current_status = status_code
,#current_action = action_code
,#pst_user_id = last_mod_user_id
FROM merch_ctlg_ipt_event
WHERE ctlg_ipt_event_id = #ctlg_ipt_event_id
Select #ready_status_code = 'o'
, #ready_action_code = 'a'
, #done_action_code = 'b'
IF #current_status <> #ready_status_code OR #current_action <> #ready_action_code
BEGIN
RETURN
END
BEGIN TRAN
declare #rows int
,#err int
,#i int
,#name nvarchar(50) --COLLATE SQL_AltDiction_Pref_CP850_CI_AS
,#resolved_View_Name_category_id int
,#xref_value int
,#availability_start_date datetime
,#availability_end_date datetime
,#status_code int
,#last_mod_user_id int
,#CT datetime
,#supplier_id int
,#View_Name_id int
select #i = 1
,#CT = current_timestamp
Select Distinct mc.name,
mc.resolved_View_Name_category_id,
mc.xref_value,
mc.availability_start_date,
mc.availability_end_date,
mc.status_code,
CASE WHEN mc.last_mod_user_id = 42
THEN #pst_user_id
ELSE mc.last_mod_user_id
END as last_mod_user_id,
CURRENT_tsp
,IDENTITY(int,1,1) as rn
,si.supplier_id
,si.View_Name_id
into #temp
FROM View_Name AS si
JOIN merch_ctlg_ipt_View_Name AS mc
ON mc.supplier_id = si.supplier_id
AND mc.resolved_View_Name_id = si.View_Name_id
AND mc.cat_imp_event_id = #ctlg_ipt_event_id
AND mc.accept_flag = 'y'
WHERE si.shipper_flag = 'n'
select #rows=##ROWCOUNT,#err=##error
if #rows > 0 and #err=0
Begin
While #i <=#rows
begin
SElect #name = name,
#resolved_View_Name_category_id = resolved_View_Name_category_id,
#xref_value = xref_value,
#availability_start_date = availability_start_date,
#availability_end_date = availability_end_date,
#status_code = mc.status_code,
#last_mod_user_id =last_mod_user_id ,
,#i=#i+1
,#supplier_id=supplier_id
,#View_Name_id=View_Name_id
from #temp
Where rn=#i
UPDATE View_Name
SET name = #name,
View_Name_category_id = #resolved_View_Name_category_id,
xref_value = #xref_value,
availability_start_date = #availability_start_date,
availability_end_date = #availability_end_date,
status_code = #status_code,
last_mod_user_id = #last_mod_user_id ,
last_mod_timestamp = #CT
Where #sup_id = supplier_id
AND #View_Name_id = View_Name_id
AND shipper_flag = 'n'
IF ##ERROR > 0
BEGIN
ROLLBACK TRAN
RETURN
END
End
End
UPDATE
merch_ctlg_ipt_event
SET action_code = #done_action_code,
last_mod_timestamp = #CT
WHERE ctlg_ipt_event_id = #ctlg_ipt_event_id
IF ##ERROR > 0
BEGIN
ROLLBACK TRAN
RETURN
END
COMMIT TRAN
Return
go
Could you please help ?
You have 2 commas in a row here
#last_mod_user_id =last_mod_user_id ,
,#i=#i+1
Also probably not relevant to the error message but you have a line
Where #sup_id = supplier_id
but the declared variable is #supplier_id
I have a string 'some.file.name',I want to grab 'some.file'.
To do that,I need to find the last occurrence of '.' in a string.
My solution is :
declare #someStr varchar(20)
declare #reversedStr varchar(20)
declare #index int
set #someStr = '001.002.003'
set #reversedStr = reverse(#someStr)
set #index = len(#someStr) - charindex('.',#reversedStr)
select left(#someStr,#index)
Well,isn't it too complicated?I was just intented to using 'some.file' in a where-clause.
Anyone has a good idea?
What do you need to do with it?? Do you need to grab the characters after the last occurence of a given delimiter?
If so: reverse the string and search using the normal CHARINDEX:
declare #test varchar(100)
set #test = 'some.file.name'
declare #reversed varchar(100)
set #reversed = REVERSE(#test)
select
REVERSE(SUBSTRING(#reversed, CHARINDEX('.', #reversed)+1, 100))
You'll get back "some.file" - the characters up to the last "." in the original file name.
There's no "LASTCHARINDEX" or anything like that in SQL Server directly. What you might consider doing in SQL Server 2005 and up is great a .NET extension library and deploy it as an assembly into SQL Server - T-SQL is not very strong with string manipulation, whereas .NET really is.
A very simple way is:
SELECT
RIGHT(#str, CHARINDEX('.', REVERSE(#str)) - 1)
This will also work:
DECLARE
#test VARCHAR(100)
SET #test = 'some.file.name'
SELECT
LEFT(#test, LEN(#test) - CHARINDEX('.', REVERSE(#test)))
Take one ')'
declare #test varchar(100)
set #test = 'some.file.name'
select left(#test,charindex('.',#test)+charindex('.',#test)-1)
CREATE FUNCTION [dbo].[Instr] (
-------------------------------------------------------------------------------------------------
-- Name: [dbo].[Instr]
-- Purpose: Find The Nth Value Within A String
-------------------------------------------------------------------------------------------------
-- Revisions:
-- 25-FEB-2011 - HESSR - Initial Revision
-------------------------------------------------------------------------------------------------
-- Parameters:
-- 1) #in_FindString - NVARCHAR(MAX) - INPUT - Input Find String
-- 2) #in_String - NVARCHAR(MAX) - INPUT - Input String
-- 3) #in_StartPos - SMALLINT - INPUT - Position In The String To Start Looking From
-- (If Start Position Is Negative, Search Begins At The End Of The String)
-- (Negative 1 Starts At End Position 1, Negative 3 Starts At End Position Minus 2)
-- 4) #in_Nth - SMALLINT - INPUT - Nth Occurrence To Find The Location For
-------------------------------------------------------------------------------------------------
-- Returns: SMALLINT - Position Of String Segment (Not Found = 0)
-------------------------------------------------------------------------------------------------
#in_FindString NVARCHAR(MAX),
#in_String NVARCHAR(MAX),
#in_StartPos SMALLINT = NULL,
#in_Nth SMALLINT = NULL
)
RETURNS SMALLINT
AS
BEGIN
DECLARE #loc_FindString NVARCHAR(MAX);
DECLARE #loc_String NVARCHAR(MAX);
DECLARE #loc_Position SMALLINT;
DECLARE #loc_StartPos SMALLINT;
DECLARE #loc_Nth SMALLINT;
DECLARE #loc_Idx SMALLINT;
DECLARE #loc_FindLength SMALLINT;
DECLARE #loc_Length SMALLINT;
SET #loc_FindString = #in_FindString;
SET #loc_String = #in_String;
SET #loc_Nth = ISNULL(ABS(#in_Nth), 1);
SET #loc_FindLength = LEN(#loc_FindString+N'.') - 1;
SET #loc_Length = LEN(#loc_String+N'.') - 1;
SET #loc_StartPos = ISNULL(#in_StartPos, 1);
SET #loc_Idx = 0;
IF (#loc_StartPos = ABS(#loc_StartPos))
BEGIN
WHILE (#loc_Idx < #loc_Nth)
BEGIN
SET #loc_Position = CHARINDEX(#loc_FindString,#loc_String,#loc_StartPos);
IF (#loc_Position > 0)
SET #loc_StartPos = #loc_Position + #loc_FindLength
ELSE
SET #loc_Idx = #loc_Nth;
SET #loc_Idx = #loc_Idx + 1;
END;
END
ELSE
BEGIN
SET #loc_StartPos = ABS(#loc_StartPos);
SET #loc_FindString = REVERSE(#in_FindString);
SET #loc_String = REVERSE(#in_String);
WHILE (#loc_Idx < #loc_Nth)
BEGIN
SET #loc_Position = CHARINDEX(#loc_FindString,#loc_String,#loc_StartPos);
IF (#loc_Position > 0)
SET #loc_StartPos = #loc_Position + #loc_FindLength
ELSE
SET #loc_Idx = #loc_Nth;
SET #loc_Idx = #loc_Idx + 1;
END;
IF (#loc_Position > 0)
SET #loc_Position = #loc_Length - #loc_Position + (1 - #loc_FindLength) + 1;
END;
RETURN (#loc_Position);
END;
GO
Here is a shorter version
DECLARE #someStr varchar(20)
set #someStr = '001.002.003'
SELECT REVERSE(Substring(REVERSE(#someStr),CHARINDEX('.', REVERSE(#someStr))+1,20))