Loop with dynamic table name and where clause stored procedure












0















I am trying to update records and insert their audits to audit table.



For this purpose stored procedure waiting for above variables.



@m_obj_id INT,
@m_obj_code NVARCHAR(250),
@m_f_code NVARCHAR(250),
@m_nv NVARCHAR(4000),
@m_last_mod_by INTEGER,
@table_name SYSNAME,
--@where_clause NVARCHAR(4000)



Stored procedure formatting these variables as;



UPDATE @table_name SET @m_f_code=@m_nv WHERE id=@m_obj_id


And at last part inserting into audit.



I can use it with doing SELECT CONCAT and copying all the rows then execute.



But my goal is here not expecting @m_obj_id from user and replace it @where_clause. And use this @where_clause to get ids inside.



So far I tried;



    DECLARE @Sql NVARCHAR(MAX)
DECLARE @RecordId int = 0
BEGIN
SET @SQL = N'
SELECT @RecordId = MIN(id)
FROM ' + @table_name + '
WHERE id > @RecordId AND (' + @where_clause + ')
IF @RecordId IS NULL BREAK
SET @m_obj_id = @RecordId'
Exec sp_executesql @sql


But couldnt get far with it.



Then I tried something like;



DECLARE @RowsToProcess  int
DECLARE @CurrentRow int
DECLARE @SelectCol1 int

DECLARE @sql NVARCHAR(MAX)
SET @sql = N'
DECLARE @table1 TABLE (RowID int not null primary key identity(1,1), col1 int )
INSERT into @table1 (col1) SELECT id FROM ' + @table_name + ' Where ' + @where_clause + '
SET @RowsToProcess=@@ROWCOUNT'
EXEC sp_executesql @sql,
N'@RowsToProcess INT OUTPUT', @RowsToProcess OUTPUT

SET @CurrentRow=0
WHILE @CurrentRow<@RowsToProcess
BEGIN
SET @CurrentRow=@CurrentRow+1
DECLARE @sql2 NVARCHAR(MAX)
SET @sql2 = N'
SET @m_obj_id =
(SELECT col1
FROM @table1
WHERE RowID=@CurrentRow)'
EXEC sp_executesql @sql2


But still no luck.



Can I achieve this any how? I am trying to do this for more than it should be.
Thanks all.










share|improve this question























  • Things like Where ' + @where_clause + ' are terrifyingly open to injection. Having a completely unparsed, unquoted, unchecked value being passed to dynamic SQL is basically leaving the door wide open for someone to inject into your server. I think we need to know a little more on the broader scope here and fix the major security flaw you have.

    – Larnu
    Nov 20 '18 at 11:26













  • Thanks for warning. I can come back to security after acheiving this. This is my top goal right now.

    – Cappydh
    Nov 20 '18 at 11:44











  • I'm pretty sure, to be honest, that this is an XY Question. But you need to consider the security as you build the solution. With something like this, if you don't then you're going to just have to rebuild everything again afterwards.

    – Larnu
    Nov 20 '18 at 11:45











  • I really understand your concern. But I need to know if I can do that in this way. If I can achieve this and understand how to do it, it will be no problem to rebuild again.

    – Cappydh
    Nov 20 '18 at 11:53
















0















I am trying to update records and insert their audits to audit table.



For this purpose stored procedure waiting for above variables.



@m_obj_id INT,
@m_obj_code NVARCHAR(250),
@m_f_code NVARCHAR(250),
@m_nv NVARCHAR(4000),
@m_last_mod_by INTEGER,
@table_name SYSNAME,
--@where_clause NVARCHAR(4000)



Stored procedure formatting these variables as;



UPDATE @table_name SET @m_f_code=@m_nv WHERE id=@m_obj_id


And at last part inserting into audit.



I can use it with doing SELECT CONCAT and copying all the rows then execute.



But my goal is here not expecting @m_obj_id from user and replace it @where_clause. And use this @where_clause to get ids inside.



So far I tried;



    DECLARE @Sql NVARCHAR(MAX)
DECLARE @RecordId int = 0
BEGIN
SET @SQL = N'
SELECT @RecordId = MIN(id)
FROM ' + @table_name + '
WHERE id > @RecordId AND (' + @where_clause + ')
IF @RecordId IS NULL BREAK
SET @m_obj_id = @RecordId'
Exec sp_executesql @sql


But couldnt get far with it.



Then I tried something like;



DECLARE @RowsToProcess  int
DECLARE @CurrentRow int
DECLARE @SelectCol1 int

