Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Alex Brown 129 posts 620 karma points
    Jul 20, 2017 @ 10:23
    Alex Brown
    0

    Problem Running Stored Procedure

    Hi All

    I'm trying to run a stored procedure but I'm having trouble doing it in C# using the Umbraco.Core.Persistence.Database class.

    The following stored procedure works when I run it in SQL Server Management Studio, however when I run it C# it throws an error saying "Invalid syntax near FROM".

    Here's my procedure (apologies for size):

    CREATE PROCEDURE get_product_filters
    
    @sectorId int
    AS
    BEGIN
    
    SET NOCOUNT ON;
    DECLARE @temp TABLE
    (
        Id int,
        Name nvarchar(max),
        SortOrder int,
        Type nvarchar(max),
        ParentId int
    )
    
    INSERT INTO @temp
        SELECT c.UmbracoNodeId [Id], c.Name, categoryNode.sortOrder [SortOrder], 'Categories' [Type], NULL
        FROM Categories c
        INNER JOIN umbracoNode categoryNode ON c.UmbracoNodeId = categoryNode.id
        INNER JOIN umbracoNode catalogue ON categoryNode.parentID = catalogue.id
        INNER JOIN umbracoNode filterLanding ON catalogue.parentID = filterLanding.id
        INNER JOIN umbracoNode sector ON filterLanding.parentID = sector.id
        WHERE sector.id = @sectorId                                         
    UNION ALL
        SELECT c.UmbracoNodeId [Id], c.Name, categoryNode.sortOrder [SortOrder], 'Subcategories' [Type], c.ParentCategoryId [ParentId]
        FROM Categories c
        INNER JOIN umbracoNode subCategoryNode ON c.UmbracoNodeId = subCategoryNode.id
        INNER JOIN umbracoNode categoryNode ON subCategoryNode.parentID = categoryNode.id
        INNER JOIN umbracoNode catalogue ON categoryNode.parentID = catalogue.id
        INNER JOIN umbracoNode filterLanding ON catalogue.parentID = filterLanding.id
        INNER JOIN umbracoNode sector ON filterLanding.parentID = sector.id
        WHERE sector.id = @sectorId AND c.Id IN (SELECT pc.CategoryId FROM ProductCategory pc)
    UNION ALL
        SELECT region.id [Id], region.text [Name], region.sortOrder [SortOrder], 'Region' [Type], NULL
        FROM umbracoNode region
        WHERE region.id IN
            (SELECT pr.RegionId FROM Products p
            INNER JOIN ProductRegion pr ON p.Id = pr.ProductId
            INNER JOIN ProductCategory pc ON p.Id = pc.ProductId
            INNER JOIN Categories c ON pc.CategoryId = c.Id
            INNER JOIN umbracoNode parentCategoryNode ON c.ParentCategoryId = parentCategoryNode.id
            INNER JOIN umbracoNode catalogue ON parentCategoryNode.parentID = catalogue.id
            INNER JOIN umbracoNode filterLanding on catalogue.parentID = filterLanding.id
            INNER JOIN umbracoNode sector ON filterLanding.parentID = sector.id
            WHERE sector.id = @sectorId )
    UNION ALL
        SELECT marketSectors.id [Id], marketSectors.text [Name], marketSectors.sortOrder [SortOrder], 'Market Sectors' [Type], NULL
        FROM umbracoNode marketSectors
        WHERE marketSectors.id IN
            (SELECT pms.SectorId FROM Products p
            INNER JOIN ProductMarketSectors pms ON p.Id = pms.ProductId
            INNER JOIN ProductCategory pc ON p.Id = pc.ProductId
            INNER JOIN Categories c ON pc.CategoryId = c.Id
            INNER JOIN umbracoNode parentCategoryNode ON c.ParentCategoryId = parentCategoryNode.id
            INNER JOIN umbracoNode catalogue ON parentCategoryNode.parentID = catalogue.id
            INNER JOIN umbracoNode filterLanding on catalogue.parentID = filterLanding.id
            INNER JOIN umbracoNode sector ON filterLanding.parentID = sector.id
            WHERE sector.id = @sectorId )
    UNION ALL
        SELECT b.Id [Id], b.Name, NULL, 'Brands' [Type], NULL
        FROM Brand b
        WHERE b.Id IN
            (SELECT pb.BrandId
            FROM Products p
            INNER JOIN ProductBrand pb ON p.Id = pb.ProductId
            INNER JOIN ProductCategory pc ON p.Id = pc.ProductId
            INNER JOIN Categories c ON pc.CategoryId = c.Id
            INNER JOIN umbracoNode parentCategoryNode ON c.ParentCategoryId = parentCategoryNode.id
            INNER JOIN umbracoNode catalogue ON parentCategoryNode.parentID = catalogue.id
            INNER JOIN umbracoNode filterLanding on catalogue.parentID = filterLanding.id
            INNER JOIN umbracoNode sector ON filterLanding.parentID = sector.id
            WHERE sector.id = @sectorId )
    
    SELECT * FROM @temp
    END
    GO
    

    I've pasted the entire thing in, however I don't think there's any problems with the joins as like I said it works fine in SSMS.

    Here's my C# command:

    return _db.Fetch<object>(@"EXEC get_product_filters @0",
                                         sectorId);
    

    Returning type "object" is just temporary, so I can get a list of results.

    I think it may have something to do with the table variable I'm creating.

    Any ideas?

    Cheers

  • Dave Woestenborghs 3504 posts 12133 karma points MVP 8x admin c-trib
    Jul 20, 2017 @ 10:34
    Dave Woestenborghs
    100

    Hi Alex,

    I just checked a project where we use stored procedures.

    We have it like this :

    return _db.Fetch<object>(@";EXEC get_product_filters @0",
                                         sectorId);
    

    Notice the ; before the exec statement. I think that is needed for it to work.

    Dave

  • Dave Woestenborghs 3504 posts 12133 karma points MVP 8x admin c-trib
    Jul 20, 2017 @ 10:36
    Dave Woestenborghs
    0

    Hi Alex,

    I didn't look at the stored procedure code at first but I know see that you are querying umbraco tables.

    IMHO it's better to use the Umbraco API to retreive content.

    Maybe you can explain what you are trying to do and we can find a solution.

    Dave

  • Alex Brown 129 posts 620 karma points
    Jul 20, 2017 @ 10:49
    Alex Brown
    0

    Hi Dave

    Thanks for the reply.

    It's pretty difficult to explain but I'm querying the tables as I'm trying to get a list of content managed objects which related to "products". Products are separate entities and are managed in a custom section.

    Users can create new market sectors for example, within the content section, then link them to products in the custom section. The custom section uses the content service in Angular to retrieve the node ids, then stores the product id and market sector id in the ProductMarketSector table.

    I'm after a list of market sectors which are assigned to products, as some aren't assigned.

    EDIT: I wasn't specific enough here. To add to the above: Each product is stored within a category (content), and located under a sector (content managed). Sectors will have some categories with products, and not all the market sectors may be assigned to the products within Sector A, Category A.

    Not sure if I'm confusing matters.

  • Alex Brown 129 posts 620 karma points
    Jul 20, 2017 @ 10:53
    Alex Brown
    0

    Also you're an absolute legend, it works! Why does it need the semi-colon?

  • Dave Woestenborghs 3504 posts 12133 karma points MVP 8x admin c-trib
    Jul 20, 2017 @ 10:57
    Dave Woestenborghs
    0

    Don't recall exactly...think it's how peta poco handles stored procedures.

    Dave

  • Dave Woestenborghs 3504 posts 12133 karma points MVP 8x admin c-trib
    Jul 20, 2017 @ 10:54
    Dave Woestenborghs
    0

    So if i understand correctly you link the content to the product in the custom section .

    So what you can do is get all products from your table. And once you have them you can loop them and get the associated content item using the API. This will be safer and you will be sure that you have the correct published version. Also your query on the db will be faster because you only need to get the products and not the content (which is already stored in memory)

    Dave

  • Alex Brown 129 posts 620 karma points
    Jul 20, 2017 @ 10:59
    Alex Brown
    0

    So with all the products I have (couple of thousand), it would be quicker to loop through and find all the associated market sectors, brands, regions and categories?

    What's the disadvantages of querying the database?

    I understand that content is already cached, but since SQL indexes its tables, I thought it'd be quicker to just run this sproc, rather than looping through many lists.

  • Dave Woestenborghs 3504 posts 12133 karma points MVP 8x admin c-trib
    Jul 20, 2017 @ 11:07
    Dave Woestenborghs
    0

    Hi Alex,

    Like I querying the db has it's risks. I don't think you are checking if the content is published in your query for example.

    Also future updates of Umbraco may change the underlying tables breaking your query, while the API will work.

    Also don't have enough information to recommend a correct solution for your use case.

    dave

  • Alex Brown 129 posts 620 karma points
    Jul 20, 2017 @ 11:14
    Alex Brown
    0

    Hi Dave

    What you're saying makes sense. I might try find a way to use Examine to get these values instead.

    Thanks again.

Please Sign in or register to post replies

Write your reply to:

Draft