Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
frankDK
Starting Member
14 Posts |
Posted - 2008-10-29 : 07:04:59
|
| Hii have problems with some syntax in a stored sql-statement, the statement looks like this:set ANSI_NULLS ONset QUOTED_IDENTIFIER ONGOALTER PROCEDURE [dbo].[getAllChildrenInCounty] @countyId intASBEGIN SET NOCOUNT ON;DECLARE @ReturnValue INTEXEC @ReturnValue = getMonths_ChildId c.childidSELECT i.institutionName, c.childid, c.navn, c.screen2, ReturnValue=@ReturnValueFROM children c inner join institutions iON c.institution = i.institutionIdwhere (c.countyid = @countyId)Group by c.institution, i.institutionName, c.childid, c.navn, c.screen2Order by i.institutionNameENDwhat i want is a result looking like this:institutionName, childid, navn, screen2, age_in_monthAge in month comes from a stored procedure, that takes childid as parameter.can anyone help me?Frank |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-10-29 : 07:12:40
|
| how is procedure getMonths_ChildId defined? does it have an OUTPUT parameter? |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2008-10-29 : 07:13:04
|
I think you should rewrite the getMonths_ChildId stored procedure and turn it into a function.You could then just use that function in the SELECT clause of your procedure.Something like.... (asuming that there is a function called fn_getMonths_ChildIdSELECT i.institutionName , c.childid , c.navn , c.screen2 , fn_getMonths_ChildId(c.[childId])FROM children c inner join institutions i ON c.institution = i.institutionIdwhere (c.countyid = @countyId)Group by c.institution , i.institutionName , c.childid , c.navn , c.screen2 , fn_getMonths_ChildId(c.[childId])Order by i.institutionName -- NB I'm not sure about your GROUP BY clause here...However, it might be a good idea for you to post1) sample data2) required output3) Code of getMonths_ChildIdRegards,-------------Charlie |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2008-10-29 : 07:17:17
|
| Another way to do this would be to rewrite getMonths_ChildId as a table value function (one that returns a table of values) Ideally returning a childId and Months columns. Then just JOIN that function in your select statement and reference the [months] column.-------------Charlie |
 |
|
|
frankDK
Starting Member
14 Posts |
Posted - 2008-10-29 : 07:34:07
|
| Hi againthis is getMonth_childId:ALTER PROCEDURE [dbo].[getMonths_ChildId] -- Add the parameters for the stored procedure here @childId bigintASBEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON;select datediff(month, convert(datetime, '20' + substring(cprnr, 5, 2) + substring(cprnr, 3, 2) + left(cprnr, 2)), getdate())from cprtabel where (id = @childId)END |
 |
|
|
frankDK
Starting Member
14 Posts |
Posted - 2008-10-29 : 07:41:24
|
| I just tried to create a function:CREATE FUNCTION fnGetMonth_ChildId( -- Add the parameters for the function here @childId bigint)RETURNS TABLE ASRETURN (select datediff(month, convert(datetime, '20' + substring(cprnr, 5, 2) + substring(cprnr, 3, 2) + left(cprnr, 2)), getdate())from cprtabel where (id = @childId))GObut it tells me that:Msg 443, Level 16, State 1, Procedure fnGetMonth_ChildId, Line 17Invalid use of 'getdate' within a function.frank |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-10-29 : 07:42:28
|
do like thisALTER PROCEDURE [dbo].[getMonths_ChildId] -- Add the parameters for the stored procedure here@childId bigint,@RetVal int OUTPUTASBEGIN-- SET NOCOUNT ON added to prevent extra result sets from-- interfering with SELECT statements.SET NOCOUNT ON;select @RetVal=datediff(month, convert(datetime, '20' + substring(cprnr, 5, 2) + substring(cprnr, 3, 2) + left(cprnr, 2)), getdate())from cprtabel where (id = @childId)END then in your procedure do like thisset ANSI_NULLS ONset QUOTED_IDENTIFIER ONGOALTER PROCEDURE [dbo].[getAllChildrenInCounty] @countyId intASBEGINSET NOCOUNT ON;DECLARE @ReturnValue INTEXEC getMonths_ChildId @childid,@ReturnValue OUTPUTSELECT i.institutionName, c.childid, c.navn, c.screen2, ReturnValue=@ReturnValueFROM children c inner join institutions iON c.institution = i.institutionIdwhere (c.countyid = @countyId)Group by c.institution, i.institutionName, c.childid, c.navn, c.screen2Order by i.institutionNameEND or consider making it a function as Charlie suggested. it will be something likeALTER FUNCTION [dbo].[getMonths_ChildId] (-- Add the parameters for the stored procedure here@childId bigint)ASBEGIN-- SET NOCOUNT ON added to prevent extra result sets from-- interfering with SELECT statements.SET NOCOUNT ON;DECLARE @RetVal intselect @RetVal=datediff(month, convert(datetime, '20' + substring(cprnr, 5, 2) + substring(cprnr, 3, 2) + left(cprnr, 2)), getdate())from cprtabel where (id = @childId)RETURN @RetValEND and then use likeALTER PROCEDURE [dbo].[getAllChildrenInCounty] @countyId intASBEGINSET NOCOUNT ON;SELECT i.institutionName, c.childid, c.navn, c.screen2, [dbo].[getMonths_ChildId] (c.childid)FROM children c inner join institutions iON c.institution = i.institutionIdwhere (c.countyid = @countyId)Group by c.institution, i.institutionName, c.childid, c.navn, c.screen2Order by i.institutionNameEND |
 |
|
|
frankDK
Starting Member
14 Posts |
Posted - 2008-10-29 : 07:49:17
|
| hi againsorry i did'nt see this:1) sample datacprtabel:id, cprnr1, 30098615652, 0506063020institutions tabel:id, institutionname1, inst12, inst23, inst3children tabel:childid,navn, screen21,name of child,29-09-2008 10:39:432, new name, 29-09-2008 10:39:43 2) required outputinstitutionName, childid, navn, screen2, age_in_monthinst1, 1, name of child, 29-09-2008 10:39:43, 260inst1, 2, name of child2, 01-02-2008 10:39:43, 2003) Code of getMonths_ChildIdthis is getMonth_childId:ALTER PROCEDURE [dbo].[getMonths_ChildId] -- Add the parameters for the stored procedure here@childId bigintASBEGIN-- SET NOCOUNT ON added to prevent extra result sets from-- interfering with SELECT statements.SET NOCOUNT ON;select datediff(month, convert(datetime, '20' + substring(cprnr, 5, 2) + substring(cprnr, 3, 2) + left(cprnr, 2)), getdate())from cprtabel where (id = @childId)END |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2008-10-29 : 07:50:30
|
Hi FrankDKFunctions should be deterministic. That is they should always produce the same output with the same inputs (assuming the data is the same).As such they have a few limitations (one being that you can't call certain other procs and functions from them (and that they can't modify data in any way).You will have to change the function so it also has an input parameter of @currentDate. Then pass that the current date from GETDATE. Also If you only want the months for 1 child then you don't want a table valued function. you want a *scaler* function. Therefore you need to return an INT (number of months)SOMETHING LIKECREATE FUNCTION fnGetMonth_ChildId( -- Add the parameters for the function here@childId bigint, @curDate DATETIME)RETURNS INTASRETURN (select datediff(month, convert(datetime, '20' + substring(cprnr, 5, 2) + substring(cprnr, 3, 2) + left(cprnr, 2)), @curDate)from cprtabel where (id = @childId))GO And then call it withDECLARE @curDate DATETIMESET @curDate = GETDATE()SELECT fnGetMonth_ChildId(childId,@curDate) -------------Charlie |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2008-10-29 : 07:52:00
|
| And the above assumes there is only 1 row returned by your select statement!-------------Charlie |
 |
|
|
frankDK
Starting Member
14 Posts |
Posted - 2008-10-29 : 07:53:52
|
| hi i used the first part, but got an error:Msg 137, Level 15, State 2, Procedure getAllChildrenInCounty2, Line 11Must declare the variable '@childid'.in this:set ANSI_NULLS ONset QUOTED_IDENTIFIER ONGOALTER PROCEDURE [dbo].[getAllChildrenInCounty] @countyId intASBEGINSET NOCOUNT ON;DECLARE @ReturnValue INTEXEC getMonths_ChildId @childid,@ReturnValue OUTPUTSELECT i.institutionName, c.childid, c.navn, c.screen2, ReturnValue=@ReturnValueFROM children c inner join institutions iON c.institution = i.institutionIdwhere (c.countyid = @countyId)Group by c.institution, i.institutionName, c.childid, c.navn, c.screen2Order by i.institutionNameEND |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2008-10-29 : 07:55:07
|
quote: Originally posted by visakh16 do like thisALTER PROCEDURE [dbo].[getMonths_ChildId] -- Add the parameters for the stored procedure here@childId bigint,@RetVal int OUTPUTASBEGIN-- SET NOCOUNT ON added to prevent extra result sets from-- interfering with SELECT statements.SET NOCOUNT ON;select @RetVal=datediff(month, convert(datetime, '20' + substring(cprnr, 5, 2) + substring(cprnr, 3, 2) + left(cprnr, 2)), getdate())from cprtabel where (id = @childId)END then in your procedure do like thisset ANSI_NULLS ONset QUOTED_IDENTIFIER ONGOALTER PROCEDURE [dbo].[getAllChildrenInCounty] @countyId intASBEGINSET NOCOUNT ON;DECLARE @ReturnValue INTEXEC getMonths_ChildId @childid,@ReturnValue OUTPUTSELECT i.institutionName, c.childid, c.navn, c.screen2, ReturnValue=@ReturnValueFROM children c inner join institutions iON c.institution = i.institutionIdwhere (c.countyid = @countyId)Group by c.institution, i.institutionName, c.childid, c.navn, c.screen2Order by i.institutionNameEND .......
Hi Viaskh,This won't work as the op wants the number of months for each child. You'd need to either make a scaler function and call it in the select statement, or CROSS APPLY which I know you are fond of, make a table valued function and JOIN it in the SELECT statement, or Make a temp table to store all the months and then populate that with an INSERT EXEC or similar. They way you've posted won't work as when the stored proc is called there is no value for childId-------------Charlie |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-10-29 : 07:56:01
|
quote: Originally posted by frankDK hi i used the first part, but got an error:Msg 137, Level 15, State 2, Procedure getAllChildrenInCounty2, Line 11Must declare the variable '@childid'.in this:set ANSI_NULLS ONset QUOTED_IDENTIFIER ONGOALTER PROCEDURE [dbo].[getAllChildrenInCounty] @countyId intASBEGINSET NOCOUNT ON;DECLARE @ReturnValue INT,@childidset @childid=...EXEC getMonths_ChildId @childid,@ReturnValue OUTPUTSELECT i.institutionName, c.childid, c.navn, c.screen2, ReturnValue=@ReturnValueFROM children c inner join institutions iON c.institution = i.institutionIdwhere (c.countyid = @countyId)Group by c.institution, i.institutionName, c.childid, c.navn, c.screen2Order by i.institutionNameEND
you need to declare it and assign it a value like above |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-10-29 : 07:58:49
|
| then only way is my second suggestion frank as you want it for each childid value |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2008-10-29 : 07:59:09
|
Yes that will compile but it will not give you all the proper values for each child in the second SELECT statement. It will only show the values for the particular childId you passed it you will then up with data like this....ChildId | Monthsa 10b 10c 10d 10e 10 Assuming that childId a is passed to the first sp and the value returned is 10. You will *not* get the proper months for each child this way.-------------Charlie |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2008-10-29 : 08:00:47
|
| I think this should be your function....Posted - 10/29/2008 : 07:50:30 Hi FrankDKFunctions should be deterministic. That is they should always produce the same output with the same inputs (assuming the data is the same).As such they have a few limitations (one being that you can't call certain other procs and functions from them (and that they can't modify data in any way).You will have to change the function so it also has an input parameter of @currentDate. Then pass that the current date from GETDATE. Also If you only want the months for 1 child then you don't want a table valued function. you want a *scaler* function. Therefore you need to return an INT (number of months)SOMETHING LIKECREATE FUNCTION fnGetMonth_ChildId( -- Add the parameters for the function here@childId bigint, @curDate DATETIME)RETURNS INTASRETURN (select datediff(month, convert(datetime, '20' + substring(cprnr, 5, 2) + substring(cprnr, 3, 2) + left(cprnr, 2)), @curDate)from cprtabel where (id = @childId))GOAnd then call it withDECLARE @curDate DATETIMESET @curDate = GETDATE()SELECT fnGetMonth_ChildId(childId,@curDate)-------------Charlie-------------Charlie |
 |
|
|
frankDK
Starting Member
14 Posts |
Posted - 2008-10-29 : 08:04:41
|
| charlie i just tried to paste your function, but i gives me:Msg 170, Level 15, State 31, Procedure fnGetMonth_ChildId, Line 9Line 9: Incorrect syntax near 'RETURN'.frank |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-10-29 : 08:05:57
|
quote: Originally posted by Transact Charlie Yes that will compile but it will not give you all the proper values for each child in the second SELECT statement. It will only show the values for the particular childId you passed it you will then up with data like this....ChildId | Monthsa 10b 10c 10d 10e 10 Assuming that childId a is passed to the first sp and the value returned is 10. You will *not* get the proper months for each child this way.-------------Charlie
sorry didnt get that. you will get value corresponding to each child if you're using it as a UDF.can you explain why you think it wont work? |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2008-10-29 : 08:08:11
|
Sry, try this instead.CREATE FUNCTION fnGetMonth_ChildId( -- Add the parameters for the function here@childId bigint, @curDate DATETIME)RETURNS INTAS BEGIN DECLARE @months INT SELECT @months = DATEDIFF ( MONTH , CONVERT(DATETIME, '20' + SUBSTRING(cprnr, 5, 2) + substring(cprnr, 3, 2) + left(cprnr, 2)) , @curDate ) FROM cprTabel WHERE Id = @childID RETURN @monthsEND -------------Charlie |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-10-29 : 08:09:25
|
quote: Originally posted by frankDK charlie i just tried to paste your function, but i gives me:Msg 170, Level 15, State 31, Procedure fnGetMonth_ChildId, Line 9Line 9: Incorrect syntax near 'RETURN'.frank
what about this small modification?CREATE FUNCTION fnGetMonth_ChildId( -- Add the parameters for the function here@childId bigint, @curDate DATETIME)RETURNS INTASDECLARE intselect @RetVal=datediff(month, convert(datetime, '20' + substring(cprnr, 5, 2) + substring(cprnr, 3, 2) + left(cprnr, 2)), @curDate)from cprtabel where (id = @childId)RETURN @RetValGO |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2008-10-29 : 08:09:49
|
quote: Originally posted by visakh16
quote: Originally posted by Transact Charlie Yes that will compile but it will not give you all the proper values for each child in the second SELECT statement. It will only show the values for the particular childId you passed it you will then up with data like this....ChildId | Monthsa 10b 10c 10d 10e 10 Assuming that childId a is passed to the first sp and the value returned is 10. You will *not* get the proper months for each child this way.-------------Charlie
sorry didnt get that. you will get value corresponding to each child if you're using it as a UDF.can you explain why you think it wont work?
Sorry Visakh -- looks like all our replies are out of synch. I was referring to the stored proc method that returned 1 value. The scaler function will work. I suggested it myself.Charlie.-------------Charlie |
 |
|
|
Next Page
|
|
|
|
|