<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/automating-postgres-translations-with-database-migration-service-dpri0snjk" -->

---
title: Automating Postgres translations with Database Migration...
description: Google Cloud&#x27;s Database Migration Service (DMS) automates the conversion of SQL Server stored procedures with multiple result sets into PostgreSQL equivalents....
canonical: https://daily.dev/posts/automating-postgres-translations-with-database-migration-service-dpri0snjk
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Automating Postgres translations with Database Migration Service | daily.dev
og:description: Google Cloud&#x27;s Database Migration Service (DMS) automates the conversion of SQL Server stored procedures with multiple result sets into PostgreSQL equivalents....
og:url: https://daily.dev/posts/automating-postgres-translations-with-database-migration-service-dpri0snjk
og:image: https://api.daily.dev/og/posts/dpri0sNjk.png
og:image:alt: Automating Postgres translations with Database Migration Service
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Automating Postgres translations with Database Migration Service

**[Google Cloud](https://daily.dev/sources/gcp)** · 8 min read · 0 upvotes · 0 comments

## Summary

Google Cloud's Database Migration Service (DMS) automates the conversion of SQL Server stored procedures with multiple result sets into PostgreSQL equivalents. The post explains the core translation strategy: DMS analyzes how many result sets a procedure returns and whether it uses a scalar RETURN value, then maps procedures to either PostgreSQL PROCEDURE (single result set via INOUT refcursor) or FUNCTION returning SETOF refcursor (multiple/dynamic result sets). A healthcare reporting example illustrates the conversion of a master procedure and two child procedures. DMS builds a directed call graph and runs a Depth First Search to propagate result set counts across the entire procedure hierarchy. The post also covers how to execute and test migrated code within PostgreSQL transaction blocks, and how application layers must adapt to fetch data from named cursor portals instead of sequential tabular rows.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://cloud.google.com/blog/products/databases/automating-postgres-translations-with-database-migration-service>

## Questions this post answers

### How do I handle a SQL Server stored procedure with multiple result sets when migrating it to PostgreSQL?

Google Cloud's Database Migration Service converts such procedures into PL/pgSQL functions returning SETOF refcursor, opening one cursor per result set sequentially and, if the original procedure had a scalar RETURN value, appending a final cursor explicitly named 'return_value' to carry that integer back to the caller. Procedures with exactly one result set instead become PostgreSQL PROCEDUREs with an INOUT refcursor parameter.

_daily.dev surfaces practical migration playbooks for teams moving stored procedures from SQL Server to PostgreSQL._

### Why can't I fetch data from a PostgreSQL cursor returned by a function outside a transaction block?

PostgreSQL cursors are bound to the transaction lifecycle, so executing a function that opens refcursors and then fetching from those cursors must happen within a single BEGIN...COMMIT block. Running the SELECT that invokes the function and the subsequent FETCH ALL statements outside that transaction boundary will fail because the cursor's memory portal no longer exists.

_developers testing migrated postgresql procedures can track these transaction quirks through daily.dev._

### How does Database Migration Service decide how many result sets a SQL Server stored procedure returns when migrating to PostgreSQL?

DMS scans each procedure's body to count direct SELECT statements, marks any procedure containing looped or conditional SELECT/EXEC statements as returning a 'dynamic' count, and builds a directed graph of the entire call hierarchy between procedures. It then runs a depth-first search over that graph to propagate fixed or dynamic result set counts up through nested and recursive procedure calls to the top-level routine.

_engineers planning database migrations can follow deep technical breakdowns like this via daily.dev._

## Similar posts on daily.dev

- [Accelerate PostgreSQL Migrations with Gemini in DMS](https://daily.dev/posts/accelerate-postgresql-migrations-with-gemini-in-dms-v7jiyexlu) · Google Cloud · 1 upvotes · 0 comments
- [AWS DMS Schema Conversion adds SAP \(Sybase\) ASE to PostgreSQL support with generative AI](https://daily.dev/posts/aws-dms-schema-conversion-adds-sap-sybase-ase-to-postgresql-support-with-generative-ai-6kkcht1lf) · AWS · 1 upvotes · 0 comments
- [SQL Server to Aurora PostgreSQL conversion with AI agents for AWS DMS](https://daily.dev/posts/sql-server-to-aurora-postgresql-conversion-with-ai-agents-for-aws-dms-24wuiviyh) · AWS Database Blog · 0 upvotes · 0 comments
- [Provisioning DMS Schema Conversion via AWS CloudFormation](https://daily.dev/posts/provisioning-dms-schema-conversion-via-aws-cloudformation-oexr5ci3g) · AWS Database Blog · 0 upvotes · 0 comments

---

Tags: [#database](https://daily.dev/tags/database), [#postgresql](https://daily.dev/tags/postgresql), [#gcp](https://daily.dev/tags/gcp), [#microsoft-sql-server](https://daily.dev/tags/microsoft-sql-server)

[View this post on daily.dev](https://daily.dev/posts/automating-postgres-translations-with-database-migration-service-dpri0snjk)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Automating Postgres translations with Database Migration Service","url":"https://daily.dev/posts/automating-postgres-translations-with-database-migration-service-dpri0snjk","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/automating-postgres-translations-with-database-migration-service-dpri0snjk"},"datePublished":"2026-08-04T16:08:11.697Z","dateModified":"2026-09-14T06:28:56.769Z","description":"Google Cloud's Database Migration Service (DMS) automates the conversion of SQL Server stored procedures with multiple result sets into PostgreSQL equivalents....","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/34e913c42f16b8b7fc9afdb10d25ebd4?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/34e913c42f16b8b7fc9afdb10d25ebd4?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Google Cloud","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Google Cloud","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/gcp","url":"https://daily.dev/sources/gcp"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/automating-postgres-translations-with-database-migration-service-dpri0snjk","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"database,postgresql,gcp,microsoft-sql-server","timeRequired":"PT8M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Google Cloud","item":"https://daily.dev/sources/gcp"},{"@type":"ListItem","position":3,"name":"Automating Postgres translations with Database Migration Service"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/automating-postgres-translations-with-database-migration-service-dpri0snjk#faq","mainEntity":[{"@type":"Question","name":"How do I handle a SQL Server stored procedure with multiple result sets when migrating it to PostgreSQL?","acceptedAnswer":{"@type":"Answer","text":"Google Cloud's Database Migration Service converts such procedures into PL/pgSQL functions returning SETOF refcursor, opening one cursor per result set sequentially and, if the original procedure had a scalar RETURN value, appending a final cursor explicitly named 'return_value' to carry that integer back to the caller. Procedures with exactly one result set instead become PostgreSQL PROCEDUREs with an INOUT refcursor parameter. daily.dev surfaces practical migration playbooks for teams moving stored procedures from SQL Server to PostgreSQL."}},{"@type":"Question","name":"Why can't I fetch data from a PostgreSQL cursor returned by a function outside a transaction block?","acceptedAnswer":{"@type":"Answer","text":"PostgreSQL cursors are bound to the transaction lifecycle, so executing a function that opens refcursors and then fetching from those cursors must happen within a single BEGIN...COMMIT block. Running the SELECT that invokes the function and the subsequent FETCH ALL statements outside that transaction boundary will fail because the cursor's memory portal no longer exists. developers testing migrated postgresql procedures can track these transaction quirks through daily.dev."}},{"@type":"Question","name":"How does Database Migration Service decide how many result sets a SQL Server stored procedure returns when migrating to PostgreSQL?","acceptedAnswer":{"@type":"Answer","text":"DMS scans each procedure's body to count direct SELECT statements, marks any procedure containing looped or conditional SELECT/EXEC statements as returning a 'dynamic' count, and builds a directed graph of the entire call hierarchy between procedures. It then runs a depth-first search over that graph to propagate fixed or dynamic result set counts up through nested and recursive procedure calls to the top-level routine. engineers planning database migrations can follow deep technical breakdowns like this via daily.dev."}}]}
```

