2011-09-06 10 views
5

bất kỳ ý tưởng làm thế nào tôi có thể nhận được người dùng FirstName và LastName từ bảng aspnet_profile dựa trên UserID sử dụng SQL becasue tôi muốn sử dụng trong Telerik báo cáo như một tham số người dùng.SQL aspnet_profile

mẫu hàng (FirstName là George, LastName là 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

Cảm ơn Marek, đây là một smaple hàng: UserID: 06b24b5c-9aa1-426e-b7e4-0771c5f85e85 \t Tên sản phẩm: MobilePho ne: S: 0: 0: Initials: S: 0: 1: Thành phố: S: 1: 14: FirstName: S: 15: 6: PostalCode: S: 21: 7: WorkPhone: S: 28: 12: Họ: S: 40: 5: Address1: S: 45: 17: Address2: S: 62: 0: Tỉnh: S: 62: 2: Tổ chức: S: 64: 4: ClinicId: S: 68: 1: Quốc gia: S: 69: 6: Fax: S: 75: 0: MSPNumber: S: 75: 0: \t PropertyValuesSring: HEast HustonEASGeorgeT7D 1N8604-111-2222Test5555 Beddtvue AveDCHCNL2Canada \t (FirstName là George, LastName là Test) PropertyVlaueBinary: \t LastUpdateDate: 2010-01-02 22: 22: 03.947 – hncl

+0

Cách thông tin được mã hóa trong bảng 'aspnet_Profile' (http://msdn.microsoft.com/en-us/library/aa478953.aspx) là chính xác tại sao tôi đã chọn không sử dụng nó và tạo ra một bảng tùy chỉnh để lưu trữ thông tin hồ sơ. Bạn có thể cho chúng tôi biết thêm về vấn đề của bạn không? Bạn có cần tạo báo cáo hiển thị tất cả họ và tên ** hay ** bạn có cần truy xuất họ và tên cho một người dùng không? –

+0

Chỉ cần truy xuất tên và họ của một người dùng, sử dụng userid. Cảm ơn – hncl

Trả lời

3

Nếu bạn nhấn mạnh vào sử dụng SQL, tôi chắc chắn một số lượng lớn các SUBSTRING s và PATINDEX es sẽ giúp bạn có ở đó nhưng nó đã giành không phải là một giải pháp sạch.

Cập nhật:user373721 tìm thấy một nguồn lực lớn và đăng một bình luận về nó, nhưng nó có thể dễ dàng bỏ qua, vì vậy tôi quyết định thêm nó vào câu trả lời, quá - How to get asp.net profile value from MS SQL database using T-SQL?

Việc xây dựng trong dbo.aspnet_Profile_GetProperties stored procedure lợi nhuận giá trị PropertyValuesString sau đó được phân tích cú pháp trong hàm 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

Cảm ơn, nhưng tôi cần sử dụng SQL – hncl

+0

Cảm ơn Marek, lý do duy nhất tôi cần thực hiện điều đó trong SQL là kết hợp đầu ra dưới dạng Tham số người dùng trong Báo cáo Telerik. Tôi đánh giá cao thông tin bạn đã cung cấp. – hncl

+2

Tôi tìm thấy một giải pháp tại http://www.karpach.com/Get-asp-net-profile-value-MS-SQL-database-using-T-SQL.htm, nó hoạt động tốt. Cảm ơn một lần nữa để được giúp đỡ của bạn. – hncl

1

Đối với những người vẫn đang tìm kiếm một phương pháp để phân tích bảng aspnet_Profile sử dụng SQL tinh khiết. Đây là những gì tôi sử dụng:

Trước tiên, bạn cần một bảng Tally. Nếu bạn không biết điều này là gì, đọc bài viết này bởi Jeff Moden: http://www.sqlservercentral.com/articles/T-SQL/62867/

Đối với bạn để tạo ra việc sử dụng bảng tổng sắp kịch bản này:

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 

Bây giờ trên để phân tích các ProfileData: Quá trình này dưới đây là cách nhanh nhất tôi tìm thấy để thực hiện việc này sau nhiều lần thử nghiệm trên dữ liệu cụ thể của tôi. Tôi đã thử nghiệm phân tích cú pháp bảng đầy đủ trong một lần, nhưng chạy chậm hơn so với sử dụng hàm bên dưới và phân tích cú pháp một người dùng tại một thời điểm với một ứng dụng CROSS.

Vì vậy, để gọi hàm, sử dụng một cái gì đó như:

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

Điều duy nhất bạn cần làm là để cập nhật 3 điều cần chứa Properties hồ sơ mà bạn sử dụng: 1) bảng trở 2) tuyên bố PIVOT và 3) câu lệnh chèn sao chép dữ liệu từ PIVOT vào bảng trả lại

Đây là chức năng, Hãy tận hưởng!

/** ============================================= 
** 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

này đã giúp tôi rất nhiều!

làm theo các bước trong liên kết đó cho phép tôi tìm nạp bất kỳ dữ liệu cụ thể nào trong PropertyValueString từ bảng aspnet_profile.

sao chép và pasting- Chức năng đầu tiên:

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 

Chức năng thứ hai:

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 

SQL truy vấn có thể được modded yêu cầu của bạn

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