SQL Server: problem with UDF - sql

I have a function and select statement
CREATE FUNCTION dbo.fun_currentday ( #dt DATETIME)
RETURNS DATETIME
AS
BEGIN
DECLARE #currentday DATETIME
SET #currentday = DATEADD(dd, DATEDIFF(dd, 0, #dt), 0)
RETURN (#currentday)
END
GO
DECLARE #pvm AS DATETIME
SET #pvm = GETDATE()
SELECT 'Last 7 days' AS Range, dbo.fun_currentday(#pvm) - 6 AS Stday, dbo.fun_currentday(#pvm) AS Endday
All works fine but when I hover over dbo.fun_currentday at the select statement, I get an error saying:
Cannot find either column "dbo" or the user-defined function or aggregate "dbo.fun_currentday", or the name is ambiguous.
Where's the problem?

Intellisense / Error highlighting always does this for newly created objects. Use Ctrl+Shift+R to refresh the local cache.
Before
After

Everything runs fine here with SQL Server 2008 Express.
Have you tried running your query on a different database?
You can try to create a new schema and create you UDF in it.
Make sure you have the necessary permissions and that the dbo schema configuration is correct.

Your stored procedure have to be stored somewhere so when you don't specify the location it goes to default database (master). So you should call it like
SELECT 'Last 7 days' AS Range,master.dbo.fun_currentday(GETDATE()) - 6 AS Stday, master.dbo.fun_currentday(GETDATE()) AS Endday
EDITED
I've checked that and I wasn't right, it not always goes to mater schema. It goes to database in contex of you were woring, so if your create procedure was created in query on root folder it goes to master, but if you created it in query of test databse you should use test.dbo.fun_currentday(GETDATE()). To avoid it always specify the databse like USE database_name GO CREATE FUNCTION dbo.fun_currentday

Related

How to track changes in development environment in SQL Server

Our development team works on SQL Server and writes stored procedures for our product.
We need something like a version control system for those procedures or any other objects.
Sometimes I change a stored procedure, and someone else in my team changes it and I don't know any thing about it.
Is there any solution for that?
If you want to do it via code you could run this on a daily or hourly basis to get a list of all procs that were changed in the last day:
select *
from sys.objects
where datediff(dd, create_date, getdate()) < 1
or datediff(dd, modify_date, getdate() < 1)
and type = 'P';
or you could create a ddl trigger:
Create trigger prochanged On database
For create_procedure, alter_procedure, drop procedure
as
begin
set nocount on
Declare #data xml
set #data = Eventdata()
-- save #data to a table...
end
This will allow you to save all kinds of information every time a proc is created, changed or deleted.

I am trying to get all the SQL caseID between two datetimes

I am building a webservice in ASP.NET that will call a stored procedure to get all the cases between two dates. I am using SQL Management Studio Here is my code:
ALTER PROCEDURE spGetNewCases
(#startDate datetime, #endDate datetime)
AS
BEGIN
SELECT
caseID
FROM
tblCases
WHERE
dateOpened BETWEEN #startDate and #endDate
END
GO
EXEC spGetNewCases
However, I get the following error:
"Could not find object spGetNewCases".
In the IDE , the words "between" and "and" are highlighted in light gray instead of dark blue. Moreover, I would like to test it with two dates, say 2015-01-01 and 2015-01-04.
The format of my datetime in my SQL server is datetime2((0),null). E.g.
2015-01-02 00:00:00.
I would greatly appreciate the community's feedback. Thank you!
EDIT:
Thank you everyone for your great help! Here is my new code that works!
-- procedure
USE [vetDatabase_Wizard]
GO
ALTER PROCEDURE sp_GetNewCases (#startDate datetime, #endDate datetime)
AS
BEGIN
SELECT caseID FROM tblCases
WHERE dateOpened BETWEEN #startDate and #endDate
END
GO
EXEC sp_GetNewCases '2015-01-01', '2015-04-04'
Check your database
USE CASE_DB
GO
Qualify your schema name.
ALTER PROCEDURE schema.spGetNewCases ...
See if that doesn't find it...
EDIT
IF you're using SSMS -- right-click your stored procedure and select 'modify'. That will give you a pre-written ALTER template that you can then modify.
If your SP is created then check your DB context. In SSMS there is a dropdown menu, you can also USE DBNAME. In ASP code it is in your connection string.
If it is not created you will need to Create Procedure first and then you can Alter Procedure.
You can call the SP like so : EXEC spGetNewCases '2016-03-01', '2016-05-01'
Side note: System Stored Procedures use the sp prefix you probably should choose something different like sp_ or usp.

SQL to Oracle Date Issue

Currently in middle of migration from SQL Server to Oracle. Whats the best practices that i should applied across?
And we also encounter some problem like the dateadd functions not working in oracle.
MSSQL Code
USE [TEST]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[GET_MONTHS_LAST_DAY](#MON int)
RETURNS DATETIME
AS
BEGIN
RETURN DATEADD(dd, -DAY(DATEADD(m,1,getdate())), DATEADD(m,-MON+1,datediff(dd,0,getdate())))
END
Converted Oracle
create or replace
FUNCTION GET_MONTHS_LAST_DAY
(
v_MON IN NUMBER
)
RETURN DATE
AS
BEGIN
RETURN utils.dateadd('DD', -utils.day_(utils.dateadd('M', 1, SYSDATE)), utils.dateadd('M', -v_MON + 1, utils.datediff('DD', 0, SYSDATE)));
END;
Any idea why i cannot compile the oracle functions? The only thing i see here is the dateadd functions are not available in oracle. Thanks.
Your script looks like Oracle SQL Developer automatic conversion script.
You need generate package utils. Yo can use button "generate utils package" ( 2nd button in capture)in util window.

SQL Variables Change in SSIS

I'm new to SSIS so forgive me if this question is trivial or has already been answered. So I have a SQL query that begins as follows:
declare #start datetime, #end datetime, #startMonth datetime, #endMonth datetime, #maxHoursToRespond int
----Set These------------------------------------------------
set #end='6/27/2014'
set #maxHoursToRespond=24
-------------------------------------------------------------
set #start=dateadd(dd, -90, #end) -- set duplication period
set #startMonth=dateadd(dd, -2, #end)-- set to start date of output you want
set #endMonth=dateadd(dd, -1, #end) -- set to day of end date of output you want
When I put this in my OLE DB Source Editor with SQL command as my data access mode,
all the variables are replaced with question marks.
It looks like :
DECLARE ? datetime, ? datetime, ? datetime, ? datetime, ? int
/*--Set These------------------------------------------------*/ SET ? = ?
SET ? = 24
/*-----------------------------------------------------------*/ SET ? = dateadd(dd, - 90, ?)
SET ? = dateadd(dd, - 2, ?)
SET ? = dateadd(dd, - 1, ?)
In the query builder.I'd like to know why this is happening.I'd also like to know how I can allow the query to be successfully built
(currently I get a syntax error of "The Declare SQL construct or statement is not supported.").
Do I have to create these variables (like #start) in SSIS itself?
You can:
Encapsulate your SQL in a stored procedure that contains all of the declarations internally (assuming the variable values are static), then call the stored procedure in the execute SQL task with EXEC. EXEC My_Stored_Procedure
Write a stored procedure that accepts the variables as inputs, map them to variables in SSIS, then execute the stored procedure like this Exec My_Stored_Proc ?,?,?,? with the user variables mapped to the corresponding stored procedure variables.
Leave the query as is, but remove the DECLARE and the SETs, and map the SSIS variables to the query. This most likely will not work, because SSIS will not know which ? corresponds with which variable (it will try to map them in the order they appear.
Number 2 is the generally accepted method, unless you store your variable values in a table or something that the SP in number can access, in which case number 1 may be cleaner.
I have pasted straight to SQL command text yours script in OLE DB Source Editor and nothing changed in it. By pressing Parse Quesry.. I checked that SQL is correct. When I tried to use Build Query.., it said, that DECLARE is not supported. So don't use builder :)

Forcing a SQL Remote Query to filter remotely instead of locally

I have a MS SQL Query that is pulling data via from a remote server. The data that I'm pulling down needs to be filtered by a date that is determined at run time.. When I run the query like this:
SELECT * FROM SERVER.Database.dbo.RemoteView
WHERE EntryDate > '1/1/2009'
then the filter is applied remotely... However, I don't actually want to use '1/1/2009' as the date - I want the date to be supplied by a user-defined function, like this:
SELECT * FROM SERVER.Database.dbo.RemoteView
WHERE EntryDate > dbo.MyCustomCLRDateFunction()
where the function is a custom CLR scalar-valued function that returns a date time... (You may ask why I need to do this... the details are a bit complicated, so just trust me - I have to do it this way.)
When I run this query, the remote query is NOT filtered remotely - the filtering is done after all of the data is pulled down (400,000 rows vs 100,000 rows) and it makes a significant difference.
Is there a way that I can force the query to do the filtering remotely?
Thanks!
You could also construct a string and use an openquery ...
set #sqlString =
' select into myTable from openquery
(remoteServer,
"SELECT * FROM Database.dbo.RemoteView WHERE EntryDate > %DTSTART"
)
'
set #sqlString =
replace(#sqlString, '%DTSTART',
(select cast(dbo.MyCustomCLRDateFunction() as char(8))
)
EXECUTE sp_executesql #stmt=#sqlString
Can't you just send a query like this, or does the clr function have to actually be called inside the select statement?
Declare #datetime datetime
Set #datetime = dbo.MyCustomCLRDateFunction()
SELECT * FROM SERVER.Database.dbo.RemoteView
WHERE EntryDate > #datetime
You need to properly decorate your CLR function to mark it as Deterministic, Precise and Data Access/System Data Access as DataAccessKind.None.