diff --git a/convert.c b/convert.c
index 8802e6e..99ec4e5 100644
--- a/convert.c
+++ b/convert.c
@@ -4116,14 +4116,11 @@ inolog("ipara=%p paramType=%d %d proc_return=%d\n", ipara, ipara ? ipara->paramT
 		}
 		else if (!handling_large_object)
 		{
-			CVT_APPEND_CHAR(qb, '?');
-			return SQL_SUCCESS;
+			/* shouldn't happen */
+			qb->errormsg = "unexpected NULL parameter value";
+			qb->errornumber = STMT_EXEC_ERROR;
+			return SQL_ERROR;
 		}
-
-		/* shouldn't happen */
-		qb->errormsg = "unexpected NULL parameter value";
-		qb->errornumber = STMT_EXEC_ERROR;
-		return SQL_ERROR;
 	}
 
 	/* replace DEFAULT with something we can use */
diff --git a/test/expected/large-object-data-at-exec.out b/test/expected/large-object-data-at-exec.out
new file mode 100644
index 0000000..e69de29
diff --git a/test/src/large-object-data-at-exec-test.c b/test/src/large-object-data-at-exec-test.c
new file mode 100644
index 0000000..585e102
--- /dev/null
+++ b/test/src/large-object-data-at-exec-test.c
@@ -0,0 +1,160 @@
+/*
+ * Test data-at-execution, for a large object.
+ */
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "common.h"
+
+static void
+printhex(unsigned char *b, int len)
+{
+	int i;
+
+	printf("hex: ");
+	for (i = 0; i < len; i++)
+		printf("%02X", b[i]);
+}
+
+#define CHECK_STMT_RESULT2(rc, msg, hstmt)\
+    if (SQL_SUCCESS != rc && SQL_SUCCESS_WITH_INFO != rc && SQL_NEED_DATA != rc) \
+    { \
+        print_diag(msg, SQL_HANDLE_STMT, hstmt);\
+        exit(1);\
+    }
+
+
+/*
+ * Insert a large object to table, using a data-at-exec param. Then read it
+ * back and print.
+ */
+static void
+do_test(HSTMT hstmt, int testno, int lobByteSize, char *lobData)
+{
+	char		sql[200];
+	int			rc;
+	SQLLEN		cbParam1;
+	char		*buf;
+	SQLLEN		ind;
+
+	/**** Insert a Large Object */
+	printf("inserting large object with len %d...\n", lobByteSize);
+	snprintf(sql, sizeof(sql),
+			 "INSERT INTO lo_test_tab VALUES (%d, ?)", testno);
+	rc = SQLPrepare(hstmt, (SQLCHAR *) sql, SQL_NTS);
+	CHECK_STMT_RESULT(rc, "SQLPrepare failed", hstmt);
+
+	/* bind LO param as a data at execution parameter */
+	cbParam1 = SQL_DATA_AT_EXEC;
+	rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT,
+						  SQL_C_BINARY,	/* value type */
+						  SQL_LONGVARBINARY,	/* param type */
+						  0,			/* column size */
+						  0,			/* dec digits */
+						  lobData,		/* param value ptr */
+						  0,			/* buffer len */
+						  &cbParam1		/* StrLen_or_IndPtr */);
+	CHECK_STMT_RESULT(rc, "SQLBindParameter failed", hstmt);
+
+	/* Execute */
+	rc = SQLExecute(hstmt);
+	CHECK_STMT_RESULT2(rc, "SQLExecute failed", hstmt);
+
+    /* Check for data-at-execute parameters */
+    if (SQL_NEED_DATA == rc)
+    {
+        SQLLEN lobChunkSize = 4096;
+        SQLPOINTER pParamId = 0;
+        const char *what = 0;
+
+        /* Get the parameter that needs data */
+        what = "SQLParamData failed (first call)";
+        rc = SQLParamData(hstmt, &pParamId);  
+        int error = SQL_SUCCESS != rc && SQL_SUCCESS_WITH_INFO != rc && SQL_NEED_DATA != rc;
+        if (SQL_NEED_DATA == rc)
+        {
+            /* Send parameter data in chunks */
+            what = "SQLPutData failed (next chunk)";
+            while (!error && lobByteSize > lobChunkSize)
+            {
+                rc = SQLPutData(hstmt, (SQLPOINTER)pParamId, lobChunkSize);
+                lobByteSize -= lobChunkSize;
+                error = SQL_SUCCESS != rc && SQL_SUCCESS_WITH_INFO != rc && SQL_NEED_DATA != rc;
+            }
+            
+            /* Send final chunk */
+            if (!error)
+            {
+                what = "SQLPutData failed (final chunk)";
+                rc = SQLPutData(hstmt, (SQLPOINTER)pParamId, lobByteSize);
+                error = SQL_SUCCESS != rc && SQL_SUCCESS_WITH_INFO != rc && SQL_NEED_DATA != rc;
+            }
+
+            /* Make final call */
+            if (!error)
+            {
+                what = "SQLParamData failed (final call)";
+                rc = SQLParamData(hstmt, &pParamId);
+                error = SQL_SUCCESS != rc && SQL_SUCCESS_WITH_INFO != rc;
+            }
+        }
+        CHECK_STMT_RESULT(rc, (char*)what, hstmt);
+    }
+
+	rc = SQLFreeStmt(hstmt, SQL_CLOSE);
+	CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
+
+	/**** Read it back ****/
+	printf("reading it back...\n");
+
+	snprintf(sql, sizeof(sql),
+			 "SELECT id, large_data FROM lo_test_tab WHERE id = %d", testno);
+	SQLExecDirect(hstmt, (SQLCHAR *) sql, SQL_NTS);
+	rc = SQLFetch(hstmt);
+	CHECK_STMT_RESULT(rc, "SQLFetch failed", hstmt);
+
+	buf = malloc(lobByteSize * 2);
+	rc = SQLGetData(hstmt, 2, SQL_C_BINARY, buf, lobByteSize * 2, &ind);
+	CHECK_STMT_RESULT(rc, "SQLGetData failed", hstmt);
+
+	printhex(buf, ind);
+	printf("\n");
+
+	free(buf);
+
+	rc = SQLFreeStmt(hstmt, SQL_CLOSE);
+	CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
+}
+
+int
+main(int argc, char **argv)
+{
+	int			rc;
+	HSTMT		hstmt = SQL_NULL_HSTMT;
+	char		param1[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+	char		param2[100];
+	int			i;
+
+	test_connect();
+
+	rc = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
+	if (!SQL_SUCCEEDED(rc))
+	{
+		print_diag("failed to allocate stmt handle", SQL_HANDLE_DBC, conn);
+		exit(1);
+	}
+
+	do_test(hstmt, 101, sizeof(param1), param1);
+
+	for (i = 0; i < sizeof(param2); i++)
+	{
+		param2[i] = i % 200;
+	}
+	do_test(hstmt, 102, sizeof(param2), param2);
+
+	/* Clean up */
+	test_disconnect();
+
+	return 0;
+}
diff --git a/test/tests b/test/tests
index e908771..eff409f 100644
--- a/test/tests
+++ b/test/tests
@@ -8,6 +8,7 @@
 # to each name in a list, but it's easy to strip them away.
 
 TESTBINS = src/connect-test \
+	src/large-object-data-at-exec-test \
 	src/stmthandles-test \
 	src/select-test \
 	src/update-test \
