Posts mit dem Label Stored Procedure werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Stored Procedure werden angezeigt. Alle Posts anzeigen

Mittwoch, 9. April 2008

SP mit dem Ergebnis eines SELECTs als Parameter aufrufen

Als kleine Gedächtnisstütze für mich, da ich jedesmal wieder vergesse, wie SQL funktioniert:

   1:  DECLARE @helper nvarchar(50)
   2:  SET @helper = (SELECT [Value] FROM dbo.[Tabelle] WHERE [id] = 1)
   3:   
   4:  EXEC dbo.EineSP @param1 = 'einWert'
   5:                , @param2 = @helper
   6:                , @param3 = 'nochEinWert'
   7:                , @param4 = 'undNochEinWert'

Zuerst muss eine Hilfsvariable (@helper) erstellt werden, die den gleichen Datentyp hat, wie das auszulesende Feld und der Parameter, für den sie übergeben werden soll. Anschließend wird ihr der gewünschte Wert mit Hilfe einer SELECT-Anweisung zugewiesen, wodurch sie dann einfach als Wert für den entsprechenden Parameter der Stored Procedure verwendet werden kann.

Gar nicht schwierig, trotzdem weigert sich mein Hirn immer wieder, sich das zu behalten.

Freitag, 4. April 2008

Mit dotNet drucken... ein Erfahrungsbericht

Das Drucken einer Datei mit dotNet ist eigentlich keine all zu große Herausforderung. Beispiele findet man wie Sand am Meer, der eigentliche Code ist auch nicht all zu komplex.
Entsprechend schnell hat die Methodik auch funktioniert, als sie lokal in einem UnitTest aufgerufen wurde. Gedruckt wurde dabei auf einen Netzwerkdrucker. Der gleiche Code sollte aber nun als Assembly im SQL Server 2005 abgelegt werden, so dass im Prinzip nur eine Stored Procedure aufgerufen werden muss, um - in diesem speziellen Fall - einen bestimmten Report aus den Reporting Services zu drucken. Und was kommt wohl jetzt? Richtig, es hat nicht funktioniert.
Nach mehreren erfolglosen Versuchen, die Druckfunktion für den Druck auf einem Netzwerkdrucker zu realisieren, kam dann die Idee, den Drucker direkt via USB mit der Entwicklungs-VM zu verbinden. Nach Tagen des Misserfolgs dann die Überraschung: auf einem lokalen Drucker wird der Report ausgegeben.

Meine Vermutung geht zur Zeit dahin, dass dem Aufruf für einen Netzwerkdrucker noch der zu verwendende Port angegeben werden muss. Beim UnitTest muss dies nicht geschehen, weil der Aufruf hier direkt aus Windows kommt. Wird jedoch die SP aus dem SQL Server aufgerufen, kommt der Aufruf für das unterliegende OS aus dem Web, was offensichtlich einen Unterschied macht.
Diese Vermutung muss noch durch ein wenig Research und Trial and Error verifiziert werden, doch bin ich zuversichtlich, der korrekten Lösung auf der Spur zu sein.

Sobald ich genaueres weiß, seid ihr die Ersten, die es erfahren.

EDIT: Des Rätsels Lösung ist gefunden!
Anders, als ich es vermutet habe, ging die Lösung doch, wie von Tropensturm vermutet, in Richtung Benutzer-Authentifizierung.
Da die Assembly im SQL Server aufgerufen wird, greift sie auch mit dessen Rechten auf das Netzwerk zu. Offenbar besteht hier allerdings nicht das Recht, auf Netzwerkdrucker zuzugreifen. Deshalb holen wir uns die Rechte des aktuell angemeldeten Windows-Benutzers. Das geschieht folgendermaßen.

   1:  // Vorbereitung
   2:  System.Security.Principal.WindowsIdentity clientId = null;
   3:  System.Security.Principal.WindowsImpersonationContext impersonatedUser = null;
   4:   
   5:  // Windows-Identität ermitteln
   6:  clientId = SqlContext.WindowsIdentity;
   7:   
   8:  try
   9:  {
  10:      // Windows-Berechtigungen holen
  11:      impersonatedUser = clientId.Impersonate();
  12:   
  13:      // An dieser Stelle drucken
  14:  }
  15:  finally
  16:  {
  17:      if(impersonatedUser != null)
  18:      {
  19:          // Windows-Rechte wieder abgeben
  20:          impersonatedUser.Undo();
  21:      }
  22:  }

Und kaum macht man es richtig, funktioniert es... ;)