2011-09-06 2 views
5

idea di come posso ottenere utente FirstName e LastName dalla tabella aspnet_profile sulla base di UserID utilizzando SQL stavano ristrutturando mi piacerebbe utilizzare in Telerik reporting come parametro utente.SQL aspnet_profile

fila del campione (FirstName è George, Cognome è Test):

UserID: 06b24b5c-9aa1-426e-b7e4-0771c5f85e85 

PropertyName: MobilePhone:S:0:0:Initials:S:0:1:City:S:1:14:FirstName:S:15:6:PostalCode:S:21:7:‌​WorkPhone:S:28:12:LastName:S:40:5:Address1:S:45:17:Address2:S:62:0:Province:S:62:‌​2:Organization:S:64:4:ClinicId:S:68:1:Country:S:69:6:Fax:S:75:0:MSPNumber:S:75:0:‌​ 

PropertyValuesString: HEast HustonEASGeorgeT7D 1N8604-111-2222Test5555 Beddtvue AveDCHCNL2Canada 

PropertyValuesBinary: <Binary data> 

LastUpdateDate: 2010-01-02 22:22:03.947 
+0

Grazie Marek, ecco uno Smaple riga: UserID: 06b24b5c-9aa1-426e-b7e4-0771c5f85e85 \t PropertyName: MobilePho ne: S: 0: 0: Iniziali: S: 0: 1: Città: S: 1: 14: FirstName: S: 15: 6: CodicePostale: S: 21: 7: WorkPhone: S: 28: 12: Cognome: S: 40: 5: Indirizzo1: S: 45: 17: Indirizzo2: S: 62: 0: Provincia: S: 62: 2: Organizzazione: S: 64: 4: ClinicId: S: 68: 1: Paese: S: 69: 6: Fax: S: 75: 0: MSPNumber: S: 75: 0: \t PropertyValuesSring: HEast HustonEASGeorgeT7D 1N8604-111-2222Test5555 Beddtvue AveDCHCNL2Canada \t (FirstName è George, Cognome è test) PropertyVlaueBinary: \t LastUpdateDate: 2010-01-02 22: 22: 03,947 – hncl

+0