DECLARE @sql NVARCHAR(MAX)
SET @sql = N'
DECLARE @table1 TABLE (RowID int not null primary key identity(1,1), col1 int )
INSERT into @table1 (col1) SELECT id FROM ' + @table_name + ' Where ' + @where_clause + '
SET @RowsToProcess=@@ROWCOUNT'
EXEC sp_executesql @sql,
N'@RowsToProcess INT OUTPUT', @RowsToProcess OUTPUT

SET @CurrentRow=0
WHILE @CurrentRow<@RowsToProcess
BEGIN
SET @CurrentRow=@CurrentRow+1
DECLARE @sql2 NVARCHAR(MAX)
SET @sql2 = N'
SET @m_obj_id =
(SELECT col1
FROM @table1
WHERE RowID=@CurrentRow)'
EXEC sp_executesql @sql2


But still no luck.



Can I achieve this any how? I am trying to do this for more than it should be.
Thanks all.










share|improve this question























  • Things like Where ' + @where_clause + ' are terrifyingly open to injection. Having a completely unparsed, unquoted, unchecked value being passed to dynamic SQL is basically leaving the door wide open for someone to inject into your server. I think we need to know a little more on the broader scope here and fix the major security flaw you have.

    – Larnu
    Nov 20 '18 at 11:26













  • Thanks for warning. I can come back to security after acheiving this. This is my top goal right now.

    – Cappydh
    Nov 20 '18 at 11:44











  • I'm pretty sure, to be honest, that this is an XY Question. But you need to consider the security as you build the solution. With something like this, if you don't then you're going to just have to rebuild everything again afterwards.

    – Larnu
    Nov 20 '18 at 11:45











  • I really understand your concern. But I need to know if I can do that in this way. If I can achieve this and understand how to do it, it will be no problem to rebuild again.

    – Cappydh
    Nov 20 '18 at 11:53














0












0








0








I am trying to update records and insert their audits to audit table.



For this purpose stored procedure waiting for above variables.



@m_obj_id INT,
@m_obj_code NVARCHAR(250),
@m_f_code NVARCHAR(250),
@m_nv NVARCHAR(4000),
@m_last_mod_by INTEGER,
@table_name SYSNAME,
--@where_clause NVARCHAR(4000)



Stored procedure formatting these variables as;



UPDATE @table_name SET @m_f_code=@m_nv WHERE id=@m_obj_id


And at last part inserting into audit.



I can use it with doing SELECT CONCAT and copying all the rows then execute.



But my goal is here not expecting @m_obj_id from user and replace it @where_clause. And use this @where_clause to get ids inside.



So far I tried;



    DECLARE @Sql NVARCHAR(MAX)
DECLARE @RecordId int = 0
BEGIN
SET @SQL = N'
SELECT @RecordId = MIN(id)
FROM ' + @table_name + '
WHERE id > @RecordId AND (' + @where_clause + ')
IF @RecordId IS NULL BREAK
SET @m_obj_id = @RecordId'
Exec sp_executesql @sql


But couldnt get far with it.



Then I tried something like;



DECLARE @RowsToProcess  int
DECLARE @CurrentRow int
DECLARE @SelectCol1 int

DECLARE @sql NVARCHAR(MAX)
SET @sql = N'
DECLARE @table1 TABLE (RowID int not null primary key identity(1,1), col1 int )
INSERT into @table1 (col1) SELECT id FROM ' + @table_name + ' Where ' + @where_clause + '
SET @RowsToProcess=@@ROWCOUNT'
EXEC sp_executesql @sql,
N'@RowsToProcess INT OUTPUT', @RowsToProcess OUTPUT

SET @CurrentRow=0
WHILE @CurrentRow<@RowsToProcess
BEGIN
SET @CurrentRow=@CurrentRow+1
DECLARE @sql2 NVARCHAR(MAX)
SET @sql2 = N'
SET @m_obj_id =
(SELECT col1
FROM @table1
WHERE RowID=@CurrentRow)'
EXEC sp_executesql @sql2


But still no luck.



Can I achieve this any how? I am trying to do this for more than it should be.
Thanks all.










share|improve this question














I am trying to update records and insert their audits to audit table.



For this purpose stored procedure waiting for above variables.



@m_obj_id INT,
@m_obj_code NVARCHAR(250),
@m_f_code NVARCHAR(250),
@m_nv NVARCHAR(4000),
@m_last_mod_by INTEGER,
@table_name SYSNAME,
--@where_clause NVARCHAR(4000)



Stored procedure formatting these variables as;



UPDATE @table_name SET @m_f_code=@m_nv WHERE id=@m_obj_id


