views:

594

answers:

2

I'm trying to execute the following line:

exit | sqlplus username/password@sid @test.sql

Works great from cmd but in powershell I get "An empty pipe element is not permitted"

Why is this and how do I fix it?

+3  A: 

Well, the exit command has no output, so there is nothing to pass down the pipe, hence you get an empty pipeline element. So while there is nothing to pipe into the other command the question is whether it actually should be executed at all.

Also, shell-builtins from cmd, such as exit, dir, etc. may work differently in Powershell. The Aliases are just there to help getting accustomed.

And fixing this is probably easy. Because there is nothing to pass down the pipeline your statement has no real meaning. You probably want to run

sqlplus username/password@sid @test.sql
exit

ETA: As your comment indicates an entirely different problem. You copied the command line from this answer wrong. If you want to send the text "exit" to the command later in the pipeline, you would need to output it in some way. This can be done in both cmd and Powershell with echo. So you shouldn't leave out the echo here:

echo exit | sqlplus username/password@sid @test.sql

Alternatively you can send "exit" directly as a string down the pipeline:

"exit" | sqlplus username/password@sid @test.sql
Joey
No, what I want is correct. See this post: http://stackoverflow.com/questions/118233/run-oracle-sql-script-and-exit-from-sqlplus-exe-via-command-prompt
George Mauer
Basically, when sqlplus is finished it looks at standard input and finds the exit command there and knows to exit. This is by far the simplest way I know of handling the situation where the script does not exit itself
George Mauer
Erm, you probably want to include the echo before exit ...
Joey
Interesting edit, though what I did worked in command prompt, I needed echo to make it work in powershell. strange
George Mauer
This may be one of the many weirdnesses of cmd. exit usually ends the cmd session, but in my testing apparently not when piped into another process. It worked because you get an implicit EOF at the end of the input when you pipe something into another process. So on that note echo.|sqlplus ... or <nul set /p foo=|sqlplus would work as well. The former emitting just an empty line, the latter emitting nothing.
Joey
oh...that makes sense. Strange sense but yeah.
George Mauer
+2  A: 

Strange question. According to the linked SO post and the Oracle documentation, it sounds like you're simply trying to return control to the script environment after SQLPlus has finished reading the file.

Unlike in CMD, 'exit' is not a language keyword; it's a directive to the script environment. (You can see for yourself by running 'gcm exit' -- won't find anything). So I'm not surprised this won't work.

Why not append an EOF character to the end of the input stream like the Oracle documentation suggests? On Windows this would be ^Z (Ctrl+Z, ASCII 0x1A). Or you can insert the text 'exit' if you really want.

Do so by modifying the file on disk, or reading the file into a stream and using the | operator -- whichever makes more sense for your situation.

edit: adding some example scripts per request in the comments

# add EOF to file on disk
[char]0x1a >> test.sql
sqlplus username/password@sid @test.sql

# add 'exit' to file on disk
'exit' >> test.sql
sqlplus username/password@sid @test.sql

# add 'exit' in-memory
# assumes sqlplus reads from stdin as shown in other examples; don't have Oracle to test
(gc test.sql) + 'exit' | sqlplus username/password@sid

# wrapper function
function Invoke-SqlPlus($file) { (gc $file) + 'exit' | sqlplus username/password@sid }
new-alias sql Invoke-SqlPlus
# usage
sql test.sql
Richard Berg
Indeed, I could do that but it is a lot of hassle for a simple automation! I would have to learn how to read files into memory, append to them, and then how to get that to play nice with sqlplus. Hopefully there is a way I can get this done in under 2 hours.
George Mauer
The < operator can't be used in Powershell. You would probably have to use Get-Content and a pipeline to redirect files to a program's standard input.
Joey
George: You can probably simply do [char]0x1a >> test.sql to get the EOF char at the end.
Joey
Thanks a lot for the example richard, quite handy
George Mauer