{"id":1195,"date":"2024-01-24T13:48:17","date_gmt":"2024-01-24T13:48:17","guid":{"rendered":"https:\/\/markedcode.com\/?p=1195"},"modified":"2024-01-24T13:48:17","modified_gmt":"2024-01-24T13:48:17","slug":"x-stored-procedure-calls","status":"publish","type":"post","link":"https:\/\/markedcode.com\/index.php\/2024\/01\/24\/x-stored-procedure-calls\/","title":{"rendered":"X++ Stored Procedure Calls"},"content":{"rendered":"\n<p>In this article, we are going to look at how to create, drop, and executing stored procedures from X++ code. Using stored procedures can allow us to execute long running queries much faster than X++ logic alone.<\/p>\n\n\n\n<p>I recently saw a user accidentally created hundreds of thousands of records in the DocuRef table with blank notes. We wanted to create a batch job that would allow a user to select a number of notes to delete and have a stored procedure clean up that many records with blank notes.<\/p>\n\n\n\n<p>We were able to accomplish this with the following code. This batch job service class contains methods to drop, create, and execute stored procedures. Please use these as a reference and make the appropriate adjustments to meet your teams requirements.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/\/ &lt;summary&gt;\n\/\/\/ DocuRefCleanup\n\/\/\/ &lt;\/summary&gt;\npublic class DocuRefCleanupService\n{\n    str executeSPStatement()\n    {\n        str ret = @\"EXECUTE DocuRefCleanup\";\n        return ret;\n    }\n\n    str dropSPStatement()\n    {\n        str ret = @\"IF EXISTS(SELECT 1 FROM sys.procedures WHERE Name = 'DocuRefCleanup')\n            BEGIN\n                DROP PROCEDURE dbo.DocuRefCleanup\n            END\";\n        return ret;\n    }\n\n    str createSPStatement(int _numberOfRecordsToDelete)\n    {\n        str ret = @\"CREATE PROCEDURE [dbo].[DocuRefCleanup]\n            AS\n            BEGIN TRANSACTION\n                DELETE TOP (\" + int2Str(_numberOfRecordsToDelete) + @\") FROM DOCUREF where Notes is NULL and TYPEID = 'Note'\n            COMMIT TRANSACTION;\";\n        return ret;\n    }\n\n    void executeSQL(str _tSQL)\n    {\n        Connection connection = new Connection();\n        Statement statement = connection.createStatement();\n\n        SqlStatementExecutePermission permission;\n        permission = new SqlStatementExecutePermission(_tSQL);\n        permission.assert();\n        try\n        {\n            statement.executeUpdate(_tSQL);\n        }\n        catch\n        {\n            throw Error(\"@Label:DocuRefCleanupError\");\n        }\n        finally\n        {\n            CodeAccessPermission::revertAssert();\n\n            if (statement != null)\n            {\n                statement.close();\n            }\n        }\n    }\n\n    \/\/\/ &lt;summary&gt;\n    \/\/\/ Removes DocuRef records with blank notes\n    \/\/\/ &lt;\/summary&gt;\n    public void cleanupDocuRef(DocuRefCleanupContract _contract)\n    {\n        if (!_contract.parmNumberOfRecordsToDelete())\n        {\n            throw error(\"Missing parameter.\");\n        }\n\n        \/\/ Drop stored procedure if it exists\n        str statement = this.dropSPStatement();\n        this.executeSQL(statement);\n\n        \/\/ A new stored procedure will be create in AXDB &gt;&gt; Programmability &gt;&gt; StoredProcedures\n        statement = this.createSPStatement(_contract.parmNumberOfRecordsToDelete());\n        this.executeSQL(statement);\n\n        \/\/ Execute stored Procedure\n        statement = this.executeSPStatement();\n        this.executeSQL(statement);\n    }\n\n}\n<\/pre>\n\n\n\n<p>Keep reading about D365 tips and tricks here:&nbsp;<a href=\"https:\/\/markedcode.com\/index.php\/category\/d365\/\">https:\/\/markedcode.com\/index.php\/category\/d365\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, we are going to look at how to create, drop, and executing stored procedures from X++ code. Using stored procedures can allow us to execute long running queries much faster than X++ logic alone. I recently saw a user accidentally created hundreds of thousands of records in the DocuRef table with blank<\/p>\n","protected":false},"author":1,"featured_media":1197,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[7],"tags":[6,40,39,50],"class_list":{"0":"post-1195","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-d365","8":"tag-d365","9":"tag-db","10":"tag-ssms","11":"tag-x"},"_links":{"self":[{"href":"https:\/\/markedcode.com\/index.php\/wp-json\/wp\/v2\/posts\/1195","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/markedcode.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/markedcode.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/markedcode.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/markedcode.com\/index.php\/wp-json\/wp\/v2\/comments?post=1195"}],"version-history":[{"count":2,"href":"https:\/\/markedcode.com\/index.php\/wp-json\/wp\/v2\/posts\/1195\/revisions"}],"predecessor-version":[{"id":1198,"href":"https:\/\/markedcode.com\/index.php\/wp-json\/wp\/v2\/posts\/1195\/revisions\/1198"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/markedcode.com\/index.php\/wp-json\/wp\/v2\/media\/1197"}],"wp:attachment":[{"href":"https:\/\/markedcode.com\/index.php\/wp-json\/wp\/v2\/media?parent=1195"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/markedcode.com\/index.php\/wp-json\/wp\/v2\/categories?post=1195"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/markedcode.com\/index.php\/wp-json\/wp\/v2\/tags?post=1195"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}