I have a very special problem and it is not easy to explain. I hope you understand what I mean.
First, we have an application in Delphi 7 with UniDAC 3.50.0.13 running on InterBase XE, Oracle 8.0.5 and MS SQL-Server 2008.
Now I wrote a function that reads the primary key of a table. Here I use TUniMetaData from UniDAC and this works fine with all servers. Below is the code from this function, but I think it's correct.
Under SQL-Server 2008 I defined two Users "USER1" and "USER2" with own tables. But USER1 owns a table KUNDEN, which is free for USER2. USER2 can select, update, insert, delete on this table. It's defined with rights and synonyms. For example USER2 exceutes "select * from KUNDEN". This works fine too.
USER1 gets the correct primary key with my function.
Now the problem: USER2 is unable to use the function to get the primary key of table KUNDEN.
The function I wrote has an empty result.
To debug this problem I used the SQL-Server-Profiler. I found two lines from TMetadata:
exec [USER2].[sys].sp_table_constraints_rowset N'KUNDEN',NULL,N'USER2',NULL,NULL,NULL,NULL
exec [USER2].[sys].sp_indexes_100_rowset N'KUNDEN',NULL,NULL
Both were completed successful. But no result.
Now my questions:
- What can I do?
- Do USER2 needs special rigths?
- Maybe an error in TMetadata?
- Is this impossible on SQL-Server?
And at last a suggestion: It will be nice, when DevArt DBMonitor shows the TMetaData-statements.
Thanks in advance for any idea.
Kind regards,
Gerd Brinkmann
invent GmbH
Code: Select all
procedure BestimmePrimaerSchluesselFelder ( DBConnection : TUniConnection;
TabellenName : string;
var arPKFelder : TWwsStringArray);
var tmpUniMetaData : TUniMetaData;
PKName,
AktFeldName : string;
i,
arPos : integer;
FeldVorhanden : boolean;
begin
setLength (arPKFelder, 0);
PKName := '';
tmpUniMetaData := TUniMetaData.Create (nil);
tmpUniMetaData.Connection := DBConnection;
tmpUniMetaData.MetaDataKind := 'Constraints';
tmpUniMetaData.Restrictions.Clear;
tmpUniMetaData.Restrictions.Add ('TABLE_NAME=' + TabellenName);
tmpUniMetaData.Open;
if not tmpUniMetaData.IsEmpty
then begin
tmpUniMetaData.First;
repeat
if UpperCase (tmpUniMetaData.FieldByName ('CONSTRAINT_TYPE').AsString)
= 'PRIMARY KEY'
then begin
if UniDacTreibername (DBConnection) = 'INTERBASE'
then PKName := tmpUniMetaData.FieldByName ('INDEX_NAME').AsString
else PKName := tmpUniMetaData.FieldByName ('CONSTRAINT_NAME').AsString;
break;
end;
tmpUniMetaData.Next;
until tmpUniMetaData.Eof;
end;
tmpUniMetaData.Close;
tmpUniMetaData.MetaDataKind := 'IndexColumns';
tmpUniMetaData.Restrictions.Clear;
tmpUniMetaData.Restrictions.Add ('TABLE_NAME=' + TabellenName);
tmpUniMetaData.Restrictions.Add ('UNIQUE=1');
tmpUniMetaData.Open;
if not tmpUniMetaData.IsEmpty
then begin
tmpUniMetaData.First;
repeat
AktFeldName := tmpUniMetaData.FieldByName ('COLUMN_NAME').AsString;
FeldVorhanden := false;
if (UpperCase (AktFeldName) 'ROWID')
and (tmpUniMetaData.FieldByName ('INDEX_NAME').AsString = PKName)
then begin
for i := 0 to High (arPKFelder) do
begin
if AktFeldName = arPKFelder [i]
then FeldVorhanden := true;
end; { for }
if not FeldVorhanden
then begin
arPos := High (arPKFelder) + 1;
SetLength (arPKFelder, ArPos + 1);
arPKFelder [arPos] := AktFeldName;
end;
end; { AktFeldname 'RowId }
tmpUniMetaData.Next;
until tmpUniMetaData.Eof;
end;
tmpUniMetaData.Close;
tmpUniMetaData.Free;
end; { BestimmePrimaerSchluesselFelder }