Il modo in cui le informazioni sono codificate nella tabella 'aspnet_Profile' (http://msdn.microsoft.com/en-us/library/aa478953.aspx) è esattamente perché ho scelto di non usarlo e ho creato una tabella personalizzata per archiviare le informazioni del profilo. Puoi dirci di più sul tuo problema? Devi creare un rapporto che mostri tutti i nomi e i cognomi ** o ** hai bisogno di recuperare nome e cognome per un singolo utente? –

+0

Basta recuperare il nome e il cognome di un singolo utente, usando userid. Grazie – hncl

risposta

3

Se ti ostini a usare SQL, sono sicuro che un gran numero di SUBSTRING s e PATINDEX es si arriva lì, ma ha vinto essere una soluzione pulita

Aggiornamento:user373721 trovato una grande risorsa e ha pubblicato un commento su di esso, ma può essere facilmente perdere, così ho deciso di aggiungerlo alla risposta, troppo - How to get asp.net profile value from MS SQL database using T-SQL?

Il built-in dbo.aspnet_Profile_GetProperties stored procedure rendimenti il valore PropertyValuesString successivamente analizzato nella funzione ParseDataFromDB .

private void GetPropertyValuesFromDatabase(string userName, SettingsPropertyValueCollection svc) 
{ 
    if (HostingEnvironment.IsHosted && EtwTrace.IsTraceEnabled(4, 8)) 
    { 
     EtwTrace.Trace(EtwTraceType.ETW_TYPE_PROFILE_BEGIN, HttpContext.Current.WorkerRequest); 
    } 
    HttpContext current = HttpContext.Current; 
    string[] names = null; 
    string values = null; 
    byte[] buffer = null; 
    if (current != null) 
    { 
     if (!current.Request.IsAuthenticated) 
     { 
      string anonymousID = current.Request.AnonymousID; 
     } 
     else 
     { 
      string name = current.User.Identity.Name; 
     } 
    } 
    try 
    { 
     SqlConnectionHolder connection = null; 
     SqlDataReader reader = null; 
     try 
     { 
      connection = SqlConnectionHelper.GetConnection(this._sqlConnectionString, true); 
      this.CheckSchemaVersion(connection.Connection); 
      SqlCommand command = new SqlCommand("dbo.aspnet_Profile_GetProperties", connection.Connection) { 
       CommandTimeout = this.CommandTimeout, 
       CommandType = CommandType.StoredProcedure 
      }; 
      command.Parameters.Add(this.CreateInputParam("@ApplicationName", SqlDbType.NVarChar, this.ApplicationName)); 
      command.Parameters.Add(this.CreateInputParam("@UserName", SqlDbType.NVarChar, userName)); 
      command.Parameters.Add(this.CreateInputParam("@CurrentTimeUtc", SqlDbType.DateTime, DateTime.UtcNow)); 
      reader = command.ExecuteReader(CommandBehavior.SingleRow); 
      if (reader.Read()) 
      { 
       names = reader.GetString(0).Split(new char[] { ':' }); 
       values = reader.GetString(1); 
       int length = (int) reader.GetBytes(2, 0L, null, 0, 0); 
       buffer = new byte[length]; 
       reader.GetBytes(2, 0L, buffer, 0, length); 
      } 
     } 
     finally 
     { 
      if (connection != null) 
      { 
       connection.Close(); 
       connection = null; 
      } 
      if (reader != null) 
      { 
       reader.Close(); 
      } 
     } 
     ProfileModule.ParseDataFromDB(names, values, buffer, svc); 
     if (HostingEnvironment.IsHosted && EtwTrace.IsTraceEnabled(4, 8)) 
     { 
      EtwTrace.Trace(EtwTraceType.ETW_TYPE_PROFILE_END, HttpContext.Current.WorkerRequest, userName); 
     } 
    } 
    catch 
    { 
     throw; 
    } 
} 

 

internal static void ParseDataFromDB(string[] names, string values, byte[] buf, SettingsPropertyValueCollection properties) 
{ 
    if (((names != null) && (values != null)) && ((buf != null) && (properties != null))) 
    { 
     try 
     { 
      for (int i = 0; i < (names.Length/4); i++) 
      { 
       string str = names[i * 4]; 
       SettingsPropertyValue value2 = properties[str]; 
       if (value2 != null) 
       { 
        int startIndex = int.Parse(names[(i * 4) + 2], CultureInfo.InvariantCulture); 
        int length = int.Parse(names[(i * 4) + 3], CultureInfo.InvariantCulture); 
        if ((length == -1) && !value2.Property.PropertyType.IsValueType) 
        { 
         value2.PropertyValue = null; 
         value2.IsDirty = false; 
         value2.Deserialized = true; 
        } 
        if (((names[(i * 4) + 1] == "S") && (startIndex >= 0)) && ((length > 0) && (values.Length >= (startIndex + length)))) 
        { 
         value2.SerializedValue = values.Substring(startIndex, length); 
        } 
        if (((names[(i * 4) + 1] == "B") && (startIndex >= 0)) && ((length > 0) && (buf.Length >= (startIndex + length)))) 
        { 
         byte[] dst = new byte[length]; 
         Buffer.BlockCopy(buf, startIndex, dst, 0, length); 
         value2.SerializedValue = dst; 
        } 
       } 
      } 
     } 
     catch 
     { 
     } 
    } 
} 
+0

Grazie, ma ho bisogno di usare SQL – hncl

+0

Grazie Marek, l'unica ragione per cui ho bisogno di farlo in SQL è di incorporare l'output come parametro utente nel report di Telerik. Apprezzo le informazioni che hai fornito. – hncl

+2

Ho trovato una soluzione all'indirizzo http://www.karpach.com/Get-asp-net-profile-value-MS-SQL-database-using-T-SQL.htm, ha funzionato bene. Grazie ancora per la tua assistenza. – hncl

1

Per coloro che sono ancora alla ricerca di un metodo per analizzare il tavolo aspnet_Profile utilizzando SQL puro. Ecco quello che io uso:

In primo luogo è necessario un tavolo Tally. Se non sapete di cosa si tratta, leggere questo articolo da Jeff Moden: http://www.sqlservercentral.com/articles/T-SQL/62867/

per voi per generare l'uso tavolo tally questo script:

SELECT TOP 11000 IDENTITY(INT,1,1) AS N INTO dbo.Tally FROM Master.dbo.SysColumns sc1, Master.dbo.SysColumns sc2 

--===== Add a Primary Key to maximize performance 
ALTER TABLE dbo.Tally ADD CONSTRAINT PK_Tally_N PRIMARY KEY CLUSTERED (N) WITH FILLFACTOR = 100 

--===== Let the public use it 
GRANT SELECT, REFERENCES ON dbo.Tally TO PUBLIC 

D'ora in poi l'analisi del profileData: Il processo di seguito è il modo più veloce che ho trovato per fare questo dopo un sacco di test sui miei dati specifici. Ho testato l'analisi della tabella completa in una volta sola, ma funziona più lentamente rispetto all'utilizzo della funzione seguente e analizzando un utente alla volta con un'applicazione CROSS.

Quindi, per chiamare la funzione, usare qualcosa come:

SELECT bla, bla 
FROM aspnet_Users u CROSS APPY dbo.ProfileProperties(u.UserID) 

L'unica cosa che devi fare è aggiornare 3 cose per contenere le proprietà del profilo che si utilizza: 1) la tabella di ritorno 2) la dichiarazione PIVOT, e 3) la dichiarazione dell'inserto di copiare i dati dal perno nella tabella di ritorno

Ecco la funzione, Enjoy!

/** ============================================= 
** Author:  Francois Grobler 
** Create date: 2013-04-25 
** Description: This function extracts all 
** Profile Properties for a given UserId, 
** and returns them as a table 
** Change History: 
** Date: Author: Change: 
** 
** ============================================= **/ 
CREATE FUNCTION dbo.ProfileProperties 
(
    @UserID UNIQUEIDENTIFIER 
) 
RETURNS @returnTable TABLE(
      FirstName nvarchar(200) 
      , LastName nvarchar(200) 
      , PassportNumber nvarchar(100) 
      , PositionCode int 
      , CellNumber nvarchar(20) 
      , Telephone nvarchar(30) 
      , FaxNumber nvarchar(20) 
      , Email nvarchar(200) 
      , PersalNumber nvarchar(10) 
      , SouthAfricanIdentityNumber nchar(13) 
      , ContractNumber nvarchar(20) 
      , DepartmentName nvarchar(200) 
      , SiteName nvarchar(200) 
      , DepartmentCode int 
      , SiteCode int 
      , UserAccessCode int 
      , ApproverCode int 
         ) 
WITH SCHEMABINDING 
AS 
BEGIN 
    WITH Properties(PropertyNo, PropertyType, UserId, Value) 
    AS 
    (
      SELECT (ROW_NUMBER() OVER(ORDER BY UserId) - 1)/4 PropertyNo 
      , (ROW_NUMBER() OVER(PARTITION BY p.UserId ORDER BY UserId) - 1) % 4 PropertyType 
      , p.UserId 
      , SUBSTRING(':' + CONVERT(nvarchar(4000), p.PropertyNames), n + 1, CHARINDEX(':', ':' + CONVERT(nvarchar(4000), p.PropertyNames), n + 1) - n - 1) Value 
      FROM dbo.Tally, dbo.aspnet_Profile p 
      WHERE n < LEN(':' + CONVERT(nvarchar(4000), p.PropertyNames)) 
       and SUBSTRING(':' + CONVERT(nvarchar(4000), p.PropertyNames), n, 1) = ':' 
       and p.UserId = @UserID 
    ) 
    , FlatProperties(UserId, Property, ValueType, StartIndex, ValueLength) 
    AS 
    (
     SELECT UserId 
     , MAX(CASE WHEN PropertyType = 0 THEN Value ELSE '' END) Property 
     , MAX(CASE WHEN PropertyType = 1 THEN Value ELSE '' END) ValueType 
     , MAX(CASE WHEN PropertyType = 2 THEN CONVERT(int, Value) + 1 ELSE 0 END) StartIndex 
     , MAX(CASE WHEN PropertyType = 3 THEN CONVERT(int, Value) ELSE 0 END) ValueLength 
     FROM 
      Properties 
     GROUP BY UserID, PropertyNo 
    ) 
    , PropertyValues(UserID, PropertyName, PropertyValue) 
    AS 
    (
     SELECT p.UserID, fp.Property 
     , CASE fp.ValueType 
      WHEN 'S' THEN SUBSTRING(p.PropertyValuesString, fp.StartIndex, fp.ValueLength) 
      ELSE SUBSTRING(p.PropertyValuesBinary, fp.StartIndex, fp.ValueLength) END Value 
     FROM dbo.aspnet_Profile p INNER JOIN flatProperties fp ON p.UserId = fp.UserId 
     WHERE p.UserId = @UserID 
    ) 
    , PropertyTable 
    AS 
    (
     SELECT 
      UserID 
      , pvt.[FirstName] 
      , pvt.[LastName] 
      , pvt.[PassportNumber] 
      , pvt.[PositionCode] 
      , pvt.[CellNumber] 
      , pvt.[Telephone] 
      , pvt.[FaxNumber] 
      , pvt.[Email] 
      , pvt.[PersalNumber] 
      , pvt.[SouthAfricanIdentityNumber] 
      , pvt.[ContractNumber] 
      , pvt.[DepartmentName] 
      , pvt.[SiteName] 
      , pvt.[DepartmentCode] 
      , pvt.[SiteCode] 
      , pvt.[UserCode] UserAccessCode 
      , pvt.[ApproverCode] 
     FROM PropertyValues 
     PIVOT (
     MAX(PropertyValue) FOR PropertyName IN ([FirstName],[LastName],[PassportNumber],[PositionCode],[CellNumber],[Telephone],[FaxNumber],[Email],[PersalNumber],[SouthAfricanIdentityNumber],[ContractNumber],[DepartmentName],[SiteName],[DepartmentCode],[SiteCode],[UserCode],[ApproverCode]) 
      ) AS pvt 
    ) 
    INSERT INTO @returnTable 
    (
     FirstName 
     , LastName 
     , PassportNumber 
     , PositionCode 
     , CellNumber 
     , Telephone 
     , FaxNumber 
     , Email 
     , PersalNumber 
     , SouthAfricanIdentityNumber 
     , ContractNumber 
     , DepartmentName 
     , SiteName 
     , DepartmentCode 
     , SiteCode 
     , UserAccessCode 
     , ApproverCode 
    ) 
    SELECT TOP 1 
     FirstName 
     , LastName 
     , PassportNumber 
     , PositionCode 
     , CellNumber 
     , Telephone 
     , FaxNumber 
     , Email 
     , PersalNumber 
     , SouthAfricanIdentityNumber 
     , ContractNumber 
     , DepartmentName 
     , SiteName 
     , DepartmentCode 
     , SiteCode 
     , UserAccessCode 
     , ApproverCode 
    FROM PropertyTable; 

    RETURN; 
END 
GO 
1

http://www.karpach.com/Get-asp-net-profile-value-MS-SQL-database-using-T-SQL.htm

questo mi ha aiutato enormemente!

seguendo la procedura descritta in quel link mi ha permesso di recuperare tutti i dati particolari nel PropertyValueString dalla tabella aspnet_profile.

copia e pasting- Funzione First:

CREATE FUNCTION dbo.fn_GetElement 
(
@ord AS INT, 
@str AS VARCHAR(8000), 
@delim AS VARCHAR(1)) 

RETURNS INT 
AS 
BEGIN 
    -- If input is invalid, return null. 
    IF @str IS NULL 
     OR LEN(@str) = 0 
     OR @ord IS NULL 
     OR @ord < 1 
     -- @ord > [is the] expression that calculates the number of elements. 
     OR @ord > LEN(@str) - LEN(REPLACE(@str, @delim, '')) + 1 
    RETURN NULL 
    DECLARE @pos AS INT, @curord AS INT 
    SELECT @pos = 1, @curord = 1 
    -- Find next element's start position and increment index. 
    WHILE @curord < @ord 
    SELECT 
     @pos = CHARINDEX(@delim, @str, @pos) + 1, 
     @curord = @curord + 1 
    RETURN 
    CAST(SUBSTRING(@str, @pos, CHARINDEX(@delim, @str + @delim, @pos) - @pos) AS INT) 
END 

seconda funzione:

CREATE FUNCTION dbo.fn_GetProfileElement 
(
@fieldName AS NVARCHAR(100), 
@fields AS NVARCHAR(4000), 
@values AS NVARCHAR(4000)) 

RETURNS NVARCHAR(4000) 
AS 
BEGIN 
    -- If input is invalid, return null. 
    IF @fieldName IS NULL 
     OR LEN(@fieldName) = 0 
     OR @fields IS NULL 
     OR LEN(@fields) = 0 
     OR @values IS NULL 
     OR LEN(@values) = 0 

    RETURN NULL 

-- locate FieldName in Fields 
DECLARE @fieldNameToken AS NVARCHAR(20) 
DECLARE @fieldNameStart AS INTEGER, 
@valueStart AS INTEGER, 
@valueLength AS INTEGER 

-- Only handle string type fields (:S:) 
SET @fieldNameStart = CHARINDEX(@fieldName + ':S',@Fields,0) 

-- If field is not found, return null 
IF @fieldNameStart = 0 RETURN NULL 
SET @fieldNameStart = @fieldNameStart + LEN(@fieldName) + 3 

-- Get the field token which I've defined as the start of the 
-- field offset to the end of the length 
SET @fieldNameToken = SUBSTRING(@Fields,@fieldNameStart,LEN(@Fields)[email protected]) 

-- Get the values for the offset and length 
SET @valueStart = dbo.fn_getelement(1,@fieldNameToken,':') 
SET @valueLength = dbo.fn_getelement(2,@fieldNameToken,':') 

-- Check for sane values, 0 length means the profile item was 
-- stored, just no data 
IF @valueLength = 0 RETURN '' 

-- Return the string 
RETURN SUBSTRING(@values, @valueStart+1, @valueLength) 

END 

query SQL può essere modded alle vostre esigenze

SELECT dbo.fn_GetProfileElement('FirstName',PropertyNames,PropertyValuesString) 
    , dbo.fn_GetProfileElement('LastName',PropertyNames,PropertyValuesString) 
FROM aspnet_Profile