And at last part inserting into audit.



I can use it with doing SELECT CONCAT and copying all the rows then execute.



But my goal is here not expecting @m_obj_id from user and replace it @where_clause. And use this @where_clause to get ids inside.



So far I tried;



    DECLARE @Sql NVARCHAR(MAX)
DECLARE @RecordId int = 0
BEGIN
SET @SQL = N'
SELECT @RecordId = MIN(id)
FROM ' + @table_name + '
WHERE id > @RecordId AND (' + @where_clause + ')
IF @RecordId IS NULL BREAK
SET @m_obj_id = @RecordId'
Exec sp_executesql @sql


But couldnt get far with it.



Then I tried something like;



DECLARE @RowsToProcess  int
DECLARE @CurrentRow int
DECLARE @SelectCol1 int

DECLARE @sql NVARCHAR(MAX)
SET @sql = N'
DECLARE @table1 TABLE (RowID int not null primary key identity(1,1), col1 int )
INSERT into @table1 (col1) SELECT id FROM ' + @table_name + ' Where ' + @where_clause + '
SET @RowsToProcess=@@ROWCOUNT'
EXEC sp_executesql @sql,
N'@RowsToProcess INT OUTPUT', @RowsToProcess OUTPUT

SET @CurrentRow=0
WHILE @CurrentRow<@RowsToProcess
BEGIN
SET @CurrentRow=@CurrentRow+1
DECLARE @sql2 NVARCHAR(MAX)
SET @sql2 = N'
SET @m_obj_id =
(SELECT col1
FROM @table1
WHERE RowID=@CurrentRow)'
EXEC sp_executesql @sql2


But still no luck.



Can I achieve this any how? I am trying to do this for more than it should be.
Thanks all.







sql-server stored-procedures






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 20 '18 at 11:22









CappydhCappydh

115




115













  • Things like Where ' + @where_clause + ' are terrifyingly open to injection. Having a completely unparsed, unquoted, unchecked value being passed to dynamic SQL is basically leaving the door wide open for someone to inject into your server. I think we need to know a little more on the broader scope here and fix the major security flaw you have.

    – Larnu
    Nov 20 '18 at 11:26













  • Thanks for warning. I can come back to security after acheiving this. This is my top goal right now.

    – Cappydh
    Nov 20 '18 at 11:44











  • I'm pretty sure, to be honest, that this is an XY Question. But you need to consider the security as you build the solution. With something like this, if you don't then you're going to just have to rebuild everything again afterwards.

    – Larnu
    Nov 20 '18 at 11:45











  • I really understand your concern. But I need to know if I can do that in this way. If I can achieve this and understand how to do it, it will be no problem to rebuild again.

    – Cappydh
    Nov 20 '18 at 11:53



















  • Things like Where ' + @where_clause + ' are terrifyingly open to injection. Having a completely unparsed, unquoted, unchecked value being passed to dynamic SQL is basically leaving the door wide open for someone to inject into your server. I think we need to know a little more on the broader scope here and fix the major security flaw you have.

    – Larnu
    Nov 20 '18 at 11:26













  • Thanks for warning. I can come back to security after acheiving this. This is my top goal right now.

    – Cappydh
    Nov 20 '18 at 11:44











  • I'm pretty sure, to be honest, that this is an XY Question. But you need to consider the security as you build the solution. With something like this, if you don't then you're going to just have to rebuild everything again afterwards.

    – Larnu
    Nov 20 '18 at 11:45











  • I really understand your concern. But I need to know if I can do that in this way. If I can achieve this and understand how to do it, it will be no problem to rebuild again.

    – Cappydh
    Nov 20 '18 at 11:53

















Things like Where ' + @where_clause + ' are terrifyingly open to injection. Having a completely unparsed, unquoted, unchecked value being passed to dynamic SQL is basically leaving the door wide open for someone to inject into your server. I think we need to know a little more on the broader scope here and fix the major security flaw you have.

– Larnu
Nov 20 '18 at 11:26







Things like Where ' + @where_clause + ' are terrifyingly open to injection. Having a completely unparsed, unquoted, unchecked value being passed to dynamic SQL is basically leaving the door wide open for someone to inject into your server. I think we need to know a little more on the broader scope here and fix the major security flaw you have.

– Larnu
Nov 20 '18 at 11:26















Thanks for warning. I can come back to security after acheiving this. This is my top goal right now.

– Cappydh
Nov 20 '18 at 11:44





Thanks for warning. I can come back to security after acheiving this. This is my top goal right now.

