Avatar billede borrisholt Novice
24. august 2005 - 17:11 Der er 4 kommentarer og
1 løsning

Create function, WITH SCHEMABINDING

Jeg har en lille funktion, som jeg har kodet :

den vil jeg gerne have lavet som en system funktion.

use master

if exists (select * from dbo.SysObjects where id = object_id(N'[dbo].[fn_ListObjects]') )
  drop function [dbo].[fn_ListObjects]

GO
CREATE FUNCTION  dbo.fn_ListObjects
  (
    @DBIntra varchar(100) = NULL,
    @DBExtra varchar(100) = NULL,
    @DBUltra tinyint = 0,
    @ObjectFilter varchar(100) = NULL
  )

  RETURNS @RetObjects  TABLE
  (
    Type varchar(2) NOT NULL,
    Parent varchar(50) NOT NULL,
    Object varchar(50) NOT NULL,
    Creation datetime NOT NULL
  )
WITH SCHEMABINDING
AS
/*
  V - view
  P - stored procedure
  FN - user-defined function, scalar
  IF - user-defined function, table-valued, in-line
  TF - user-defined function, table-valued, multi-statement
  TR - trigger

  U - user table
  UC - user column (a column in a user table)
  K - constraint, primary key (or unique constraint)
  F - constraint, foreign key
  C - constraint, check
  D - constraint, default
  I - index
*/

BEGIN
--SET NOCOUNT ON

declare @TmpObjects  TABLE
  (
    Type varchar(2) NOT NULL,
    Parent varchar(50) NOT NULL,
    Object varchar(50) NOT NULL,
    Creation datetime NOT NULL
  )

DECLARE @TPre varchar(10)
DECLARE @TDo3 tinyint
DECLARE @TDo4 tinyint

SET @TPre = ''

SET @TDo3 = LEN(@TPre)
SET @TDo4 = LEN(@TPre) + 1

DECLARE @CreateDate datetime
DECLARE @itype char(2)
SET @itype = 'I'

IF @DBIntra IS NULL AND @DBExtra IS NULL
BEGIN
  SET @DBIntra =
  case @DBUltra
    when  0 then 'V|P|FN|IF|TF|TR|U|K|F|C|D|UC|' + RTRIM(@itype) --All
    when  1 then  'V|P|FN|IF|TF|TR' -- Code Objects
    else 'U|K|F|C|D|UC|' + RTRIM(@itype)
  END
END

INSERT @TmpObjects
SELECT
  O.type            AS Type,
  ISNULL(T.name,'')     AS Parent,
  O.name            AS Object,
  ISNULL(CONVERT(varchar(30),O.crdate,120),'') AS Creation
FROM
  dbo.SysObjects AS O
  LEFT JOIN dbo.SysObjects AS T ON O.parent_obj = T.id
WHERE ISNULL(OBJECTPROPERTY(O.id,'IsMSShipped'),1) = 0
      AND O.Status > 0
      AND (@DBIntra IS NULL OR CHARINDEX('|'+RTRIM(O.type)+'|','|'+(@DBIntra)+'|') > 0)
      AND (@DBExtra IS NULL OR CHARINDEX('|'+RTRIM(O.type)+'|','|'+(@DBExtra)+'|') = 0)
      AND O.name LIKE IsNull(@ObjectFilter, '%')
  UNION ALL
  SELECT       
    @itype AS Type,
    ISNULL(O.name, '') AS Parent,
    I.name AS Object,
    ISNULL(CONVERT(varchar(20),@CreateDate,113),'') AS Creation
  FROM
    dbo.SysObjects AS O JOIN dbo.SysIndexes AS I ON O.id = I.id
  WHERE
      ISNULL(OBJECTPROPERTY(O.id,'IsMSShipped'),1) = 0
      AND O.Status > 0
      AND RTRIM(O.type) = 'U'
      AND LEFT(O.name,@TDo3) = @TPre
      AND I.indid BETWEEN 1 AND 254
      AND LEFT(I.name,8) <> '_WA_Sys_'
      AND O.name LIKE IsNull(@ObjectFilter, '%')
      AND (@DBIntra IS NULL OR CHARINDEX('|'+RTRIM(@itype)+'|','|'+(@DBIntra)+'|') > 0)
      AND (@DBExtra IS NULL OR CHARINDEX('|'+RTRIM(@itype)+'|','|'+(@DBExtra)+'|') = 0)
  UNION ALL
  SELECT       
    'UC' AS Type,
    ISNULL(O.name, '') AS Parent,
    I.name AS Object,
    ISNULL(CONVERT(varchar(20),@CreateDate,113),'') AS Creation
  FROM
    dbo.SysObjects O
  INNER JOIN dbo.SysColumns I ON O.ID = I.ID
  WHERE
      ISNULL(OBJECTPROPERTY(O.id,'IsMSShipped'),1) = 0
      AND RTRIM(O.type) = 'U'
      AND O.Status > 0
      AND LEFT(O.name,@TDo3) = @TPre
      AND I.Name LIKE IsNull(@ObjectFilter, '%') 
      AND (@DBIntra IS NULL OR CHARINDEX('|UC|','|'+(@DBIntra)+'|') > 0)
      AND (@DBExtra IS NULL OR CHARINDEX('|UC|','|'+(@DBExtra)+'|') = 0)

  insert @RetObjects
  Select
    Type, Parent, Object, Creation from  @TmpObjects
  return
END
GO
exec sp_changeobjectowner 'fn_ListObjects', 'system_function_schema'




Hvis jeg opretter funktonen med WITH SCHEMABINDING få jeg følgende fejl :

Server: Msg 4513, Level 16, State 1, Procedure fn_ListObjects, Line 122
Cannot schema bind function 'dbo.fn_ListObjects'. 'dbo.SysObjects' is not schema bound.

Hvis så jeg fjerner WITH SCHEMABINDING får jeg følgende fejl :

Cannot change owner of object 'fn_ListObjects' or one of its child objects because the new owner 'system_function_schema' already has an object with the same name.

Hvad gør jeg ?

Jens B
Avatar billede arne_v Ekspert
28. august 2005 - 22:17 #1
det er noget af en søslange

skud i tågen: sæt eksplicit database på databasenavn.dbo.tabelnavn
Avatar billede borrisholt Novice
28. august 2005 - 22:22 #2
Den har heller ikke været nemt at lave .... Meen jeg kan ikke lige se hvordan jeg skulle kunne fuld kvalificere mine tabel navnne, fordi jeg netop vil have det som en system funktion. Hvad skulle jeg så klacificere dem med ? master ?

Jens B
Avatar billede arne_v Ekspert
28. august 2005 - 22:25 #3
hvordan pokker kan man have en schema bound function som skal bruges i flere database ?
Avatar billede borrisholt Novice
31. august 2005 - 20:11 #4
arne_v>> Nu stller du et ret godt spørgsmål. Jeg har temmelig godt styr på T - SQL, men jeg har aldrig forsket ret dybt i. Jeg læste i en bog, som jeg ikke kan huske titlen på, fordi den ligger på job, men der læste jeg at det var måden at gøre det på :

Lave din funktion WITH SCHEMABOUND og der efter kalde sp_changeobjectowner

Men hvis du kender en metode til at gøre det så prøver vi bare den

Jens B
Avatar billede borrisholt Novice
04. september 2005 - 20:09 #5
Ikke flere indput så lukker jeg.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester