Avatar billede hedemann Nybegynder
04. april 2008 - 11:50 Der er 27 kommentarer

Kald til ekstern URL fra SQL server

Jeg har brug for at kunne kalde et eksternt site med en querystring fra en stored procedure, således at det kan opdateres en ekstern database. Jeg ved godt at det nok ikke er den helt rigtige måde at gøre det på, med det er pt. den eneste måde der er tilgængelig i den anden ende.

Jeg vil gerne have at det sker i en SP, og jeg vil helt ikke have at der kaldes en exe-program idet der i perioder kan forkomme over 1000 opdateringer i timen.

Det er tale om en 2005 sql server
Avatar billede janus_007 Nybegynder
04. april 2008 - 12:08 #1
Der ville jeg måske anbefale dig at bruge CLR.
http://www.devsource.com/c/a/Using-VS/Introducing-SQL-Server-2005s-CLR-Integration/

Er det HTML eller XML url's du skal kalde?
Avatar billede Slettet bruger
04. april 2008 - 12:37 #2
janus hehe :-) det tage vist lige nogle måneder at lære
Jeg har et lille hurtigt shell program, som du kan lægge ind i en sp, hastigheden er ikke noget problem da det typisk er serveren og netværket der æder tiden og 1000 opslag er ikke noget problem.

fra en dos prompt kan man skrive http.exe http://www.dr.dk og den returnere htlm eller xml koden eller hvad det nu er.
vil du have den? du kan også få koden med
Avatar billede hedemann Nybegynder
04. april 2008 - 12:50 #3
jape44 ==> jeg vil gerne prøve et omtalte program - hvordan får jeg fat i det?
Avatar billede Slettet bruger
04. april 2008 - 12:53 #4
smid en mail
Avatar billede hedemann Nybegynder
04. april 2008 - 13:03 #5
er det en mail adresse du ønsker
Avatar billede Slettet bruger
04. april 2008 - 13:06 #6
ja
Avatar billede Slettet bruger
04. april 2008 - 13:17 #7
nu skal du skynde dig for jeg er på vej hjem :-)ellers mandag
Avatar billede Slettet bruger
04. april 2008 - 13:25 #8
Avatar billede hedemann Nybegynder
04. april 2008 - 13:34 #9
mange tak - så ikke dit forrige svar
Downloader nu
Avatar billede hedemann Nybegynder
07. april 2008 - 09:29 #10
Jape44 - dit program virker ikke...... det går i fejl
Avatar billede hedemann Nybegynder
07. april 2008 - 09:35 #11
eller også så er det mig der ikke forstår hvordan det virker/skal afvikles.

Skal programmet (Http.exe) kaldes fra SP eller skal man kalde det fra en dos-boks og så bruge outputtet i en SP?
Avatar billede Slettet bruger
07. april 2008 - 09:48 #12
det virker fint, men du skal skriver den fulde url eks. http://www.dr.dk og ikke www.dr.dk

så kalder du med EXEC master..xp_cmdshell "c:\<din folder>\http 'http://www.dr.dk'.
forsøg dig frem SQL query analyzer og så se hvordan du får et resultat tilbage.
Avatar billede Slettet bruger
07. april 2008 - 09:51 #13
der er også en httpf.exe den returnere kun tekst og all html kode er filtreret fra hvis du får brug for det
Avatar billede hedemann Nybegynder
07. april 2008 - 10:29 #14
Jeg skal lige høre (bare betragt mig som fatsvag ;-)) men skal Http.exe afvikles på server hver der skal skabes kontakt til URL adressen. Jeg havde nu håbet på at kunne benytte nogle indbygget funktioner i SQL serveren.
Avatar billede Slettet bruger
07. april 2008 - 10:39 #15
der er ingen indbygget funktioner til det du efterspørger andet end xp_cmdshell men der er også mulighed for selv at kode sin egen xtendet procedure i form af en dll, men det ville være lidt tåbeligt at gå så vidt da dette er en simpel opgave.

Og ja den skal afvikles på serveren. prøv feks denne i SQL query analyzer EXEC master..xp_cmdshell 'dir' så vil du se hvordan ms sql arbejder med dette.
Avatar billede arne_v Ekspert
14. april 2008 - 04:38 #16
Sådan en CLR UDF er nu ellers ret simpel:

using System;
using System.Data.SqlTypes;
using System.Net;

using Microsoft.SqlServer.Server;

namespace E
{
    public class Http
    {
        [SqlFunction]
        public static SqlString Get(string url)
        {
            string res = "";
            using(WebClient wc = new WebClient())
            {
                res = wc.DownloadString(url);
            }
            return res;
        }
    }
}
Avatar billede hedemann Nybegynder
17. april 2008 - 11:14 #17
Arne_v: Erstatter CLR UDF'er stored procedure eller der det noget der går hånd i hånd
Avatar billede Slettet bruger
17. april 2008 - 11:28 #18
uuuhhhh... ;-) se det var interessant arne_v. Overvejer virkelig at opgradere.
Hedemann, prøv at følge denne forklaring: http://davidhayden.com/blog/dave/archive/2006/04/18/2917.aspx
Avatar billede arne_v Ekspert
17. april 2008 - 14:31 #19
en UDF er noget der kun returnerer en enkelt værdi mens en SP kan returnere
op til flere result sets med mange felter