– Cappydh
Nov 20 '18 at 11:44













I'm pretty sure, to be honest, that this is an XY Question. But you need to consider the security as you build the solution. With something like this, if you don't then you're going to just have to rebuild everything again afterwards.

– Larnu
Nov 20 '18 at 11:45





I'm pretty sure, to be honest, that this is an XY Question. But you need to consider the security as you build the solution. With something like this, if you don't then you're going to just have to rebuild everything again afterwards.

– Larnu
Nov 20 '18 at 11:45













I really understand your concern. But I need to know if I can do that in this way. If I can achieve this and understand how to do it, it will be no problem to rebuild again.

– Cappydh
Nov 20 '18 at 11:53





I really understand your concern. But I need to know if I can do that in this way. If I can achieve this and understand how to do it, it will be no problem to rebuild again.

– Cappydh
Nov 20 '18 at 11:53












2 Answers
2






active

oldest

votes


















0














The non-dynamic way to implement dynamic filtering on sql is the following:



where id=@m_obj_id or @m_obj_id is null



For a LOT of more details on how to choose between dynamic and non-dynamic sql on this, I recommend this article by Erland Sommarskog






share|improve this answer
























  • But I am also getting table name dynamic. So it will not allow me to just put id on where clause.

    – Cappydh
    Nov 20 '18 at 11:46





















0














I found a solution. Thanks everyone for responding.



I used a temp table like



DECLARE @RowsToProcess INTEGER
DECLARE @CurrentRow INTEGER
DECLARE @SelectCol1 INTEGER

CREATE TABLE #tmp (RowID INTEGER NOT NULL PRIMARY KEY IDENTITY(1,1), col1 int)

DECLARE @sql NVARCHAR(MAX)
SET @sql = N'
INSERT into #tmp (col1) SELECT id FROM ' + @table_name + ' Where ' + @where_clause + '
SET @RowsToProcess=@@ROWCOUNT'
INSERT INTO #tmp
EXEC sp_executesql @sql,
N'@RowsToProcess INT OUTPUT', @RowsToProcess OUTPUT

SET @CurrentRow=0
WHILE @CurrentRow<@RowsToProcess
BEGIN
SET @CurrentRow=@CurrentRow+1
SET @m_obj_id =
(SELECT col1
FROM #tmp
WHERE RowID=@CurrentRow)

