@@ -176,38 +176,28 @@ let rec parseDefaultValue (definition: string) (expr: Microsoft.SqlServer.Transa
176176 | _ -> None
177177 | _ -> None
178178
179- type Routine =
180- | StoredProcedure of schema : string * name : string * definition : string * description : string option
181- | TableValuedFunction of schema : string * name : string * definition : string * description : string option
182- | ScalarValuedFunction of schema : string * name : string * definition : string * description : string option
183-
184- member this.Definition =
185- match this with
186- | StoredProcedure(_, _, definition, _)
187- | TableValuedFunction(_, _, definition, _)
188- | ScalarValuedFunction(_, _, definition, _) -> definition
189-
190- member this.Description =
191- match this with
192- | StoredProcedure(_, _, _, description)
193- | TableValuedFunction(_, _, _, description)
194- | ScalarValuedFunction(_, _, _, description) -> description
195-
196- member this.TwoPartName =
197- match this with
198- | StoredProcedure( schema, name, _, _)
199- | TableValuedFunction( schema, name, _, _)
200- | ScalarValuedFunction( schema, name, _, _) -> schema, name
201-
202- member this.IsStoredProc = match this with StoredProcedure _ -> true | _ -> false
179+ type internal RoutineType = StoredProcedure | TableValuedFunction | ScalarValuedFunction
180+
181+ type internal Routine = {
182+ Type: RoutineType
183+ Schema: string
184+ Name: string
185+ Definition: string
186+ Description: string option
187+ BaseObject: string * string
188+ } with
189+
190+ member this.TwoPartName = this.Schema, this.Name
191+
192+ member this.IsStoredProc = this.Type = StoredProcedure
203193
204194 member this.ToCommantText ( parameters : Parameter list ) =
205195 let twoPartNameIdentifier = sprintf " %s .%s " <|| this.TwoPartName
206- match this with
207- | StoredProcedure _ -> twoPartNameIdentifier
208- | TableValuedFunction _ ->
196+ match this.Type with
197+ | StoredProcedure -> twoPartNameIdentifier
198+ | TableValuedFunction ->
209199 parameters |> List.map ( fun p -> p.Name) |> String.concat " , " |> sprintf " SELECT * FROM %s (%s )" twoPartNameIdentifier
210- | ScalarValuedFunction _ ->
200+ | ScalarValuedFunction ->
211201 parameters |> List.map ( fun p -> p.Name) |> String.concat " , " |> sprintf " SELECT %s (%s )" twoPartNameIdentifier
212202
213203let internal providerTypes =
@@ -305,30 +295,82 @@ type SqlConnection with
305295 then
306296 " (SELECT NULL AS Value)"
307297 else
308- " fn_listextendedproperty ('MS_Description', 'schema', SPECIFIC_SCHEMA, ROUTINE_TYPE, SPECIFIC_NAME, default, default)"
309-
310- let getRoutinesQuery = sprintf "
311- SELECT
312- SPECIFIC_SCHEMA
313- ,SPECIFIC_NAME
314- ,DATA_TYPE
315- ,DEFINITION = ISNULL( OBJECT_DEFINITION( OBJECT_ID( SPECIFIC_SCHEMA + '.' + SPECIFIC_NAME)), '')
316- ,DESCRIPTION = XProp.Value
317- FROM
318- INFORMATION_SCHEMA.ROUTINES
319- OUTER APPLY %s AS XProp
320- WHERE
321- ROUTINE_SCHEMA = '%s '" descriptionSelector schema
298+ " fn_listextendedproperty ('MS_Description', 'schema', BaseObjectSchema, ROUTINE_TYPE, BaseObjectName, default, default)"
299+
300+ let getRoutinesQuery =
301+ sprintf "
302+ WITH ExplicitRoutines AS
303+ (
304+ SELECT
305+ SPECIFIC_SCHEMA AS [Schema]
306+ ,SPECIFIC_NAME AS Name
307+ ,ROUTINE_TYPE
308+ ,DATA_TYPE
309+ ,SPECIFIC_SCHEMA AS BaseObjectSchema
310+ ,SPECIFIC_NAME AS BaseObjectName
311+ FROM
312+ INFORMATION_SCHEMA.ROUTINES
313+ ),
314+ Synonyms AS
315+ (
316+ SELECT
317+ OBJECT_SCHEMA_NAME(object_id) AS [Schema]
318+ ,name AS Name
319+ ,ROUTINE_TYPE
320+ ,DATA_TYPE
321+ ,SPECIFIC_SCHEMA AS BaseObjectSchema
322+ ,SPECIFIC_NAME AS BaseObjectName
323+ FROM
324+ sys.synonyms
325+ JOIN INFORMATION_SCHEMA.ROUTINES ON
326+ OBJECT_ID(ROUTINES.ROUTINE_SCHEMA + '.' + ROUTINES.ROUTINE_NAME) = OBJECT_ID(base_object_name)
327+ )
328+ SELECT
329+ XS.[Schema]
330+ ,XS.Name
331+ ,RoutineSubType =
332+ CASE
333+ WHEN XS.DATA_TYPE = 'TABLE' THEN 'TableValuedFunction'
334+ WHEN XS.DATA_TYPE IS NULL THEN 'StoredProcedure'
335+ ELSE 'ScalarValuedFunction'
336+ END
337+ ,ISNULL( OBJECT_DEFINITION( OBJECT_ID( XS.BaseObjectSchema + '.' + XS.BaseObjectName)), '') AS [Definition]
338+ ,XS.BaseObjectSchema
339+ ,XS.BaseObjectName
340+ ,[Description] = XProp.Value
341+ FROM
342+ (
343+ SELECT * FROM ExplicitRoutines
344+ UNION ALL
345+ SELECT * FROM Synonyms
346+ ) AS XS
347+ OUTER APPLY %s AS XProp
348+ WHERE
349+ [Schema] = @schema
350+ " descriptionSelector
322351
323352 use cmd = new SqlCommand( getRoutinesQuery, this)
353+ cmd.Parameters.AddWithValue( " @schema" , schema) |> ignore
354+
324355 cmd.ExecuteQuery( fun x ->
325- let schema , name = unbox x.[ " SPECIFIC_SCHEMA" ], unbox x.[ " SPECIFIC_NAME" ]
326- let definition = unbox x.[ " DEFINITION" ]
327- let description = x.TryGetValue( " DESCRIPTION" )
328- match x.[ " DATA_TYPE" ] with
329- | :? string as x when x = " TABLE" -> TableValuedFunction( schema, name, definition, description)
330- | :? DBNull -> StoredProcedure( schema, name, definition, description)
331- | _ -> ScalarValuedFunction( schema, name, definition, description)
356+ let schema , name = unbox x.[ " Schema" ], unbox x.[ " Name" ]
357+ let definition = unbox x.[ " Definition" ]
358+ let description = x.TryGetValue( " Description" )
359+ let routineType =
360+ match string x.[ " RoutineSubType" ] with
361+ | " TableValuedFunction" -> TableValuedFunction
362+ | " StoredProcedure" -> StoredProcedure
363+ | " ScalarValuedFunction" -> ScalarValuedFunction
364+ | unexpected -> failwithf " Unexpected database routine type: %s ." unexpected
365+
366+ {
367+ Type = routineType
368+ Schema = schema
369+ Name = name
370+ Definition = definition
371+ Description = description
372+ BaseObject = unbox x.[ " BaseObjectSchema" ], unbox x.[ " BaseObjectName" ]
373+ }
332374 )
333375 |> Seq.toArray
334376
@@ -377,7 +419,7 @@ type SqlConnection with
377419 OUTER APPLY %s AS XProp
378420 WHERE
379421 p.Name <> ''
380- AND OBJECT_ID('%s .%s ') = object_id" descriptionSelector <|| routine.TwoPartName
422+ AND OBJECT_ID('%s .%s ') = object_id" descriptionSelector <|| routine.BaseObject
381423
382424 [
383425 use cmd = new SqlCommand( query, this)
0 commit comments