Jeg synes at det var nemmest med en UDF:

SELECT dbo.HttpGet('http://www.eksperten.dk/')
GO
Avatar billede hedemann Nybegynder
30. april 2008 - 13:21 #20
Er på banen igen og har nu fået lavet en funktion under SQL der kalder en url adresse og fanger svaret. Når jeg kalder funktionen med:

SELECT dbo.CallUrl('http://www.eksperten.dk/')
GO

Får jeg flg fejl.

Msg 6522, Level 16, State 2, Line 2
A .NET Framework error occurred during execution of user-defined routine or aggregate "CallUrl":
System.Security.SecurityException: Request for the permission of type 'System.Net.WebPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.

Jeg kan godt se at der måske mangler nogle eksterne rettigheder - men hvor sætter jeg dem.
Avatar billede arne_v Ekspert
01. maj 2008 - 01:44 #21
Avatar billede hedemann Nybegynder
02. maj 2008 - 09:32 #22
Ved du hvordan man giver database owner "External_Access_Assembly" rettigheder?
Avatar billede arne_v Ekspert
03. maj 2008 - 02:44 #23
Avatar billede hedemann Nybegynder
10. maj 2008 - 10:55 #24
Okay nu er jeg kommet lidt længer, men nu får jeg flg. fejl/meddelelse... nogle ide til hvad jeg skal gøre?

Msg 6522, Level 16, State 2, Line 2
A .NET Framework error occurred during execution of user-defined routine or aggregate "CallUrl":
System.InvalidOperationException: Data access is not allowed in this context.  Either the context is a function or method not marked with DataAccessKind.Read or SystemDataAccessKind.Read, is a callback to obtain data from FillRow method of a Table Valued Function, or is a UDT validation method.
System.InvalidOperationException:
  at System.Data.SqlServer.Internal.ClrLevelContext.CheckSqlAccessReturnCode(SqlAccessApiReturnCode eRc)
  at System.Data.SqlServer.Internal.ClrLevelContext.GetCurrentContext(SmiEventSink sink, Boolean throwIfNotASqlClrThread, Boolean fAllowImpersonation)
  at Microsoft.SqlServer.Server.InProcLink.GetCurrentContext(SmiEventSink eventSink)
  at Microsoft.SqlServer.Server.SmiContextFactory.GetCurrentContext()
  at Microsoft.SqlServer.Server.SqlContext.get_CurrentContext()
  at Microsoft.SqlServer.Server.SqlContext.get_WindowsIdentity()
  at CallURLFromSQL.UserDefinedFunctions.CallUrl(String sURL)
Avatar billede arne_v Ekspert
10. maj 2008 - 18:51 #25
Avatar billede hedemann Nybegynder
13. maj 2008 - 14:19 #26
Mener at jeg har en .Undo der hvor der skal være en - men det kan være at jeg tager fejl. Jeg vedhæfter lige min kode og håber at du kan se hvor det går galt. Den URL jeg forsøger kalde til sendes over via et paremeter og jeg benytter flg. sql.

KLAD TIL CLR med URL
====================
SELECT dbo.callurl('http://xxx.yyy.zz')
GO

PROGRAM KODE
============
Partial Public Class UserDefinedFunctions
    <Microsoft.SqlServer.Server.SqlFunction()> _
    Public Shared Function CallUrl(ByVal sURL As String) As SqlString

        'impersonate the calling user
        Dim newContext As System.Security.Principal.WindowsImpersonationContext
        newContext = SqlContext.WindowsIdentity.Impersonate()

        Try
            Dim url As String = sURL
            Dim req As HttpWebRequest = CType(WebRequest.Create(url), HttpWebRequest)
            Dim resp As HttpWebResponse = CType(req.GetResponse, HttpWebResponse)
            Dim stmrdr As StreamReader = New StreamReader(resp.GetResponseStream)
            Dim html = stmrdr.ReadToEnd
            stmrdr.Close()
            resp.Close()
            Return New SqlString(html)
        Catch ex As Exception
            'Kald til procedure der skriver i eventloggen
            LogToEventLog(ex.Message)
            Return New SqlString("Error")
        Finally
            newContext.Undo()
        End Try

    End Function

    Public Shared Sub LogToEventLog(ByVal errorMessage As String)
        Dim log As System.Diagnostics.EventLog = New System.Diagnostics.EventLog
        log.Source = "My Application"
        log.WriteEntry(errorMessage)
    End Sub
End Class
Avatar billede arne_v Ekspert
29. juni 2008 - 22:04 #27
Prøv evt. kun at impersonate for eventlog men ikke for HTTP.
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