Do stuff....





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53391923%2floop-with-dynamic-table-name-and-where-clause-stored-procedure%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    The non-dynamic way to implement dynamic filtering on sql is the following:



    where id=@m_obj_id or @m_obj_id is null



    For a LOT of more details on how to choose between dynamic and non-dynamic sql on this, I recommend this article by Erland Sommarskog






    share|improve this answer
























    • But I am also getting table name dynamic. So it will not allow me to just put id on where clause.

      – Cappydh
      Nov 20 '18 at 11:46


















    0














    The non-dynamic way to implement dynamic filtering on sql is the following:



    where id=@m_obj_id or @m_obj_id is null



    For a LOT of more details on how to choose between dynamic and non-dynamic sql on this, I recommend this article by Erland Sommarskog






    share|improve this answer
























    • But I am also getting table name dynamic. So it will not allow me to just put id on where clause.

      – Cappydh
      Nov 20 '18 at 11:46
















    0












    0








    0







    The non-dynamic way to implement dynamic filtering on sql is the following:



    where id=@m_obj_id or @m_obj_id is null



    For a LOT of more details on how to choose between dynamic and non-dynamic sql on this, I recommend this article by Erland Sommarskog






    share|improve this answer













    The non-dynamic way to implement dynamic filtering on sql is the following:



    where id=@m_obj_id or @m_obj_id is null



    For a LOT of more details on how to choose between dynamic and non-dynamic sql on this, I recommend this article by Erland Sommarskog







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 20 '18 at 11:31









    George MenoutisGeorge Menoutis

    2,584419




    2,584419













    • But I am also getting table name dynamic. So it will not allow me to just put id on where clause.

      – Cappydh
      Nov 20 '18 at 11:46





















    • But I am also getting table name dynamic. So it will not allow me to just put id on where clause.

      – Cappydh
      Nov 20 '18 at 11:46



















    But I am also getting table name dynamic. So it will not allow me to just put id on where clause.

    – Cappydh
    Nov 20 '18 at 11:46







    But I am also getting table name dynamic. So it will not allow me to just put id on where clause.

    – Cappydh
    Nov 20 '18 at 11:46















    0














    I found a solution. Thanks everyone for responding.



    I used a temp table like



    DECLARE @RowsToProcess INTEGER
    DECLARE @CurrentRow INTEGER
    DECLARE @SelectCol1 INTEGER

    CREATE TABLE #tmp (RowID INTEGER NOT NULL PRIMARY KEY IDENTITY(1,1), col1 int)

    DECLARE @sql NVARCHAR(MAX)
    SET @sql = N'
    INSERT into #tmp (col1) SELECT id FROM ' + @table_name + ' Where ' + @where_clause + '
    SET @RowsToProcess=@@ROWCOUNT'
    INSERT INTO #tmp
    EXEC sp_executesql @sql,
    N'@RowsToProcess INT OUTPUT', @RowsToProcess OUTPUT

    SET @CurrentRow=0
    WHILE @CurrentRow<@RowsToProcess
    BEGIN
    SET @CurrentRow=@CurrentRow+1
    SET @m_obj_id =
    (SELECT col1
    FROM #tmp
    WHERE RowID=@CurrentRow)

    Do stuff....





    share|improve this answer




























      0














      I found a solution. Thanks everyone for responding.



      I used a temp table like



      DECLARE @RowsToProcess INTEGER
      DECLARE @CurrentRow INTEGER
      DECLARE @SelectCol1 INTEGER

      CREATE TABLE #tmp (RowID INTEGER NOT NULL PRIMARY KEY IDENTITY(1,1), col1 int)

      DECLARE @sql NVARCHAR(MAX)
      SET @sql = N'
      INSERT into #tmp (col1) SELECT id FROM ' + @table_name + ' Where ' + @where_clause + '
      SET @RowsToProcess=@@ROWCOUNT'
      INSERT INTO #tmp
      EXEC sp_executesql @sql,
      N'@RowsToProcess INT OUTPUT', @RowsToProcess OUTPUT

      SET @CurrentRow=0
      WHILE @CurrentRow<@RowsToProcess
      BEGIN
      SET @CurrentRow=@CurrentRow+1
      SET @m_obj_id =
      (SELECT col1
      FROM #tmp
      WHERE RowID=@CurrentRow)

      Do stuff....





      share|improve this answer


























        0












        0








        0







        I found a solution. Thanks everyone for responding.



        I used a temp table like



        DECLARE @RowsToProcess INTEGER
        DECLARE @CurrentRow INTEGER
        DECLARE @SelectCol1 INTEGER

        CREATE TABLE #tmp (RowID INTEGER NOT NULL PRIMARY KEY IDENTITY(1,1), col1 int)

        DECLARE @sql NVARCHAR(MAX)
        SET @sql = N'
        INSERT into #tmp (col1) SELECT id FROM ' + @table_name + ' Where ' + @where_clause + '
        SET @RowsToProcess=@@ROWCOUNT'
        INSERT INTO #tmp
        EXEC sp_executesql @sql,
        N'@RowsToProcess INT OUTPUT', @RowsToProcess OUTPUT

        SET @CurrentRow=0
        WHILE @CurrentRow<@RowsToProcess
        BEGIN
        SET @CurrentRow=@CurrentRow+1
        SET @m_obj_id =
        (SELECT col1
        FROM #tmp
        WHERE RowID=@CurrentRow)

        Do stuff....





        share|improve this answer













        I found a solution. Thanks everyone for responding.



        I used a temp table like



        DECLARE @RowsToProcess INTEGER
        DECLARE @CurrentRow INTEGER
        DECLARE @SelectCol1 INTEGER

        CREATE TABLE #tmp (RowID INTEGER NOT NULL PRIMARY KEY IDENTITY(1,1), col1 int)

        DECLARE @sql NVARCHAR(MAX)
        SET @sql = N'
        INSERT into #tmp (col1) SELECT id FROM ' + @table_name + ' Where ' + @where_clause + '
        SET @RowsToProcess=@@ROWCOUNT'
        INSERT INTO #tmp
        EXEC sp_executesql @sql,
        N'@RowsToProcess INT OUTPUT', @RowsToProcess OUTPUT

        SET @CurrentRow=0
        WHILE @CurrentRow<@RowsToProcess
        BEGIN
        SET @CurrentRow=@CurrentRow+1
        SET @m_obj_id =
        (SELECT col1
        FROM #tmp
        WHERE RowID=@CurrentRow)

        Do stuff....






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 21 '18 at 5:23









        CappydhCappydh

        115




        115






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53391923%2floop-with-dynamic-table-name-and-where-clause-stored-procedure%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

            Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

            A Topological Invariant for $pi_3(U(n))$